From cac225ba7daf8d88d858292902480415f0fa00e2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 10 Feb 2008 00:56:55 +0100 Subject: More syntax fixes, use more standard python functions. (This used to be commit ea07509b4a9335a3b3fe6f6da1124fd1aab33c96) --- source4/scripting/bin/minschema.py | 575 ++++++++++++++++--------------------- 1 file changed, 247 insertions(+), 328 deletions(-) (limited to 'source4') diff --git a/source4/scripting/bin/minschema.py b/source4/scripting/bin/minschema.py index 0a16cc9886..fb9d7b05aa 100755 --- a/source4/scripting/bin/minschema.py +++ b/source4/scripting/bin/minschema.py @@ -3,9 +3,10 @@ # work out the minimal schema for a set of objectclasses # -import getopt import optparse import samba +from samba import getopt as options +import sys parser = optparse.OptionParser("minschema ") sambaopts = options.SambaOptions(parser) @@ -28,14 +29,14 @@ if opts.dump_attributes: opts.dump_all = False if opts.dump_subschema: opts.dump_all = False -if dump_subschema_auto: - opts.dump_all = False - opts.dump_subschema = True +if opts.dump_subschema_auto: + opts.dump_all = False + opts.dump_subschema = True if opts.dump_all: - opts.dump_classes = True - opts.dump_attributes = True - opts.dump_subschema = True - opts.dump_subschema_auto = True + opts.dump_classes = True + opts.dump_attributes = True + opts.dump_subschema = True + opts.dump_subschema_auto = True if len(args) != 2: parser.print_usage() @@ -48,9 +49,8 @@ ldb = Ldb(url, credentials=creds) objectclasses = [] attributes = [] -rootDse = {} -objectclasses_expanded = [] +objectclasses_expanded = set() # the attributes we need for objectclasses class_attrs = ["objectClass", @@ -130,33 +130,28 @@ attrib_attrs = ["objectClass", # def dprintf(text): if verbose is not None: - print text + print text def get_object_cn(ldb, name): - attrs = ["cn"] + attrs = ["cn"] - res = ldb.search("(ldapDisplayName=%s)" % name, rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs) - assert len(res) == 1 + res = ldb.search("(ldapDisplayName=%s)" % name, rootDse["schemaNamingContext"], ldb.SCOPE_SUBTREE, attrs) + assert len(res) == 1 - cn = res[0]["cn"] + return res[0]["cn"] -# -# create an objectclass object -# -def obj_objectClass(ldb, name): - var o = new Object() - o.name = name - o.cn = get_object_cn(ldb, name) - return o +class Objectclass: + def __init__(self, ldb, name): + """create an objectclass object""" + self.name = name + self.cn = get_object_cn(ldb, name) -# -# create an attribute object -# -def obj_attribute(ldb, name): - var o = new Object() - o.name = name - o.cn = get_object_cn(ldb, name) - return o + +class Attribute: + def __init__(self, ldb, name): + """create an attribute object""" + self.name = name + self.cn = get_object_cn(ldb, name) syntaxmap = dict() @@ -179,397 +174,330 @@ syntaxmap['2.5.5.15'] = '1.2.840.113556.1.4.907' syntaxmap['2.5.5.16'] = '1.2.840.113556.1.4.906' syntaxmap['2.5.5.17'] = '1.3.6.1.4.1.1466.115.121.1.40' -# -# map some attribute syntaxes from some apparently MS specific -# syntaxes to the standard syntaxes -# + def map_attribute_syntax(s): + """map some attribute syntaxes from some apparently MS specific + syntaxes to the standard syntaxes""" if syntaxmap.has_key(s): - return syntaxmap[s] - return s + return syntaxmap[s] + return s + -# -# fix a string DN to use ${SCHEMADN} -# def fix_dn(dn): - s = strstr(dn, rootDse.schemaNamingContext) - if (s == NULL) { - return dn - } - return substr(dn, 0, strlen(dn) - strlen(s)) + "${SCHEMADN}" + """fix a string DN to use ${SCHEMADN}""" + return dn.replace(rootDse["schemaNamingContext"], "${SCHEMADN}") + -# -# dump an object as ldif -# def write_ldif_one(o, attrs): - print "dn: CN=%s,${SCHEMADN}\n" % o["cn"] + """dump an object as ldif""" + print "dn: CN=%s,${SCHEMADN}\n" % o["cn"] for a in attrs: if not o.has_key(a): - continue - # special case for oMObjectClass, which is a binary object + continue + # special case for oMObjectClass, which is a binary object if a == "oMObjectClass": - print "%s:: %s\n" % (a, o[a]) - continue - v = o[a] + print "%s:: %s\n" % (a, o[a]) + continue + v = o[a] if isinstance(v, str): - v = [v] + v = [v] for j in v: - print "%s: %s\n" % (a, fix_dn(j)) - print "\n" + print "%s: %s\n" % (a, fix_dn(j)) + print "\n" -# -# dump an array of objects as ldif -# def write_ldif(o, attrs): + """dump an array of objects as ldif""" for i in o: - write_ldif_one(i, attrs) + write_ldif_one(i, attrs) -# -# create a testDN based an an example DN -# the idea is to ensure we obey any structural rules -# def create_testdn(exampleDN): - a = split(",", exampleDN) - a[0] = "CN=TestDN" - return ",".join(a) + """create a testDN based an an example DN + the idea is to ensure we obey any structural rules""" + a = exampleDN.split(",") + a[0] = "CN=TestDN" + return ",".join(a) + -# -# find the properties of an objectclass -# def find_objectclass_properties(ldb, o): - res = ldb.search( - expression="(ldapDisplayName=%s)" % o.name, - rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, class_attrs) - assert(len(res) == 1) + """the properties of an objectclass""" + res = ldb.search( + expression="(ldapDisplayName=%s)" % o.name, + basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE, attrs=class_attrs) + assert(len(res) == 1) msg = res[0] for a in msg: - o[a] = msg[a] + o[a] = msg[a] -# -# find the properties of an attribute -# def find_attribute_properties(ldb, o): - res = ldb.search( - expression="(ldapDisplayName=%s)" % o.name, - rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrib_attrs) - assert(len(res) == 1) + """find the properties of an attribute""" + res = ldb.search( + expression="(ldapDisplayName=%s)" % o.name, + basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE, + attrs=attrib_attrs) + assert(len(res) == 1) msg = res[0] for a in msg: - # special case for oMObjectClass, which is a binary object + # special case for oMObjectClass, which is a binary object if a == "oMObjectClass": - o[a] = ldb.encode(msg[a]) - continue - o[a] = msg[a] + o[a] = ldb.encode(msg[a]) + continue + o[a] = msg[a] + -# -# find the auto-created properties of an objectclass. Only works for classes -# that can be created using just a DN and the objectclass -# def find_objectclass_auto(ldb, o): + """find the auto-created properties of an objectclass. Only works for + classes that can be created using just a DN and the objectclass""" if not o.has_key("exampleDN"): - return - testdn = create_testdn(o.exampleDN) + return + testdn = create_testdn(o.exampleDN) - print "testdn is '%s'\n" % testdn + print "testdn is '%s'\n" % testdn - ldif = "dn: " + testdn - ldif += "\nobjectClass: " + o.name + ldif = "dn: " + testdn + ldif += "\nobjectClass: " + o.name try: ldb.add(ldif) except LdbError, e: print "error adding %s: %s\n" % (o.name, e) - print "%s\n" % ldif + print "%s\n" % ldif return - res = ldb.search("", testdn, ldb.SCOPE_BASE) - ldb.delete(testdn) + res = ldb.search("", testdn, ldb.SCOPE_BASE) + ldb.delete(testdn) for a in res.msgs[0]: - attributes[a].autocreate = True + attributes[a].autocreate = True -# -# look at auxiliary information from a class to intuit the existance of more -# classes needed for a minimal schema -# def expand_objectclass(ldb, o): - attrs = ["auxiliaryClass", "systemAuxiliaryClass", - "possSuperiors", "systemPossSuperiors", - "subClassOf"] - res = ldb.search( - "(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name, - rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs) - print "Expanding class %s\n" % o.name - assert(len(res) == 1) - msg = res[0] + """look at auxiliary information from a class to intuit the existance of + more classes needed for a minimal schema""" + attrs = ["auxiliaryClass", "systemAuxiliaryClass", + "possSuperiors", "systemPossSuperiors", + "subClassOf"] + res = ldb.search( + expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name, + basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE, + attrs=attrs) + print "Expanding class %s\n" % o.name + assert(len(res) == 1) + msg = res[0] for a in attrs: if not msg.has_key(aname): - continue - list = msg[aname] + continue + list = msg[aname] if isinstance(list, str): - list = [msg[aname]] + list = [msg[aname]] for name in list: if not objectclasses.has_key(name): - print "Found new objectclass '%s'\n" % name - objectclasses[name] = obj_objectClass(ldb, name) + print "Found new objectclass '%s'\n" % name + objectclasses[name] = Objectclass(ldb, name) -# -# add the must and may attributes from an objectclass to the full list -# of attributes -# -def add_objectclass_attributes(ldb, class): - attrs = ["mustContain", "systemMustContain", - "mayContain", "systemMayContain"] +def add_objectclass_attributes(ldb, objectclass): + """add the must and may attributes from an objectclass to the full list + of attributes""" + attrs = ["mustContain", "systemMustContain", + "mayContain", "systemMayContain"] for aname in attrs: - if not class.has_key(aname): - continue - alist = class[aname] + if not objectclass.has_key(aname): + continue + alist = objectclass[aname] if isinstance(alist, str): - alist = [alist] + alist = [alist] for a in alist: if not attributes.has_key(a): - attributes[a] = obj_attribute(ldb, a) + attributes[a] = Attribute(ldb, a) -# -# process an individual record, working out what attributes it has -# def walk_dn(ldb, dn): - # get a list of all possible attributes for this object - attrs = ["allowedAttributes"] + """process an individual record, working out what attributes it has""" + # get a list of all possible attributes for this object + attrs = ["allowedAttributes"] try: res = ldb.search("objectClass=*", dn, ldb.SCOPE_BASE, attrs) except LdbError, e: - print "Unable to fetch allowedAttributes for '%s' - %r\n" % (dn, e) - return - allattrs = res[0]["allowedAttributes"] + print "Unable to fetch allowedAttributes for '%s' - %r\n" % (dn, e) + return + allattrs = res[0]["allowedAttributes"] try: res = ldb.search("objectClass=*", dn, ldb.SCOPE_BASE, allattrs) except LdbError, e: print "Unable to fetch all attributes for '%s' - %s\n" % (dn, e) - return - msg = res[0] + return + msg = res[0] for a in msg: if not attributes.has_key(a): - attributes[a] = obj_attribute(ldb, a) + attributes[a] = Attribute(ldb, a) -# -# walk a naming context, looking for all records -# def walk_naming_context(ldb, namingContext): + """walk a naming context, looking for all records""" try: res = ldb.search("objectClass=*", namingContext, ldb.SCOPE_DEFAULT, ["objectClass"]) except LdbError, e: - print "Unable to fetch objectClasses for '%s' - %s\n" % (namingContext, e) - return + print "Unable to fetch objectClasses for '%s' - %s\n" % (namingContext, e) + return for msg in res: - msg = res.msgs[r]["objectClass"] + msg = res.msgs[r]["objectClass"] for objectClass in msg: if not objectclasses.has_key(objectClass): - objectclasses[objectClass] = obj_objectClass(ldb, objectClass) - objectclasses[objectClass].exampleDN = res.msgs[r]["dn"] - walk_dn(ldb, res.msgs[r].dn) - -# -# trim the may attributes for an objectClass -# -def trim_objectclass_attributes(ldb, class): - # trim possibleInferiors, - # include only the classes we extracted - if class.has_key("possibleInferiors"): - possinf = class["possibleInferiors"] - newpossinf = [] + objectclasses[objectClass] = Objectclass(ldb, objectClass) + objectclasses[objectClass].exampleDN = res.msgs[r]["dn"] + walk_dn(ldb, res.msgs[r].dn) + +def trim_objectclass_attributes(ldb, objectclass): + """trim the may attributes for an objectClass""" + # trim possibleInferiors, + # include only the classes we extracted + if objectclass.has_key("possibleInferiors"): + possinf = objectclass["possibleInferiors"] + newpossinf = [] if isinstance(possinf, str): - possinf = [possinf] + possinf = [possinf] for x in possinf: if objectclasses.has_key(x): - newpossinf[n] = x - n++ - class["possibleInferiors"] = newpossinf - - # trim systemMayContain, - # remove duplicates - if class.has_key("systemMayContain"): - sysmay = class["systemMayContain"] - newsysmay = [] + newpossinf[n] = x + n+=1 + objectclass["possibleInferiors"] = newpossinf + + # trim systemMayContain, + # remove duplicates + if objectclass.has_key("systemMayContain"): + sysmay = objectclass["systemMayContain"] + newsysmay = [] if isinstance(sysmay, str): - sysmay = [sysmay] + sysmay = [sysmay] for x in sysmay: - dup = False - if newsysmay[0] == undefined) { - newsysmay[0] = x - else: - for (n = 0; n < newsysmay.length; n++) { - if (newsysmay[n] == x) { - dup = True - if not dup: - newsysmay[n] = x - class["systemMayContain"] = newsysmay - - # trim mayContain, - # remove duplicates - if not class.has_key("mayContain"): - may = class["mayContain"] - newmay = [] + if not x in newsysmay: + newsysmay.append(x) + objectclass["systemMayContain"] = newsysmay + + # trim mayContain, + # remove duplicates + if not objectclass.has_key("mayContain"): + may = objectclass["mayContain"] + newmay = [] if isinstance(may, str): - may = [may] + may = [may] for x in may: - dup = False - if (newmay[0] == undefined) { - newmay[0] = x - } else { - for (n = 0; n < newmay.length; n++) { - if (newmay[n] == x) { - dup = True - if not dup: - newmay[n] = x - class["mayContain"] = newmay + if not x in newmay: + newmay.append(x) + objectclass["mayContain"] = newmay -# -# load the basic attributes of an objectClass -# def build_objectclass(ldb, name): - attrs = ["name"] + """load the basic attributes of an objectClass""" + attrs = ["name"] try: res = ldb.search( expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name, - rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs) + basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE, + attrs=attrs) except LdbError, e: - print "unknown class '%s'\n" % name - return None + print "unknown class '%s'\n" % name + return None if len(res) == 0: - print "unknown class '%s'\n" % name - return None - return obj_objectClass(ldb, name) - -# -# append 2 lists -# -def list_append(a1, a2): - if (a1 == undefined) { - return a2 - if (a2 == undefined) - return a1 - for (i=0;i