📄 minschema.py
字号:
#!/usr/bin/python# # work out the minimal schema for a set of objectclasses #import optparseimport os, sys# Find right directory when running from source treesys.path.insert(0, "bin/python")import sambafrom samba import getopt as optionsimport sysparser = optparse.OptionParser("minschema <URL> <classfile>")sambaopts = options.SambaOptions(parser)parser.add_option_group(sambaopts)credopts = options.CredentialsOptions(parser)parser.add_option_group(credopts)parser.add_option_group(options.VersionOptions(parser))parser.add_option("--verbose", help="Be verbose", action="store_true")parser.add_option("--dump-classes", action="store_true")parser.add_option("--dump-attributes", action="store_true")parser.add_option("--dump-subschema", action="store_true")parser.add_option("--dump-subschema-auto", action="store_true")opts, args = parser.parse_args()opts.dump_all = Trueif opts.dump_classes: opts.dump_all = Falseif opts.dump_attributes: opts.dump_all = Falseif opts.dump_subschema: opts.dump_all = Falseif opts.dump_subschema_auto: opts.dump_all = False opts.dump_subschema = Trueif opts.dump_all: opts.dump_classes = True opts.dump_attributes = True opts.dump_subschema = True opts.dump_subschema_auto = Trueif len(args) != 2: parser.print_usage() sys.exit(1)(url, classfile) = argscreds = credopts.get_credentials()ldb = Ldb(url, credentials=creds)objectclasses = []attributes = []objectclasses_expanded = set()# the attributes we need for objectclassesclass_attrs = ["objectClass", "subClassOf", "governsID", "possSuperiors", "possibleInferiors", "mayContain", "mustContain", "auxiliaryClass", "rDNAttID", "showInAdvancedViewOnly", "adminDisplayName", "adminDescription", "objectClassCategory", "lDAPDisplayName", "schemaIDGUID", "systemOnly", "systemPossSuperiors", "systemMayContain", "systemMustContain", "systemAuxiliaryClass", "defaultSecurityDescriptor", "systemFlags", "defaultHidingValue", "objectCategory", "defaultObjectCategory", # this attributes are not used by w2k3 "schemaFlagsEx", "msDs-IntId", "msDs-Schema-Extensions", "classDisplayName", "isDefunct"]attrib_attrs = ["objectClass", "attributeID", "attributeSyntax", "isSingleValued", "rangeLower", "rangeUpper", "mAPIID", "linkID", "showInAdvancedViewOnly", "adminDisplayName", "oMObjectClass", "adminDescription", "oMSyntax", "searchFlags", "extendedCharsAllowed", "lDAPDisplayName", "schemaIDGUID", "attributeSecurityGUID", "systemOnly", "systemFlags", "isMemberOfPartialAttributeSet", "objectCategory", # this attributes are not used by w2k3 "schemaFlagsEx", "msDs-IntId", "msDs-Schema-Extensions", "classDisplayName", "isEphemeral", "isDefunct"]## notes:## objectClassCategory # 1: structural# 2: abstract# 3: auxiliary## print only if verbose is set#def dprintf(text): if verbose is not None: print textdef get_object_cn(ldb, name): attrs = ["cn"] res = ldb.search("(ldapDisplayName=%s)" % name, rootDse["schemaNamingContext"], ldb.SCOPE_SUBTREE, attrs) assert len(res) == 1 return res[0]["cn"]class Objectclass: def __init__(self, ldb, name): """create an objectclass object""" self.name = name self.cn = get_object_cn(ldb, name)class Attribute: def __init__(self, ldb, name): """create an attribute object""" self.name = name self.cn = get_object_cn(ldb, name)syntaxmap = dict()syntaxmap['2.5.5.1'] = '1.3.6.1.4.1.1466.115.121.1.12'syntaxmap['2.5.5.2'] = '1.3.6.1.4.1.1466.115.121.1.38'syntaxmap['2.5.5.3'] = '1.2.840.113556.1.4.1362'syntaxmap['2.5.5.4'] = '1.2.840.113556.1.4.905'syntaxmap['2.5.5.5'] = '1.3.6.1.4.1.1466.115.121.1.26'syntaxmap['2.5.5.6'] = '1.3.6.1.4.1.1466.115.121.1.36'syntaxmap['2.5.5.7'] = '1.2.840.113556.1.4.903'syntaxmap['2.5.5.8'] = '1.3.6.1.4.1.1466.115.121.1.7'syntaxmap['2.5.5.9'] = '1.3.6.1.4.1.1466.115.121.1.27'syntaxmap['2.5.5.10'] = '1.3.6.1.4.1.1466.115.121.1.40'syntaxmap['2.5.5.11'] = '1.3.6.1.4.1.1466.115.121.1.24'syntaxmap['2.5.5.12'] = '1.3.6.1.4.1.1466.115.121.1.15'syntaxmap['2.5.5.13'] = '1.3.6.1.4.1.1466.115.121.1.43'syntaxmap['2.5.5.14'] = '1.2.840.113556.1.4.904'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'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 sdef fix_dn(dn): """fix a string DN to use ${SCHEMADN}""" return dn.replace(rootDse["schemaNamingContext"], "${SCHEMADN}")def write_ldif_one(o, attrs): """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 if a == "oMObjectClass": print "%s:: %s\n" % (a, o[a]) continue v = o[a] if isinstance(v, str): v = [v] for j in v: print "%s: %s\n" % (a, fix_dn(j)) print "\n"def write_ldif(o, attrs): """dump an array of objects as ldif""" for i in o: write_ldif_one(i, attrs)def create_testdn(exampleDN): """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)def find_objectclass_properties(ldb, o): """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]def find_attribute_properties(ldb, o): """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 if a == "oMObjectClass": o[a] = ldb.encode(msg[a]) continue o[a] = msg[a]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) print "testdn is '%s'\n" % testdn 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 return res = ldb.search("", testdn, ldb.SCOPE_BASE) ldb.delete(testdn) for a in res.msgs[0]: attributes[a].autocreate = Truedef expand_objectclass(ldb, o): """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):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -