LDAP query for checking group membership using C#

168 views Asked by At

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:

  • first one to fetch my group's DN,
  • another to check if a user is a member the group (given by its DN).

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);
1

There are 1 answers

2
ixe013 On BEST ANSWER

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:

  1. Find the dn attribute of your user
  2. See if that dn is in the (multi-valued) member attribute of the group

You 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.