1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-24 21:49:29 +03:00

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.
This commit is contained in:
Andrew Tridgell
2009-09-12 11:10:19 +10:00
parent 0ba9a1bd3f
commit 94183eb7e6

View File

@ -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);
}