PHP ldap_add函数用于在DN语法中转义ldap特殊字符

时间:2011-12-19 11:49:19

标签: php ldap escaping special-characters

我正在尝试将一些用户添加到我的Ldap数据库中,但是当我使用一些特殊字符(如“,”)时,我会收到一些错误(无效的dn语法)。我需要一个能够逃避所有角色的功能。我尝试preg_quote但在某些情况下我遇到了一些错误。

提前致谢

代码:

$user = 'Test , Name S.L';

    if(!(ldap_add($ds, "cn=" . $user . ",".LDAP_DN_BASE, $info))) {

            include 'error_new_account.php';

    }

2 个答案:

答案 0 :(得分:2)

PHP 5.6 Beta 最近发布了ldap_escape()函数并且它已生效,但是,此版本目前尚未生产就绪,您现在可以将其用于开发目的

答案 1 :(得分:2)

如果您还没有使用PHP 5.6,那么您可以使用我在下面创建的方法镜像确切的PHP 5.6函数ldap_escape(),请记住这是为了在类中使用。上面的答案与ldap_escape函数完全不同,因为如果没有给出标记,它不会将所有字符转义为十六进制字符串,所以这更适合于一个drop以面向对象的方式替代早期版本的PHP。

我已经记录了每一行,以便更容易理解最新情况。向下滚动输出。

方法(与PHP 5或更高版本兼容):

/**
 * 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;
}

测试(请注意,LDAP_ESCAPE常量仅在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链接:https://gist.github.com/stevebauman/0db9b5daa414d60fc266