python ldap search returns error when ou is filtered

45 Views Asked by At

I have a python script to search in an LDAP server. I used to search filtering the DC in my base DN. Now, I want to expand my filter to OU too. But when I use OU in my base DN, I get following error:

/usr/bin/python3.6 /home/zeinab/PycharmProjects/ldap-test/main.py
Traceback (most recent call last):
  File "/home/zeinab/PycharmProjects/ldap-test/main.py", line 29, in <module>
    search_scope=SUBTREE)
  File "/home/zeinab/.local/lib/python3.6/site-packages/ldap3/core/connection.py", line 853, in search
    response = self.post_send_search(self.send('searchRequest', request, controls))
  File "/home/zeinab/.local/lib/python3.6/site-packages/ldap3/strategy/sync.py", line 178, in post_send_search
    responses, result = self.get_response(message_id)
  File "/home/zeinab/.local/lib/python3.6/site-packages/ldap3/strategy/base.py", line 403, in get_response
    raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type'])
ldap3.core.exceptions.LDAPOperationsErrorResult: LDAPOperationsErrorResult - 1 - operationsError - None - 000020D6: SvcErr: DSID-03100837, problem 5012 (DIR_ERROR), data 0
  - searchResDone - None

This is my script:

from ldap3 import Server, Connection, SIMPLE, ALL, SUBTREE

server = Server(host=host, port=port, get_info=ALL, connect_timeout=10, use_ssl=True)
connection = Connection(
    server=server,
    user=username,
    password=password,
    raise_exceptions=True,
    authentication=SIMPLE,
)

connection.open()
connection.bind()

base_dn = "dc=dc1,dc=local,ou=ou0,ou=ou1"
search_filter = "(&(objectClass=person)(mail=john*))"
search_attribute = ['mail']

connection.search(search_base=base_dn,
                  search_filter=search_filter,
                  attributes=search_attribute,
                  search_scope=SUBTREE)
resp = connection.response
print(len(resp))
print(resp)
connection.unbind()

EDIT 1: I have also tried this solution:

base_dn = "dc=dc1,dc=local,ou=ou0,ou=ou1"
search_filter = "(&(objectClass=person)(mail=john*)(ou:dn:=ou1))"

But I got the exact same error.

EDIT 2: I tried previous solution this way:

base_dn = "dc=dc1,dc=local"
search_filter = "(&(objectClass=person)(mail=john*)(ou:dn:=ou1))"

And also this way:

base_dn = "dc=dc1,dc=local"
search_filter = "(&(objectClass=person)(mail=john*)(ou:=ou1))"

These two didn't raise any error, but returned no result; even though I have results matching the filter.

1

There are 1 best solutions below

0
user1686 On

This is my script:

base_dn = "dc=dc1,dc=local,ou=ou0,ou=ou1"

Your DN is backwards. LDAP-format DNs are hierarchical from right to left – the child of dc=dc,dc=local would actually be ou=ou0,dc=dc1,dc=local. In other words, the directory structure would look like this – imagine it like a filesystem structure but with the paths going right-to-left:

DC=example,DC=com
 └─OU=Users,DC=example,DC=com
    └─OU=Staff,OU=Users,DC=example,DC=com
       └─CN=Fred Foobar,OU=Staff,OU=Users,DC=example,DC=com

Additionally, the "base DN" can only match a specific entry. If you have OU1 that is inside OU0, then a base DN of OU=ou1,OU=ou0,DC=... would be correct. But if you want to match OU1 or OU0, that cannot be done with a single search operation – you need to combine two searches, each under its own base.

EDIT 1: I have also tried this solution:

base_dn = "dc=dc1,dc=local,ou=ou0,ou=ou1"
search_filter = "(&(objectClass=person)(mail=john*)(ou:dn:=ou1))"

The :dn: modifier is, unfortunately, only supported by OpenLDAP (and maybe 389ds/FreeIPA). It is not supported by Active Directory; AD DCs treat the filter as if it were just (ou=ou1), which will never match the child entries.