summaryrefslogtreecommitdiff
path: root/source4/scripting/python
diff options
context:
space:
mode:
authorZahari Zahariev <zahari.zahariev@postpath.com>2011-01-05 18:56:23 +0200
committerAnatoliy Atanasov <anatoliy.atanasov@postpath.com>2011-01-07 13:22:26 +0100
commit6a0a0478ad6f77e3279775dcb0dad51bc3b1457a (patch)
tree150ffdb56a9a382af2a69b017da6e2de505a6212 /source4/scripting/python
parent2187c490137b420fd09343fcc03c04320b9f8183 (diff)
downloadsamba-6a0a0478ad6f77e3279775dcb0dad51bc3b1457a.tar.gz
samba-6a0a0478ad6f77e3279775dcb0dad51bc3b1457a.tar.bz2
samba-6a0a0478ad6f77e3279775dcb0dad51bc3b1457a.zip
s4/ldapcmp: Two new options are added to the tool
The new ones are --base and --scope they give us the opportunity to compare DN subsets of the partitions. Now we are also able to compare any two objects even if they have different DNs. This is exteremely helpful when you are after nasty nTSecurityDescriptor bug. Signed-off-by: Anatoliy Atanasov <anatoliy.atanasov@postpath.com> Autobuild-User: Anatoliy Atanasov <anatoliy.atanasov@postpath.com> Autobuild-Date: Fri Jan 7 13:22:26 CET 2011 on sn-devel-104
Diffstat (limited to 'source4/scripting/python')
-rwxr-xr-xsource4/scripting/python/samba/netcmd/ldapcmp.py116
1 files changed, 76 insertions, 40 deletions
diff --git a/source4/scripting/python/samba/netcmd/ldapcmp.py b/source4/scripting/python/samba/netcmd/ldapcmp.py
index 7816fce4d8..dff0c1e8fd 100755
--- a/source4/scripting/python/samba/netcmd/ldapcmp.py
+++ b/source4/scripting/python/samba/netcmd/ldapcmp.py
@@ -47,7 +47,7 @@ class LDAPBase(object):
def __init__(self, host, creds, lp,
two=False, quiet=False, descriptor=False, verbose=False,
- view="section"):
+ view="section", base="", scope="SUB"):
ldb_options = []
samdb_url = host
if not "://" in host:
@@ -62,6 +62,8 @@ class LDAPBase(object):
credentials=creds,
lp=lp,
options=ldb_options)
+ self.search_base = base
+ self.search_scope = scope
self.two_domains = two
self.quiet = quiet
self.descriptor = descriptor
@@ -591,6 +593,8 @@ class LDAPBundel(object):
self.two_domains = self.con.two_domains
self.quiet = self.con.quiet
self.verbose = self.con.verbose
+ self.search_base = self.con.search_base
+ self.search_scope = self.con.search_scope
self.summary = {}
self.summary["unique_attrs"] = []
self.summary["df_value_attrs"] = []
@@ -635,32 +639,36 @@ class LDAPBundel(object):
self.log( "\n* DN lists have different size: %s != %s" % (self.size, other.size) )
res = False
#
- title= "\n* DNs found only in %s:" % self.con.host
- for x in self.dn_list:
- if not x.upper() in [q.upper() for q in other.dn_list]:
- if title:
- self.log( title )
- title = None
- res = False
- self.log( 4*" " + x )
- self.dn_list[self.dn_list.index(x)] = ""
- self.dn_list = [x for x in self.dn_list if x]
- #
- title= "\n* DNs found only in %s:" % other.con.host
- for x in other.dn_list:
- if not x.upper() in [q.upper() for q in self.dn_list]:
- if title:
- self.log( title )
- title = None
- res = False
- self.log( 4*" " + x )
- other.dn_list[other.dn_list.index(x)] = ""
- other.dn_list = [x for x in other.dn_list if x]
- #
- self.update_size()
- other.update_size()
- assert self.size == other.size
- assert sorted([x.upper() for x in self.dn_list]) == sorted([x.upper() for x in other.dn_list])
+ # This is the case where we want to explicitly compare two objects with different DNs.
+ # It does not matter if they are in the same DC, in two DC in one domain or in two
+ # different domains.
+ if self.search_scope != SCOPE_BASE:
+ title= "\n* DNs found only in %s:" % self.con.host
+ for x in self.dn_list:
+ if not x.upper() in [q.upper() for q in other.dn_list]:
+ if title:
+ self.log( title )
+ title = None
+ res = False
+ self.log( 4*" " + x )
+ self.dn_list[self.dn_list.index(x)] = ""
+ self.dn_list = [x for x in self.dn_list if x]
+ #
+ title= "\n* DNs found only in %s:" % other.con.host
+ for x in other.dn_list:
+ if not x.upper() in [q.upper() for q in self.dn_list]:
+ if title:
+ self.log( title )
+ title = None
+ res = False
+ self.log( 4*" " + x )
+ other.dn_list[other.dn_list.index(x)] = ""
+ other.dn_list = [x for x in other.dn_list if x]
+ #
+ self.update_size()
+ other.update_size()
+ assert self.size == other.size
+ assert sorted([x.upper() for x in self.dn_list]) == sorted([x.upper() for x in other.dn_list])
self.log( "\n* Objects to be compared: %s" % self.size )
index = 0
@@ -718,10 +726,22 @@ class LDAPBundel(object):
search_base = "CN=Schema,CN=Configuration,%s" % self.con.base_dn
dn_list = []
- res = self.con.ldb.search(base=search_base, scope=SCOPE_SUBTREE, attrs=["dn"])
+ if not self.search_base:
+ self.search_base = search_base
+ self.search_scope = self.search_scope.upper()
+ if self.search_scope == "SUB":
+ self.search_scope = SCOPE_SUBTREE
+ elif self.search_scope == "BASE":
+ self.search_scope = SCOPE_BASE
+ elif self.search_scope == "ONE":
+ self.search_scope = SCOPE_ONELEVEL
+ else:
+ raise StandardError("Wrong 'scope' given. Choose from: SUB, ONE, BASE")
+ if not self.search_base.upper().endswith(search_base.upper()):
+ raise StandardError("Invalid search base specified: %s" % self.search_base)
+ res = self.con.ldb.search(base=self.search_base, scope=self.search_scope, attrs=["dn"])
for x in res:
dn_list.append(x["dn"].get_linearized())
-
#
global summary
#
@@ -754,24 +774,31 @@ class cmd_ldapcmp(Command):
takes_options = [
Option("-w", "--two", dest="two", action="store_true", default=False,
- help="Hosts are in two different domains"),
+ help="Hosts are in two different domains"),
Option("-q", "--quiet", dest="quiet", action="store_true", default=False,
- help="Do not print anything but relay on just exit code"),
+ help="Do not print anything but relay on just exit code"),
Option("-v", "--verbose", dest="verbose", action="store_true", default=False,
- help="Print all DN pairs that have been compared"),
+ help="Print all DN pairs that have been compared"),
Option("--sd", dest="descriptor", action="store_true", default=False,
- help="Compare nTSecurityDescriptor attibutes only"),
+ help="Compare nTSecurityDescriptor attibutes only"),
Option("--view", dest="view", default="section",
- help="Display mode for nTSecurityDescriptor results. Possible values: section or collision.")
+ help="Display mode for nTSecurityDescriptor results. Possible values: section or collision."),
+ Option("--base", dest="base", default="",
+ help="Pass search base that will build DN list for the first DC."),
+ Option("--base2", dest="base2", default="",
+ help="Pass search base that will build DN list for the second DC. Used when --two or when compare two different DNs."),
+ Option("--scope", dest="scope", default="SUB",
+ help="Pass search scope that builds DN list. Options: SUB, ONE, BASE"),
]
def run(self, URL1, URL2,
context1=None, context2=None, context3=None,
two=False, quiet=False, verbose=False, descriptor=False, view="section",
+ base="", base2="", scope="SUB",
credopts=None, sambaopts=None, versionopts=None):
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp, fallback_machine=True)
- creds2 = credopts.get_credentials2(lp, False)
+ creds2 = credopts.get_credentials2(lp, guess=False)
if creds2.is_anonymous():
creds2 = creds
else:
@@ -783,8 +810,13 @@ class cmd_ldapcmp(Command):
# make a list of contexts to compare in
contexts = []
if context1 is None:
- # if no argument given, we compare all contexts
- contexts = ["DOMAIN", "CONFIGURATION", "SCHEMA"]
+ if base and base2:
+ # If search bases are specified context is defaulted to
+ # DOMAIN so the given search bases can be verified.
+ contexts = ["DOMAIN"]
+ else:
+ # if no argument given, we compare all contexts
+ contexts = ["DOMAIN", "CONFIGURATION", "SCHEMA"]
else:
for c in [context1, context2, context3]:
if c is None:
@@ -795,15 +827,19 @@ class cmd_ldapcmp(Command):
if verbose and quiet:
raise CommandError("You cannot set --verbose and --quiet together")
+ if (not base and base2) or (base and not base2):
+ raise CommandError("You need to specify both --base and --base2 at the same time")
if descriptor and view.upper() not in ["SECTION", "COLLISION"]:
- raise CommandError("Unknown --view option value. Choose from: section or collision.")
+ raise CommandError("Invalid --view value. Choose from: section or collision")
+ if not scope.upper() in ["SUB", "ONE", "BASE"]:
+ raise CommandError("Invalid --scope value. Choose from: SUB, ONE, BASE")
con1 = LDAPBase(URL1, creds, lp,
- two=two, quiet=quiet, descriptor=descriptor, verbose=verbose, view=view)
+ two=two, quiet=quiet, descriptor=descriptor, verbose=verbose, view=view, base=base, scope=scope)
assert len(con1.base_dn) > 0
con2 = LDAPBase(URL2, creds2, lp,
- two=two, quiet=quiet, descriptor=descriptor, verbose=verbose, view=view)
+ two=two, quiet=quiet, descriptor=descriptor, verbose=verbose, view=view, base=base2, scope=scope)
assert len(con2.base_dn) > 0
status = 0