-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: System.DirectoryServices.Protocols.LdapFilter #59900
Comments
Tagging subscribers to this area: @jay98014 Issue DetailsBackground and motivationAs per discussion at #38609 (comment), it was suggested that runtime might benefit from LDAP query escape functionality. As per RFC 4515, LDAP search filter arguments should be properly escaped. Detailed context (copied from linked issue):Another case with escaping is when filter argument (e.g. group CN) contains parentheses, e.g.
The correct representation, as per RFC, is:
What's interesting is that the first one works on Windows, but fails on Linux.
I think this might benefit from some general escape method which we can call manually when constructing filters, like:
Something along the lines of what I did here: dotnet/aspnetcore@7f72499 Originally posted by @RoadTrain in #38609 (comment) API Proposalnamespace System.DirectoryServices.Protocols
{
public static class LdapFilter
{
public static string EscapeFilterArgument(string filterArgument);
}
} API Usage// Construct the LDAP filter by correctly escaping filter arguments
var filter = $"(&(objectClass=group)(sAMAccountName={LdapFilter.EscapeFilterArgument("Some (very) important group")}))";
Console.WriteLine(filter);
// Output:
// (&(objectClass=group)(sAMAccountName=Some \28very\29 important group)) RisksNone that I'm aware of.
|
One thing to consider: the escaping method should only do one thing -- replace reserved characters with their RFC-compliant form. |
This sounds like a great feature, thanks for the proposal. Can you confirm a list of all characters that would need to be escaped for this? Also, we would need to make sure that the RFC-compliant form works for both wldap32 and libldap (openldap) which are the native libraries that we use underneath. |
The RFC lists 5 characters that must be escaped:
From Richard L. Mueller:
That would probably require some custom AD setup. In our case I tested probably the most common occurrence -- escaping parentheses. It worked on both Linux (openldap) and Windows (wldap32). There's a note on this at Technet. An interesting detail is:
I believe it's an implementation detail of wldap32, since openldap still needs matched parentheses escaped. |
Great, I guess last thing to consider is whether we want to have this type public, or instead simply make it part of the LdapConnection request implementation detail, where we automatically escape all filters that get sent to us. what are your thoughts around that @RoadTrain? Main thinking behind that being that this way more folks would benefit from the escaping, as opposed to just folks who know about the new API. |
That would be ideal, but the problem is that it would require parsing the entire query, which adds a whole bunch of issues and risks to the generalizability of implementation.
we would need to determine where the filter argument ( I think this problem is better illustrated by this example: https://stackoverflow.com/a/62193991 I personally don't know how many people use |
Another approach might be to implement some form of an LDAP query builder.
That would require an additional parameter in the constructor of Maybe the best way is to do both via statics:
|
You have a good point regarding it being better to scope it down to a helper method for now, specially since that way it can be used for something else and not just SearchRequest. I think this API is ready for review so I’ll mark it as such. |
One last question here, I was looking for precedence in the framework and found a similar pattern in Regex, which has the static API Regex.Escape for escaping special characters on a regex pattern directly onto the regex class. The question being, would it make sense to add these APIs directly into LdapConnection? That could help a lot with the visibility and discoverability of the API. |
Yeah, I think it's a valid approach. One thing to consider is possibly breaking SRP in case of |
namespace System.DirectoryServices.Protocols
{
public static class LdapFilter
{
public static string EscapeFilterArgument(string filterArgument);
}
} |
Background and motivation
As per discussion at #38609 (comment), it was suggested that runtime might benefit from LDAP query escape functionality.
As per RFC 4515, LDAP search filter arguments should be properly escaped.
S.DS.P currently lacks such a functionality, which prevents some corner cases to work without consumer implementing such functionality themselves.
Detailed context (copied from #38609 (comment)):
Another case with escaping is when filter argument (e.g. group CN) contains parentheses, e.g.
Some (very) important group
.Since parentheses are a part of filter syntax itself, it might be problematic to correctly parse the filter.
The correct representation, as per RFC, is:
What's interesting is that the first one works on Windows, but fails on Linux.
The second one works on both Windows and Linux, as per my tests.
I think this might benefit from some general escape method which we can call manually when constructing filters, like:
Something along the lines of what I did here: dotnet/aspnetcore@7f72499
Is it a good idea to provide such a method as part of core
System.DirectoryServices.Protocols
functionality?Originally posted by @RoadTrain in #38609 (comment)
API Proposal
API Usage
Risks
None that I'm aware of.
The text was updated successfully, but these errors were encountered: