I'm trying to write a filter to get all the users of a given group in Active Directory.
To that end I have the following query
LDAPSearch("DC=test,DC=myorg,DC=com", "(objectClass=user)", 1, "name")
I'm a bit confused as to where I should give the name of the group on which to base the search on. As far as I know you cannot have two groups in AD with the same name.
In general, user objects have an attribute called memberOf that lists DNs of groups that a user is member of. Therefore you can search with a filter like (&(objectClass=user)(memberOf=<DN of requested group>)).
Please note that due to AD design, user's primary group is not included in memberOf attribute. For most users that group would be Domain Users (unless explicitly changed), but if changed, that group will no longer list in memberOf and this query will not find such user.
Related
I'm working with a vendor who needs to use LDAP queries to pull information on our Active Directory. The query pulls from the 'members' attribute of the AD Group directly. However it only pulls 8 of the 20+ users in this group. If I look at the group's Members tab, I can see all of the users, and they work without an issue. I switch to the Attributes tab and scroll to the members entry view the values which shows only 8 of the users. The LDAP query only pulls these 8 and not the rest of the users.
How do I fix this so the attribute and members list match without deleting/recreating the group? If I delete and recreate it would take down our production environment.
I've tried removing and re-adding users to the group and it does not fix the issue.
I'm going to guess that this group is the primary group for the users that you don't see in the member attribute. Members don't appear in the member attribute if the group is the primary group. I don't know why this is... blame Microsoft.
To find those users, look at the primaryGroupToken of the group. It will be a number. Then search for users that have that value in their primaryGroupId attribute.
Usually, the primary group is the built-in Domain Users group, which always has a primaryGroupToken of 513. So to find users of that, you would use this LDAP query:
(primaryGroupId=513)
According to the documentation, the primaryGroupId attribute is indexed, so you don't need any other criteria.
If you want to learn more about how memberships work, I wrote an article a while ago about What makes a member a member?
I'm trying to make a query that outputs all the groups (and nested groups) that a user is part off, queried for by sAMAccountName value.
For example, the following query works and gives the expected output but uses the displayname instead.
(&(objectCategory=group)(member:1.2.840.113556.1.4.1941:=cn=Tester,ou=people,dc=Windomain,dc=local))
Simply changing "cn" to "sAMAccountName" doesn't work (I did verify that the sAMAccountName value is correct)
Is it possible to do this with LDAP queries?
There are a couple of options to display the complete group membership of a user, including all nested groups.
The simplest method is to query the TokenGroups attribute of the user object. This is a constructed attribute, that will return all the SIDs of the groups that will be added to the user's access token when the user authenticates. The only condition for the constructed attribute, the search scope must be Base scope for the attribute to be returned.
The LDAP_MATCHING_RULE_IN_CHAIN (1.2.840.113556.1.4.1941) matching rule is limited in its functionality, it will only return the groups that the user's DN has been added to the member attribute of the group, so some nested groups will not be included in the query.
The other option is to use a 3rd party tool to return the nested groups by transverse the groups membership to see the group membership. Such as NetTools User's membership option https://nettools.net/users-membership and the NetTools AD Properties dialog which includes the TokenGroups tab which will display the TokenGroups attribute with the SIDs resolved.
You can search for the user by the sAMAccountName and ask for the msds-memberOfTransitive attribute, which contains a recursive list of the distinguished names of the groups the user is a member of.
There is also the msds-tokenGroupNames attribute, which contains the distinguished names of all the groups whose SIDs appear in the tokenGroups attribute.
The difference is that tokenGroups only includes security groups, whereas memberOf includes distribution lists as well. Only security groups can be used to assign permissions.
Both are constructed attributes, so you have to specifically put it in the list of attributes to return in the search.
Sorry unable to add comments
Be careful of the msds-memberoftransitive attribute, it has some funky logic which doesn't follow the normal value ranging rules and can return incomplete results, see https://blog.joeware.net/2021/04/19/6068/
we have a weird behaviour we cannot explain.
We have a query like this
(memberOf:1.2.840.113556.1.4.1941:=CN=Backup Operators,CN=Builtin,DC=test,DC=env)
To get all members of a group. E.g. we configured the Backup Operators group (Test env) to have the following members:
The query will only find Authenticated users and Leea. This is, for some reason the behaviour every time. All Foreign Security Principals except the "Authenticated Users" one are never picked up by the query and we can't figure out why.
Any ideas?
You are searching your domain for users where the memberOf attribute contains that group, or a group nested inside of that group.
The problem is that those objects do not have their memberOf attribute populated. If you open those accounts in AD Users and Computers, you'll that the Member Of tab is blank.
I can't really say why, since Authenticated Users looks like the same type of object, but it does have the memberOf attribute populated.
In general, memberOf can be spotty. For various reasons, you won't always find every member of a group by searching memberOf. To get every member of a group, you need to look at the member attribute of the group itself.
I have a LDAP searchquery where i am using the following filter
"(&(objectClass=user)(objectCategory=person))"
and running against AD in order to get User-accounts out. One of the attributes being returned ("memberOf") holds a ";" separated string of groups that user is a member of.
i.e.
CN=MyGroup,OU=MyMainOU,DC=masterdom,DC=local;
CN=Administrators,CN=Builtin,DC=masterdom,DC=local
I want to filter out the BuiltIn security groups, when processing the list can I rely on the "built in" groups containing the string "cn=builtin"? Or could it change with local etc. If so what is the correct method?
You if want to utilize the memberOf attribute, you can include it in your filter by using the full container name :
(&(objectClass=user)(objectCategory=person)(memberof=CN=Builtin,DC=masterdom,DC=local))
Something to keep in mind though, is that the memberOf attribute will only show groups native to the domain component (DC) in which the user is derived from - by that I mean, if user A is part of both the Developers and Management groups, but the Developers group doesn't exist within the current domain component you're querying, then the memberOf attribute will only show the Management group for the user when queried.
Plus, the memberOf attribute is a computed back-link attribute or a constructed attribute. It's maintained and calculated by Active Directory, so as you move users and groups around, that value will automatically change for the user.
However, judging by your post, if you're just iterating through a list of users and checking the memberOf attributes for the existence of CN=Builtin (ex. a .Contains check), then yes, you can rely on that string being there, given it's part of the DC you're querying.
I need to implement nested group membership for generic AD services.
Previously, i was using a specific search-filter ("member:1.2.840.113556.1.4.1941:=") through which using a single search request, i was able to get hold of all group membership through which that user was part of. However, it looks like that search-filter seems to work only for MS AD servers and not for generic AD servers.
So, is anybody aware of any specific search filter which we can send in a search request (applicable to All AD servers), through which i can derive nested group membership via a single search query.
Thanks in advance for your help on this.
"member:1.2.840.113556.1.4.1941" is LDAP_MATCHING_RULE_IN_CHAIN and might very well not be implemented by other LDAP vendors. LDAP Wiki
Edit:
You could do something like this if you want to reurse the groups:
Use the filter:
(&(objectCategory=organizationalPerson)(objectClass=User)(sAMAccountName=YOURUSER)
get "distinguishedName" (this is the user's distinguishedName)
get "memberOf" (this is a collection of distinguishedNames of the groups the user is a member of (minus the primary group in MS Active Directory, which should be "Domain Users"))
Foreach memberOf in the collection: (This is the first level, so there is no need to check if he is there, because he is.)
(&(objectCategory=group)(distinguishedName=THISMEMBEROF))
get "member" (this is a collection of distinguishedNames of group members)
Foreach memberOf in the collection:
This is the second level (the groups within the groups), so first check if the users distinguishedName is present.
(&(objectCategory=group)(distinguishedName=THISMEMBEROF))
get "member" (this is a collection of distinguishedNames of group members)
Foreach memberOf in the collection:
This is the third level (the groups within the groups), so first check if the users distinguishedName is present.
(&(objectCategory=group)(distinguishedName=THISMEMBEROF))
get "member" (this is a collection of distinguishedNames of group members)
etc.