如何转义LDAP特殊字符?

7

我正在使用python-ldap查询Active Directory

我有这个DN

CN=Whalen\, Sean,OU=Users,OU=Users and Groups,DC=example,DC=net

这在查询中作为基础是可以的,但如果我尝试在搜索过滤器中使用它,就像这样

(&(objectClass=group)(memberof:1.2.840.113556.1.4.1941:=CN=Whalen\, Sean,OU=Users,OU=Users and Groups,DC=example,DC=net))

我收到了一个“搜索过滤器错误”。经过我的测试,CN中的逗号似乎是罪魁祸首,即使我用反斜杠(\)转义了它。然而,在Microsoft文档中没有将逗号列为需要在筛选器中转义的字符。
我漏掉了什么?

你尝试添加第二个反斜杠了吗?根据搜索的执行方式,第一个反斜杠可能需要转义才能传递到LDAP ;) - heiglandreas
2个回答

9

LDAP筛选器规范将以下字符* ( ) \ NUL赋予特殊含义,当在搜索筛选器中使用时,应该用反斜杠后跟该字符的两个ASCII十六进制表示形式进行转义(rfc2254):

*   \2A
(   \28
)   \29
\   \5C
Nul \00

这意味着任何用于转义“可分辨名称”特殊字符(包括逗号)的反斜杠在搜索过滤器中必须表示为\5c

(&(objectClass=group)(memberof:1.2.840.113556.1.4.1941:=CN=Whalen\5c, Sean,OU=Users,OU=Users and Groups,DC=example,DC=net))

以下是必须使用\\5C进行转义的特殊字符列表,当用于搜索过滤器时需要注意:

    +-------------------------------+---+
    | comma                         | , |
    +-------------------------------+---+
    | Backslash character           | \ |
    +-------------------------------+---+
    | Pound sign (hash sign)        | # |
    +-------------------------------+---+
    | Plus sign                     | + |
    +-------------------------------+---+
    | Less than symbol              | < |
    +-------------------------------+---+
    | Greater than symbol           | > |
    +-------------------------------+---+
    | Semicolon                     | ; |
    +-------------------------------+---+
    | Double quote (quotation mark) | " |
    +-------------------------------+---+
    | Equal sign                    | = |
    +-------------------------------+---+
    | Leading or trailing spaces    |   |
    +-------------------------------+---+

非常感谢您详细的回复。现在查询似乎正在运行,但是它花费的时间和PowerShell中一样长,却返回零结果。有什么想法吗? - Sean W.
我不确定,但确保ldap正确解析查询可能是值得的。根据执行查询的程序(什么类型的程序以及如何解析字符串),并且正如heiglandreas所建议的那样,可能需要转义反斜杠本身(以被解析为文字反斜杠),从而导致\\5c - EricLavault
@EricLavault 我也遇到过奇怪的问题,即使正确转义搜索词,但只有在进行递归搜索时才会出现零结果。我已经将完整描述添加为答案。 - John Rees
@SeanW。自从将\转义为\5C后,您的“Bad search filter”错误消失了,我认为Python字符串转义和AD转义之间存在奇怪的相互作用。由于\5C然后被发送到AD,当\被转义为\5C时,你就会遇到AD递归搜索的缺陷(请参见下面的答案)。我建议你将\转义为\而不是\5C,这样搜索术语的结尾将是“CN=Whalen\, Sean,OU=Users,OU=Users and Groups,DC=example,DC=net”。我的猜测是Python将解析\为\,然后将其发送到Active Directory,一切都会好起来。 - John Rees

0

当使用带有转义字符的member:1.2.840.113556.1.4.1941进行搜索时,我遇到了非常奇怪的行为。

当搜索词被“正确地”转义时,搜索似乎会失败,但是当搜索词没有被转义时,搜索成功!

相比之下,使用member进行普通搜索无论搜索词是否被转义都可以正常工作。

这里是一个PowerShell示例。

function Find-AdObjects([string]$Filter) {

    $DirectorySearcher = New-Object System.DirectoryServices.DirectorySearcher
    $DirectorySearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry
    $DirectorySearcher.SearchScope = [System.DirectoryServices.SearchScope]::Subtree
    $DirectorySearcher.PropertiesToLoad.Add('distinguishedname') > $null
    $DirectorySearcher.PageSize = 100
    $DirectorySearcher.Filter = $Filter

    $SearchResultCollection = $DirectorySearcher.FindAll()

    foreach ($r in $SearchResultCollection) {
        $r.Properties['distinguishedname']
    }

    $SearchResultCollection.Dispose()
    $DirectorySearcher.Dispose()
}

$UserDn        = 'CN=Rees\, John,OU=Tier3,DC=big,DC=com'
$EscapedUserDn = 'CN=Rees\5C, John,OU=Tier3,DC=big,DC=com'

# Returns expected results with escaped search term
Find-AdObjects "(&(member=$EscapedUserDn))"

# Returns same results even though search term is NOT escaped correctly
Find-AdObjects "(&(member=$UserDn))"

# Returns NO results even though search term is escaped correctly
Find-AdObjects "(&(member:1.2.840.113556.1.4.1941:=$EscapedUserDn))"

# Returns recursive results even though search term is NOT escaped correctly
Find-AdObjects "(&(member:1.2.840.113556.1.4.1941:=$UserDn))"

所以我并没有看到一个可接受的解决方法,因为似乎没有一种可靠的方法来转义可能包含各种特殊字符的DN:\*()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接