summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-09-12 11:10:19 +1000
committerAndrew Tridgell <tridge@samba.org>2009-09-12 11:15:27 +1000
commit94183eb7e617dbfead93b9342bc85ebb27d93903 (patch)
tree33c600c9721e5f69379d330c54d7b762d70f8eea /source4/dsdb/samdb/ldb_modules/repl_meta_data.c
parent0ba9a1bd3f2f0b278a86f6e244162b0efa7dd510 (diff)
downloadsamba-94183eb7e617dbfead93b9342bc85ebb27d93903.tar.gz
samba-94183eb7e617dbfead93b9342bc85ebb27d93903.tar.bz2
samba-94183eb7e617dbfead93b9342bc85ebb27d93903.zip
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.
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/repl_meta_data.c')
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c68
1 files changed, 39 insertions, 29 deletions
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; i<msg->num_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);
}