PHP ldap_add function to escape ldap special characters in DN syntax

前端 未结 4 919
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 06:16

    Just a heads up if your not on PHP 5.6 yet, you can mirror the exact PHP 5.6 function ldap_escape() using the methods I created below, keep in mind this is meant for use in a class. The above answer doesn't perform exactly like the ldap_escape function, as in it doesn't escape all characters into a hex string if no flags have been given, so this would be more suitable for a drop in replacement for earlier versions of PHP, in an object oriented way.

    I've documented every line for an easier understanding on whats going on. Scroll down for output.

    Methods (Compatible with PHP 5 or greater):

    /**
     * Escapes the inserted value for LDAP.
     *
     * @param string $value The value to escape
     * @param string $ignore The characters to ignore
     * @param int $flags The PHP flag to use
     *
     * @return bool|string
     */
    public function escapeManual($value, $ignore = '*', $flags = 0)
    {
        /*
         * If a flag was supplied, we'll send the value
         * off to be escaped using the PHP flag values
         * and return the result.
         */
        if($flags) {
            return $this->escapeWithFlags($value, $ignore, $flags);
        }
    
        // Convert ignore string into an array
        $ignores = str_split($ignore);
    
        // Convert the value to a hex string
        $hex = bin2hex($value);
    
        /*
         * Separate the string, with the hex length of 2,
         * and place a backslash on the end of each section
         */
        $value = chunk_split($hex, 2, "\\");
    
        /*
         * We'll append a backslash at the front of the string
         * and remove the ending backslash of the string
         */
        $value = "\\" . substr($value, 0, -1);
    
        // Go through each character to ignore
        foreach($ignores as $charToIgnore)
        {
            // Convert the characterToIgnore to a hex
            $hexed = bin2hex($charToIgnore);
    
            // Replace the hexed variant with the original character
            $value = str_replace("\\" . $hexed, $charToIgnore, $value);
        }
    
        // Finally we can return the escaped value
        return $value;
    }
    
    /**
     * Escapes the inserted value with flags. Supplying either 1
     * or 2 into the flags parameter will escape only certain values
     *
     *
     * @param string $value The value to escape
     * @param string $ignore The characters to ignore
     * @param int $flags The PHP flag to use
     * @return bool|string
     */
    public function escapeWithFlags($value, $ignore = '*', $flags = 0)
    {
        // Convert ignore string into an array
        $ignores = str_split($ignore);
    
        $escapeFilter = ['\\', '*', '(', ')'];
        $escapeDn = ['\\', ',', '=', '+', '<', '>', ';', '"', '#'];
    
        switch($flags)
        {
            case 1:
                // Int 1 equals to LDAP_ESCAPE_FILTER
                $escapes = $escapeFilter;
                break;
            case 2:
                // Int 2 equals to LDAP_ESCAPE_DN
                $escapes = $escapeDn;
                break;
            case 3:
                // If both LDAP_ESCAPE_FILTER and LDAP_ESCAPE_DN are used
                $escapes = array_merge($escapeFilter, $escapeDn);
                break;
            default:
                // Customize your own default return value
                return false;
        }
    
        foreach($escapes as $escape)
        {
            // Make sure the escaped value isn't inside the ignore array
            if( ! in_array($escape, $ignores))
            {
                $hexed = chunk_split(bin2hex($escape), 2, "\\");
    
                $hexed = "\\" . substr($hexed, 0, -1);
    
                $value = str_replace($escape, $hexed, $value);
            }
        }
    
        return $value;
    }
    

    Tests (be aware that LDAP_ESCAPE constants are only available in PHP 5.6):

    // Value to escape
    $value = 'testing=+<>"";:#()*\x00';
    
    $php = ldap_escape($value, $ignore = '*');
    
    $man = $this->escapeManual($value, $ignore = '*');
    
    echo $php; // \74\65\73\74\69\6e\67\3d\2b\3c\3e\22\22\3b\3a\23\28\29*\5c\78\30\30
    echo $man; // \74\65\73\74\69\6e\67\3d\2b\3c\3e\22\22\3b\3a\23\28\29*\5c\78\30\30
    
    
    $php = ldap_escape($value, $ignore = '*', LDAP_ESCAPE_DN);
    
    $man = $this->escapeManual($value, $ignore = '*', LDAP_ESCAPE_DN);
    
    echo $php; // testing\3d\2b\3c\3e\22\22\3b:\23()*\5cx00
    echo $man; // testing\3d\2b\3c\3e\22\22\3b:\23()*\5cx00
    
    
    $php = ldap_escape($value, $ignore = '*', LDAP_ESCAPE_FILTER);
    
    $man = $this->escapeManual($value, $ignore = '*', LDAP_ESCAPE_FILTER);
    
    echo $php; // testing=+<>"";:#\28\29*\5cx00
    echo $man; // testing=+<>"";:#\28\29*\5cx00
    

    Github Gist link: https://gist.github.com/stevebauman/0db9b5daa414d60fc266

提交回复
热议问题