dbcheck: Allow removal of one-way links to missing objects
authorAndrew Bartlett <abartlet@samba.org>
Tue, 17 Oct 2017 10:01:51 +0000 (23:01 +1300)
committerJeremy Allison <jra@samba.org>
Wed, 18 Oct 2017 22:50:19 +0000 (00:50 +0200)
If dbcheck is not run within the tombstone lifetime, these links can
persist in the database forever.  The risk of unintentional information loss
is why these links are only removed within the same partition.  A
replication may be in progress which has created only one end of
the link, so we must keep that.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Rowland Penny <rpenny@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Oct 19 00:50:19 CEST 2017 on sn-devel-144

python/samba/dbchecker.py

index 1a73fe0e5644b49bf30eb6e59c9064d912f21cfc..82088a00d14f18b34e016e3b19f53cc269d4178c 100644 (file)
@@ -523,8 +523,26 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
         # 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:
-            self.report("Not removing dangling forward link")
-            return
+
+            linkID, reverse_link_name \
+                = self.get_attr_linkID_and_reverse_name(attrname)
+            if reverse_link_name is not None:
+                self.report("Not removing dangling forward link")
+                return
+
+            nc_root = self.samdb.get_nc_root(dn)
+            target_nc_root = self.samdb.get_nc_root(dsdb_dn.dn)
+            if nc_root != target_nc_root:
+                self.report("Not removing dangling one-way "
+                            "cross-partition link "
+                            "(we might be mid-replication)")
+                return
+
+            # Due to our link handling one-way links pointing to
+            # missing objects are plausible.
+            self.err_deleted_dn(dn, attrname, val,
+                                dsdb_dn, dsdb_dn, True)
+
         self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn, False)
 
     def err_missing_dn_GUID_component(self, dn, attrname, val, dsdb_dn, errstr):