diff options
author | Andrew Bartlett <abartlet@samba.org> | 2012-07-06 19:59:09 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2012-07-06 22:55:50 +1000 |
commit | f9d90922f577dfedfca967e2b7112e0714ea414d (patch) | |
tree | 104dce0b9b85d4a035e9d694dd589bc04c0a0281 /source4/scripting/python | |
parent | 7782e334b9ce6c0517136ae25be4e4f0629e0059 (diff) | |
download | samba-f9d90922f577dfedfca967e2b7112e0714ea414d.tar.gz samba-f9d90922f577dfedfca967e2b7112e0714ea414d.tar.bz2 samba-f9d90922f577dfedfca967e2b7112e0714ea414d.zip |
s4-dbcheck: Check for an object without a parent
Such objects are then moved to the appropriate LostAndFound container,
just as they would be if replicated.
Andrew Bartlett
Diffstat (limited to 'source4/scripting/python')
-rw-r--r-- | source4/scripting/python/samba/dbchecker.py | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py index 72d0604b34..284c52908c 100644 --- a/source4/scripting/python/samba/dbchecker.py +++ b/source4/scripting/python/samba/dbchecker.py @@ -50,6 +50,7 @@ class dbcheck(object): self.fix_all_orphaned_backlinks = False self.fix_rmd_flags = False self.seize_fsmo_role = False + self.move_to_lost_and_found = False self.in_transaction = in_transaction self.infrastructure_dn = ldb.Dn(samdb, "CN=Infrastructure," + samdb.domain_dn()) self.naming_dn = ldb.Dn(samdb, "CN=Partitions,%s" % samdb.get_config_basedn()) @@ -125,6 +126,23 @@ class dbcheck(object): return False return True + def do_rename(self, from_dn, to_rdn, to_base, controls, msg): + '''perform a modify with optional verbose output''' + if self.verbose: + self.report("""dn: %s +changeType: modrdn +newrdn: %s +deleteOldRdn: 1 +newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) + try: + to_dn = to_rdn + to_base + controls = controls + ["local_oid:%s:0" % dsdb.DSDB_CONTROL_DBCHECK] + self.samdb.rename(from_dn, to_dn, controls=controls) + except Exception, err: + self.report("%s : %s" % (msg, err)) + return False + return True + def err_empty_attribute(self, dn, attrname): '''fix empty attributes''' self.report("ERROR: Empty attribute %s in %s" % (attrname, dn)) @@ -333,6 +351,21 @@ class dbcheck(object): "Failed to sieze role %s onto current DC by adding fSMORoleOwner=%s" % (obj.dn, serviceName)): self.report("Siezed role %s onto current DC by adding fSMORoleOwner=%s" % (obj.dn, serviceName)) + def err_missing_parent(self, obj): + '''handle a missing parent''' + self.report("ERROR: parent object not found for %s" % (obj.dn)) + if not self.confirm_all('Move object %s into LostAndFound?' % (obj.dn), 'move_to_lost_and_found'): + self.report('Not moving object %s into LostAndFound' % (obj.dn)) + return + + nc_root = self.samdb.get_nc_root(obj.dn); + lost_and_found = self.samdb.get_wellknown_dn(nc_root, dsdb.DS_GUID_LOSTANDFOUND_CONTAINER) + new_dn = ldb.Dn(self.samdb, str(obj.dn)) + new_dn.remove_base_components(len(new_dn) - 1) + if self.do_rename(obj.dn, new_dn, lost_and_found, ["show_deleted:0", "relax:0"], + "Failed to rename object %s into lostAndFound at %s" % (obj.dn, new_dn + lost_and_found)): + self.report("Renamed object %s into lostAndFound at %s" % (obj.dn, new_dn + lost_and_found)) + def find_revealed_link(self, dn, attrname, guid): '''return a revealed link in an object''' res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE, attrs=[attrname], @@ -592,6 +625,17 @@ class dbcheck(object): self.err_no_fsmoRoleOwner(obj) error_count += 1 + try: + if dn != self.samdb.get_root_basedn(): + res = self.samdb.search(base=dn.parent(), scope=ldb.SCOPE_BASE, + controls=["show_recycled:1", "show_deleted:1"]) + except ldb.LdbError, (enum, estr): + if enum == ldb.ERR_NO_SUCH_OBJECT: + self.err_missing_parent(obj) + error_count += 1 + else: + raise + return error_count ################################################################ |