0

First of all, the documentation and examples are so bad, please explain for simple people, like me. Rant over.

I am trying to access my organizations ldap server. Ive tried python-ldap, but i ran into issues, where it decodes and encodes responses super weird. I am testing ldap3 lib atm. But i cannot use the same stuff using ldap3.

def ldap3_connection_initalizer(username, password):
    server = ldap3.Server('ldap.blaah.blaaah')
    connection = ldap3.Connection(server, user=f'uid={username},ou=people,ou=users,dc=blaah,dc=blaah', password=f'{password}')
    with ldap3.Connection(server, user=f'uid={username},ou=people,ou=users,dc=blaah,dc=blaaah', password=f'{password}', auto_bind = True) as c:
        print(c)
        base_dn='ou=people,ou=users,dc=blaaah,dc=blaaah'
        status, result, response, _ = c.search(search_base=base_dn, search_filter='(objectClass=group)', search_scope='SUBTREE', attributes = ['member'])

        print(status)
        print(result)
        print(response)

Running this I get : ldap3.core.exceptions.LDAPObjectClassError: invalid class in objectClass attribute: group

and before that raise LDAPObjectClassError('invalid class in objectClass attribute: ' + str(value))

Could anyone explain why is this not working, but examples in the internet use similar response and it works?

EDIT: Update, tried to change group to person and got this error TypeError: cannot unpack non-iterable bool object

Taavi Ansper
  • 143
  • 9

1 Answers1

1

The 1st error says that group is not a valid objectClass (actually it exists but is specific to some Active Directory groups - AD only), so you need to fix the filter. The most generic objectClass for structuring a group entry (ie. having member attribute) is groupOfNames (cf. LDAP Group).

Then you changed the filter with (objectClass=person) which is valid (but for user entries), so you run into the 2nd error which is related to how is unpacked the returned value(s) from c.search(). By default ldap3' search() function returns only the status (other values are returned only when the "strategy" is defined to be thread-safe, which is not obvious at all).

When running a search the response is always added to the connection object via the response keyword, so in order to get the actual ldap entries whatever the thread mode, we can just iterate the connection response.

To sum it up, you can do :

status = c.search(search_base=base_dn, search_filter='(objectClass=groupOfNames)', search_scope='SUBTREE', attributes = ['member'])
print(status)
for entry in c.response:
    print(entry['dn'])
    print(entry['attributes'])
EricLavault
  • 12,130
  • 3
  • 23
  • 45