60

Is it possible to create an LDAP query which will return (or check for) users in a nested group? e.g. UserA is a member of GroupA, and GroupA is a member of GroupB. I want a query on GroupB to return that UserA is a member. LDAP only. The server is Active Directory.

Abhijeet Kasurde
  • 3,937
  • 1
  • 24
  • 33
askvictor
  • 3,621
  • 4
  • 32
  • 45
  • See also: [LDAP_MATCHING_RULE_IN_CHAIN performance problems](https://stackoverflow.com/q/40024425/1026). – Nickolay Oct 07 '19 at 09:50

3 Answers3

106

Yes, using the LDAP_MATCHING_RULE_IN_CHAIN matching rule (OID 1.2.840.113556.1.4.1941). For example:

(memberOf:1.2.840.113556.1.4.1941:=cn=group,cn=users,DC=x)

see http://msdn.microsoft.com/en-us/library/aa746475%28VS.85%29.aspx

Andrew Strong
  • 4,303
  • 2
  • 24
  • 26
  • Thanks; though it's memberof in this case (member would tell me the groups that a user is a member of) – askvictor Jun 07 '11 at 03:46
  • 15
    Can you explain that a little bit for those of us who aren't very good at LDAPese? – docwhat Oct 25 '11 at 16:12
  • 3
    Is this rule a Microsoft extension? – Gearoid Murphy Sep 26 '12 at 10:55
  • 5
    If I could, I would bake you a cake and mail it to you as a thank you. – Shawn D. Mar 07 '13 at 22:13
  • 3
    It sounds like the question is looking for something that takes a group argument and lists all members (including members from nested groups). All of these solutions appear to take a user argument -or- a user and a group argument both. – Martin Apr 11 '13 at 20:54
  • Please note that this rule does not work with current versions of Samba 4. – kroimon Sep 23 '14 at 12:14
  • 1
    Any idea how to do this in OpenLDAP? I use OpenLDAP as a proxy for AD. – Newerth Apr 10 '15 at 06:45
  • 2
    I'm an LDAP newb, What the heck is 1.2.840.113556.1.4.1941? I see it on the link you posted, any idea why it's a long string of numbers like that? – Sean256 Dec 20 '16 at 01:50
  • 2
    @kroimon, specifically it does not work until Samba 4.4, which [fixed the broken implementation](https://bugzilla.samba.org/show_bug.cgi?id=10493). – George Hilliard Jun 06 '17 at 00:26
  • What if the object is a Foreign Security Principal? – Mike May 13 '19 at 19:37
13

You must use the full distinguished name of your group when using memberOf:1.2.840.113556.1.4.1941:= in my case CN=MyGroup,OU=User,OU=Groups,OU=Security,DC=domain,DC=com was the whole distinguished name

(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=MyGroup,OU=User,OU=Groups,OU=Security,DC=domain,DC=com))

you can get the distinguished name of you group by running the following code and putting in this filter (&(objectClass=group)(name=MyGroup))

Imports System.DirectoryServices

Module Module1

Sub Main()
    Dim run As Boolean = True
    Dim Filter As String
    While run
        Console.WriteLine("Enter Filter:")
        Filter = Console.ReadLine()
        If Filter = "exit" Then
            run = False
        Else
            checkFilter(Filter)
        End If
    End While
End Sub

Function checkFilter(Filter As String) As Boolean
    Dim search As New DirectorySearcher("LDAP://dc=Domain,dc=com")
    Try
        search.Filter = Filter
        search.PropertiesToLoad.Add("name")
        search.PropertiesToLoad.Add("distinguishedName")
        search.SearchScope = SearchScope.Subtree
        Dim results As SearchResultCollection = search.FindAll()
        If results Is Nothing Then
            Console.WriteLine("Nothing")
            Return False
        Else
            If results.Count() = 0 Then
                Console.WriteLine("non found")
            End If
            Dim result As SearchResult
            For Each result In results
                Console.WriteLine(result.Properties("name")(0).ToString())
                Console.WriteLine(result.Properties("distinguishedName")(0).ToString())
                'For Each prop In result.Properties("members")
                '    Console.WriteLine(prop.ToString())
                'Next
            Next
            Console.WriteLine(String.Format("{0} Users Found", results.Count()))
        End If
    Catch ex As Exception
        Console.WriteLine(ex.Message)
    End Try
    Return True
End Function

End Module
Flup
  • 604
  • 5
  • 15
Mothware
  • 312
  • 2
  • 10
5

Per your question, the query should be

(&(memberOf:1.2.840.113556.1.4.1941:={0})(objectCategory=person)(objectClass=user)(sAMAccountName={1}))

{0} is the nested group, it should be a Distinguished name

{1} is the user sAMAccountName you want (you could use any other user property than sAMAccountName within (sAMAccountName={1}))

Then you will get the user detail for response if the user is the member of nested group

John Jang
  • 2,567
  • 24
  • 28