Merge "Enable a parameters on ldap to allow paged_search of ldap queries This fixes bug 1083463"
This commit is contained in:
commit
2505662bba
@ -137,6 +137,7 @@
|
|||||||
# use_dumb_member = False
|
# use_dumb_member = False
|
||||||
# allow_subtree_delete = False
|
# allow_subtree_delete = False
|
||||||
# dumb_member = cn=dumb,dc=example,dc=com
|
# dumb_member = cn=dumb,dc=example,dc=com
|
||||||
|
# page_size = 0
|
||||||
|
|
||||||
# The LDAP scope for queries, this can be either 'one'
|
# The LDAP scope for queries, this can be either 'one'
|
||||||
# (onelevel/singleLevel) or 'sub' (subtree/wholeSubtree)
|
# (onelevel/singleLevel) or 'sub' (subtree/wholeSubtree)
|
||||||
|
@ -88,6 +88,7 @@ class BaseLdap(object):
|
|||||||
self.LDAP_USER = conf.ldap.user
|
self.LDAP_USER = conf.ldap.user
|
||||||
self.LDAP_PASSWORD = conf.ldap.password
|
self.LDAP_PASSWORD = conf.ldap.password
|
||||||
self.LDAP_SCOPE = ldap_scope(conf.ldap.query_scope)
|
self.LDAP_SCOPE = ldap_scope(conf.ldap.query_scope)
|
||||||
|
self.page_size = conf.ldap.page_size
|
||||||
|
|
||||||
if self.options_name is not None:
|
if self.options_name is not None:
|
||||||
self.suffix = conf.ldap.suffix
|
self.suffix = conf.ldap.suffix
|
||||||
@ -128,7 +129,8 @@ class BaseLdap(object):
|
|||||||
if self.LDAP_URL.startswith('fake://'):
|
if self.LDAP_URL.startswith('fake://'):
|
||||||
conn = fakeldap.FakeLdap(self.LDAP_URL)
|
conn = fakeldap.FakeLdap(self.LDAP_URL)
|
||||||
else:
|
else:
|
||||||
conn = LdapWrapper(self.LDAP_URL)
|
conn = LdapWrapper(self.LDAP_URL,
|
||||||
|
self.page_size)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
user = self.LDAP_USER
|
user = self.LDAP_USER
|
||||||
@ -361,9 +363,10 @@ class BaseLdap(object):
|
|||||||
|
|
||||||
|
|
||||||
class LdapWrapper(object):
|
class LdapWrapper(object):
|
||||||
def __init__(self, url):
|
def __init__(self, url, page_size):
|
||||||
LOG.debug(_("LDAP init: url=%s"), url)
|
LOG.debug(_("LDAP init: url=%s"), url)
|
||||||
self.conn = ldap.initialize(url)
|
self.conn = ldap.initialize(url)
|
||||||
|
self.page_size = page_size
|
||||||
|
|
||||||
def simple_bind_s(self, user, password):
|
def simple_bind_s(self, user, password):
|
||||||
LOG.debug(_("LDAP bind: dn=%s"), user)
|
LOG.debug(_("LDAP bind: dn=%s"), user)
|
||||||
@ -387,15 +390,59 @@ class LdapWrapper(object):
|
|||||||
scope,
|
scope,
|
||||||
query,
|
query,
|
||||||
attrlist)
|
attrlist)
|
||||||
res = self.conn.search_s(dn, scope, query, attrlist)
|
if self.page_size:
|
||||||
|
res = self.paged_search_s(dn, scope, query, attrlist)
|
||||||
|
else:
|
||||||
|
res = self.conn.search_s(dn, scope, query, attrlist)
|
||||||
|
|
||||||
o = []
|
o = []
|
||||||
for dn, attrs in res:
|
for dn, attrs in res:
|
||||||
o.append((dn, dict((kind, [ldap2py(x) for x in values])
|
o.append((dn, dict((kind, [ldap2py(x) for x in values])
|
||||||
for kind, values in attrs.iteritems())))
|
for kind, values in attrs.iteritems())))
|
||||||
|
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def paged_search_s(self, dn, scope, query, attrlist=None):
|
||||||
|
res = []
|
||||||
|
lc = ldap.controls.SimplePagedResultsControl(
|
||||||
|
controlType=ldap.LDAP_CONTROL_PAGE_OID,
|
||||||
|
criticality=True,
|
||||||
|
controlValue=(self.page_size, ''))
|
||||||
|
msgid = self.conn.search_ext(dn,
|
||||||
|
scope,
|
||||||
|
query,
|
||||||
|
attrlist,
|
||||||
|
serverctrls=[lc])
|
||||||
|
# Endless loop request pages on ldap server until it has no data
|
||||||
|
while True:
|
||||||
|
# Request to the ldap server a page with 'page_size' entries
|
||||||
|
rtype, rdata, rmsgid, serverctrls = self.conn.result3(msgid)
|
||||||
|
# Receive the data
|
||||||
|
res.extend(rdata)
|
||||||
|
pctrls = [c for c in serverctrls
|
||||||
|
if c.controlType == ldap.LDAP_CONTROL_PAGE_OID]
|
||||||
|
if pctrls:
|
||||||
|
# LDAP server supports pagination
|
||||||
|
est, cookie = pctrls[0].controlValue
|
||||||
|
if cookie:
|
||||||
|
# There is more data still on the server
|
||||||
|
# so we request another page
|
||||||
|
lc.controlValue = (self.page_size, cookie)
|
||||||
|
msgid = self.conn.search_ext(dn,
|
||||||
|
scope,
|
||||||
|
query,
|
||||||
|
attrlist,
|
||||||
|
serverctrls=[lc])
|
||||||
|
else:
|
||||||
|
# Exit condition no more data on server
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
LOG.warning(_('LDAP Server does not support paging.'
|
||||||
|
'Disable paging in keystone.conf to'
|
||||||
|
'avoid this message'))
|
||||||
|
self._disable_paging()
|
||||||
|
break
|
||||||
|
return res
|
||||||
|
|
||||||
def modify_s(self, dn, modlist):
|
def modify_s(self, dn, modlist):
|
||||||
ldap_modlist = [
|
ldap_modlist = [
|
||||||
(op, kind, (None if values is None
|
(op, kind, (None if values is None
|
||||||
@ -418,6 +465,10 @@ class LdapWrapper(object):
|
|||||||
LOG.debug(_("LDAP delete_ext: dn=%s, serverctrls=%s"), dn, serverctrls)
|
LOG.debug(_("LDAP delete_ext: dn=%s, serverctrls=%s"), dn, serverctrls)
|
||||||
return self.conn.delete_ext_s(dn, serverctrls)
|
return self.conn.delete_ext_s(dn, serverctrls)
|
||||||
|
|
||||||
|
def _disable_paging(self):
|
||||||
|
# Disable the pagination from now on
|
||||||
|
self.page_size = 0
|
||||||
|
|
||||||
|
|
||||||
class EnabledEmuMixIn(BaseLdap):
|
class EnabledEmuMixIn(BaseLdap):
|
||||||
"""Emulates boolean 'enabled' attribute if turned on.
|
"""Emulates boolean 'enabled' attribute if turned on.
|
||||||
|
@ -250,6 +250,7 @@ register_bool('use_dumb_member', group='ldap', default=False)
|
|||||||
register_str('dumb_member', group='ldap', default='cn=dumb,dc=nonexistent')
|
register_str('dumb_member', group='ldap', default='cn=dumb,dc=nonexistent')
|
||||||
register_bool('allow_subtree_delete', group='ldap', default=False)
|
register_bool('allow_subtree_delete', group='ldap', default=False)
|
||||||
register_str('query_scope', group='ldap', default='one')
|
register_str('query_scope', group='ldap', default='one')
|
||||||
|
register_int('page_size', group='ldap', default=0)
|
||||||
|
|
||||||
register_str('user_tree_dn', group='ldap', default=None)
|
register_str('user_tree_dn', group='ldap', default=None)
|
||||||
register_str('user_filter', group='ldap', default=None)
|
register_str('user_filter', group='ldap', default=None)
|
||||||
|
Loading…
Reference in New Issue
Block a user