ldap.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 389 行

PHP
389
字号
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +--------------------------------------------------------------------------+
// | Net_LDAP                                                                 |
// +--------------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group                                    |
// +--------------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or            |
// | modify it under the terms of the GNU Lesser General Public               |
// | License as published by the Free Software Foundation; either             |
// | version 2.1 of the License, or (at your option) any later version.       |
// |                                                                          |
// | This library is distributed in the hope that it will be useful,          |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of           |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        |
// | Lesser General Public License for more details.                          |
// |                                                                          |
// | You should have received a copy of the GNU Lesser General Public         |
// | License along with this library; if not, write to the Free Software      |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA |
// +--------------------------------------------------------------------------+
// | Authors: Tarjej Huse                                                     |
// |          Jan Wagner                                                      |
// +--------------------------------------------------------------------------+
//
// $Id: LDAP.php 8112 2008-02-21 08:11:46Z megan_w $

require_once('PEAR.php');
require_once('LDAP/Entry.php');
require_once('LDAP/Search.php');


/**
 *  Error constants for errors that are not LDAP errors
 */

define ('NET_LDAP_ERROR', 1000);


/**
 * Net_LDAP - manipulate LDAP servers the right way!
 *
 * @author Tarjei Huse
 * @author Jan Wagner
 * @version $Revision: 8112 $
 * @package Net_LDAP
 */
 class Net_LDAP extends PEAR
{
    /**
     * Class configuration array
     *
     * dn       = the DN to bind as.
     * host     = the ldap host to connect to
     * password = no explanation needed
     * base     = ldap base
     * port     = the server port
     * tls      = when set, ldap_start_tls() is run after connecting.
     * version  = ldap version (defaults to v 3)
     * filter   = default search filter
     * scope    = default search scope
     *
     * @access private
     * @var array
     */
     var $_config = array('dn' => '',
                          'host' => 'localhost',
                          'password' => '',
                          'tls' => false,
                          'base' => '',
                          'port' => 389,
                          'version' => 3,
                          'options' => array(),
                          'filter' => '(objectClass=*)',
                          'scope' => 'sub');

    /**
     * LDAP resource link.
     *
     * @access private
     * @var resource
     */
    var $_link;

    /**
     * Net_LDAP Release Version
     *
     * @access private
     * @var string
     */
    var $_version = "0.6.6";

    /**
     * Net_LDAP_Schema object
     *
     * @access private
     * @var object Net_LDAP_Schema
     */
    var $_schema = null;

    /**
     * Cache for attribute encoding checks
     *
     * @access private
     * @var array Hash with attribute names as key and boolean value
     *            to determine whether they should be utf8 encoded or not.
     */
    var $_schemaAttrs = array();

    /**
     * Net_LDAP constructor
     *
     * Sets the config array
     *
     * @access protected
     * @param array Configuration array
     * @return void
     * @see $_config
     */
    function Net_LDAP($_config = array())
    {
        $this->PEAR('Net_LDAP_Error');

        foreach ($_config as $k => $v) {
            $this->_config[$k] = $v;
        }
    }

    /**
     * Creates the initial ldap-object
     *
     * Static function that returns either an error object or the new Net_LDAP object.
     * Something like a factory. Takes a config array with the needed parameters.
     *
     * @access public
     * @param array Configuration array
     * @return mixed object Net_LDAP_Error or Net_LDAP
     * @see $_config
     */
    function &connect($config = array())
    {
        if (!function_exists('ldap_connect')){
            return Net_LDAP::raiseError("It seems that you do not have the ldap-extension installed. Please install it before using this package.");
        }
        @$obj =& new Net_LDAP($config);
        $err  = $obj->bind();

        if (Net_LDAP::isError($err)) {
            return $err;
        }
        return $obj;
    }

    /**
     * Bind to the ldap-server
     *
     * The function may be used if you do not create the object using Net_LDAP::connect.
     *
     * @access public
     * @param array Configuration array
     * @return mixed Net_LDAP_Error or true
     * @see $_config
     */
    function bind($config = array())
    {
        foreach ($config as $k => $v) {
            $this->_config[$k] = $v;
        }

        if ($this->_config['host']) {
             $this->_link = @ldap_connect($this->_config['host'], $this->_config['port']);
        } else {
             return $this->raiseError("Host not defined in config. {$this->_config['host']}");
        }

        if (!$this->_link) {
            // there is no good errorcode for this one! I chose 52.
            return $this->raiseError("Could not connect to server. ldap_connect failed.", 52);
        }
        // You must set the version and start tls BEFORE binding!

        if ($this->_config['version'] != 2 && Net_LDAP::isError($msg = $this->setLDAPVersion())) {
            return $msg;
        }

        if ($this->_config['tls'] && Net_LDAP::isError($msg = $this->startTLS())) {
            return $msg;
        }

        if (isset($this->_config['options']) &&
            is_array($this->_config['options']) &&
            count($this->_config['options']))
        {
            foreach ($this->_config['options'] as $opt => $val) {
                $err = $this->setOption($opt, $val);
                if (Net_LDAP::isError($err)) {
                    return $err;
                }
            }
        }

        if (isset($this->_config['dn']) && isset($this->_config['password'])) {
             $bind = @ldap_bind($this->_link, $this->_config['dn'], $this->_config['password']);
        } else {
             $bind = @ldap_bind($this->_link);
        }

        if (!$bind) {
             return $this->raiseError("Bind failed " . @ldap_error($this->_link), @ldap_errno($this->_link));
        }

        return true;
    }

    /**
     * ReBind to the ldap-server using another dn and password
     *
     * The function may be used if you do not create the object using Net_LDAP::connect.
     *
     * @access public
     * @param string $dn - the DN to bind as.
     *        string $password - the bassword to use.
     * @return mixed Net_LDAP_Error or true
     * @see $_config
     */

    function reBind ($dn = null, $password = null)
    {

        if ($dn && $password ) {
            $bind = @ldap_bind($this->_link, $dn, $password);
        } else {
            $bind = @ldap_bind($this->_link);
        }

        if (!$bind) {
            return $this->raiseError("Bind failed " . @ldap_error($this->_link), @ldap_errno($this->_link));
        }
        return true;
    }

    /**
     * Starts an encrypted session
     *
     * @access public
     * @return mixed True or Net_LDAP_Error
     */
    function startTLS()
    {
        if (!@ldap_start_tls($this->_link)) {
            return $this->raiseError("TLS not started. Error:" . @ldap_error($this->_link), @ldap_errno($this->_link));
        }
        return true;
    }

    /**
     * alias function of startTLS() for perl-ldap interface
     *
     * @see startTLS()
     */
    function start_tls()
    {
        $args = func_get_args();
        return call_user_func_array(array($this, 'startTLS' ), $args);
    }

    /**
     * Close LDAP connection.
     *
     * Closes the connection. Use this when the session is over.
     *
     * @return void
     */
    function done()
    {
        $this->_Net_LDAP();
    }

    /**
     * Destructor
     *
     * @access private
     */
    function _Net_LDAP()
    {
        @ldap_close($this->_link);
    }

    /**
     * Add a new entryobject to a directory.
     *
     * Use add to add a new Net_LDAP_Entry object to the directory.
     *
     * @param object Net_LDAP_Entry
     * @return mixed Net_LDAP_Error or true
     */
    function add($entry)
    {
        if (@ldap_add($this->_link, $entry->dn(), $entry->attributes())) {
             return true;
        } else {
             return $this->raiseError("Could not add entry " . $entry->dn() . " " . @ldap_error($this->_link),
                                       @ldap_errno($this->_link));
        }
    }

    /**
     * Delete an entry from the directory
     *
     * The object may either be a string representing the dn or a Net_LDAP_Entry object.
     * The param array may contain a boolean value named recursive. When set, all subentries
     * of the Entry will be deleted as well
     *
     * @access public
     * @param mixed string or Net_LDAP_Entry
     * @param array
     * @return mixed Net_LDAP_Error or true
     */
    function delete($dn, $param = array())
    {
        if (is_object($dn) && strtolower(get_class($dn)) == 'net_ldap_entry') {
             $dn = $dn->dn();
        } else {
            if (!is_string($dn)) {
                // this is what the server would say: invalid_dn_syntax.
                return $this->raiseError("$dn not a string nor an entryobject!", 34);
            }
        }

        if ($param['recursive'] ) {
            $searchresult = @ldap_list($this->_link, $dn, '(objectClass=*)', array());

            if ($searchresult) {
                $entries = @ldap_get_entries($this->_link, $searchresult);

                for ($i=0; $i<$entries['count']; $i++) {
                    $result = $this->delete($entries[$i]['dn'], array('recursive' => true));
                    if (!$result) {
                        $errno = @ldap_errno($this->_link);
                        return $this->raiseMessage ("Net_LDAP::delete: " . $this->errorMessage($errno), $errno);
                    }
                    if(PEAR::isError($result)){
                        return $result;
                    }
                }
            }
        }
        if (!@ldap_delete($this->_link, $dn)) {
            $error = ldap_errno($this->_link );
            if ($error == 66) {
                /* entry has subentries */
                return $this->raiseError('Net_LDAP::delete: Cound not delete entry ' . $dn .
                                         ' because of subentries. Use the recursive param to delete them.');
            } else {
                return $this->raiseError("Net_LDAP::delete: Could not delete entry " . $dn ." because: ".
                                         $this->errorMessage($error),  $error);
            }
        }
        return true;
    }

    /**
     * Modify an ldapentry
     *
     * This is taken from the perlpod of net::ldap, and explains things quite nicely.
     * modify ( DN, OPTIONS )
     * Modify the contents of DN on the server. DN May be a
     * string or a Net::LDAP::Entry object.
     *
     * dn  This option is here for compatibility only, and
     * may be removed in future.  Previous releases did
     * not take the DN argument which replaces this
     * option.
     *
     * add The add option should be a reference to a HASH.
     * The values of the HASH are the attributes to add,
     * and the values may be a string or a reference to a
     * list of values.
     *
     * delete
     * A reference to an ARRAY of attributes to delete.
     * TODO: This does not support deleting one or two values yet - use
     * replace.
     *
     * replace
     * The <replace> option takes a argument in the same
     * form as add, but will cause any existing
     * attributes with the same name to be replaced. If
     * the value for any attribute in the 錼ray is a ref

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?