summaryrefslogtreecommitdiff
path: root/source4/dsdb/repl
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb/repl')
-rw-r--r--source4/dsdb/repl/drepl_notify.c14
-rw-r--r--source4/dsdb/repl/drepl_partitions.c45
-rw-r--r--source4/dsdb/repl/drepl_service.h6
3 files changed, 58 insertions, 7 deletions
diff --git a/source4/dsdb/repl/drepl_notify.c b/source4/dsdb/repl/drepl_notify.c
index 836509b3eb..0178e97e55 100644
--- a/source4/dsdb/repl/drepl_notify.c
+++ b/source4/dsdb/repl/drepl_notify.c
@@ -270,16 +270,24 @@ void dreplsrv_notify_run_ops(struct dreplsrv_service *s)
/*
find a source_dsa for a given guid
*/
-static struct dreplsrv_partition_source_dsa *dreplsrv_find_source_dsa(struct dreplsrv_partition *p,
+static struct dreplsrv_partition_source_dsa *dreplsrv_find_notify_dsa(struct dreplsrv_partition *p,
struct GUID *guid)
{
struct dreplsrv_partition_source_dsa *s;
+ /* first check the sources list */
for (s=p->sources; s; s=s->next) {
if (GUID_compare(&s->repsFrom1->source_dsa_obj_guid, guid) == 0) {
return s;
}
}
+
+ /* then the notifies list */
+ for (s=p->notifies; s; s=s->next) {
+ if (GUID_compare(&s->repsFrom1->source_dsa_obj_guid, guid) == 0) {
+ return s;
+ }
+ }
return NULL;
}
@@ -298,7 +306,7 @@ static WERROR dreplsrv_schedule_notify_sync(struct dreplsrv_service *service,
struct dreplsrv_notify_operation *op;
struct dreplsrv_partition_source_dsa *s;
- s = dreplsrv_find_source_dsa(p, &reps->ctr.ctr1.source_dsa_obj_guid);
+ s = dreplsrv_find_notify_dsa(p, &reps->ctr.ctr1.source_dsa_obj_guid);
if (s == NULL) {
DEBUG(0,(__location__ ": Unable to find source_dsa for %s\n",
GUID_string(mem_ctx, &reps->ctr.ctr1.source_dsa_obj_guid)));
@@ -375,7 +383,7 @@ static WERROR dreplsrv_notify_check(struct dreplsrv_service *s,
for (i=0; i<count; i++) {
struct dreplsrv_partition_source_dsa *sdsa;
uint32_t replica_flags;
- sdsa = dreplsrv_find_source_dsa(p, &reps[i].ctr.ctr1.source_dsa_obj_guid);
+ sdsa = dreplsrv_find_notify_dsa(p, &reps[i].ctr.ctr1.source_dsa_obj_guid);
replica_flags = reps[i].ctr.ctr1.replica_flags;
if (sdsa == NULL) continue;
if (sdsa->notify_uSN < uSNHighest) {
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 76f261d4f8..70173fea01 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -209,8 +209,27 @@ WERROR dreplsrv_out_connection_attach(struct dreplsrv_service *s,
return WERR_OK;
}
+/*
+ find an existing source dsa in a list
+ */
+static struct dreplsrv_partition_source_dsa *dreplsrv_find_source_dsa(struct dreplsrv_partition_source_dsa *list,
+ struct GUID *guid)
+{
+ struct dreplsrv_partition_source_dsa *s;
+ for (s=list; s; s=s->next) {
+ if (GUID_compare(&s->repsFrom1->source_dsa_obj_guid, guid) == 0) {
+ return s;
+ }
+ }
+ return NULL;
+}
+
+
+
static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
struct dreplsrv_partition *p,
+ struct dreplsrv_partition_source_dsa **listp,
+ struct dreplsrv_partition_source_dsa *check_list,
const struct ldb_val *val)
{
WERROR status;
@@ -240,8 +259,15 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
status = dreplsrv_out_connection_attach(s, source->repsFrom1, &source->conn);
W_ERROR_NOT_OK_RETURN(status);
- /* remove any existing source with the same GUID */
- for (s2=p->sources; s2; s2=s2->next) {
+ if (check_list &&
+ dreplsrv_find_source_dsa(check_list, &source->repsFrom1->source_dsa_obj_guid)) {
+ /* its in the check list, don't add it again */
+ talloc_free(source);
+ return WERR_OK;
+ }
+
+ /* re-use an existing source if found */
+ for (s2=*listp; s2; s2=s2->next) {
if (GUID_compare(&s2->repsFrom1->source_dsa_obj_guid,
&source->repsFrom1->source_dsa_obj_guid) == 0) {
talloc_free(s2->repsFrom1->other_info);
@@ -252,7 +278,7 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
}
}
- DLIST_ADD_END(p->sources, source, struct dreplsrv_partition_source_dsa *);
+ DLIST_ADD_END(*listp, source, struct dreplsrv_partition_source_dsa *);
return WERR_OK;
}
@@ -343,6 +369,7 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
"objectSid",
"objectGUID",
"repsFrom",
+ "repsTo",
NULL
};
@@ -380,7 +407,17 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
orf_el = ldb_msg_find_element(r->msgs[0], "repsFrom");
if (orf_el) {
for (i=0; i < orf_el->num_values; i++) {
- status = dreplsrv_partition_add_source_dsa(s, p, &orf_el->values[i]);
+ status = dreplsrv_partition_add_source_dsa(s, p, &p->sources,
+ NULL, &orf_el->values[i]);
+ W_ERROR_NOT_OK_RETURN(status);
+ }
+ }
+
+ orf_el = ldb_msg_find_element(r->msgs[0], "repsTo");
+ if (orf_el) {
+ for (i=0; i < orf_el->num_values; i++) {
+ status = dreplsrv_partition_add_source_dsa(s, p, &p->notifies,
+ p->sources, &orf_el->values[i]);
W_ERROR_NOT_OK_RETURN(status);
}
}
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index ba1f1950ef..9ad62fd538 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -103,6 +103,12 @@ struct dreplsrv_partition {
*/
struct dreplsrv_partition_source_dsa *sources;
+ /*
+ * a linked list of all source dsa's we will notify,
+ * that are not also in sources
+ */
+ struct dreplsrv_partition_source_dsa *notifies;
+
bool incoming_only;
};