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.
Your DN is backwards. LDAP-format DNs are hierarchical from right to left – the child of
dc=dc,dc=localwould actually beou=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: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.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.