From c5a5f989a9bf91927e6bb627f9f789800ce02fad Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Fri, 1 Feb 2013 15:24:33 +0100 Subject: Allow to list contact groups in (paged) list (yet incomplete) --- config/main.inc.php.dist | 1 + 1 file changed, 1 insertion(+) (limited to 'config') diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index b113b41a8..d4246a001 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -680,6 +680,7 @@ $rcmail_config['ldap_public']['Verisign'] = array( 'object_classes' => array("top", "groupOfNames"), 'member_attr' => 'member', // name of the member attribute, e.g. uniqueMember 'name_attr' => 'cn', // attribute to be used as group name + 'member_filter' => '(objectclass=*)', // optional filter to use when querying for group members ), ); */ -- cgit v1.2.3 From e43cc4bd9d6c99f8737ee8a316c21ba3a0dbd04a Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Thu, 7 Feb 2013 17:49:05 +0100 Subject: Describe the new option 'group_filters' in the sample config block --- config/main.inc.php.dist | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'config') diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index d4246a001..e0b6807e5 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -636,6 +636,7 @@ $rcmail_config['ldap_public']['Verisign'] = array( 'phone:work' => 'telephoneNumber', 'phone:mobile' => 'mobile', 'phone:pager' => 'pager', + 'phone:workfax' => 'facsimileTelephoneNumber', 'street' => 'street', 'zipcode' => 'postalCode', 'region' => 'st', @@ -646,9 +647,8 @@ $rcmail_config['ldap_public']['Verisign'] = array( 'department' => 'ou', 'jobtitle' => 'title', 'notes' => 'description', + 'photo' => 'jpegPhoto', // these currently don't work: - // 'phone:workfax' => 'facsimileTelephoneNumber', - // 'photo' => 'jpegPhoto', // 'manager' => 'manager', // 'assistant' => 'secretary', ), @@ -682,6 +682,23 @@ $rcmail_config['ldap_public']['Verisign'] = array( 'name_attr' => 'cn', // attribute to be used as group name 'member_filter' => '(objectclass=*)', // optional filter to use when querying for group members ), + // this configuration replaces the regular groups listing in the directory tree with + // a hard-coded list of groups, each listing entries with the configured base DN and filter. + // if the 'groups' option from above is set, it'll be shown as the first entry with the name 'Groups' + 'group_filters' => array( + 'departments' => array( + 'name' => 'Company Departments', + 'scope' => 'list', + 'base_dn' => 'ou=Groups,dc=mydomain,dc=com', + 'filter' => '(|(objectclass=groupofuniquenames)(objectclass=groupofurls))', + ), + 'customers' => array( + 'name' => 'Customers', + 'scope' => 'sub', + 'base_dn' => 'ou=Customers,dc=mydomain,dc=com', + 'filter' => '(objectClass=inetOrgPerson)', + ), + ), ); */ -- cgit v1.2.3 From a6d4185a896a721a16c9cad4518687474c939d8b Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Wed, 13 Feb 2013 18:08:20 +0100 Subject: Describe new options for LDAP address books --- config/main.inc.php.dist | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'config') diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index e0b6807e5..543bdb6dc 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -659,28 +659,31 @@ $rcmail_config['ldap_public']['Verisign'] = array( // 'uid' => 'md5(microtime())', // You may specify PHP code snippets which are then eval'ed // 'mail' => '{givenname}.{sn}@mydomain.com', // or composite strings with placeholders for existing attributes ), - 'sort' => 'cn', // The field to sort the listing by. - 'scope' => 'sub', // search mode: sub|base|list - 'filter' => '(objectClass=inetOrgPerson)', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act - 'fuzzy_search' => true, // server allows wildcard search - 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it) - 'numsub_filter' => '(objectClass=organizationalUnit)', // with VLV, we also use numSubOrdinates to query the total number of records. Set this filter to get all numSubOrdinates attributes for counting - 'sizelimit' => '0', // Enables you to limit the count of entries fetched. Setting this to 0 means no limit. - 'timelimit' => '0', // Sets the number of seconds how long is spend on the search. Setting this to 0 means no limit. - 'referrals' => true|false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups + 'sort' => 'cn', // The field to sort the listing by. + 'scope' => 'sub', // search mode: sub|base|list + 'filter' => '(objectClass=inetOrgPerson)', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act + 'fuzzy_search' => true, // server allows wildcard search + 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it) + 'vlv_search' => false, // Use Virtual List View functions for autocompletion searches (if server supports it) + 'numsub_filter' => '(objectClass=organizationalUnit)', // with VLV, we also use numSubOrdinates to query the total number of records. Set this filter to get all numSubOrdinates attributes for counting + 'config_root_dn' => 'cn=config', // Root DN to search config entries (e.g. vlv indexes) + 'sizelimit' => '0', // Enables you to limit the count of entries fetched. Setting this to 0 means no limit. + 'timelimit' => '0', // Sets the number of seconds how long is spend on the search. Setting this to 0 means no limit. + 'referrals' => false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups // definition for contact groups (uncomment if no groups are supported) // for the groups base_dn, the user replacements %fu, %u, $d and %dc work as for base_dn (see above) // if the groups base_dn is empty, the contact base_dn is used for the groups as well // -> in this case, assure that groups and contacts are separated due to the concernig filters! - 'groups' => array( - 'base_dn' => '', - 'scope' => 'sub', // search mode: sub|base|list - 'filter' => '(objectClass=groupOfNames)', + 'groups' => array( + 'base_dn' => '', + 'scope' => 'sub', // Search mode: sub|base|list + 'filter' => '(objectClass=groupOfNames)', 'object_classes' => array("top", "groupOfNames"), - 'member_attr' => 'member', // name of the member attribute, e.g. uniqueMember - 'name_attr' => 'cn', // attribute to be used as group name - 'member_filter' => '(objectclass=*)', // optional filter to use when querying for group members + 'member_attr' => 'member', // Name of the member attribute, e.g. uniqueMember + 'name_attr' => 'cn', // Attribute to be used as group name + 'member_filter' => '(objectclass=*)', // Optional filter to use when querying for group members + 'vlv' => false, // Use VLV controls to list groups ), // this configuration replaces the regular groups listing in the directory tree with // a hard-coded list of groups, each listing entries with the configured base DN and filter. -- cgit v1.2.3 From c64beed6bb31c697459290484a256cd83b377922 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 18 Jun 2013 18:10:04 +0200 Subject: Unify LDAP debug messages --- config/main.inc.php.dist | 2 +- program/lib/Roundcube/rcube_ldap.php | 8 +++---- program/lib/Roundcube/rcube_ldap_generic.php | 34 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 23 deletions(-) (limited to 'config') diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index 5c1bb1a07..1b73dd46a 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -590,7 +590,7 @@ $rcmail_config['ldap_public']['Verisign'] = array( // For example %n = mail.domain.tld, %t = domain.tld 'hosts' => array('directory.verisign.com'), 'port' => 389, - 'use_tls' => false, + 'use_tls' => false, 'ldap_version' => 3, // using LDAPv3 'network_timeout' => 10, // The timeout (in seconds) for connect + bind arrempts. This is only supported in PHP >= 5.3.0 with OpenLDAP 2.x 'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login. diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php index ca50b6056..ef7e1b32d 100644 --- a/program/lib/Roundcube/rcube_ldap.php +++ b/program/lib/Roundcube/rcube_ldap.php @@ -55,7 +55,7 @@ class rcube_ldap extends rcube_addressbook /** * Object constructor * - * @param array $p LDAP connection properties + * @param array $p LDAP connection properties * @param boolean $debug Enables debug mode * @param string $mail_domain Current user mail domain name */ @@ -274,7 +274,7 @@ class rcube_ldap extends rcube_addressbook $this->prop['search_base_dn'] = strtr($this->prop['search_base_dn'], $replaces); $this->prop['search_filter'] = strtr($this->prop['search_filter'], $replaces); - $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}"); + $this->_debug("S: Search {$this->prop['search_base_dn']} for {$this->prop['search_filter']}"); // TODO: use $this->ldap->search() here $res = @ldap_search($this->ldap->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid')); @@ -282,7 +282,7 @@ class rcube_ldap extends rcube_addressbook if (($entry = ldap_first_entry($this->ldap->conn, $res)) && ($bind_dn = ldap_get_dn($this->ldap->conn, $entry)) ) { - $this->_debug("S: search returned dn: $bind_dn"); + $this->_debug("S: OK. Found $bind_dn"); $dn = ldap_explode_dn($bind_dn, 1); $replaces['%dn'] = $dn[0]; } @@ -523,7 +523,6 @@ class rcube_ldap extends rcube_addressbook // fetch group object if (empty($entries)) { - $this->_debug("C: Read Group [dn: $dn]"); $entries = $this->ldap->read_entries($dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL')); if ($entries === false) { return $group_members; @@ -1623,7 +1622,6 @@ class rcube_ldap extends rcube_addressbook $name_attr = $this->prop['groups']['name_attr']; $dn = self::dn_decode($group_id); - $this->_debug("C: Read Group [dn: $dn]"); if ($list = $this->ldap->read_entries($dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL',$name_attr,$this->fieldmap['email']))) { $entry = $list[0]; $group_name = is_array($entry[$name_attr]) ? $entry[$name_attr][0] : $entry[$name_attr]; diff --git a/program/lib/Roundcube/rcube_ldap_generic.php b/program/lib/Roundcube/rcube_ldap_generic.php index 651e524db..d79c1303d 100644 --- a/program/lib/Roundcube/rcube_ldap_generic.php +++ b/program/lib/Roundcube/rcube_ldap_generic.php @@ -176,7 +176,7 @@ class rcube_ldap_generic $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host)); $hostname = $host . ($this->config['port'] ? ':'.$this->config['port'] : ''); - $this->_debug("C: Connect [$hostname] [{$this->config['name']}]"); + $this->_debug("C: Connect to $hostname [{$this->config['name']}]"); if ($lc = @ldap_connect($host, $this->config['port'])) { if ($this->config['use_tls'] === true) @@ -245,7 +245,7 @@ class rcube_ldap_generic $method = 'DIGEST-MD5'; } - $this->_debug("C: Bind [mech: $method, authc: $authc, authz: $authz] [pass: $pass]"); + $this->_debug("C: SASL Bind [mech: $method, authc: $authc, authz: $authz, pass: $pass]"); if (ldap_sasl_bind($this->conn, NULL, $pass, $method, NULL, $authc, $authz)) { $this->_debug("S: OK"); @@ -277,7 +277,7 @@ class rcube_ldap_generic return false; } - $this->_debug("C: Bind [dn: $dn] [pass: $pass]"); + $this->_debug("C: Bind $dn [pass: $pass]"); if (@ldap_bind($this->conn, $dn, $pass)) { $this->_debug("S: OK"); @@ -331,7 +331,7 @@ class rcube_ldap_generic $rec = null; if ($this->conn && $dn) { - $this->_debug("C: Read [dn: $dn] [(objectclass=*)]"); + $this->_debug("C: Read $dn [(objectclass=*)]"); if ($ldap_result = @ldap_read($this->conn, $dn, '(objectclass=*)', $this->attributes)) { $this->_debug("S: OK"); @@ -373,7 +373,7 @@ class rcube_ldap_generic if (empty($filter)) $filter = $filter = '(objectclass=*)'; - $this->_debug("C: Search [$filter][dn: $base_dn]"); + $this->_debug("C: Search $base_dn for $filter"); $function = self::scope2func($scope, $ns_function); @@ -450,7 +450,7 @@ class rcube_ldap_generic */ public function add($dn, $entry) { - $this->_debug("C: Add [dn: $dn]: ".print_r($entry, true)); + $this->_debug("C: Add $dn: ".print_r($entry, true)); $res = ldap_add($this->conn, $dn, $entry); if ($res === false) { @@ -469,7 +469,7 @@ class rcube_ldap_generic */ public function delete($dn) { - $this->_debug("C: Delete [dn: $dn]"); + $this->_debug("C: Delete $dn"); $res = ldap_delete($this->conn, $dn); if ($res === false) { @@ -488,7 +488,7 @@ class rcube_ldap_generic */ public function mod_replace($dn, $entry) { - $this->_debug("C: Replace [dn: $dn]: ".print_r($entry, true)); + $this->_debug("C: Replace $dn: ".print_r($entry, true)); if (!ldap_mod_replace($this->conn, $dn, $entry)) { $this->_debug("S: ".ldap_error($this->conn)); @@ -506,7 +506,7 @@ class rcube_ldap_generic */ public function mod_add($dn, $entry) { - $this->_debug("C: Add [dn: $dn]: ".print_r($entry, true)); + $this->_debug("C: Add $dn: ".print_r($entry, true)); if (!ldap_mod_add($this->conn, $dn, $entry)) { $this->_debug("S: ".ldap_error($this->conn)); @@ -524,7 +524,7 @@ class rcube_ldap_generic */ public function mod_del($dn, $entry) { - $this->_debug("C: Delete [dn: $dn]: ".print_r($entry, true)); + $this->_debug("C: Delete $dn: ".print_r($entry, true)); if (!ldap_mod_del($this->conn, $dn, $entry)) { $this->_debug("S: ".ldap_error($this->conn)); @@ -542,7 +542,7 @@ class rcube_ldap_generic */ public function rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true) { - $this->_debug("C: Rename [dn: $dn] [dn: $newrdn]"); + $this->_debug("C: Rename $dn to $newrdn"); if (!ldap_rename($this->conn, $dn, $newrdn, $newparent, $deleteoldrdn)) { $this->_debug("S: ".ldap_error($this->conn)); @@ -562,7 +562,7 @@ class rcube_ldap_generic public function list_entries($dn, $filter, $attributes = array('dn')) { $list = array(); - $this->_debug("C: List [dn: $dn] [{$filter}]"); + $this->_debug("C: List $dn [{$filter}]"); if ($result = ldap_list($this->conn, $dn, $filter, $attributes)) { $list = ldap_get_entries($this->conn, $result); @@ -592,7 +592,7 @@ class rcube_ldap_generic */ public function read_entries($dn, $filter, $attributes = null) { - $this->_debug("C: Read [dn: $dn] [{$filter}]"); + $this->_debug("C: Read $dn [{$filter}]"); if ($this->conn && $dn) { if (!$attributes) @@ -737,7 +737,7 @@ class rcube_ldap_generic $sort_ctrl = array('oid' => "1.2.840.113556.1.4.473", 'value' => self::_sort_ber_encode((array)$sort)); $vlv_ctrl = array('oid' => "2.16.840.1.113730.3.4.9", 'value' => self::_vlv_ber_encode(($offset = ($list_page-1) * $page_size + 1), $page_size, $search), 'iscritical' => true); - $this->_debug("C: set controls sort=" . join(' ', unpack('H'.(strlen($sort_ctrl['value'])*2), $sort_ctrl['value'])) . " ($sort[0]);" + $this->_debug("C: Set controls sort=" . join(' ', unpack('H'.(strlen($sort_ctrl['value'])*2), $sort_ctrl['value'])) . " ($sort[0]);" . " vlv=" . join(' ', (unpack('H'.(strlen($vlv_ctrl['value'])*2), $vlv_ctrl['value']))) . " ($offset/$page_size; $search)"); if (!ldap_set_option($this->conn, LDAP_OPT_SERVER_CONTROLS, array($sort_ctrl, $vlv_ctrl))) { @@ -839,7 +839,7 @@ class rcube_ldap_generic $vlv_config = $this->_read_vlv_config(); if ($vlv = $vlv_config[$base_dn]) { - $this->_debug("D: Found a VLV for base_dn: " . $base_dn); + $this->_debug("D: Found a VLV for $base_dn"); if ($vlv['filter'] == strtolower($filter) || stripos($filter, '(&'.$vlv['filter'].'(') === 0) { $this->_debug("D: Filter matches"); @@ -858,7 +858,7 @@ class rcube_ldap_generic } } else { - $this->_debug("D: No VLV for base dn " . $base_dn); + $this->_debug("D: No VLV for $base_dn"); } return false; @@ -883,7 +883,7 @@ class rcube_ldap_generic if (is_array($this->vlv_config)) { return $this->vlv_config; } - + if ($this->cache && ($cached_config = $this->cache->get('vlvconfig'))) { $this->vlv_config = $cached_config; return $this->vlv_config; -- cgit v1.2.3