diff options
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 63 |
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", |