LdapServer: Add paged_search()
This commit is contained in:
parent
1f72a85b71
commit
4135d00dd3
1 changed files with 70 additions and 0 deletions
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue