2
votes

I'm currently using Python and LDAP to query Active Directory for users.

I have a list of names that are First Last. Not specific enough to find the exact user.

I would like a filter that would find all users matching 'Last, First*' and belonging to any group with a keyword in it.

    _filter = '''(& (objectclass=user)
                    (objectcategory=person)
                    (name={}*) )'''.format(search_string)

and I've tried adding...

                    (memberOf=CN=*Keyword*,OU=Delegated,OU=Groups,DC=amr,DC=corp,DC=xxxxxx,DC=com)

To my filter, but with no success.

If this was SQL, I would write something like:

 Select *  
 From    
    Users 
 Where
    Users.name like 'First, Last%'    
 and Users.memberOf like 'Keyword%'

Update:

After reviewing Gabriel's answer I'm running this.

def get_idsids(self, search_string):
   _filter = '''(& (objectclass=user)
                   (objectcategory=person)
                   (anr={}) )'''.format(search_string)

    # Search for user. 
    # Will return list of users matching criteria.
    # The results are wrapped up as a list(tuple(dict))) where the dict vals are binary strings or lists of binary strings.
    users = self.con.search_s(ActiveDirUser.BASEDN, ldap.SCOPE_SUBTREE, _filter, ['displayName', 'sAMAccountName', 'memberOf'])

    # This line is ugly... It just converts the results to a list of ids
    # So long as the user has at least one group with 'Keyword' in the name.
    # upper() is used to make the Keyword requriement case insensitive.
    return [user[1]['sAMAccountName'][0].decode() for user in users if 'KEYWORD' in ''.join(map(str, user[1]['memberOf'])).upper()]

I do wonder though, could I search for groups with 'Keyword' in the name and build filters from that? Further, would that be faster? I assume it would as AD probably hashes group membership.

I will go do some reading, but I assume group names are wildcard searchable?

1

1 Answers

1
votes

I suggest you use Ambiguous Name Resolution:

_filter = '''(& (objectclass=user)
                (objectcategory=person)
                (anr={}) )'''.format(search_string)

Read that documentation to understand how it works, but it can find users if you give it a string of "first last". This is what the search box in AD Users and Computers uses.

Just be aware that you can get doubles if people have similar names. If you take my name for example: if you would search for "Gabriel Luci", and there was someone else with the name "Gabriel Luciano", you would find both of us.

This:

(memberOf=CN=*Keyword*,OU=Delegated,OU=Groups,DC=amr,DC=corp,DC=xxxxxx,DC=com)

doesn't work because you can't use wildcards on any attribute that is a distinguishedName, like memberOf.

That's for Active Directory anyway. Other LDAP directories might allow it.

If you need to check if the users are members of groups, then you can tell your search to return the memberOf attribute in the search (I don't know phython, but you should have a way of telling it which attributes you want returned). Then you can loop through the groups in the memberOf attribute and look for that keyword.