PHP ldap_add function to escape ldap special characters in DN syntax

前端 未结 4 924
Happy的楠姐
Happy的楠姐 2020-12-30 05:20

I\'m trying to add some users to my Ldap DB but I get some errors (invalid dn syntax) when I use some special characters like \",.\". I need a function that escape all chara

4条回答
  •  轮回少年
    2020-12-30 05:59

    EDIT Jan 2013: added support for escaping leading/trailing spaces in DN strings, per RFC 4514. Thanks to Eugenio for pointing out this issue.

    EDIT 2014: I added this function to PHP 5.6. The code below is now a like-for-like drop-in replacement for earlier PHP versions.

    if (!function_exists('ldap_escape')) {
        define('LDAP_ESCAPE_FILTER', 0x01);
        define('LDAP_ESCAPE_DN',     0x02);
    
        /**
         * @param string $subject The subject string
         * @param string $ignore Set of characters to leave untouched
         * @param int $flags Any combination of LDAP_ESCAPE_* flags to indicate the
         *                   set(s) of characters to escape.
         * @return string
         */
        function ldap_escape($subject, $ignore = '', $flags = 0)
        {
            static $charMaps = array(
                LDAP_ESCAPE_FILTER => array('\\', '*', '(', ')', "\x00"),
                LDAP_ESCAPE_DN     => array('\\', ',', '=', '+', '<', '>', ';', '"', '#'),
            );
    
            // Pre-process the char maps on first call
            if (!isset($charMaps[0])) {
                $charMaps[0] = array();
                for ($i = 0; $i < 256; $i++) {
                    $charMaps[0][chr($i)] = sprintf('\\%02x', $i);;
                }
    
                for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_FILTER]); $i < $l; $i++) {
                    $chr = $charMaps[LDAP_ESCAPE_FILTER][$i];
                    unset($charMaps[LDAP_ESCAPE_FILTER][$i]);
                    $charMaps[LDAP_ESCAPE_FILTER][$chr] = $charMaps[0][$chr];
                }
    
                for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_DN]); $i < $l; $i++) {
                    $chr = $charMaps[LDAP_ESCAPE_DN][$i];
                    unset($charMaps[LDAP_ESCAPE_DN][$i]);
                    $charMaps[LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr];
                }
            }
    
            // Create the base char map to escape
            $flags = (int)$flags;
            $charMap = array();
            if ($flags & LDAP_ESCAPE_FILTER) {
                $charMap += $charMaps[LDAP_ESCAPE_FILTER];
            }
            if ($flags & LDAP_ESCAPE_DN) {
                $charMap += $charMaps[LDAP_ESCAPE_DN];
            }
            if (!$charMap) {
                $charMap = $charMaps[0];
            }
    
            // Remove any chars to ignore from the list
            $ignore = (string)$ignore;
            for ($i = 0, $l = strlen($ignore); $i < $l; $i++) {
                unset($charMap[$ignore[$i]]);
            }
    
            // Do the main replacement
            $result = strtr($subject, $charMap);
    
            // Encode leading/trailing spaces if LDAP_ESCAPE_DN is passed
            if ($flags & LDAP_ESCAPE_DN) {
                if ($result[0] === ' ') {
                    $result = '\\20' . substr($result, 1);
                }
                if ($result[strlen($result) - 1] === ' ') {
                    $result = substr($result, 0, -1) . '\\20';
                }
            }
    
            return $result;
        }
    }
    

    So you would do:

    $user = 'Test , Name S.L';
    $cn = ldap_escape($user, '', LDAP_ESCAPE_DN);
    if (!ldap_add($ds, "cn={$cn}," . LDAP_DN_BASE, $info)) {
        include 'error_new_account.php';
    }
    

提交回复
热议问题