From: Stefan Metzmacher Date: Thu, 10 Feb 2022 14:08:47 +0000 (+0100) Subject: s4:dsdb/descriptor: pass parent guid to dsdb_module_schedule_sd_propagation() X-Git-Tag: tevent-0.12.0~203 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce38b30cdcf4a8d7225f830b8054c1df1d748da0;p=thirdparty%2Fsamba.git s4:dsdb/descriptor: pass parent guid to dsdb_module_schedule_sd_propagation() This is preparation to optimize the security descriptor propagation in the following commits. Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c index 08a95c1c310..12f00fbff16 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_util.c +++ b/source4/dsdb/samdb/ldb_modules/acl_util.c @@ -327,6 +327,7 @@ uint32_t dsdb_request_sd_flags(struct ldb_request *req, bool *explicit) int dsdb_module_schedule_sd_propagation(struct ldb_module *module, struct ldb_dn *nc_root, struct GUID guid, + struct GUID parent_guid, bool include_self) { struct ldb_context *ldb = ldb_module_get_ctx(module); @@ -341,6 +342,7 @@ int dsdb_module_schedule_sd_propagation(struct ldb_module *module, op->nc_root = nc_root; op->guid = guid; op->include_self = include_self; + op->parent_guid = parent_guid; ret = dsdb_module_extended(module, op, NULL, DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID, diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index f27a6151960..82245b1cf2b 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -50,6 +50,7 @@ struct descriptor_changes { 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; @@ -751,6 +752,7 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) 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; @@ -826,6 +828,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) * 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); @@ -834,7 +838,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) 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", @@ -845,6 +850,13 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) 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); @@ -935,6 +947,7 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) ret = dsdb_module_schedule_sd_propagation(module, nc_root, guid, + parent_guid, false); if (ret != LDB_SUCCESS) { return ldb_operr(ldb); @@ -1035,10 +1048,22 @@ static int descriptor_rename(struct ldb_module *module, struct ldb_request *req) * 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); @@ -1087,6 +1112,17 @@ static int descriptor_extended_sec_desc_propagation(struct ldb_module *module, 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. @@ -1138,6 +1174,11 @@ static int descriptor_extended_sec_desc_propagation(struct ldb_module *module, 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 diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index d3baf3ae7dd..1aef120a123 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -5724,6 +5724,9 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar) 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); @@ -6430,6 +6433,9 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) 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); @@ -6450,6 +6456,9 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) 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); diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index c9b8ff89397..286c97f2ea5 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -299,6 +299,7 @@ struct dsdb_extended_sec_desc_propagation_op { struct ldb_dn *nc_root; struct GUID guid; bool include_self; + struct GUID parent_guid; }; /* this takes no data */