LDAP Query to find all groups with more than one parent - active-directory

Is there a way to construct an LDAP search string that would return all groups that have more than one parent group? I have searched and searched Google, and perhaps this can't be done, or perhaps I am just not looking for the right thing, but it seems like I should be able to do this.
What I am trying to solve:
We have a batch application that maintains an organizational hierarchy of groups. In our hierarchy, a group can only have one parent "org" group. It have have any number of non-Org parent groups, just not Organizational unit groups. Orgs are identified by a CN that consists of 8 separate numbers withing a very specific range, lets say 1000 to 1001 for sake of argument, where 10000000 is the "Base" Org unit. An Org can only be a child of one other Org, but can have other parent groups that are not Org units.
The problem is that someone, in their infinite wisdom, has gone out and broke the cardinal rule that an Org group should have one and only one Org parent. Now I have to update the batch program to handle and correct it. But, first, I need to know how to find these.
My thought is something like this:
(&(objectClass=group)(count(members) > 2))
Where count is some aggregate function that returns the number of members a group might have. Or, maybe some way to return all groups that have more than one memberOf?

LDAP has no aggregate function to determine the number of members. Some LDAP implementations may have added features for aggregation, but AFIK, Microsoft Active Directory does not.
You could move you baseDN to a higher point to encompass all the possible OUs in which there are groups or even root.
As you tagged the question as Microsoft Active Directory, you may then need to chase referrals.
I was not able to determine if Microsoft Active Directory supports extensible matching for DNs which would allow matching only within two or more containers. If Microsoft Active Directory does, then a filter similar to: (&(|(ou:dn:=groups)(ou:dn:=groups2))(objectclass=groups)) might work.
-jim

Related

LDAP attribute to filter built-in or default OUs in AD

To reduce clutter in a selector GUI element I need a way to
tell OUs that ship with AD and Exchange by default (builtins, schema
defined, security or whatever) from such that the admin
created to organize their domain. E. g. the filter should
ignore OUs like:
OU=Domain Controllers,DC=example,DC=com
OU=Microsoft Exchange Security Groups,DC=example,DC=com
and only let those pass that were manually added.
So far I’ve been investigating the bits in the systemFlags:
attribute.
The values are inconclusive though as some bits e. g. non-removability
are set for basic AD objects but don’t appear so for objects added
by Exchange.
I’m not sure if the attribute itself can be present in user
defined OUs. If not, that would be a sufficient signal to
base the filter on. [MS-ADTS] lists it as optional though.
You can't filter by OU in an LDAP query, since a query cannot do partial matches on the distinguishedName (e.g. this won't work: (!disginguishedName=*OU=Domain Controllers*))
If you want to exclude objects in certain OUs, you have two options:
Do it after the query, in your own code, where you can do partial comparisons on the distinguishedName, or
Make separate searches in the OUs that you do want. You can set the search root in each query to the OU you want, then repeat that for every OU you want to include.
Depending what you are trying to search for and the number of results, the first method might be faster than the second.

Finding fellow members of an Active Directory group?

I need to list all members of all groups, where a given user (or a small group of users) are members.
The straightforward way to do it is to get the list of groups from the memberOf-attribute of the seed-user(s) and loop through them collecting their other members.
But, perhaps, there is some better way -- with advanced LDAP -- to do it in fewer (or even just one) query?
If it matters, I'm talking to Active Directory from a PHP-script using the ldap-extension. Thanks!
For a given user, you can obtain all groups where the user is a member, including nested groups using the filter:
(member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))
-jim

retrieving group members/membership from active directory when members attrib doesn't work

I am trying to get all group members from "Domain Users". When using AD Users MMC tab, I get a lot of results. When using ADSI - not. The following DOESN'T work as expected:
looking at members attribute of the group entry via LDAP/ADSI. It returns only 56 members when there are considerably more.
searching by memberOf (returns just a few entries)
searching by primaryGroup (it is not a primary group)
searching by tokenGrops (it is a constructed attribute)
any ideas appreciated.
(I just read more carefully and saw that you mentioend it's not primary group...but I'm suspicious this is the answer anyway :))
There is another mechanism by which a user can be a member of a group, and it's controlled by the primaryGroupID attribute of the user in the group.
If the primaryGroupID of a user is set to some RID of a group, the user is functionally in the group, even though they don't show up in the member attribute of the group. Tools like ADUC are wise enough to look for this. When you step a bit lower in the stack and hit the directory over LDAP, it is up to you to be smart enough to go hunting for it.
You can either do searches for this or use constructed attributes in the directory that take this in to account.

Is it possible to LDAP query users common to a set of groups

I need a list of all the users common to a known collection of groups, using a single LDAP query of our Active Directory. It would seem, from the our reading so far, that such is not possible, but I thought it best to ask the hive mind.
Try this:
(&(objectCategory=Person)
(&
(memberOf=CN=group1,dc=company,dc=local)
(memberOf=CN=group2,dc=company,dc=local)
(memberOf=CN=group3,dc=company,dc=local)
)
)
This is similar to my question, except there I wanted all users who were NOT members of groups. You'll need to delete all the whitespace for most query tools to work.
Yes it's possible with an attribute scoped query. It requires W2K3 AD or later but will give you the all of the users that have a particular attribue i.e. membership in a group or in your case multiple groups (intersection of groups). One of the best examples is from Joe Kaplan and Ryan Dunns book "The .NET Developers Guide to Directory Services Programming" for AD work it's hard to beat look at page 179 for a good walk through.
Caveat:At this point you are past trivial searches in AD and a number of things are becoming important like the search root, scope and the effect of searching through some potentially HUGE set of data for the items you want. Looking through 50 or 60K users to find the members of a group does have an effect on performance and be prepared to do paged results or similar in case the dataset is large. Kaplan/Ryan do an excellent job of down to earth work to get you where you need to be. That said, I have used them on two AD projects with great success. Being able retrieve the data from AD without recursive queries is VERY worth while and I found that it is fast as long as I control the size of my dataset.
It's not possible in a single query if your groups contain nested groups.
You would need to write some code that recursively resolves the group members and does the logical equivalent of an "inner join" on the results, producing a list of users that are common to all the original groups.

LDAP filter for searching students

I am fairly new to LDAP and AD. I want to create an LDAP filter to show all the students in the AD. But the problem is that the students are in different BASE DN:
OU=STUDENTS,OU=USERS,OU=SOE,OU=FOAE,OU=UNIVERSITY,DC=sepang
OU=STUDENTS,OU=USERS,OU=SOMLC,OU=FOAE,OU=UNIVERSITY,DC=sepang
OU=STUDENTS,OU=USERS,OU=SOCS,OU=FOS,OU=UNIVERSITY,DC=sepang
i.e for each student it is like
CN =khx72b,OU=STUDENTS,OU=USERS,OU=SOCS,OU=FOS,OU=UNIVERSITY,DC=sepang
As you can see students from different faculties are in different places.
Given an username how can I search and find if the given user is in the directory?
The objectClass for all the students is 'user'.
As it seems you are searching for objects of type 'user' which are in OUs called 'STUDENTS' but otherwise have no common parent.
This cannot be done in one step (i.e. with a single LDAP query).
You must either retrieve all OUs named 'STUDENTS' and use them as Base DNs one by one, like you've already indicated.
Or you find a property that all students share (a direct group membership, for example, or a special value somewhere) and use that as the filter. This is a more dangerous approach since nothing guarantees that every student actually has the feature you rely on - some might have been not entered into AD correctly.
Tomalak, is right, Microsoft does provide many attributes that you could use for this purpose such as "employeeType", "comment", "department", "company", "department", "divison", etc, but the problem with these is that they are not prepopulated with any information that can help you now. You can start using one of these for future purposes, but then you must maintain that practice in order for it to be consistent. I thing the easiest solution for you is to probably put each of the users into a group that is named similar to the OU name, which should be an really easy task if they're currently in the same OU. then once this is done you can easily create a LDAP query which will then look at the membership of that group like this:
((objectCategory=person)(objectClass=user)(memberOf=CN=STUDENTS GROUP,OU=USERS,OU=SOCS,OU=FOS,OU=UNIVERSITY,DC=sepang))
Please note when using the "memberOf" in an LDAP filter the search value must be a complete string to a group, and so you CAN'T use a wildcard such as: memberOf=CN=STUDENTS GROUP*).
You will still have to maintain a practice that you or someone or something (such as an automated schedule script task) which maintains the group membership to ensure that your LDAP query will be accurate.
I did see this post which says what your trying to do is possible without having to do anything extra by "Matching Components of Distinguished Names", but I have never seen this before and I could not get it to work. Also take a look at this tutorial on ADO searches to learn more about these things work
Search for objects in an OU by setting "searchRoot" to teh LDAP path to the OU. all searches will then be confined to that OU.

Resources