summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 7e1993cada..3ac1e6adbb 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -3654,6 +3654,7 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
struct ldb_val md_value;
unsigned int i;
int ret;
+ bool remote_isDeleted = false;
/*
* TODO: check if the parent object exist
@@ -3707,6 +3708,9 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
}
}
+ remote_isDeleted = ldb_msg_find_attr_as_bool(msg,
+ "isDeleted", false);
+
/*
* the meta data array is already sorted by the caller
*/
@@ -3726,6 +3730,15 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
replmd_ldb_message_sort(msg, ar->schema);
+ if (!remote_isDeleted) {
+ ret = dsdb_module_schedule_sd_propagation(ar->module,
+ ar->objs->partition_dn,
+ msg->dn, true);
+ if (ret != LDB_SUCCESS) {
+ return replmd_replicated_request_error(ar, ret);
+ }
+ }
+
if (DEBUGLVL(4)) {
char *s = ldb_ldif_message_string(ldb, ar, LDB_CHANGETYPE_ADD, msg);
DEBUG(4, ("DRS replication add message:\n%s\n", s));
@@ -3920,11 +3933,14 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
struct ldb_message *msg,
struct replPropertyMetaDataBlob *rmd,
struct replPropertyMetaDataBlob *omd,
- struct ldb_request *parent)
+ struct ldb_request *parent,
+ bool *renamed)
{
struct replPropertyMetaData1 *md_remote;
struct replPropertyMetaData1 *md_local;
+ *renamed = true;
+
if (ldb_dn_compare(msg->dn, ar->search_msg->dn) == 0) {
/* no rename */
return LDB_SUCCESS;
@@ -4012,6 +4028,12 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
unsigned int removed_attrs = 0;
int ret;
int (*callback)(struct ldb_request *req, struct ldb_reply *ares) = replmd_op_callback;
+ bool isDeleted = false;
+ bool local_isDeleted = false;
+ bool remote_isDeleted = false;
+ bool take_remote_isDeleted = false;
+ bool sd_updated = false;
+ bool renamed = false;
ldb = ldb_module_get_ctx(ar->module);
msg = ar->objs->objects[ar->index_current].msg;
@@ -4035,8 +4057,14 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
}
}
+ local_isDeleted = ldb_msg_find_attr_as_bool(ar->search_msg,
+ "isDeleted", false);
+ remote_isDeleted = ldb_msg_find_attr_as_bool(msg,
+ "isDeleted", false);
+
/* handle renames that come in over DRS */
- ret = replmd_replicated_handle_rename(ar, msg, rmd, &omd, ar->req);
+ ret = replmd_replicated_handle_rename(ar, msg, rmd, &omd,
+ ar->req, &renamed);
/*
* This particular error code means that we already tried the
@@ -4075,6 +4103,7 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
/* Set the callback to one that will fix up the name to be a conflict DN */
callback = replmd_op_name_modify_callback;
msg->dn = new_dn;
+ renamed = true;
} else if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
"replmd_replicated_request rename %s => %s failed - %s\n",
@@ -4132,6 +4161,16 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
}
}
nmd.ctr.ctr1.array[j].local_usn = ar->seq_num;
+ switch (nmd.ctr.ctr1.array[j].attid) {
+ case DRSUAPI_ATTID_ntSecurityDescriptor:
+ sd_updated = true;
+ break;
+ case DRSUAPI_ATTID_isDeleted:
+ take_remote_isDeleted = true;
+ break;
+ default:
+ break;
+ }
found = true;
break;
}
@@ -4161,6 +4200,16 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
}
}
nmd.ctr.ctr1.array[ni].local_usn = ar->seq_num;
+ switch (nmd.ctr.ctr1.array[ni].attid) {
+ case DRSUAPI_ATTID_ntSecurityDescriptor:
+ sd_updated = true;
+ break;
+ case DRSUAPI_ATTID_isDeleted:
+ take_remote_isDeleted = true;
+ break;
+ default:
+ break;
+ }
ni++;
}
@@ -4195,6 +4244,25 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_replicated_apply_merge[%u]: replace %u attributes\n",
ar->index_current, msg->num_elements);
+ if (take_remote_isDeleted) {
+ isDeleted = remote_isDeleted;
+ } else {
+ isDeleted = local_isDeleted;
+ }
+
+ if (renamed) {
+ sd_updated = true;
+ }
+
+ if (sd_updated && !isDeleted) {
+ ret = dsdb_module_schedule_sd_propagation(ar->module,
+ ar->objs->partition_dn,
+ msg->dn, true);
+ if (ret != LDB_SUCCESS) {
+ return ldb_operr(ldb);
+ }
+ }
+
/* create the meta data value */
ndr_err = ndr_push_struct_blob(&nmd_value, msg, &nmd,
(ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob);