📄 minschema.js
字号:
#!/bin/shexec smbscript "$0" ${1+"$@"}/* work out the minimal schema for a set of objectclasses */libinclude("base.js");var ldb = ldb_init();var options = GetOptions(ARGV, "POPT_AUTOHELP", "POPT_COMMON_SAMBA", "POPT_COMMON_CREDENTIALS", "verbose", "classes", "attributes", "subschema", "subschema-auto");if (options == undefined) { println("Failed to parse options"); return -1;}verbose = options["verbose"];dump_all = "yes";dump_classes = options["classes"];dump_attributes = options["attributes"];dump_subschema = options["subschema"];dump_subschema_auto = options["subschema-auto"];if (dump_classes != undefined) { dump_all = undefined;}if (dump_attributes != undefined) { dump_all = undefined;}if (dump_subschema != undefined) { dump_all = undefined;}if (dump_subschema_auto != undefined) { dump_all = undefined; dump_subschema = "yes";}if (dump_all != undefined) { dump_classes = "yes"; dump_attributes = "yes"; dump_subschema = "yes"; dump_subschema_auto = "yes";}if (options.ARGV.length != 2) { println("Usage: minschema.js <URL> <classfile>"); return -1;}var url = options.ARGV[0];var classfile = options.ARGV[1];/* use command line creds if available */ldb.credentials = options.get_credentials();var ok = ldb.connect(url);assert(ok);objectclasses = new Object();attributes = new Object();rootDse = new Object();objectclasses_expanded = new Object();/* the attributes we need for objectclasses */class_attrs = new Array("objectClass", "subClassOf", "governsID", "possSuperiors", "possibleInferiors", "mayContain", "mustContain", "auxiliaryClass", "rDNAttID", "showInAdvancedViewOnly", "adminDisplayName", "adminDescription", "objectClassCategory", "lDAPDisplayName", "schemaIDGUID", "systemOnly", "systemPossSuperiors", "systemMayContain", "systemMustContain", "systemAuxiliaryClass", "defaultSecurityDescriptor", "systemFlags", "defaultHidingValue", "defaultObjectCategory", /* this attributes are not used by w2k3 */ "schemaFlagsEx", "msDs-IntId", "msDs-Schema-Extensions", "classDisplayName", "isDefunct");attrib_attrs = new Array("objectClass", "attributeID", "attributeSyntax", "isSingleValued", "rangeLower", "rangeUpper", "mAPIID", "linkID", "showInAdvancedViewOnly", "adminDisplayName", "oMObjectClass", "adminDescription", "oMSyntax", "searchFlags", "extendedCharsAllowed", "lDAPDisplayName", "schemaIDGUID", "attributeSecurityGUID", "systemOnly", "systemFlags", "isMemberOfPartialAttributeSet", /* 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*/function dprintf() { if (verbose != undefined) { print(vsprintf(arguments)); }}function get_object_cn(ldb, name) { var attrs = new Array("cn"); var res = ldb.search(sprintf("(ldapDisplayName=%s)", name), rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs); assert(res != undefined); assert(res.msgs.length == 1); var cn = res.msgs[0]["cn"]; assert(cn != undefined); if (typeof(cn) == "string") { return cn; } return cn[0];}/* create an objectclass object*/function obj_objectClass(ldb, name) { var o = new Object(); o.name = name; o.cn = get_object_cn(ldb, name); return o;}/* create an attribute object*/function obj_attribute(ldb, name) { var o = new Object(); o.name = name; o.cn = get_object_cn(ldb, name); return o;}syntaxmap = new Object();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';/* map some attribute syntaxes from some apparently MS specific syntaxes to the standard syntaxes*/function map_attribute_syntax(s) { if (syntaxmap[s] != undefined) { return syntaxmap[s]; } return s;}/* fix a string DN to use ${SCHEMADN}*/function fix_dn(dn) { var s = strstr(dn, rootDse.schemaNamingContext); if (s == NULL) { return dn; } return substr(dn, 0, strlen(dn) - strlen(s)) + "${SCHEMADN}";}/* dump an object as ldif*/function write_ldif_one(o, attrs) { var i; printf("dn: CN=%s,${SCHEMADN}\n", o.cn); for (i=0;i<attrs.length;i++) { var a = attrs[i]; if (o[a] == undefined) { continue; } /* special case for oMObjectClass, which is a binary object */ if (a == "oMObjectClass") { printf("%s:: %s\n", a, o[a]); continue; } var v = o[a]; if (typeof(v) == "string") { v = new Array(v); } var j; for (j=0;j<v.length;j++) { printf("%s: %s\n", a, fix_dn(v[j])); } } printf("\n");}/* dump an array of objects as ldif*/function write_ldif(o, attrs) { var i; for (i in o) { write_ldif_one(o[i], attrs); }}/* create a testDN based an an example DN the idea is to ensure we obey any structural rules*/function create_testdn(exampleDN) { var a = split(",", exampleDN); a[0] = "CN=TestDN"; return join(",", a);}/* find the properties of an objectclass */function find_objectclass_properties(ldb, o) { var res = ldb.search( sprintf("(ldapDisplayName=%s)", o.name), rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, class_attrs); assert(res != undefined); assert(res.msgs.length == 1); var msg = res.msgs[0]; var a; for (a in msg) { o[a] = msg[a]; }}/* find the properties of an attribute */function find_attribute_properties(ldb, o) { var res = ldb.search( sprintf("(ldapDisplayName=%s)", o.name), rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrib_attrs); assert(res != undefined); assert(res.msgs.length == 1); var msg = res.msgs[0]; var a; 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]; }}/* find the auto-created properties of an objectclass. Only works for classes that can be created using just a DN and the objectclass */function find_objectclass_auto(ldb, o) { if (o["exampleDN"] == undefined) { return; } var testdn = create_testdn(o.exampleDN); var ok; dprintf("testdn is '%s'\n", testdn); var ldif = "dn: " + testdn; ldif = ldif + "\nobjectClass: " + o.name; ok = ldb.add(ldif); if (ok.error != 0) { dprintf("error adding %s: %s\n", o.name, ok.errstr); dprintf("%s\n", ldif); return; } var res = ldb.search("", testdn, ldb.SCOPE_BASE); ok = ldb.del(testdn); assert(ok.error == 0); var a; for (a in res.msgs[0]) { attributes[a].autocreate = true; }}/* look at auxiliary information from a class to intuit the existance of more classes needed for a minimal schema*/function expand_objectclass(ldb, o) { var attrs = new Array("auxiliaryClass", "systemAuxiliaryClass", "possSuperiors", "systemPossSuperiors", "subClassOf"); var res = ldb.search( sprintf("(&(objectClass=classSchema)(ldapDisplayName=%s))", o.name), rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs); var a; dprintf("Expanding class %s\n", o.name); assert(res != undefined); assert(res.msgs.length == 1); var msg = res.msgs[0]; for (a=0;a<attrs.length;a++) { var aname = attrs[a]; if (msg[aname] == undefined) { continue; } var list = msg[aname]; if (typeof(list) == "string") { list = new Array(msg[aname]); } var i; for (i=0;i<list.length;i++) { var name = list[i]; if (objectclasses[name] == undefined) { dprintf("Found new objectclass '%s'\n", name); objectclasses[name] = obj_objectClass(ldb, name); } } }}/* add the must and may attributes from an objectclass to the full list of attributes*/function add_objectclass_attributes(ldb, class) { var attrs = new Array("mustContain", "systemMustContain", "mayContain", "systemMayContain"); var i; for (i=0;i<attrs.length;i++) { var aname = attrs[i]; if (class[aname] == undefined) { continue; } var alist = class[aname]; if (typeof(alist) == "string") { alist = new Array(alist); } var j; var len = alist.length; for (j=0;j<len;j++) { var a = alist[j]; if (attributes[a] == undefined) { attributes[a] = obj_attribute(ldb, a); } } }}/* process an individual record, working out what attributes it has*/function walk_dn(ldb, dn) { /* get a list of all possible attributes for this object */ var attrs = new Array("allowedAttributes");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -