Having an ldapConnection
established, I want to check if a given user is a member of a group given by name (note: I mean the "user frielndly" name, not a DN).
I've been experimenting with LDAP filter syntax for the first time and found out something that works, but it requires me to make two calls:
As I said, this works fine, but I'm wondering if this could be improved. In particular: maybe it's possible to solve the problem using a single query.
The work-in-progress version of my code is below. It's definitely not production-ready, but shows the big picture.
Last thing: when it comes to userStore
value, I found it by trying and failing (mostly failing). The value I discovered seems to work, but please let me know if there's something better.
using var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(myServer, myPort));
var networkCreds = new NetworkCredential(myUserName, myPassword, myDomain);
ldapConnection.Bind(networkCreds);
var userStore = $"DC=domain,DC=local";
var groupSearchFilter = $"(sAMAccountName={myGroupName})";
var groupSearchRequest = new SearchRequest
(userStore, groupSearchFilter, System.DirectoryServices.Protocols.SearchScope.Subtree, new string[] { "DistinguishedName" });
var groupDN = ((SearchResponse)ldapConnection.SendRequest(groupSearchRequest)).Entries[0];
var searchFilter = $"(&(sAMAccountName={myUserName})(memberof={groupDN.DistinguishedName}))";
var searchRequest = new SearchRequest
(userStore, searchFilter, System.DirectoryServices.Protocols.SearchScope.Subtree, new string[] { "DistinguishedName" });
var response = (SearchResponse)ldapConnection.SendRequest(searchRequest);
return (response.Entries.Count > 0);
In a typical LDAP server, like Active Directory you seem to be using, group membership is stored so that "Groups have members" (member
attribute). The membership is reflected in the user (memberOf
attribute).
But membership are stored using distinguished names. So to test for membership you must:
dn
attribute of your userdn
is in the (multi-valued) member
attribute of the groupYou already get the DN of the group, but its sAMAccountName
attribute is unique and indexed, use it as-is. Change that code to search for the user's DN instead with this filter:
var userSearchFilter = $"(sAMAccountName={myUserName})";
Extract from that the user's dn
in a variable called userDN
(for example). Then verify membership with this ldap search:
var searchFilter = $"(&(objectClass=group)(sAMAccountName={myGroupName})(member={userDN.DistinguishedName}))";
Here I added the objectClass
to the search. It is not required, but it could speed up the search if you have a whole lot of users and very few groups. For symmetry, you could add (objectClass=user)
when you search for the user.