struct descriptor_changes *prev, *next;
struct ldb_dn *nc_root;
struct GUID guid;
+ struct GUID parent_guid;
bool force_self;
bool force_children;
struct ldb_dn *stopped_dn;
static const char * const current_attrs[] = { "nTSecurityDescriptor",
"instanceType",
"objectClass", NULL };
+ struct GUID parent_guid = { .time_low = 0 };
struct ldb_control *sd_propagation_control;
int cmp_ret = -1;
* use for calculation */
if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
+ NTSTATUS status;
+
parent_dn = ldb_dn_get_parent(req, dn);
if (parent_dn == NULL) {
return ldb_oom(ldb);
parent_attrs,
DSDB_FLAG_NEXT_MODULE |
DSDB_FLAG_AS_SYSTEM |
- DSDB_SEARCH_SHOW_RECYCLED,
+ DSDB_SEARCH_SHOW_RECYCLED |
+ DSDB_SEARCH_SHOW_EXTENDED_DN,
req);
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
return ldb_operr(ldb);
}
parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
+
+ status = dsdb_get_extended_dn_guid(parent_res->msgs[0]->dn,
+ &parent_guid,
+ "GUID");
+ if (!NT_STATUS_IS_OK(status)) {
+ return ldb_operr(ldb);
+ }
}
schema = dsdb_get_schema(ldb, req);
ret = dsdb_module_schedule_sd_propagation(module,
nc_root,
guid,
+ parent_guid,
false);
if (ret != LDB_SUCCESS) {
return ldb_operr(ldb);
* does not exit, force SD propagation on
* this record (get a new inherited SD from
* the potentially new parent
+ *
+ * We don't now the parent guid here,
+ * but we're not in a hot code path here,
+ * as the "descriptor" module is located
+ * above the "repl_meta_data", only
+ * originating changes are handled here.
+ *
+ * If it turns out to be a problem we may
+ * search for the new parent guid.
*/
+ struct GUID parent_guid = { .time_low = 0 };
+
ret = dsdb_module_schedule_sd_propagation(module,
nc_root,
guid,
+ parent_guid,
true);
if (ret != LDB_SUCCESS) {
return ldb_operr(ldb);
return ldb_module_operr(module);
}
+ if (GUID_equal(&op->parent_guid, &op->guid)) {
+ /*
+ * This is an unexpected situation,
+ * it should never happen!
+ */
+ DBG_ERR("ERROR: Object %s is its own parent (nc_root=%s)\n",
+ GUID_string(t->mem, &op->guid),
+ ldb_dn_get_extended_linearized(t->mem, op->nc_root, 1));
+ return ldb_module_operr(module);
+ }
+
/*
* First we check if we already have an registration
* for the given object.
c->ref_count += 1;
+ /*
+ * always use the last known parent_guid.
+ */
+ c->parent_guid = op->parent_guid;
+
/*
* Note that we only set, but don't clear values here,
* it means c->force_self and c->force_children can
ret = dsdb_module_schedule_sd_propagation(ar->module,
ar->objs->partition_dn,
ar->objs->objects[ar->index_current].object_guid,
+ ar->objs->objects[ar->index_current].parent_guid ?
+ *ar->objs->objects[ar->index_current].parent_guid :
+ GUID_zero(),
true);
if (ret != LDB_SUCCESS) {
return replmd_replicated_request_error(ar, ret);
ret = dsdb_module_schedule_sd_propagation(ar->module,
ar->objs->partition_dn,
ar->objs->objects[ar->index_current].object_guid,
+ ar->objs->objects[ar->index_current].parent_guid ?
+ *ar->objs->objects[ar->index_current].parent_guid :
+ GUID_zero(),
true);
if (ret != LDB_SUCCESS) {
return ldb_operr(ldb);
ret = dsdb_module_schedule_sd_propagation(ar->module,
ar->objs->partition_dn,
ar->objs->objects[ar->index_current].object_guid,
+ ar->objs->objects[ar->index_current].parent_guid ?
+ *ar->objs->objects[ar->index_current].parent_guid :
+ GUID_zero(),
false);
if (ret != LDB_SUCCESS) {
return ldb_operr(ldb);