summaryrefslogtreecommitdiff
path: root/python/samba
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2016-10-25 10:10:34 +1300
committerKarolin Seeger <kseeger@samba.org>2016-11-30 12:19:33 +0100
commit48d45ef07c369a5de400e83f256be96b2e75e54c (patch)
treebed27f8f63057bb1eb84ad59dd766f0d964bb594 /python/samba
parent068f9fd135390278151f41affb69c12697357b51 (diff)
downloadsamba-48d45ef07c369a5de400e83f256be96b2e75e54c.tar.gz
dbcheck: Be more careful with link checks
Here we are more careful when checking links, flagging errors only when a non-deleted forward link appears incorrect. In particular, we trust the GUID more than we trust the name, as otherwise we can get caught out if there is a swap of names, (the link should follow the swap, staying on the same target GUID). Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12297 (cherry picked from commit f051e5bf00d6df70048dd0cf901dd7b37be09669)
Diffstat (limited to 'python/samba')
-rw-r--r--python/samba/dbchecker.py30
1 files changed, 23 insertions, 7 deletions
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index 9b0784bb5f2..972efbbb3f7 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -492,8 +492,9 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
"Failed to remove deleted DN attribute %s" % attrname):
self.report("Removed deleted DN on attribute %s" % attrname)
- def err_missing_dn_GUID(self, dn, attrname, val, dsdb_dn):
- """handle a missing target DN (both GUID and DN string form are missing)"""
+ def err_missing_target_dn_or_GUID(self, dn, attrname, val, dsdb_dn):
+ """handle a missing target DN (if specified, GUID form can't be found,
+ and otherwise DN string form can't be found)"""
# check if its a backlink
linkID, _ = self.get_attr_linkID_and_reverse_name(attrname)
if (linkID & 1 == 0) and str(dsdb_dn).find('\\0ADEL') == -1:
@@ -501,7 +502,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
return
self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn, False)
- def err_incorrect_dn_GUID(self, dn, attrname, val, dsdb_dn, errstr):
+ def err_missing_dn_GUID_component(self, dn, attrname, val, dsdb_dn, errstr):
"""handle a missing GUID extended DN component"""
self.report("ERROR: %s component for %s in object %s - %s" % (errstr, attrname, dn, val))
controls=["extended_dn:1:1", "show_recycled:1"]
@@ -510,11 +511,13 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
attrs=[], controls=controls)
except ldb.LdbError, (enum, 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)
+ if enum != ldb.ERR_NO_SUCH_OBJECT:
+ raise
+ self.err_missing_target_dn_or_GUID(dn, attrname, val, dsdb_dn)
return
if len(res) == 0:
self.report("unable to find object for DN %s" % dsdb_dn.dn)
- self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn)
+ self.err_missing_target_dn_or_GUID(dn, attrname, val, dsdb_dn)
return
dsdb_dn.dn = res[0].dn
@@ -797,7 +800,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
guid = dsdb_dn.dn.get_extended_component("GUID")
if guid is None:
error_count += 1
- self.err_incorrect_dn_GUID(obj.dn, attrname, val, dsdb_dn,
+ self.err_missing_dn_GUID_component(obj.dn, attrname, val, dsdb_dn,
"missing GUID")
continue
@@ -822,7 +825,11 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
])
except ldb.LdbError, (enum, estr):
error_count += 1
- self.err_incorrect_dn_GUID(obj.dn, attrname, val, dsdb_dn, "incorrect GUID")
+ self.report("ERROR: no target object found for GUID component for %s in object %s - %s" % (attrname, obj.dn, val))
+ if enum != ldb.ERR_NO_SUCH_OBJECT:
+ raise
+
+ self.err_missing_target_dn_or_GUID(obj.dn, attrname, val, dsdb_dn)
continue
if fixing_msDS_HasInstantiatedNCs:
@@ -874,6 +881,15 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
self.err_deleted_dn(obj.dn, attrname, val, dsdb_dn, res[0].dn, False)
continue
+ # We should not check for incorrect
+ # components on deleted links, as these are allowed to
+ # go stale (we just need the GUID, not the name)
+ rmd_blob = dsdb_dn.dn.get_extended_component("RMD_FLAGS")
+ if rmd_blob is not None:
+ rmd_flags = int(rmd_blob)
+ if rmd_flags & 1:
+ continue
+
# check the DN matches in string form
if str(res[0].dn) != str(dsdb_dn.dn):
error_count += 1