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.parser
import dateutil.tz import dateutil.tz
import ldap import ldap
from ldap.controls import SimplePagedResultsControl
import ldap.modlist as modlist import ldap.modlist as modlist
import logging import logging
import pytz import pytz
@ -87,6 +88,75 @@ class LdapServer(object):
result = self.search(dn, filterstr=filterstr, scope='base', attrs=attrs) result = self.search(dn, filterstr=filterstr, scope='base', attrs=attrs)
return result[dn] if dn in result else None 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): def add_object(self,dn,attrs):
ldif = modlist.addModlist(attrs) ldif = modlist.addModlist(attrs)
try: try: