From 4efb4ebe633350e8d260d1b063d6997001bedd06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Sep 2011 08:52:14 +1000 Subject: [PATCH] s4-dsdb: added support for replicating with GC partial attribute set if we are replicating a partial replica, then we need to supply the partial attribute set we want to replicate to the server --- source4/dsdb/repl/drepl_out_helpers.c | 53 +++++++++++++++++++++++++-- source4/dsdb/repl/drepl_service.h | 1 + 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 19d09572c4c..0ecea176f09 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -262,7 +262,7 @@ static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq) static void dreplsrv_op_pull_source_get_changes_done(struct tevent_req *subreq); /* - get a partial attribute set for a replication call + get a RODC partial attribute set for a replication call */ static NTSTATUS dreplsrv_get_rodc_partial_attribute_set(struct dreplsrv_service *service, TALLOC_CTX *mem_ctx, @@ -294,6 +294,47 @@ static NTSTATUS dreplsrv_get_rodc_partial_attribute_set(struct dreplsrv_service pas->attids[pas->num_attids] = dsdb_attribute_get_attid(a, for_schema); pas->num_attids++; } + + pas->attids = talloc_realloc(pas, pas->attids, enum drsuapi_DsAttributeId, pas->num_attids); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(pas->attids, pas); + + *_pas = pas; + return NT_STATUS_OK; +} + + +/* + get a GC partial attribute set for a replication call + */ +static NTSTATUS dreplsrv_get_gc_partial_attribute_set(struct dreplsrv_service *service, + TALLOC_CTX *mem_ctx, + struct drsuapi_DsPartialAttributeSet **_pas) +{ + struct drsuapi_DsPartialAttributeSet *pas; + struct dsdb_schema *schema; + uint32_t i; + + pas = talloc_zero(mem_ctx, struct drsuapi_DsPartialAttributeSet); + NT_STATUS_HAVE_NO_MEMORY(pas); + + schema = dsdb_get_schema(service->samdb, NULL); + + pas->version = 1; + pas->attids = talloc_array(pas, enum drsuapi_DsAttributeId, schema->num_attributes); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(pas->attids, pas); + + for (i=0; inum_attributes; i++) { + struct dsdb_attribute *a; + a = schema->attributes_by_attributeID_id[i]; + if (a->isMemberOfPartialAttributeSet) { + pas->attids[pas->num_attids] = dsdb_attribute_get_attid(a, false); + pas->num_attids++; + } + } + + pas->attids = talloc_realloc(pas, pas->attids, enum drsuapi_DsAttributeId, pas->num_attids); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(pas->attids, pas); + *_pas = pas; return NT_STATUS_OK; } @@ -374,7 +415,13 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req) replica_flags = rf1->replica_flags; - if (service->am_rodc) { + if (partition->partial_replica) { + status = dreplsrv_get_gc_partial_attribute_set(service, r, &pas); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ ": Failed to construct GC partial attribute set : %s\n", nt_errstr(status))); + return; + } + } else if (service->am_rodc) { bool for_schema = false; if (ldb_dn_compare_base(ldb_get_schema_basedn(service->samdb), partition->dn) == 0) { for_schema = true; @@ -382,7 +429,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req) status = dreplsrv_get_rodc_partial_attribute_set(service, r, &pas, for_schema); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,(__location__ ": Failed to construct partial attribute set : %s\n", nt_errstr(status))); + DEBUG(0,(__location__ ": Failed to construct RODC partial attribute set : %s\n", nt_errstr(status))); return; } if (state->op->extended_op == DRSUAPI_EXOP_REPL_SECRET) { diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h index c454ac618ad..d912ec7ab71 100644 --- a/source4/dsdb/repl/drepl_service.h +++ b/source4/dsdb/repl/drepl_service.h @@ -110,6 +110,7 @@ struct dreplsrv_partition { struct dreplsrv_partition_source_dsa *notifies; bool incoming_only; + bool partial_replica; }; typedef void (*dreplsrv_extended_callback_t)(struct dreplsrv_service *, -- 2.34.1