diff options
Diffstat (limited to 'source4/dsdb/samdb')
-rwxr-xr-x | source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py new file mode 100755 index 0000000000..0e74456dac --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py @@ -0,0 +1,155 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Andrew Tridgell 2009 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +"""Tests the possibleInferiors generation in the schema_fsmo ldb module""" + +import optparse +import sys + + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + +import samba +from samba import getopt as options, Ldb +import ldb + +parser = optparse.OptionParser("possibleinferiors.py <URL> [<CLASS>]") +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)) + +opts, args = parser.parse_args() + +if len(args) < 1: + parser.print_usage() + sys.exit(1) + +url = args[0] +if (len(args) > 1): + objectclass = args[1] +else: + objectclass = None + +def uniq_list(alist): + """return a unique list""" + set = {} + return [set.setdefault(e,e) for e in alist if e not in set] + + +lp_ctx = sambaopts.get_loadparm() + +creds = credopts.get_credentials(lp_ctx) +db = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"]) + +# get the rootDSE +res = db.search(base="", expression="", + scope=ldb.SCOPE_BASE, + attrs=["schemaNamingContext"]) +rootDse = res[0] + +schema_base = rootDse["schemaNamingContext"][0] + +def possible_inferiors_search(db, oc): + """return the possible inferiors via a search for the possibleInferiors attribute""" + res = db.search(base=schema_base, + expression=("ldapdisplayname=%s" % oc), + attrs=["possibleInferiors"]) + + poss=[] + if len(res) == 0 or res[0].get("possibleInferiors") is None: + return poss + for item in res[0]["possibleInferiors"]: + poss.append(str(item)) + poss = uniq_list(poss) + poss.sort() + return poss; + + + +# see [MS-ADTS] section 3.1.1.4.5.21 +# for this algorithm + +# !systemOnly=TRUE +# !objectClassCategory=2 +# !objectClassCategory=3 + +def POSSINFERIORS(db, oc): + """returns a list of possible inferiors to a class. Returned list has the ldapdisplayname, systemOnly and objectClassCategory for each element""" + expanded = [oc] + res = db.search(base=schema_base, + expression=("subclassof=%s" % str(oc["ldapdisplayname"][0])), + attrs=["ldapdisplayname", "systemOnly", "objectClassCategory"]) + for r in res: + expanded.extend(POSSINFERIORS(db,r)) + return expanded + +def possible_inferiors_constructed(db, oc): + """return the possbible inferiors via a recursive search and match""" + res = db.search(base=schema_base, + expression=("(&(objectclass=classSchema)(|(posssuperiors=%s)(systemposssuperiors=%s)))" % (oc,oc)), + attrs=["ldapdisplayname", "systemOnly", "objectClassCategory"]) + + poss = [] + for r in res: + poss.extend(POSSINFERIORS(db,r)) + + poss2 = [] + for p in poss: + if (not (p["systemOnly"][0] == "TRUE" or + int(p["objectClassCategory"][0]) == 2 or + int(p["objectClassCategory"][0]) == 3)): + poss2.append(p["ldapdisplayname"][0]) + + poss2 = uniq_list(poss2) + poss2.sort() + return poss2 + +def test_class(db, oc): + """test to see if one objectclass returns the correct possibleInferiors""" + poss1 = possible_inferiors_search(db, oc) + poss2 = possible_inferiors_constructed(db, oc) + if poss1 != poss2: + print "Returned incorrect list for objectclass %s" % oc + print poss1 + print poss2 + for i in range(0,min(len(poss1),len(poss2))): + print "%30s %30s" % (poss1[i], poss2[i]) + exit(1) + +def get_object_classes(db): + """return a list of all object classes""" + res = db.search(base=schema_base, + expression="objectClass=classSchema", + attrs=["ldapdisplayname"]) + list=[] + for item in res: + list.append(item["ldapdisplayname"][0]) + return list + +if objectclass is None: + for oc in get_object_classes(db): + print "testing objectClass %s" % oc + test_class(db,oc) +else: + test_class(db,objectclass) + +print "Lists match OK" |