samba-tool drs replicate: Add --single-object
authorAndrew Bartlett <abartlet@samba.org>
Thu, 23 Feb 2017 00:00:19 +0000 (13:00 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 23 Feb 2017 10:36:21 +0000 (11:36 +0100)
This may help when an object has been incorrectly locally removed from the NC
or there is an urgent need to replicate a specific object (say when full
replication is inoperable).

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
python/samba/netcmd/drs.py
source4/libnet/libnet_vampire.c

index 11e04ad81eb8001bbdb1c96d330ccd2460f16673..b9b876af65a6af530e25e3b5dbcd3432eacea781 100644 (file)
@@ -241,7 +241,7 @@ class cmd_drs_kcc(Command):
 
 
 
-def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False):
+def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False, single_object=False):
     '''replicate from a source DC to the local SAM'''
 
     self.server = SOURCE_DC
@@ -267,6 +267,12 @@ def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False):
     dest_dsa_invocation_id = misc.GUID(self.local_samdb.get_invocation_id())
     destination_dsa_guid = self.ntds_guid
 
+    exop = drsuapi.DRSUAPI_EXOP_NONE
+
+    if single_object:
+        exop = drsuapi.DRSUAPI_EXOP_REPL_OBJ
+        full_sync = True
+
     self.samdb.transaction_start()
     repl = drs_utils.drs_Replicate("ncacn_ip_tcp:%s[seal]" % self.server, self.lp,
                                    self.creds, self.local_samdb, dest_dsa_invocation_id)
@@ -277,7 +283,8 @@ def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False):
     try:
         (num_objects, num_links) = repl.replicate(NC,
                                                   source_dsa_invocation_id, destination_dsa_guid,
-                                                  rodc=rodc, full_sync=full_sync)
+                                                  rodc=rodc, full_sync=full_sync,
+                                                  exop=exop)
     except Exception, e:
         raise CommandError("Error replicating DN %s" % NC, e)
     self.samdb.transaction_commit()
@@ -311,11 +318,12 @@ class cmd_drs_replicate(Command):
         Option("--local", help="pull changes directly into the local database (destination DC is ignored)", action="store_true"),
         Option("--local-online", help="pull changes into the local database (destination DC is ignored) as a normal online replication", action="store_true"),
         Option("--async-op", help="use ASYNC_OP for the replication", action="store_true"),
+        Option("--single-object", help="Replicate only the object specified, instead of the whole Naming Context (only with --local)", action="store_true"),
         ]
 
     def run(self, DEST_DC, SOURCE_DC, NC,
             add_ref=False, sync_forced=False, sync_all=False, full_sync=False,
-            local=False, local_online=False, async_op=False,
+            local=False, local_online=False, async_op=False, single_object=False,
             sambaopts=None, credopts=None, versionopts=None, server=None):
 
         self.server = DEST_DC
@@ -324,7 +332,7 @@ class cmd_drs_replicate(Command):
         self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
 
         if local:
-            drs_local_replicate(self, SOURCE_DC, NC, full_sync=full_sync)
+            drs_local_replicate(self, SOURCE_DC, NC, full_sync=full_sync, single_object=single_object)
             return
 
         if local_online:
index f74f9bb4f78c1b01620fcb92fd9a435e6569c693..f6bcf2951a3696cc612c57744a6bba8571aa1b04 100644 (file)
@@ -652,10 +652,10 @@ WERROR libnet_vampire_cb_store_chunk(void *private_data,
                return WERR_INVALID_PARAMETER;
        }
 
-       if (req_replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) {
+       if (req_replica_flags & DRSUAPI_DRS_CRITICAL_ONLY || is_exop) {
                /*
-                * If we only replicate the critical objects
-                * we should not remember what we already
+                * If we only replicate the critical objects, or this
+                * is an exop we should not remember what we already
                 * got, as it is incomplete.
                 */
                ZERO_STRUCT(s_dsa->highwatermark);