summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 3e6455c089..7f797752d0 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -1255,6 +1255,35 @@ static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct ds
return LDB_SUCCESS;
}
+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);
+
+/*
+ check if any links need upgrading from w2k format
+ */
+static int replmd_check_upgrade_links(struct parsed_dn *dns, uint32_t count, const struct GUID *invocation_id)
+{
+ int i;
+ for (i=0; i<count; i++) {
+ NTSTATUS status;
+ uint32_t version;
+ int ret;
+
+ status = dsdb_get_extended_dn_uint32(dns[i].dsdb_dn->dn, &version, "RMD_VERSION");
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ continue;
+ }
+
+ /* 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);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ return LDB_SUCCESS;
+}
/*
update an extended DN, including all meta data fields
@@ -1399,9 +1428,16 @@ static int replmd_modify_la_add(struct ldb_module *module,
invocation_id = samdb_ntds_invocation_id(ldb);
if (!invocation_id) {
+ talloc_free(tmp_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
+ ret = replmd_check_upgrade_links(old_dns, old_num_values, invocation_id);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
/* for each new value, see if it exists already with the same GUID */
for (i=0; i<el->num_values; i++) {
struct parsed_dn *p = parsed_dn_find(old_dns, old_num_values, dns[i].guid);
@@ -1521,6 +1557,12 @@ static int replmd_modify_la_delete(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
+ ret = replmd_check_upgrade_links(old_dns, old_el->num_values, invocation_id);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
el->values = NULL;
/* see if we are being asked to delete any links that
@@ -1633,6 +1675,12 @@ static int replmd_modify_la_replace(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
+ ret = replmd_check_upgrade_links(old_dns, old_num_values, invocation_id);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
/* mark all the old ones as deleted */
for (i=0; i<old_num_values; i++) {
struct parsed_dn *old_p = &old_dns[i];
@@ -3277,6 +3325,7 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
struct GUID guid;
NTSTATUS ntstatus;
bool active = (la->flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)?true:false;
+ const struct GUID *our_invocation_id;
drs.value_ctr.num_values = 1;
drs.value_ctr.values = &val;
@@ -3368,6 +3417,20 @@ linked_attributes[0]:
return ret;
}
+ /* get our invocationId */
+ our_invocation_id = samdb_ntds_invocation_id(ldb);
+ if (!our_invocation_id) {
+ ldb_debug_set(ldb, LDB_DEBUG_ERROR, __location__ ": unable to find invocationId\n");
+ talloc_free(tmp_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = replmd_check_upgrade_links(pdn_list, old_el->num_values, our_invocation_id);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
status = attr->syntax->drsuapi_to_ldb(ldb, schema, attr, &drs, tmp_ctx, &new_el);
if (!W_ERROR_IS_OK(status)) {
ldb_asprintf_errstring(ldb, "Failed to parsed linked attribute blob for %s on %s\n",