From 94183eb7e617dbfead93b9342bc85ebb27d93903 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Sep 2009 11:10:19 +1000 Subject: s4-repl: we should only update uSNChanged when replication data changes When changing non-replicated attributes we should not update the uSNChanged attribute on the record, otherwise the DRS server will think this record needs replicating. --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 68 ++++++++++++++----------- 1 file changed, 39 insertions(+), 29 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index b9de04a684..5000c56d4e 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -280,7 +280,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) schema = dsdb_get_schema(ldb); if (!schema) { ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "replmd_modify: no dsdb_schema loaded"); + "replmd_add: no dsdb_schema loaded"); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -475,10 +475,9 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, struct ldb_message_element *el, struct replPropertyMetaDataBlob *omd, struct dsdb_schema *schema, - uint64_t seq_num, + uint64_t *seq_num, const struct GUID *our_invocation_id, - NTTIME now, - bool *modified) + NTTIME now) { int i; const struct dsdb_attribute *a; @@ -512,15 +511,25 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, omd->ctr.ctr1.count++; } + /* Get a new sequence number from the backend. We only do this + * if we have a change that requires a new + * replPropertyMetaData element + */ + if (*seq_num == 0) { + int ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, seq_num); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + md1 = &omd->ctr.ctr1.array[i]; md1->version = 1; md1->attid = a->attributeID_id; md1->originating_change_time = now; md1->originating_invocation_id = *our_invocation_id; - md1->originating_usn = seq_num; - md1->local_usn = seq_num; + md1->originating_usn = *seq_num; + md1->local_usn = *seq_num; - *modified = true; return LDB_SUCCESS; } @@ -530,13 +539,12 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, * client is based on this object */ static int replmd_update_rpmd(struct ldb_context *ldb, struct ldb_message *msg, - uint64_t seq_num) + uint64_t *seq_num) { const struct ldb_val *omd_value; enum ndr_err_code ndr_err; struct replPropertyMetaDataBlob omd; int i; - bool modified = false; struct dsdb_schema *schema; time_t t = time(NULL); NTTIME now; @@ -590,13 +598,17 @@ static int replmd_update_rpmd(struct ldb_context *ldb, struct ldb_message *msg, for (i=0; inum_elements; i++) { ret = replmd_update_rpmd_element(ldb, msg, &msg->elements[i], &omd, schema, seq_num, - our_invocation_id, now, &modified); + our_invocation_id, now); if (ret != LDB_SUCCESS) { return ret; } } - if (modified) { + /* + * replmd_update_rpmd_element has done an update if the + * seq_num is set + */ + if (*seq_num != 0) { struct ldb_val *md_value; struct ldb_message_element *el; @@ -640,7 +652,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) struct ldb_message *msg; int ret; time_t t = time(NULL); - uint64_t seq_num; + uint64_t seq_num = 0; /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { @@ -683,27 +695,11 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) * attribute was changed */ - /* Get a sequence number from the backend */ - ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = replmd_update_rpmd(ldb, msg, seq_num); + ret = replmd_update_rpmd(ldb, msg, &seq_num); if (ret != LDB_SUCCESS) { return ret; } - if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - /* TODO: * - sort the attributes by attid with replmd_ldb_message_sort() * - replace the old object with the newly constructed one @@ -719,6 +715,20 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) } talloc_steal(down_req, msg); + /* we only change whenChanged and uSNChanged if the seq_num + has changed */ + if (seq_num != 0) { + if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + } + /* go on with the call chain */ return ldb_next_request(module, down_req); } -- cgit