From b423d83729f3f096078fe49f7e46481b1b46679a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Feb 2011 14:18:14 +0100 Subject: 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 Autobuild-Date: Mon Feb 14 16:26:46 CET 2011 on sn-devel-104 --- source4/scripting/python/samba/netcmd/ldapcmp.py | 73 +++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'source4/scripting') diff --git a/source4/scripting/python/samba/netcmd/ldapcmp.py b/source4/scripting/python/samba/netcmd/ldapcmp.py index 1cde860fb1..160aa31258 100755 --- a/source4/scripting/python/samba/netcmd/ldapcmp.py +++ b/source4/scripting/python/samba/netcmd/ldapcmp.py @@ -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): -- cgit