python 3.7 and ldap3 reading group membership

4.4k Views Asked by At

I am using Python 3.7 and ldap3. I can make a connection and retrieve a list of the groups in which I am interested. I am having trouble getting group members though.

server = Server('ldaps.ad.company.com', use_ssl=True, get_info=ALL)
with Connection(server, 'mydomain\\ldapUser', '******', auto_bind=True) as conn:

    base = "OU=AccountGroups,OU=UsersAndGroups,OU=WidgetDepartment," \
           + "OU=LocalLocation,DC=ad,DC=company,DC=com"

    criteria = """(
        &(objectClass=group)
         (
            |(sAMAccountName=grp-*widgets*)
             (sAMAccountName=grp-oldWidgets)
         )
    )"""

    attributes = ['sAMAccountName', 'distinguishedName']
    conn.search(base, criteria, attributes=attributes)
    groups = conn.entries

At this point groups contains all the groups I want. I want to itterate over the groups to collect the members.

    for group in groups:
        # print(cn)

        criteria = f"""
            (&
                (objectClass=person)
                (memberof:1.2.840.113556.1.4.1941:={group.distinguishedName})
            )
        """
        # criteria = f"""
        #    (&
        #       (objectClass=person)
        #        (memberof={group.distinguishedName})
        #    )
        # """

        attributes = ['displayName', 'sAMAccountName', 'mail']
        conn.search(base, criteria, attributes=attributes)
        people = conn.entries

I know there are people in the groups but people is always an empty list. It doesn't matter if I do a recirsive search or not.

What am I missing?

Edit

There is a longer backstory to this question that is too long to go into. I have a theory about this particular issue though. I was running out of time and switched to a different python LDAP library -- which is working. I think the issue with this question might be that I "formated" the query over multiple lines. The new ldap lib (python-ldap) complained and I stripped out the newlines and it just worked. I have not had time to go back and test that theory with ldap3.

1

There are 1 best solutions below

0
On

people is overwritten in each iteration of your loop over groups. Maybe the search result for the last group entry in groups is just empty.

You should initialise an empty list outside of your loop and extend it with your results:

people = []
for group in groups:
    ...
    conn.search(...)
    people.extend(conn.entries)

Another note about your code snippet above. When combining objectClass definitions with attribute definitions in your search filter you may consider using the Reader class which will combine those internally.

Furthermore I would like to point out that I've created an object relational mapper where you can simply define your queries using declarative python syntax, e.g.:

from ldap3_orm import ObjectDef, Reader
from ldap3_orm.config import config
from ldap3_orm.connection import conn

PersonDef = ObjectDef("person", conn)
r = Reader(conn, PersonDef, config.base_dn, PersonDef.memberof == group.distinguishedName)
r.search()

ldap3-orm documentation can be found at http://code.bsm-felder.de/doc/ldap3-orm