1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-14 12:59:07 +03:00

s4:ldapcmp: cope with range retrivals of multivalued attributes

A Windows Server returns a 'member;range=0-1499' attribute
with the first 1500 values of the 'member' attribute.

The client can do a BASE search on the given object
and ask for the 'member;range=1500-*' attribute.
It needs to loop until the high part of the returned
range is '*'.

metze

Autobuild-User: Stefan Metzmacher <metze@samba.org>
Autobuild-Date: Mon Feb 14 16:26:46 CET 2011 on sn-devel-104
This commit is contained in:
Stefan Metzmacher
2011-02-14 14:18:14 +01:00
parent d3c082e539
commit b423d83729

View File

@ -133,6 +133,73 @@ class LDAPBase(object):
except Ldb.LdbError, e:
assert "No such object" in str(e)
def get_attribute_name(self, key):
""" Returns the real attribute name
It resolved ranged results e.g. member;range=0-1499
"""
r = re.compile("^([^;]+);range=(\d+)-(\d+|\*)$")
m = r.match(key)
if m is None:
return key
return m.group(1)
def get_attribute_values(self, object_dn, key, vals):
""" Returns list with all attribute values
It resolved ranged results e.g. member;range=0-1499
"""
r = re.compile("^([^;]+);range=(\d+)-(\d+|\*)$")
m = r.match(key)
if m is None:
# no range, just return the values
return vals
attr = m.group(1)
hi = int(m.group(3))
# get additional values in a loop
# until we get a response with '*' at the end
while True:
n = "%s;range=%d-*" % (attr, hi + 1)
res = self.ldb.search(base=object_dn, scope=SCOPE_BASE, attrs=[n])
assert len(res) == 1
res = dict(res[0])
del res["dn"]
fm = None
fvals = None
for key in res.keys():
m = r.match(key)
if m is None:
continue
if m.group(1) != attr:
continue
fm = m
fvals = list(res[key])
break
if fm is None:
break
vals.extend(fvals)
if fm.group(3) == "*":
# if we got "*" we're done
break
assert int(fm.group(2)) == hi + 1
hi = int(fm.group(3))
return vals
def get_attributes(self, object_dn):
""" Returns dict with all default visible attributes
"""
@ -142,7 +209,11 @@ class LDAPBase(object):
# 'Dn' element is not iterable and we have it as 'distinguishedName'
del res["dn"]
for key in res.keys():
res[key] = list(res[key])
vals = list(res[key])
del res[key]
name = self.get_attribute_name(key)
res[name] = self.get_attribute_values(object_dn, key, vals)
return res
def get_descriptor_sddl(self, object_dn):