How to write LDAP query to test if user is member of a group?
Asked Answered
R

4

152

I want to write an LDAP query which tests whether a user (sAMAccountName) is a member of a particular group. Is it possible to do that so that I get either 0 or 1 result records?

I guess I can get all groups for the user and test each one for a match but I was wondering if I could pack it into one LDAP expression.

Any ideas?

Thanks

Reenareenforce answered 23/6, 2009 at 12:46 Comment(1)
See also questions like Recursively querying LDAP group membershipSkate
O
213

You should be able to create a query with this filter here:

(&(objectClass=user)(sAMAccountName=yourUserName)
  (memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))

and when you run that against your LDAP server, if you get a result, your user "yourUserName" is indeed a member of the group "CN=YourGroup,OU=Users,DC=YourDomain,DC=com

Try and see if this works!

If you use C# / VB.Net and System.DirectoryServices, this snippet should do the trick:

DirectoryEntry rootEntry = new DirectoryEntry("LDAP://dc=yourcompany,dc=com");

DirectorySearcher srch = new DirectorySearcher(rootEntry);
srch.SearchScope = SearchScope.Subtree;

srch.Filter = "(&(objectClass=user)(sAMAccountName=yourusername)(memberOf=CN=yourgroup,OU=yourOU,DC=yourcompany,DC=com))";

SearchResultCollection res = srch.FindAll();

if(res == null || res.Count <= 0) {
    Console.WriteLine("This user is *NOT* member of that group");
} else {
    Console.WriteLine("This user is INDEED a member of that group");
}

Word of caution: this will only test for immediate group memberships, and it will not test for membership in what is called the "primary group" (usually "cn=Users") in your domain. It does not handle nested memberships, e.g. User A is member of Group A which is member of Group B - that fact that User A is really a member of Group B as well doesn't get reflected here.

Marc

Oleary answered 23/6, 2009 at 12:59 Comment(10)
Tried, but still not working for me. Should it be 'OU=Users' or 'OU=Groups' in the memberOf clause?Reenareenforce
What's the DN of your group name? It depends on what you really want to check for......Oleary
You need to put in the actual real values in your case - my stuff is just demo placeholders!Oleary
This is my query: (&(objectClass=person)(sAMAccountName=USERID)(memberof='CN=SPSAdmins,OU=Groups,OU=MYTOWN,OU=Germany,OU=MYCOMPANY,DC=MYTOWN,DC=MYCOMPANY,DC=com')) The DN really is that long. I agree that it ought to work. Thanks for helping!Reenareenforce
On a whim I removed the single quotes after memberof and I now get a result! ThanksReenareenforce
Is the memberof keyword case sensitive? On active-directory I only got memberOf (note captial O) to work.Supination
Good answer. but it should be pointed out that it will only work in LDAP servers that maintain a 'memberOf' attribute. The more general technique is to fetch the group object and examine its uniqueMember, roleOccupant, etc. attributes for the DN of the user, depending on what schema the group object uses.Kerenkeresan
@Supination LDAP attribute names and values aren't case-sensitive, and neither are DNs, but AD has its own rules ...Kerenkeresan
This works perfectly on AIX 7.1: ldapsearch -h dc1.example.com -D [email protected] -w \? -b DC=example,DC=com -v "(&(objectClass=user)(memberof=CN=AIX-users,OU=AIX,DC=example,DC=com))"Eugenle
I know this is old, but I get tired of people perpetuating FUD about AD LDAP. Per the RFCs for LDAP, the DN is not case-sensitive. However, unlike other LDAP implementations, you can't perform a case-sensitive query (btw, not a mandatory feature in LDAP). The only exception is when performing searches for boolean values: i.e. TRUE/FALSE must be uppercase.Confection
A
44

If you are using OpenLDAP (i.e. slapd) which is common on Linux servers, then you must enable the memberof overlay to be able to match against a filter using the (memberOf=XXX) attribute.

Also, once you enable the overlay, it does not update the memberOf attributes for existing groups (you will need to delete out the existing groups and add them back in again). If you enabled the overlay to start with, when the database was empty then you should be OK.

Achromatism answered 1/11, 2011 at 4:25 Comment(3)
A link to a page that explains how to enable memberof overlay would be useful i guess.Ible
Tutorial that worked for me: schenkels.nl/2013/03/… @Telford Tendrys, dude you saved my life with this notice about pre-existing groups. Many thanks!Lurie
Thanks, wasted so much time trying to make this work in openldap, didn't know this memberOf didn't come out of the box.Fridge
H
27

I would add one more thing to Marc's answer: The memberOf attribute can't contain wildcards, so you can't say something like "memberof=CN=SPS*", and expect it to find all groups that start with "SPS".

Hairstreak answered 23/2, 2011 at 22:28 Comment(1)
Thank you for that information. I've been trying to do what you say can not be done. How can I go about doing that with PHP? Is it possible to have the same result in another way? to find all groups start with SPS and then whatever... I can always grab everything and loop my array then preg match to the CN I want but I prefer just searching for it straight up if possible.Pravit
E
20

You must set your query base to the DN of the user in question, then set your filter to the DN of the group you're wondering if they're a member of. To see if jdoe is a member of the office group then your query will look something like this:

ldapsearch -x -D "ldap_user" -w "user_passwd" -b "cn=jdoe,dc=example,dc=local" -h ldap_host '(memberof=cn=officegroup,dc=example,dc=local)'

If you want to see ALL the groups he's a member of, just request only the 'memberof' attribute in your search, like this:

ldapsearch -x -D "ldap_user" -w "user_passwd" -b "cn=jdoe,dc=example,dc=local" -h ldap_host **memberof**
Elinoreeliot answered 21/8, 2014 at 22:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.