1

Let's say I have a forest setup with many domains. If I were to pick an arbitrary security group from any of the domains, what is the best way to find ALL user members of that group, including user members resulting from nested groups? I want to be able to do this regardless of the group type (i.e., Universal, Global, or Domain Local). My understanding is that we can't use the Global Catalog alone because group members are not replicated there for all group types.

We will ultimately do this with code but for now I just want to understand the process. For the sake of simplicity, let's say I already know the group's objectGUID value. Would the high-level steps be:

  1. Query any global catalog in the forest for the group (via the objectGUID) and retrieve the domain in which the group is defined via its objectCategory attribute distinguished name

  2. Query the domain controller in which the group is defined (retrieved in step 1) using the group's objectGUID and memberOf:1.2.840.113556.1.4.1941 as the filter

Is there anything else? Are there edge cases where I would have to query further domain controllers (e.g., further sub-domains)? Are there other cases where I wouldn't have to go further than the global catalog because the group type (or some other attribute) guarantees that all its member information is replicated in the global catalog?

EDIT

  • Changed objectCategory to distinguished name
Hmmmmm
  • 113
  • 5

1 Answers1

2

Searching by memberOf won't give you all results, since you will only find users in the scope of your search (e.g. if you search one domain, you will only find users on that domain, even if the group has members from other domains).

The authoritative list of who is a member of a group is in the member attribute of the group itself. The member attribute contains the distinguishedName of all members of the group. The member attribute is replicated to the Global Catalog (only for Universal groups), however, AD only gives you 1500 members at a time. For any groups with more than that, you need to ask for more.

If you are planning to start with the objectGuid, then you can bind directly to the object using that. You don't need to search at all. You use this notation to bind to an object with the GUID:

LDAP://<GUID={guid}>

where {guid} is the string GUID. Then you read the member attribute.

If a group has members on other domains, that can complicate things a bit if the domain is not in the same forest. In those cases, the member attribute of the group will contain an object on the same domain of the group called a "Foreign Security Principal" that contains the SID of the actual account on the external domain. If you want to get information about that account (like the name or email address), then you need to use that information to connect to the external domain to retrieve that information.

AD also has an idea of "primary groups", which are different, but you may not need to worry about it. I wrote an article about this called What makes a member a member?.

I also wrote an article with example code in C# about finding all members of a group, including following Foreign Security Principals. Even if you don't plan on using C#, it's all LDAP in the background anyway, so the same results can be replicated in another language.

Gabriel Luci
  • 136
  • 4
  • Sorry, I don't know why I said objectCategory, I meant the distinguished name. What I was planning on doing was finding the domain from the distinguished name (by parsing out the individual domain components) and then proceeding as stated above. – Hmmmmm Dec 24 '19 at 22:24
  • I am using memberOf because I want to recursively find all members in the group using one command and I thought I could do that with the following filter: (memberOf:1.2.840.113556.1.4.1941:= cn=Test,ou=East,dc=Domain,dc=com). I got this filter from here: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx#Examples – Hmmmmm Dec 24 '19 at 22:28
  • As for the Global Catalog, I was under the impression that group membership for non-Universal groups are not replicated to the Global Catalog (see https://social.technet.microsoft.com/Forums/en-US/57025d48-3c1b-42c8-866e-16aaf77ef095/are-global-groups-and-domain-local-groups-replicated-to-global-catalog-) and so wouldn't I have to query the correct domain controller to retrieve this information? – Hmmmmm Dec 24 '19 at 22:30
  • @Hmmmmm Yes, sorry, that is true for Global and Domain Local groups. So yeah, your best bet is to connect directly to the domain that the group is on. – Gabriel Luci Dec 24 '19 at 23:04
  • @Hmmmmm Yes, you can use `memberOf` to recursively find members of a group, but you will only find the members on the domain (or forest) that you are searching. If the group has members from another domain, you won't find those. – Gabriel Luci Dec 24 '19 at 23:07
  • What is the best way to retrieve all members of a group (including nested groups) within a forest? Do I have to perform the `memberOf` query on the domain in which the group is defined **and** and all of its subdomains? Note: I am **not** concerned with external forests. – Hmmmmm Dec 24 '19 at 23:31
  • The best way (least amount of network requests) for a Universal group is to do a `memberOf` search at the Global Catalog. For a Global or Domain Local group, you really have no choice but to look at the `member` attribute of the group itself and then look up each nested group as well (which what the code example on my site does). – Gabriel Luci Dec 25 '19 at 00:54