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:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user