I am in an organization with an Active Directory with a very deep nested group structure. I would like to query the directory to recursively find user members of a group from a Linux machine. On a Windows machine,
dsget group "dn_of_group" -members -expand
does exactly what I want and does it very quickly. When I tried to get the same results via LDAP with
(memberOf:1.2.840.113556.1.4.1941:=dn_of_group)
the query takes almost a minute to run. Does dsget use LDAP under the hood or does it use some other means to query the directory? And if so, is there any way for me to also use that?
Edit:
Clarified that I need the members which are users.
The framework 3.5 with System.DirectoryServices.AccountManagement Namespace provides a method that searches all groups recursively and returns the groups in which the user is a member. The returned set may also include additional groups that system would consider the user a member of for authorization purposes.
UserPrincipal.GetAuthorizationGroups()
The groups that are returned by this method may include groups from a different scope and store than the principal. For example, if the principal is an AD DS object that has a DN of "CN=SpecialGroups,DC=Fabrikam,DC=com, the returned set can contain groups that belong to the "CN=NormalGroups,DC=Fabrikam,DC=com
In the other direction you've got :
GroupPrincipal.GetMembers(bool recursive)
See Remarks
Related
I have an application with which I would like to connect my ldap users.
I want two types of users to be able to log in: internal and external.
In the application that I deploy, three parameters are taken into account (ldapjs protocol, scope sub)
export LDAP_FILTER LDAP_BASEDN LDAP_UIDTAG
How do I get
"OU=Internal,OU=Users,DC=test,DC=example,DC=com"
and
"OU=External,OU=Users,DC=test,DC=example,DC=com"
members to connect to it?
How should I fill in these parameters knowing that the cn is username ?
Thank you for your help
I tried
export LDAP_FILTER (|(&(ou=Internal)(cn={{username}}))(&(ou=External)(cn={{username}}))
and many more
Those are OU's (organizational units) not groups. You cannot filter by OU in an LDAP filter. You use the Base DN to limit results to one OU. However, you can only use one.
You may be better off creating a group and adding all of the users from both OUs into that group, and then you can filter on the group, like this:
(memberOf=CN=MyAppGroup,OU=Groups,DC=test,DC=example,DC=com)
That should be the full distinguishedName of the group.
Is it possible to retrieve all AD groups recursively given a user's SAM Account identifier?
I've been using the following ldapsearch filter
ldapsearch -D 'domain\john.doe' -W -h 'ldap.domain.com' -b 'DC=domain,DC=local' '(member:1.2.840.113556.1.4.1941:=CN=John Doe,OU=Users,OU=World,DC=domain,DC=local)' dn
to query our local LDAP server (based off AD) to retrieve the user's AD groups but it's a two-step process since I need to the users full DN.
Previously I used to get a user's direct groups by users the non-recursive filter:
ldapsearch -D 'domain\john.doe' -W -h 'ldap.domain.com' -b 'DC=domain,DC=local' '(|(userPrincipalName=john.doe#domain.com)(sAMAccountName=john.doe))' dn
Is it possible to achive the result of the first query (all AD groups recursively) and the single step of the second query (since I only needed to know the email address of user of the username
No you cannot without performing multiple queries.
If your server is based off AD, it may use memberOf attribute in which case you can get user's groups in one single query but without nested groups :
ldapsearch -D 'domain\john.doe' -W -h 'ldap.domain.com' -b 'DC=domain,DC=local' '(|(userPrincipalName=john.doe#domain.com)(sAMAccountName=john.doe))' memberOf
It would be great if we could use the extensible match as an attribute request in the query above, using memberof:1.2.840.113556.1.4.1941: instead of memberOf, but it's not a maintained attribute for which you can grab values when searching groups, it can only be used for extensible match in a filter (cf. LDAP_MATCHING_RULE_IN_CHAIN), and it's specific to AD (not implemented in OpenLDAP).
On the other side, you can search for groups using filter member:1.2.840.113556.1.4.1941: but the problem is precisely that it requires knowing user's dn in the first place.
One might come with the idea of querying groups with a filter matching memberUid with user login or sAMAccountName, but it depends whether or not this attributes is maintained in your directory, and I'm pretty sure you can't have extensible match with this one, meaning this filter cannot match nested group membership.
So, in the end you need to use your second query to grab all user dn's, and for each one of them build the query that will grab that user's group membership including nested groups.
I am trying to find a objectCategory query that will return all the "users" in my active directory.
I thought this would be as simple as (objectCategory=user). And while that does return the bulk of my users, it does not return them all.
I have some Group Managed Service Accounts (gMSA) in my Active Directory. They have the objectCategory of msDS-GroupManagedServiceAccount. When I look up msDS-GroupManagedServiceAccount it indicates that it has fields derived from user.
That leads me to to believe that msDS-GroupManagedServiceAccount is a subclass of user. Which leads to my question:
Is there a way to indicate that I want all objects that are of objectCategory user AND all objects that descend from objectCategory user?
Search by objectClass instead of objectCategory:
(objectClass=user)
The objectClass attribute started being indexed in Windows Server 2008, so as long as you're running 2008+, it will be just as fast as searching by objectCategory.
Not a complete answer to your bolded question, but a workaround for for your particular case would be to use an or expression.
(|(objectCategory=person)(objectCategory=msDS-GroupManagedServiceAccount))
I have to get all users (not USER objects, but users added to groups) inside the groups of a determined OU.
Is it possible or should I first look for groups then loop them and find its users?
AFAIK in ActiveDirectory group membership is stored inside the user-node. Therefore it should be possible to select all users that have a group-attribute set and that are below the given OU.
In ldapsearch that should look something like this:
ldapsearch -h ldap -b "ou=known,..." (memberof=*) cn```
where memberof=* is the filter to ´query for all entries that have a "memberof"-attribute set. You can extend that filter to query also for a certain objecttype to only get user-nodes if that is a problem in this setup.
Sorry, I can't test it currently as I don't have an ActiveDirectory at hand.
I need to query Active Directory for a list of users whose password is about to expire. The obvious (and easy) way to do this is with:
dsquery user -stalepwd n
The problem is that I need to add additional filters to only look for users who are in certain security groups. This is hard to do with the "dsquery user" syntax that has the built-in -stalepwd option, so I've been using the "dsquery * -filter" option which allows you to use LDAP query syntax. Unfortunately, while its relatively easy to do apply the other filters with an LDAP query, I'm having trouble filtering users who have a password age greater than n.
Does anyone know the syntax (or if it is even possible) to filter for old passwords using the "dsquery * -filter" method instead of the "dsquery user -stalepwd" method.
You can write an LDAP Query that compares "stale" passwords by comparing the pwdLastSet attribute on the user object:
(&(objectClass=person)(objectClass=User)(pwdLastSet<=n))
ActiveDirectory uses a very specific format for this time stamp. I believe it a file-time, but I would double check on the web.
There are better tools than dsquery to use.
FindExpAcc from joeware will do the same as stalepwd and allow a filter through its -f switch.
The filter would then look like:
&(objectCategory=user)(memberof=CN=User Group,OU=Test,DC=foo,dc=com)
Also check out adfind and admod tools from joeware which are more powerful than the command line query tools from Microsoft, but can be a little harder to learn.