diff options
author | Andrew Tridgell <tridge@samba.org> | 2011-10-06 14:21:41 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2011-10-06 07:08:35 +0200 |
commit | 3fca66e2b343c6386476a52832591ae4e435d6b2 (patch) | |
tree | 8a60373ed27643e4b37a3e377a5e85939327fc75 | |
parent | d7f617e2e180eab6decb18e697f1e1294194a2cb (diff) | |
download | samba-3fca66e2b343c6386476a52832591ae4e435d6b2.tar.gz samba-3fca66e2b343c6386476a52832591ae4e435d6b2.tar.bz2 samba-3fca66e2b343c6386476a52832591ae4e435d6b2.zip |
samba-tool: add support for fixing broken backlinks in dbcheck
this allows dangling backlinks to be removed
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
Autobuild-User: Andrew Tridgell <tridge@samba.org>
Autobuild-Date: Thu Oct 6 07:08:35 CEST 2011 on sn-devel-104
-rw-r--r-- | source4/scripting/python/samba/dbchecker.py | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py index ea5a9030c6..f19891a8d9 100644 --- a/source4/scripting/python/samba/dbchecker.py +++ b/source4/scripting/python/samba/dbchecker.py @@ -201,6 +201,32 @@ class dbcheck(object): ################################################################ + # handle a DN pointing to a deleted object + def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn): + self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) + self.report("Target GUID points at deleted DN %s" % correct_dn) + if not self.confirm_all('Remove DN link?', 'remove_all_deleted_DN_links'): + self.report("Not removing") + return + m = ldb.Message() + m.dn = dn + m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) + if self.do_modify(m, ["show_recycled:1", "%s:0" % dsdb.DSDB_CONTROL_DBCHECK], + "Failed to remove deleted DN attribute %s" % attrname): + self.report("Removed deleted DN on attribute %s" % attrname) + + ################################################################ + # handle a missing target DN (both GUID and DN string form are missing) + def err_missing_dn_GUID(self, dn, attrname, val, dsdb_dn): + # check if its a backlink + linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname) + if (linkID & 1 == 0) and str(dsdb_dn).find('DEL\\0A') == -1: + self.report("Not removing dangling forward link") + return + self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn) + + + ################################################################ # handle a missing GUID extended DN component def err_incorrect_dn_GUID(self, dn, attrname, val, dsdb_dn, errstr): self.report("ERROR: %s component for %s in object %s - %s" % (errstr, attrname, dn, val)) @@ -209,10 +235,12 @@ class dbcheck(object): res = self.samdb.search(base=str(dsdb_dn.dn), scope=ldb.SCOPE_BASE, attrs=[], controls=controls) except ldb.LdbError, (enum, estr): - self.report("unable to find object for DN %s - cannot fix (%s)" % (dsdb_dn.dn, estr)) + self.report("unable to find object for DN %s - (%s)" % (dsdb_dn.dn, estr)) + self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn) return if len(res) == 0: - self.report("unable to find object for DN %s - cannot fix" % dsdb_dn.dn) + self.report("unable to find object for DN %s" % dsdb_dn.dn) + self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn) return dsdb_dn.dn = res[0].dn @@ -230,22 +258,6 @@ class dbcheck(object): ################################################################ - # handle a DN pointing to a deleted object - def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn): - self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) - self.report("Target GUID points at deleted DN %s" % correct_dn) - if not self.confirm_all('Remove DN?', 'remove_all_deleted_DN_links'): - self.report("Not removing") - return - m = ldb.Message() - m.dn = dn - m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) - if self.do_modify(m, ["show_recycled:1"], - "Failed to remove deleted DN attribute %s" % attrname): - self.report("Removed deleted DN on attribute %s" % attrname) - - - ################################################################ # handle a DN string being incorrect def err_dn_target_mismatch(self, dn, attrname, val, dsdb_dn, correct_dn, errstr): self.report("ERROR: incorrect DN string component for %s in object %s - %s" % (attrname, dn, val)) @@ -329,7 +341,7 @@ class dbcheck(object): guidstr = str(misc.GUID(guid)) attrs=['isDeleted'] - linkkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname) + linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname) reverse_link_name = self.samdb_schema.get_backlink_from_lDAPDisplayName(attrname) if reverse_link_name is not None: attrs.append(reverse_link_name) @@ -370,7 +382,7 @@ class dbcheck(object): match_count += 1 if match_count != 1: error_count += 1 - if linkkID & 1: + if linkID & 1: self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn) else: self.err_missing_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn) |