s4-dsdb: enable initial replication of partitions via DsReplicaSync
authorAndrew Tridgell <tridge@samba.org>
Tue, 20 Sep 2011 22:56:32 +0000 (08:56 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 22 Sep 2011 00:00:48 +0000 (10:00 +1000)
we need to create a temporary dsa object to allow the replication task
to replicate a NC that is not listed in a repsFrom attribute

source4/dsdb/repl/drepl_partitions.c
source4/dsdb/repl/drepl_service.c

index b947e4fad8b2fe480c587138e4efe0f4363d1f79..2aa2d7c8d68eb649576022f091c493ce8aaeb27d 100644 (file)
@@ -405,6 +405,48 @@ WERROR dreplsrv_partition_source_dsa_by_dns(const struct dreplsrv_partition *p,
 }
 
 
+/*
+  create a temporary dsa structure for a replication. This is needed
+  for the initial replication of a new partition, such as when a new
+  domain NC is created and we are a global catalog server
+ */
+WERROR dreplsrv_partition_source_dsa_temporary(struct dreplsrv_partition *p,
+                                              TALLOC_CTX *mem_ctx,
+                                              const struct GUID *dsa_guid,
+                                              struct dreplsrv_partition_source_dsa **_dsa)
+{
+       struct dreplsrv_partition_source_dsa *dsa;
+       WERROR werr;
+
+       dsa = talloc_zero(mem_ctx, struct dreplsrv_partition_source_dsa);
+       W_ERROR_HAVE_NO_MEMORY(dsa);
+
+       dsa->partition = p;
+       dsa->repsFrom1 = &dsa->_repsFromBlob.ctr.ctr1;
+       dsa->repsFrom1->replica_flags = 0;
+       dsa->repsFrom1->source_dsa_obj_guid = *dsa_guid;
+
+       dsa->repsFrom1->other_info = talloc_zero(dsa, struct repsFromTo1OtherInfo);
+       W_ERROR_HAVE_NO_MEMORY(dsa->repsFrom1->other_info);
+
+       dsa->repsFrom1->other_info->dns_name = samdb_ntds_msdcs_dns_name(p->service->samdb,
+                                                                        dsa->repsFrom1->other_info, dsa_guid);
+       W_ERROR_HAVE_NO_MEMORY(dsa->repsFrom1->other_info->dns_name);
+
+       werr = dreplsrv_out_connection_attach(p->service, dsa->repsFrom1, &dsa->conn);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0,(__location__ ": Failed to attach connection to %s\n",
+                        ldb_dn_get_linearized(p->dn)));
+               talloc_free(dsa);
+               return werr;
+       }
+
+       *_dsa = dsa;
+
+       return WERR_OK;
+}
+
+
 static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
                                         struct dreplsrv_partition *p)
 {
index ec803f6fdb05c1345371e363cfdbdd6d6e59bb60..e12ff1e81963c93ab789df643f3c81d9983758fe 100644 (file)
@@ -306,6 +306,16 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg,
                        werr = dreplsrv_partition_source_dsa_by_guid(p,
                                                                     &req1->source_dsa_guid,
                                                                     &dsa);
+                       if (W_ERROR_EQUAL(werr, WERR_DS_DRA_NO_REPLICA)) {
+                               /* we don't have this source setup as
+                                  a replication partner. Create a
+                                  temporary dsa structure for this
+                                  replication */
+                               werr = dreplsrv_partition_source_dsa_temporary(p,
+                                                                              msg,
+                                                                              &req1->source_dsa_guid,
+                                                                              &dsa);
+                       }
                }
                if (!W_ERROR_IS_OK(werr)) {
                        REPLICA_SYNC_FAIL("Failed to locate source DSA for given NC",