ldap.php

来自「Bug tracker, and reporter.」· PHP 代码 · 共 708 行 · 第 1/2 页

PHP
708
字号
<?php/** * Zend Framework * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://framework.zend.com/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@zend.com so we can send you a copy immediately. * * @category   Zend * @package    Zend_Ldap * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license    http://framework.zend.com/license/new-bsd     New BSD License * @version    $Id: Ldap.php 8403 2008-02-25 19:43:31Z darby $ *//** * @category   Zend * @package    Zend_Ldap * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license    http://framework.zend.com/license/new-bsd     New BSD License */class Zend_Ldap{    const ACCTNAME_FORM_DN        = 1;    const ACCTNAME_FORM_USERNAME  = 2;    const ACCTNAME_FORM_BACKSLASH = 3;    const ACCTNAME_FORM_PRINCIPAL = 4;    /**     * String used with ldap_connect for error handling purposes.     *     * @var string     */    private $_connectString;    /**     * The raw LDAP extension resource.     *     * @var resource     */    protected $_resource = null;    /**     * @param  string $str The string to escape.     * @return string The escaped string     */    public static function filterEscape($str)    {        $ret = '';        $len = strlen($str);        for ($si = 0; $si < $len; $si++) {            $ch = $str[$si];            $ord = ord($ch);            if ($ord < 0x20 || $ord > 0x7e || strstr('*()\/', $ch)) {                $ch = '\\' . dechex($ord);            }            $ret .= $ch;        }        return $ret;    }    /**     * @param  string $dn   The DN to parse     * @param  array  $keys An optional array to receive DN keys (e.g. CN, OU, DC, ...)     * @param  array  $vals An optional array to receive DN values     * @return bool   True if the DN was successfully parsed or false if the string is not a valid DN.     */    public static function explodeDn($dn, array &$keys = null, array &$vals = null)    {        /* This is a classic state machine parser. Each iteration of the         * loop processes one character. State 1 collects the key. When equals (=)         * is encountered the state changes to 2 where the value is collected         * until a comma (,) or semicolon (;) is encountered after which we switch back         * to state 1. If a backslash (\) is encountered, state 3 is used to collect the         * following character without engaging the logic of other states.         */        $key = null;        $slen = strlen($dn);        $state = 1;        $ko = $vo = 0;        for ($di = 0; $di <= $slen; $di++) {            $ch = $di == $slen ? 0 : $dn[$di];            switch ($state) {                case 1: // collect key                    if ($ch === '=') {                        $key = trim(substr($dn, $ko, $di - $ko));                        if ($keys !== null) {                            $keys[] = $key;                         }                        $state = 2;                        $vo = $di + 1;                    } else if ($ch === ',' || $ch === ';') {                        return false;                    }                    break;                case 2: // collect value                    if ($ch === '\\') {                        $state = 3;                    } else if ($ch === ',' || $ch === ';' || $ch === 0) {                        if ($vals !== null) {                            $vals[] = trim(substr($dn, $vo, $di - $vo));                        }                        $state = 1;                        $ko = $di + 1;                    } else if ($ch === '=') {                        return false;                    }                    break;                case 3: // escaped                    $state = 2;                    break;            }        }        return $state === 1 && $ko > 0;     }    /**     * @param  array $options Options used in connecting, binding, etc.     * @return void     */    public function __construct(array $options = array())    {        $this->setOptions($options);    }    /**     * Sets the options used in connecting, binding, etc.     *     * Valid option keys:     *  host     *  port     *  useSsl     *  username     *  password     *  bindRequiresDn     *  baseDn     *  accountCanonicalForm     *  accountDomainName     *  accountDomainNameShort     *  accountFilterFormat     *     * @param  array $options Options used in connecting, binding, etc.     * @return Zend_Ldap Provides a fluent interface     * @throws Zend_Ldap_Exception     */    public function setOptions(array $options)    {        $permittedOptions = array(            'host'                      => null,            'port'                      => null,            'useSsl'                    => null,            'username'                  => null,            'password'                  => null,            'bindRequiresDn'            => null,            'baseDn'                    => null,            'accountCanonicalForm'      => null,            'accountDomainName'         => null,            'accountDomainNameShort'    => null,            'accountFilterFormat'       => null,        );        $diff = array_diff_key($options, $permittedOptions);        if ($diff) {            list($key, $val) = each($diff);            require_once 'Zend/Ldap/Exception.php';            throw new Zend_Ldap_Exception(null, "Unknown Zend_Ldap option: $key");        }        foreach ($permittedOptions as $key => $val) {            if (!array_key_exists($key, $options)) {                $options[$key] = null;            }        }        $this->_options = $options;        return $this;    }    /**     * @return array The current options.     */    public function getOptions()    {        return $this->_options;    }    /**     * @return resource The raw LDAP extension resource.     */    public function getResource()    {        /**         * @todo by reference?         */        return $this->_resource;    }    /**     * @return string The hostname of the LDAP server being used to authenticate accounts     */    protected function _getHost()    {        return $this->_options['host'];    }    /**     * @return int The port of the LDAP server or 0 to indicate that no port value is set     */    protected function _getPort()    {        if ($this->_options['port'])            return $this->_options['port'];        return 0;    }    /**     * @return string The default acctname for binding     */    protected function _getUsername()    {        return $this->_options['username'];    }    /**     * @return string The default password for binding     */    protected function _getPassword()    {        return $this->_options['password'];    }    /**     * @return boolean The default SSL / TLS encrypted transport control     */    protected function _getUseSsl()    {        return $this->_options['useSsl'];    }    /**     * @return string The default base DN under which objects of interest are located     */    protected function _getBaseDn()    {        return $this->_options['baseDn'];    }    /**     * @return string Either ACCTNAME_FORM_BACKSLASH, ACCTNAME_FORM_PRINCIPAL or ACCTNAME_FORM_USERNAME indicating the form usernames should be canonicalized to.     */    protected function _getAccountCanonicalForm()    {        /* Account names should always be qualified with a domain. In some scenarios         * using non-qualified account names can lead to security vulnerabilities. If         * no account canonical form is specified, we guess based in what domain         * names have been supplied.         */        $accountCanonicalForm = $this->_options['accountCanonicalForm'];        if (!$accountCanonicalForm) {            $accountDomainName = $this->_options['accountDomainName'];            $accountDomainNameShort = $this->_options['accountDomainNameShort'];            if ($accountDomainNameShort) {                $accountCanonicalForm = Zend_Ldap::ACCTNAME_FORM_BACKSLASH;            } else if ($accountDomainName) {                $accountCanonicalForm = Zend_Ldap::ACCTNAME_FORM_PRINCIPAL;            } else {                $accountCanonicalForm = Zend_Ldap::ACCTNAME_FORM_USERNAME;            }        }        return $accountCanonicalForm;    }    /**     * @return string A format string for building an LDAP search filter to match an account     */    protected function _getAccountFilterFormat()    {        return $this->_options['accountFilterFormat'];    }    /**     * @return string The LDAP search filter for matching directory accounts     */    protected function _getAccountFilter($acctname)    {        $this->_splitName($acctname, $dname, $aname);        $accountFilterFormat = $this->_getAccountFilterFormat();        $aname = Zend_Ldap::filterEscape($aname);        if ($accountFilterFormat)            return sprintf($accountFilterFormat, $aname);        if (!$this->_options['bindRequiresDn']) {            // is there a better way to detect this?            return "(&(objectClass=user)(sAMAccountName=$aname))";        }        return "(&(objectClass=posixAccount)(uid=$aname))";    }    /**     * @param string $name The name to split     * @param string $dname The resulting domain name (this is an out parameter)     * @param string $aname The resulting account name (this is an out parameter)     */    protected function _splitName($name, &$dname, &$aname)    {        $dname = NULL;        $aname = $name;        $pos = strpos($name, '@');        if ($pos) {            $dname = substr($name, $pos + 1);            $aname = substr($name, 0, $pos);        } else {            $pos = strpos($name, '\\');            if ($pos) {                $dname = substr($name, 0, $pos);                $aname = substr($name, $pos + 1);            }        }    }    /**     * @param string $acctname The name of the account     * @return string The DN of the specified account     * @throws Zend_Ldap_Exception     */    protected function _getAccountDn($acctname)    {        if (Zend_Ldap::explodeDn($acctname))            return $acctname;        $acctname = $this->getCanonicalAccountName($acctname, Zend_Ldap::ACCTNAME_FORM_USERNAME);        $acct = $this->_getAccount($acctname, array('dn'));        return $acct['dn'];    }    /**     * @param string $dname The domain name to check     * @return bool     */    protected function _isPossibleAuthority($dname)    {

⌨️ 快捷键说明

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