s4:dsdb/descriptor: pass parent guid to dsdb_module_schedule_sd_propagation()
authorStefan Metzmacher <metze@samba.org>
Thu, 10 Feb 2022 14:08:47 +0000 (15:08 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 30 Mar 2022 11:13:35 +0000 (11:13 +0000)
This is preparation to optimize the security descriptor propagation
in the following commits.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/acl_util.c
source4/dsdb/samdb/ldb_modules/descriptor.c
source4/dsdb/samdb/ldb_modules/repl_meta_data.c
source4/dsdb/samdb/samdb.h

index 08a95c1c310e2b41fa5f786f0c235e60b2ee4963..12f00fbff160096ed70b4623ecddedb9b2dc2ade 100644 (file)
@@ -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,
index f27a615196069888ee91ed7da0f766c803ed97dd..82245b1cf2b2dce0577f044e679ef45ef938ab42 100644 (file)
@@ -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
index d3baf3ae7dd618c5423a33005972a314e0c0c173..1aef120a1230a1c68a37e5c74d1759a13c7e66bc 100644 (file)
@@ -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);
index c9b8ff89397abac823a6a2df77f5f57044dc2561..286c97f2ea57b81bcfd72f5c29dfd30eb5daa6c0 100644 (file)
@@ -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 */