go-ldap / ldap

Basic LDAP v3 functionality for the GO programming language.
Other
2.22k stars 353 forks source link

LDAP filter cannot contain DN with parenthesis #221

Open aastein opened 5 years ago

aastein commented 5 years ago

This filter is not parsed correctly because the CN contains parenthesis.

(memberOf=CN=Some CN with (parenthesis),OU=Foo,DC=Left,DC=Right)

The error given is LDAP Result Code 201 "Filter Compile Error": ldap: finished compiling filter with extra at end: ,OU=Foo,DC=Left,DC=Right)

I think this is because there is a break for any close parenthesis when parsing the remaining filter. https://github.com/go-ldap/ldap/blob/master/filter.go#L265

aastein commented 5 years ago

According to https://ldapwiki.com/wiki/DN%20Escape%20Values and https://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx the parens characters should not be escaped.

Some characters that are allowed in distinguished names and do not need to be escaped include:
* ( ) . & - _ [ ] ` ~ | @ $ % ^ ? : { } ! '

but ldap.go escapes parenthesis and *

https://github.com/go-ldap/ldap/blob/master/ldap.go#L308

func mustEscape(c byte) bool {
    return c > 0x7f || c == '(' || c == ')' || c == '\\' || c == '*' || c == 0
}
emsearcy commented 5 years ago

mustEscape is called by EscapeFilter which is for filter escaping. Filter escaping has different needs from DN escaping, which is what the article you quote is referring to.

go-ldap does not currently have a helper for DN escaping. There are a couple open old PRs to address this - see issue #154 and PRs #154 and #104. (Either of these would also have enough example code for you to implement this in your own app as a stopgap.)