Horde_Ldap::_connect PHP Метод

_connect() защищенный Метод

This function connects to the LDAP server specified in the configuration, binds and set up the LDAP protocol as needed.
protected _connect ( )
    protected function _connect()
    {
        /* Connecting is briefly described in RFC1777. Basicly it works like
         * this:
         *  1. set up TCP connection
         *  2. secure that connection if neccessary
         *  3a. setVersion to tell server which version we want to speak
         *  3b. perform bind
         *  3c. setVersion to tell server which version we want to speak
         *      together with a test for supported versions
         *  4. set additional protocol options */
        /* Return if we are already connected. */
        if ($this->_link) {
            return;
        }
        /* Connnect to the LDAP server if we are not connected.  Note that
         * ldap_connect() may return a link value even if no connection is
         * made.  We need to do at least one anonymous bind to ensure that a
         * connection is actually valid.
         *
         * See: http://www.php.net/manual/en/function.ldap-connect.php */
        /* Default error message in case all connection attempts fail but no
         * message is set. */
        $current_error = new Horde_Ldap_Exception('Unknown connection error');
        /* Catch empty $_hostList arrays. */
        if (!is_array($this->_hostList) || !count($this->_hostList)) {
            throw new Horde_Ldap_Exception('No servers configured');
        }
        /* Cycle through the host list. */
        foreach ($this->_hostList as $host) {
            /* Ensure we have a valid string for host name. */
            if (is_array($host)) {
                $current_error = new Horde_Ldap_Exception('No Servers configured');
                continue;
            }
            /* Skip this host if it is known to be down. */
            if (in_array($host, $this->_downHostList)) {
                continue;
            }
            /* Record the host that we are actually connecting to in case we
             * need it later. */
            $this->_config['hostspec'] = $host;
            /* The ldap extension doesn't allow to provide connection timeouts
             * and seems to default to 2 minutes. Open a socket manually
             * instead to ping the server. */
            $failed = true;
            $url = @parse_url($host);
            $sockhost = !empty($url['host']) ? $url['host'] : $host;
            if ($fp = @fsockopen($sockhost, $this->_config['port'], $errno, $errstr, $this->_config['timeout'])) {
                $failed = false;
                fclose($fp);
            }
            /* Attempt a connection. */
            if (!$failed) {
                $this->_link = @ldap_connect($host, $this->_config['port']);
            }
            if (!$this->_link) {
                $current_error = new Horde_Ldap_Exception('Could not connect to ' . $host . ':' . $this->_config['port']);
                $this->_downHostList[] = $host;
                continue;
            }
            /* If we're supposed to use TLS, do so before we try to bind, as
             * some strict servers only allow binding via secure
             * connections. */
            if ($this->_config['tls']) {
                try {
                    $this->startTLS();
                } catch (Horde_Ldap_Exception $e) {
                    $current_error = $e;
                    $this->_link = false;
                    $this->_downHostList[] = $host;
                    continue;
                }
            }
            /* Try to set the configured LDAP version on the connection if LDAP
             * server needs that before binding (eg OpenLDAP).
             * This could be necessary since RFC 1777 states that the protocol
             * version has to be set at the bind request.
             * We use force here which means that the test in the rootDSE is
             * skipped; this is neccessary, because some strict LDAP servers
             * only allow to read the LDAP rootDSE (which tells us the
             * supported protocol versions) with authenticated clients.
             * This may fail in which case we try again after binding.
             * In this case, most probably the bind() or setVersion() call
             * below will also fail, providing error messages. */
            $version_set = false;
            $this->setVersion(0, true);
            /* Attempt to bind to the server. If we have credentials
             * configured, we try to use them, otherwise it's an anonymous
             * bind.
             * As stated by RFC 1777, the bind request should be the first
             * operation to be performed after the connection is established.
             * This may give an protocol error if the server does not support
             * v2 binds and the above call to setVersion() failed.
             * If the above call failed, we try an v2 bind here and set the
             * version afterwards (with checking to the rootDSE). */
            try {
                $this->bind();
            } catch (Exception $e) {
                /* The bind failed, discard link and save error msg.
                 * Then record the host as down and try next one. */
                if ($this->errorName($e->getCode()) == 'LDAP_PROTOCOL_ERROR' && !$version_set) {
                    /* Provide a finer grained error message if protocol error
                     * arises because of invalid version. */
                    $e = new Horde_Ldap_Exception($e->getMessage() . ' (could not set LDAP protocol version to ' . $this->_config['version'] . ')', $e->getCode());
                }
                $this->_link = false;
                $current_error = $e;
                $this->_downHostList[] = $host;
                continue;
            }
            /* Set desired LDAP version if not successfully set before.
             * Here, a check against the rootDSE is performed, so we get a
             * error message if the server does not support the version.
             * The rootDSE entry should tell us which LDAP versions are
             * supported. However, some strict LDAP servers only allow
             * bound users to read the rootDSE. */
            if (!$version_set) {
                try {
                    $this->setVersion();
                } catch (Exception $e) {
                    $current_error = $e;
                    $this->_link = false;
                    $this->_downHostList[] = $host;
                    continue;
                }
            }
            /* Set LDAP parameters, now that we know we have a valid
             * connection. */
            if (isset($this->_config['options']) && is_array($this->_config['options']) && count($this->_config['options'])) {
                foreach ($this->_config['options'] as $opt => $val) {
                    try {
                        $this->setOption($opt, $val);
                    } catch (Exception $e) {
                        $current_error = $e;
                        $this->_link = false;
                        $this->_downHostList[] = $host;
                        continue 2;
                    }
                }
            }
            /* At this stage we have connected, bound, and set up options, so
             * we have a known good LDAP server.  Time to go home. */
            return;
        }
        /* All connection attempts have failed, return the last error. */
        throw $current_error;
    }