A group in Active Directory has three entries. The application reads the member attribute, finds three people and is done. In reality seven people belong to it, because two of the three entries are groups themselves. Nobody notices until a policy fails to apply to four people.
The problem with member
A group's member attribute lists its direct members: users, contacts, computers and other groups. It resolves nothing. Nesting is the norm in grown directories, for example department groups inside site groups inside a group for all staff.
The chain rule in Active Directory
Active Directory has its own matching rule for chains, LDAP_MATCHING_RULE_IN_CHAIN with the identifier 1.2.840.113556.1.4.1941. It follows a link across any number of levels.
All users who are direct or indirect members of a group:
ldapsearch -H ldaps://dc1.company.local -b "DC=company,DC=local" \ "(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=FieldSales,OU=Groups,DC=company,DC=local))" \ mail displayName
The other way round, the same rule on member returns all groups a user belongs to directly or indirectly. For a single user the constructed attribute tokenGroups is faster, read with scope base on the user object.
In PowerShell, Get-ADGroupMember -Identity FieldSales -Recursive does the same.
Three traps
Large groups
If a group has more members than the domain controller returns in one response, 1500 by default, member stays incomplete. The rest comes through range retrieval with member;range=0-1499, then member;range=1500-2999 and so on, until the response ends with an asterisk. The chain rule in the filter avoids this, because it searches for users instead of reading values.
The primary group
Users whose primaryGroupID points to a group are not in its member. For Domain Users that usually means everyone. The chain rule does not find them either. If you need primary groups, also search for primaryGroupID with the group's RID.
Members from other domains
Members from a trusted forest show up as objects under ForeignSecurityPrincipals with their SID. Their address lives in the other directory.
OpenLDAP and related directories
The chain rule is an Active Directory feature. OpenLDAP, 389 Directory Server and related directories do not have it. The memberof overlay there only returns direct memberships as well.
Resolution therefore happens in the client:
- Read the group, collect entries from
memberoruniqueMember. - Check each entry: take people, queue groups.
- Remember visited groups so that cycles do not loop forever.
Two findings from the lab: range retrieval with member;range=0-* is an Active Directory feature. OpenLDAP answers it with an empty attribute and no error, and every group suddenly has zero members. And if you search a group by GUID, you have to convert the display form: the first three fields are stored with reversed byte order in binary.
Where it matters
Wherever groups decide rights and rules: licences per group, encryption policies, signature templates per department. Incomplete resolution does not show up as an error there, but as a person a rule does not apply to.
How Conbool solves it
The Conbool directory agent resolves groups in Active Directory with the chain rule on the server and walks the chain itself in other LDAP directories. In the lab a group with three direct entries resulted in seven people, all the way into the database. More on the page email security without Entra ID and in the groups documentation.


