netcmd: Use dbcheck to fix DB problems introduced by restore itself
authorTim Beale <timbeale@catalyst.net.nz>
Wed, 4 Jul 2018 01:23:59 +0000 (13:23 +1200)
committerDouglas Bagnall <dbagnall@samba.org>
Thu, 5 Jul 2018 02:01:26 +0000 (04:01 +0200)
As part of the restore process, we remove all the old DCs from the DB.
However, this introduces some dbcheck errors - there are some DN
attributes and one-way links that reference the deleted objects that
need fixing up. To resolve this, we can run dbcheck as part of the
restore process. This problem affects both renames and plain restores.

The dbcheck.sh test didn't spot this problem because it fixes this type
of DB error first, before it checks the DB.

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/netcmd/domain_backup.py

index 931e333b57bb81c9be643c54d0104a94b8599824..c156046b26ea98037be5d7f27dd19a0c89e62b34 100644 (file)
@@ -282,6 +282,31 @@ class cmd_domain_backup_restore(cmd_fsmo_seize):
                                  host_ip, host_ip6, domainguid, ntdsguid,
                                  dnsadmins_sid, add_root=False)
 
+    def fix_old_dc_references(self, samdb):
+        '''Fixes attributes that reference the old/removed DCs'''
+
+        # we just want to fix up DB problems here that were introduced by us
+        # removing the old DCs. We restrict what we fix up so that the restored
+        # DB matches the backed-up DB as close as possible. (There may be other
+        # DB issues inherited from the backed-up DC, but it's not our place to
+        # silently try to fix them here).
+        samdb.transaction_start()
+        chk = dbcheck(samdb, quiet=True, fix=True, yes=False,
+                      in_transaction=True)
+
+        # fix up stale references to the old DC
+        setattr(chk, 'fix_all_old_dn_string_component_mismatch', 'ALL')
+        attrs = ['lastKnownParent', 'interSiteTopologyGenerator']
+
+        # fix-up stale one-way links that point to the old DC
+        setattr(chk, 'remove_plausible_deleted_DN_links', 'ALL')
+        attrs += ['msDS-NC-Replica-Locations']
+
+        cross_ncs_ctrl = 'search_options:1:2'
+        controls = ['show_deleted:1', cross_ncs_ctrl]
+        chk.check_database(controls=controls, attrs=attrs)
+        samdb.transaction_commit()
+
     def run(self, sambaopts=None, credopts=None, backup_file=None,
             targetdir=None, newservername=None, host_ip=None, host_ip6=None):
         if not (backup_file and os.path.exists(backup_file)):
@@ -442,6 +467,10 @@ class cmd_domain_backup_restore(cmd_fsmo_seize):
         backup_restore(sysvol_tar, dest_sysvol_dir, samdb, smbconf)
         os.remove(sysvol_tar)
 
+        # fix up any stale links to the old DCs we just removed
+        logger.info("Fixing up any remaining references to the old DCs...")
+        self.fix_old_dc_references(samdb)
+
         # Remove DB markers added by the backup process
         m = ldb.Message()
         m.dn = ldb.Dn(samdb, "@SAMBA_DSDB")