-
Notifications
You must be signed in to change notification settings - Fork 465
Unable to escape comma when searching for an attribute whose value is a DN #109
Comments
I'm using ldapjs version 0.5.7. Running on MacOS (although I duplicated the behavior on CentOS Linux). Running against Active Directory as the LDAP server. |
We had the same problem. The error is the in the filter classes as they escape the value in the constructor which is correct for the string representation of the filter but invalid in the ber. The following coffeescript code monky-patches the builtin ldapjs filters {filters} = require 'ldapjs'
escape = require('ldapjs/lib/filters/escape').escape
module.exports = filters
patch = (name, type) ->
class filters[name] extends filters[name]
constructor: (options) ->
super
@attribute = options.attribute if @attribute?
@value = options.value if @value?
toString: -> "(#{escape @attribute}#{type}#{escape @value})"
patch 'ApproximateFilter', '~='
patch 'EqualityFilter', '='
patch 'GreaterThanEqualsFilter', '>='
patch 'LessThanEqualsFilter', '<='
class filters.PresenceFilter extends filters.PresenceFilter
constructor: (options) ->
super
@attribute = options.attribute if @attribute?
toString: -> "(#{escape @attribute}=*)"
class filters.SubstringFilter extends filters.SubstringFilter
constructor: (options) ->
super
@attribute = options.attribute if @attribute?
@initial = options.initial if @initial?
@any = options.any[..] if @any.length
@final = options.final if @final?
toString: ->
res = "(#{escape @attribute}="
res += escape @initial if @initial
res += '*'
res += "#{escape any}*" for any in @any
res += escape @final if @final
res += ')' |
@sastan - do you want to send a PR over for that? |
@mcavage Doing it right now. |
sastan's pull request resolved the issue for searching using the filter objects (e.g. EqualityFilter). It's been working great. Thank you! I found that there still is an issue when using strings as filters from how parseFilter handles the backslashes, although it could just be a misunderstanding on my part. (It doesn't impact me, since I switched to using the filter objects for searching rather than filter strings.) It is probably best demonstrated with an example. The example queries for a person's entry then uses the "manager" attribute which holds a DN to query again for the person's manager. I perform the query for the manager three different ways: two using a string filter and one using and EqualityFilter object. Here's the snippet where I build the three filters:
I also call parseFilter() on them just so I can print out what is going on:
Then I print it all out. Any backslashes in the string filters will be printed as-is; any in the objects will be doubled by the JSON stringify.
Finally, I perform three searches using each of the three filters. Below are the results. I have modified the names and domains, but otherwise the output (including the backslashes) is from a real test run.
Is the behavior I'm seeing the way it is supposed to work - that if you want to build a string query using a value fetched from another entry it needs to be escaped first - or is there an issue with parseFilter? |
I'm closing out very old issues. Please comment if this should be reopened. |
Resolved by #521. |
When searching with a filter where the desired attribute value is a DN, LDAP servers require that any commas which are not separators be escaped with a backslash. E.g. if I wanted to search for entries whose "manager" attribute equals the DN "CN=Doe, John,DC=example,DC=com" I would need to specify a search of "(manager=CN=Doe, John,DC=example,DC=com)" (note the backslash between "Doe" and the comma).
The problem is that I cannot get ldapjs to pass the backslash on to the LDAP server correctly, and hence I get no search results. I tried passing the filter both as a string and as an EqualityFilter object (per the workaround in issue 48) and tried using 0, 1, and 2 backslashes. I hacked my local copy of writeCallback in client.js to dump the value of message.toBer() to a file so I could see what was actually being sent and here's the results:
Using a string filter:
0 backslashes: CN=Doe, John,DC=...
1 backslash: CN=Doe, John,DC=... (backslash is lost)
2 backslashes: CN=Doe\5c, John,DC=... (backslash itself if escaped - treated as if I wanted a literal backslash as part of the data. note the \5c is literally 3 characters '', '5', and 'c')
Using an object filter:
0 backslashes: CN=Doe, John,DC=...
1 backslash: CN=Doe\5c, John,DC=...
2 backslashes: CN=Doe\5c\5c, John,DC=...
It needs to be CN=Doe, John,DC=... (..., 'e', '', ',', ' ', 'J', 'o', ...), and when I hacked my local copy to do that, the search returned the results I expected. (I just made _parseString in lib/filters/index.js just do a 1-for-1 replacement of a tilde with a backslash in the result of serializeTree, so it was just to test the behavior - not an actual fix for the issue.)
The text was updated successfully, but these errors were encountered: