summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index d3a7e3791c..bf4a55054a 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -581,7 +581,7 @@ static void replmd_ldb_message_sort(struct ldb_message *msg,
static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
const struct GUID *invocation_id, uint64_t seq_num,
- uint64_t local_usn, NTTIME nttime, bool deleted);
+ uint64_t local_usn, NTTIME nttime, uint32_t version, bool deleted);
/*
@@ -609,7 +609,7 @@ static int replmd_add_fix_la(struct ldb_module *module, struct ldb_message_eleme
int ret;
ret = replmd_build_la_val(el->values, v, dsdb_dn, invocationId,
- seq_num, seq_num, now, false);
+ seq_num, seq_num, now, 0, false);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -1188,7 +1188,7 @@ static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
*/
static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
const struct GUID *invocation_id, uint64_t seq_num,
- uint64_t local_usn, NTTIME nttime, bool deleted)
+ uint64_t local_usn, NTTIME nttime, uint32_t version, bool deleted)
{
struct ldb_dn *dn = dsdb_dn->dn;
const char *tstring, *usn_string;
@@ -1199,6 +1199,7 @@ static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct ds
NTSTATUS status;
int ret;
const char *dnstring;
+ char *vstring;
tstring = talloc_asprintf(mem_ctx, "%llu", (unsigned long long)nttime);
if (!tstring) {
@@ -1218,7 +1219,8 @@ static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct ds
}
local_usnv = data_blob_string_const(usn_string);
- vers = data_blob_string_const("0");
+ vstring = talloc_asprintf(mem_ctx, "%lu", (unsigned long)version);
+ vers = data_blob_string_const(vstring);
status = GUID_to_ndr_blob(invocation_id, dn, &iid);
if (!NT_STATUS_IS_OK(status)) {
@@ -1257,7 +1259,8 @@ static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct ds
static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
struct dsdb_dn *old_dsdb_dn, const struct GUID *invocation_id,
- uint64_t seq_num, uint64_t local_usn, NTTIME nttime, bool deleted);
+ uint64_t seq_num, uint64_t local_usn, NTTIME nttime,
+ uint32_t version, bool deleted);
/*
check if any links need upgrading from w2k format
@@ -1277,7 +1280,7 @@ static int replmd_check_upgrade_links(struct parsed_dn *dns, uint32_t count, con
/* it's an old one that needs upgrading */
ret = replmd_update_la_val(dns, dns[i].v, dns[i].dsdb_dn, dns[i].dsdb_dn, invocation_id,
- 1, 1, 0, false);
+ 1, 1, 0, 0, false);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -1292,7 +1295,8 @@ static int replmd_check_upgrade_links(struct parsed_dn *dns, uint32_t count, con
*/
static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
struct dsdb_dn *old_dsdb_dn, const struct GUID *invocation_id,
- uint64_t seq_num, uint64_t local_usn, NTTIME nttime, bool deleted)
+ uint64_t seq_num, uint64_t local_usn, NTTIME nttime,
+ uint32_t version, bool deleted)
{
struct ldb_dn *dn = dsdb_dn->dn;
const char *tstring, *usn_string;
@@ -1300,10 +1304,12 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d
struct ldb_val iid;
struct ldb_val usnv, local_usnv;
struct ldb_val vers;
- const struct ldb_val *old_addtime, *old_version;
+ const struct ldb_val *old_addtime;
+ uint32_t old_version;
NTSTATUS status;
int ret;
const char *dnstring;
+ char *vstring;
tstring = talloc_asprintf(mem_ctx, "%llu", (unsigned long long)nttime);
if (!tstring) {
@@ -1363,19 +1369,12 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d
if (ret != LDB_SUCCESS) return ret;
/* increase the version by 1 */
- old_version = ldb_dn_get_extended_component(old_dsdb_dn->dn, "RMD_VERSION");
- if (old_version == NULL) {
- vers = data_blob_string_const("0");
- } else {
- char *vstring;
- vstring = talloc_strndup(dn, (const char *)old_version->data, old_version->length);
- if (!vstring) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- vstring = talloc_asprintf(dn, "%lu",
- (unsigned long)strtoul(vstring, NULL, 0)+1);
- vers = data_blob_string_const(vstring);
+ status = dsdb_get_extended_dn_uint32(old_dsdb_dn->dn, &old_version, "RMD_VERSION");
+ if (NT_STATUS_IS_OK(status) && old_version >= version) {
+ version = old_version+1;
}
+ vstring = talloc_asprintf(dn, "%lu", (unsigned long)version);
+ vers = data_blob_string_const(vstring);
ret = ldb_dn_set_extended_component(dn, "RMD_VERSION", &vers);
if (ret != LDB_SUCCESS) return ret;
@@ -1450,7 +1449,7 @@ static int replmd_modify_la_add(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
ret = replmd_build_la_val(new_values, &new_values[num_new_values], dns[i].dsdb_dn,
- invocation_id, seq_num, seq_num, now, false);
+ invocation_id, seq_num, seq_num, now, 0, false);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -1468,7 +1467,7 @@ static int replmd_modify_la_add(struct ldb_module *module,
return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
}
ret = replmd_update_la_val(old_el->values, p->v, dns[i].dsdb_dn, p->dsdb_dn,
- invocation_id, seq_num, seq_num, now, false);
+ invocation_id, seq_num, seq_num, now, 0, false);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -1601,7 +1600,7 @@ static int replmd_modify_la_delete(struct ldb_module *module,
if (v != NULL) continue;
ret = replmd_update_la_val(old_el->values, p->v, p->dsdb_dn, p->dsdb_dn,
- invocation_id, seq_num, seq_num, now, true);
+ invocation_id, seq_num, seq_num, now, 0, true);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -1703,7 +1702,7 @@ static int replmd_modify_la_replace(struct ldb_module *module,
}
ret = replmd_update_la_val(old_el->values, old_p->v, old_p->dsdb_dn, old_p->dsdb_dn,
- invocation_id, seq_num, seq_num, now, true);
+ invocation_id, seq_num, seq_num, now, 0, true);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -1722,7 +1721,7 @@ static int replmd_modify_la_replace(struct ldb_module *module,
/* update in place */
ret = replmd_update_la_val(old_el->values, old_p->v, old_p->dsdb_dn,
old_p->dsdb_dn, invocation_id,
- seq_num, seq_num, now, false);
+ seq_num, seq_num, now, 0, false);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -1737,7 +1736,7 @@ static int replmd_modify_la_replace(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
ret = replmd_build_la_val(new_values, &new_values[num_new_values], dns[i].dsdb_dn,
- invocation_id, seq_num, seq_num, now, false);
+ invocation_id, seq_num, seq_num, now, 0, false);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -3504,6 +3503,7 @@ linked_attributes[0]:
&la->meta_data.originating_invocation_id,
la->meta_data.originating_usn, seq_num,
la->meta_data.originating_change_time,
+ la->meta_data.version,
!active);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
@@ -3538,6 +3538,7 @@ linked_attributes[0]:
&la->meta_data.originating_invocation_id,
la->meta_data.originating_usn, seq_num,
la->meta_data.originating_change_time,
+ la->meta_data.version,
(la->flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)?false:true);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);