Thomas Bruederli
2013-01-23 e114a6040606afabf84f11651a040cef30bc55a2
Use LDAP fallback hosts on connect + bind because with OpenLDAP 2.x ldap_connect() always succeeds but ldap_bind() will fail if host isn't reachable.
Add option for LDAP bind timeout (sets LDAP_OPT_NETWORK_TIMEOUT on PHP > 5.3.0)
2 files modified
39 ■■■■■ changed files
config/main.inc.php.dist 1 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_ldap.php 38 ●●●●● patch | view | raw | blame | history
config/main.inc.php.dist
@@ -577,6 +577,7 @@
  'port'          => 389,
  '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.
  // %fu - The full username provided, assumes the username is an email
  //       address, uses the username_domain value if not an email address.
program/lib/Roundcube/rcube_ldap.php
@@ -214,15 +214,16 @@
        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;
@@ -233,24 +234,20 @@
                $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'];
@@ -342,6 +339,21 @@
            }
        }
            // 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;
    }