diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-04-26 22:51:11 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-04-27 10:38:59 +1000 |
commit | 3119296e425a4c640fe9bd2bb97f09bab8a9ccf0 (patch) | |
tree | e71425cff99c47b20d034ffe16383194c0b6e8e6 | |
parent | c375b90f5d1b1cbef2896f9a9d5964126ce82022 (diff) | |
download | samba-3119296e425a4c640fe9bd2bb97f09bab8a9ccf0.tar.gz samba-3119296e425a4c640fe9bd2bb97f09bab8a9ccf0.tar.xz samba-3119296e425a4c640fe9bd2bb97f09bab8a9ccf0.zip |
s4-drepl: don't setup a repsFrom from a DC that isn't a master for a NC
use hasMasterNCs to see what NCs we should be pulling from each DC
-rw-r--r-- | source4/dsdb/kcc/kcc_periodic.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c index 14e15e8aea6..e05ac56fcc4 100644 --- a/source4/dsdb/kcc/kcc_periodic.c +++ b/source4/dsdb/kcc/kcc_periodic.c @@ -52,12 +52,55 @@ static bool reps_in_list(struct repsFromToBlob *r, struct repsFromToBlob *reps, return false; } +/* + make sure we only add repsFrom entries for DCs who are masters for + the partition + */ +static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r, + struct ldb_result *res) +{ + struct repsFromTo1 *r1; + r1 = &r->ctr.ctr1; + struct GUID invocation_id = r1->source_dsa_invocation_id; + int i, j; + + for (i=0; i<res->count; i++) { + struct ldb_message *msg = res->msgs[i]; + struct ldb_message_element *el; + struct ldb_dn *dn; + + struct GUID id2 = samdb_result_guid(msg, "invocationID"); + if (!GUID_equal(&invocation_id, &id2)) { + continue; + } + + el = ldb_msg_find_element(msg, "hasMasterNCs"); + if (!el || el->num_values == 0) { + continue; + } + for (j=0; j<el->num_values; j++) { + dn = ldb_dn_from_ldb_val(p, p->service->samdb, &el->values[j]); + if (!ldb_dn_validate(dn)) { + talloc_free(dn); + continue; + } + if (ldb_dn_compare(dn, p->dn) == 0) { + talloc_free(dn); + return true; + } + talloc_free(dn); + } + } + return false; +} + /* * add any missing repsFrom structures to our partitions */ static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx, - struct repsFromToBlob *reps, uint32_t count) + struct repsFromToBlob *reps, uint32_t count, + struct ldb_result *res) { struct kccsrv_partition *p; @@ -78,7 +121,8 @@ static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ct /* add any new ones */ for (i=0; i<count; i++) { - if (!reps_in_list(&reps[i], old_reps, old_count)) { + if (!reps_in_list(&reps[i], old_reps, old_count) && + check_MasterNC(p, &reps[i], res)) { old_reps = talloc_realloc(mem_ctx, old_reps, struct repsFromToBlob, old_count+1); NT_STATUS_HAVE_NO_MEMORY(old_reps); old_reps[old_count] = reps[i]; @@ -89,7 +133,8 @@ static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ct /* remove any stale ones */ for (i=0; i<old_count; i++) { - if (!reps_in_list(&old_reps[i], reps, count)) { + if (!reps_in_list(&old_reps[i], reps, count) || + !check_MasterNC(p, &old_reps[i], res)) { memmove(&old_reps[i], &old_reps[i+1], (old_count-(i+1))*sizeof(old_reps[0])); old_count--; i--; @@ -121,7 +166,7 @@ NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) struct ldb_result *res; unsigned int i; int ret; - const char *attrs[] = { "objectGUID", "invocationID", NULL }; + const char *attrs[] = { "objectGUID", "invocationID", "hasMasterNCs", NULL }; struct repsFromToBlob *reps = NULL; uint32_t count = 0; struct kcc_connection_list *ntds_conn, *dsa_conn; @@ -181,7 +226,7 @@ NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) kccsrv_apply_connections(s, ntds_conn, dsa_conn); - return kccsrv_add_repsFrom(s, mem_ctx, reps, count); + return kccsrv_add_repsFrom(s, mem_ctx, reps, count, res); } |