LdapServer: Add paged_search()

This commit is contained in:
Benjamin Renard 2020-12-15 18:24:50 +01:00 committed by root
parent 1f72a85b71
commit 4135d00dd3

View file

@ -5,6 +5,7 @@ import datetime
import dateutil.parser
import dateutil.tz
import ldap
from ldap.controls import SimplePagedResultsControl
import ldap.modlist as modlist
import logging
import pytz
@ -87,6 +88,75 @@ class LdapServer(object):
result = self.search(dn, filterstr=filterstr, scope='base', attrs=attrs)
return result[dn] if dn in result else None
def paged_search(self, basedn, filterstr, attrs, scope='sub', pagesize=500):
# Initialize SimplePagedResultsControl object
page_control = SimplePagedResultsControl(
True,
size=pagesize,
cookie='' # Start without cookie
)
ret = {}
pages_count = 0
self.logger.debug(
"LdapServer - Paged search with base DN '%s', filter '%s', scope '%s', pagesize=%d and attrs=%s",
basedn,
filterstr,
scope,
pagesize,
attrs
)
while True:
pages_count += 1
self.logger.debug(
"LdapServer - Paged search: request page %d with a maximum of %d objects (current total count: %d)",
pages_count,
pagesize,
len(ret)
)
try:
res_id = self.con.search_ext(
basedn,
self.get_scope(scope),
filterstr,
attrs,
serverctrls=[page_control]
)
except ldap.LDAPError, e:
self._error('LdapServer - Error running paged search on LDAP server: %s' % e, logging.CRITICAL)
return False
try:
rtype, rdata, rmsgid, rctrls = self.con.result3(res_id)
except ldap.LDAPError, e:
self._error('LdapServer - Error pulling paged search result from LDAP server: %s' % e, logging.CRITICAL)
return False
# Detect and catch PagedResultsControl answer from rctrls
result_page_control = None
if rctrls:
for rctrl in rctrls:
if rctrl.controlType == SimplePagedResultsControl.controlType:
result_page_control = rctrl
break
# If PagedResultsControl answer not detected, paged serach
if not result_page_control:
self._error('LdapServer - Server ignores RFC2696 control, paged search can not works', logging.CRITICAL)
return False
# Store results of this page
for obj_dn, obj_attrs in rdata:
ret[obj_dn] = obj_attrs
# If no cookie returned, we are done
if not result_page_control.cookie:
break
# Otherwise, set cookie for the next search
page_control.cookie = result_page_control.cookie
self.logger.debug("LdapServer - Paged search end: %d object(s) retreived in %d page(s) of %d object(s)", len(ret), pages_count, pagesize)
return ret
def add_object(self,dn,attrs):
ldif = modlist.addModlist(attrs)
try: