summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorTim Beale <timbeale@catalyst.net.nz>2018-11-08 17:34:26 +1300
committerAndrew Bartlett <abartlet@samba.org>2018-11-20 01:33:33 +0100
commit008449d99f7f0bcc165cdf9dc479eb9dc5e1a856 (patch)
treee825497de69212ed9915ab4d3970ee4864a4c1ba /python
parent5ca2726a402f061a73ab7b52064d8b1e4028caca (diff)
downloadsamba-008449d99f7f0bcc165cdf9dc479eb9dc5e1a856.tar.gz
netcmd: Flush replUpToDateVector when restoring offline backup
The replUpToDateVector could be incorrect after an offline backup was restored. This means replication propagation dampening doesn't work properly. In the worst case, a singleton DC would have no replUpToDateVector at all, and so *all* objects created on that DC get replicated every time a new DRS connection is established between 2 DCs. This becomes a real problem if you used that singleton DC to create 100K objects... This patch flushes the replUpToDateVector when an offline backup gets restored. We need to do this before we add in the new DC and remove the old DCs. Note that this is only a problem for offline backups. The online/rename backups are received over DRS, and as part of the replication they receive the latest replUpToDateVector from the DC being backed up. Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'python')
-rw-r--r--python/samba/netcmd/domain_backup.py38
1 files changed, 34 insertions, 4 deletions
diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py
index afa70e3b34e..c7602a8be26 100644
--- a/python/samba/netcmd/domain_backup.py
+++ b/python/samba/netcmd/domain_backup.py
@@ -33,7 +33,7 @@ from samba.auth import system_session
from samba.join import DCJoinContext, join_clone, DCCloneAndRenameContext
from samba.dcerpc.security import dom_sid
from samba.netcmd import Option, CommandError
-from samba.dcerpc import misc, security
+from samba.dcerpc import misc, security, drsblobs
from samba import Ldb
from . fsmo import cmd_fsmo_seize
from samba.provision import make_smbconf, DEFAULTSITE
@@ -51,6 +51,8 @@ from samba.mdb_util import mdb_copy
import errno
from subprocess import CalledProcessError
from samba import sites
+from samba.dsdb import _dsdb_load_udv_v2
+from samba.ndr import ndr_pack
# work out a SID (based on a free RID) to use when the domain gets restored.
@@ -417,6 +419,26 @@ class cmd_domain_backup_restore(cmd_fsmo_seize):
return backup_type
+ def save_uptodate_vectors(self, samdb, partitions):
+ """Ensures the UTDV used by DRS is correct after an offline backup"""
+ for nc in partitions:
+ # load the replUpToDateVector we *should* have
+ utdv = _dsdb_load_udv_v2(samdb, nc)
+
+ # convert it to NDR format and write it into the DB
+ utdv_blob = drsblobs.replUpToDateVectorBlob()
+ utdv_blob.version = 2
+ utdv_blob.ctr.cursors = utdv
+ utdv_blob.ctr.count = len(utdv)
+ new_value = ndr_pack(utdv_blob)
+
+ m = ldb.Message()
+ m.dn = ldb.Dn(samdb, nc)
+ m["replUpToDateVector"] = ldb.MessageElement(new_value,
+ ldb.FLAG_MOD_REPLACE,
+ "replUpToDateVector")
+ samdb.modify(m)
+
def run(self, sambaopts=None, credopts=None, backup_file=None,
targetdir=None, newservername=None, host_ip=None, host_ip6=None,
site=None):
@@ -471,13 +493,21 @@ class cmd_domain_backup_restore(cmd_fsmo_seize):
site = self.create_default_site(samdb, logger)
logger.info("Adding new DC to site '{0}'".format(site))
- # Create account using the join_add_objects function in the join object
- # We need namingContexts, account control flags, and the sid saved by
- # the backup process.
+ # read the naming contexts out of the DB
res = samdb.search(base="", scope=ldb.SCOPE_BASE,
attrs=['namingContexts'])
ncs = [str(r) for r in res[0].get('namingContexts')]
+ # for offline backups we need to make sure the upToDateness info
+ # contains the invocation-ID and highest-USN of the DC we backed up.
+ # Otherwise replication propagation dampening won't correctly filter
+ # objects created by that DC
+ if backup_type == "offline":
+ self.save_uptodate_vectors(samdb, ncs)
+
+ # Create account using the join_add_objects function in the join object
+ # We need namingContexts, account control flags, and the sid saved by
+ # the backup process.
creds = credopts.get_credentials(lp)
ctx = DCJoinContext(logger, creds=creds, lp=lp, site=site,
forced_local_samdb=samdb,