| | |
| | | |
| | | /* |
| | | +-----------------------------------------------------------------------+ |
| | | | program/include/rcube_ldap.php | |
| | | | | |
| | | | This file is part of the Roundcube Webmail client | |
| | | | Copyright (C) 2006-2012, The Roundcube Dev Team | |
| | | | Copyright (C) 2011-2012, Kolab Systems AG | |
| | |
| | | | | |
| | | | PURPOSE: | |
| | | | Interface to an LDAP address directory | |
| | | | | |
| | | +-----------------------------------------------------------------------+ |
| | | | Author: Thomas Bruederli <roundcube@gmail.com> | |
| | | | Andreas Dick <andudi (at) gmx (dot) ch> | |
| | | | Aleksander Machniak <machniak@kolabsys.com> | |
| | | +-----------------------------------------------------------------------+ |
| | | */ |
| | | |
| | | |
| | | /** |
| | | * Model class to access an LDAP address directory |
| | |
| | | if (empty($this->prop['ldap_version'])) |
| | | $this->prop['ldap_version'] = 3; |
| | | |
| | | foreach ($this->prop['hosts'] as $host) |
| | | { |
| | | // try to connect + bind for every host configured |
| | | // with OpenLDAP 2.x ldap_connect() always succeeds but ldap_bind will fail if host isn't reachable |
| | | // see http://www.php.net/manual/en/function.ldap-connect.php |
| | | foreach ($this->prop['hosts'] as $host) { |
| | | $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host)); |
| | | $hostname = $host.($this->prop['port'] ? ':'.$this->prop['port'] : ''); |
| | | |
| | | $this->_debug("C: Connect [$hostname] [{$this->prop['name']}]"); |
| | | |
| | | if ($lc = @ldap_connect($host, $this->prop['port'])) |
| | | { |
| | | if ($lc = @ldap_connect($host, $this->prop['port'])) { |
| | | if ($this->prop['use_tls'] === true) |
| | | if (!ldap_start_tls($lc)) |
| | | continue; |
| | |
| | | $this->prop['host'] = $host; |
| | | $this->conn = $lc; |
| | | |
| | | if (!empty($this->prop['network_timeout'])) |
| | | ldap_set_option($lc, LDAP_OPT_NETWORK_TIMEOUT, $this->prop['network_timeout']); |
| | | |
| | | if (isset($this->prop['referrals'])) |
| | | ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->prop['referrals']); |
| | | break; |
| | | } |
| | | else { |
| | | $this->_debug("S: NOT OK"); |
| | | continue; |
| | | } |
| | | |
| | | // See if the directory is writeable. |
| | | if ($this->prop['writable']) { |
| | | $this->readonly = false; |
| | | } |
| | | |
| | | if (!is_resource($this->conn)) { |
| | | rcube::raise_error(array('code' => 100, 'type' => 'ldap', |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | | 'message' => "Could not connect to any LDAP server, last tried $hostname"), true); |
| | | |
| | | return false; |
| | | } |
| | | |
| | | $bind_pass = $this->prop['bind_pass']; |
| | |
| | | else { |
| | | $this->ready = $this->sasl_bind($bind_user, $bind_pass); |
| | | } |
| | | } |
| | | |
| | | // connection established, we're done here |
| | | if ($this->ready) { |
| | | break; |
| | | } |
| | | |
| | | } // end foreach hosts |
| | | |
| | | if (!is_resource($this->conn)) { |
| | | rcube::raise_error(array('code' => 100, 'type' => 'ldap', |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | | 'message' => "Could not connect to any LDAP server, last tried $hostname"), true); |
| | | |
| | | return false; |
| | | } |
| | | |
| | | return $this->ready; |
| | |
| | | $rec = $this->_ldap2result($entries[$i]); |
| | | foreach ($fields as $f) { |
| | | foreach ((array)$rec[$f] as $val) { |
| | | $val = mb_strtolower($val); |
| | | switch ($mode) { |
| | | case 1: |
| | | $got = ($val == $search); |
| | | break; |
| | | case 2: |
| | | $got = ($search == substr($val, 0, strlen($search))); |
| | | break; |
| | | default: |
| | | $got = (strpos($val, $search) !== false); |
| | | break; |
| | | } |
| | | |
| | | if ($got) { |
| | | if ($this->compare_search_value($f, $val, $search, $mode)) { |
| | | $this->result->add($rec); |
| | | $this->result->count++; |
| | | break 2; |
| | |
| | | if ($this->vlv_active && function_exists('ldap_parse_virtuallist_control')) { |
| | | if (ldap_parse_result($this->conn, $this->ldap_result, |
| | | $errcode, $matcheddn, $errmsg, $referrals, $serverctrls) |
| | | && $serverctrls // can be null e.g. in case of adm. limit error |
| | | ) { |
| | | ldap_parse_virtuallist_control($this->conn, $serverctrls, |
| | | $last_offset, $this->vlv_count, $vresult); |