From 86f5ecdc0c97b21be6d9d2f7be4e15b8d95af219 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Sep 2011 08:53:15 +1000 Subject: s4-repl: get NCs to replicate from our NTDS object we need to use the hasMasterNCs and hasPartialReplicaNCs attributes on our NTDS object to get the list of NCs to replicate, instead of using the rootDSE. This is needed to support replicating of GC partial replicas, which are not listed in the rootDSE --- source4/dsdb/repl/drepl_partitions.c | 92 +++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c index e0f404511e..b947e4fad8 100644 --- a/source4/dsdb/repl/drepl_partitions.c +++ b/source4/dsdb/repl/drepl_partitions.c @@ -32,57 +32,93 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "libcli/security/security.h" #include "param/param.h" +#include "dsdb/common/util.h" WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; - static const char *attrs[] = { "namingContexts", NULL }; + static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", NULL }; unsigned int i; int ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message_element *el; + struct ldb_dn *ntds_dn; tmp_ctx = talloc_new(s); W_ERROR_HAVE_NO_MEMORY(tmp_ctx); - ret = ldb_search(s->samdb, tmp_ctx, &res, - ldb_dn_new(tmp_ctx, s->samdb, ""), LDB_SCOPE_BASE, attrs, NULL); + ntds_dn = samdb_ntds_settings_dn(s->samdb); + if (!ntds_dn) { + DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN); if (ret != LDB_SUCCESS) { - DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(s->samdb))); + DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs"); + if (!el) { + DEBUG(1,("Finding hasMasterNCs element in root_res failed: %s\n", + ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; - } + } + + for (i=0; inum_values; i++) { + struct ldb_dn *pdn; + struct dreplsrv_partition *p; - el = ldb_msg_find_element(res->msgs[0], "namingContexts"); - if (!el) { - DEBUG(1,("Finding namingContexts element in root_res failed: %s\n", - ldb_errstring(s->samdb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } + pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); + if (pdn == NULL) { + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + if (!ldb_dn_validate(pdn)) { + return WERR_DS_DRA_INTERNAL_ERROR; + } + + p = talloc_zero(s, struct dreplsrv_partition); + W_ERROR_HAVE_NO_MEMORY(p); + + p->dn = talloc_steal(p, pdn); + p->service = s; + + DLIST_ADD(s->partitions, p); - for (i=0; inum_values; i++) { - struct ldb_dn *pdn; - struct dreplsrv_partition *p; + DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn))); + } + + el = ldb_msg_find_element(res->msgs[0], "hasPartialReplicaNCs"); + + for (i=0; el && inum_values; i++) { + struct ldb_dn *pdn; + struct dreplsrv_partition *p; - pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); - if (pdn == NULL) { - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } - if (!ldb_dn_validate(pdn)) { - return WERR_DS_DRA_INTERNAL_ERROR; - } + pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); + if (pdn == NULL) { + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + if (!ldb_dn_validate(pdn)) { + return WERR_DS_DRA_INTERNAL_ERROR; + } - p = talloc_zero(s, struct dreplsrv_partition); - W_ERROR_HAVE_NO_MEMORY(p); + p = talloc_zero(s, struct dreplsrv_partition); + W_ERROR_HAVE_NO_MEMORY(p); - p->dn = talloc_steal(p, pdn); + p->dn = talloc_steal(p, pdn); + p->partial_replica = true; + p->service = s; - DLIST_ADD(s->partitions, p); + DLIST_ADD(s->partitions, p); - DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn))); + DEBUG(2, ("dreplsrv_partition[%s] loaded (partial replica)\n", ldb_dn_get_linearized(p->dn))); } talloc_free(tmp_ctx); -- cgit