LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - acl_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 109 141 77.3 %
Date: 2024-01-11 09:59:51 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :   ACL utility functions
       3             : 
       4             :   Copyright (C) Nadezhda Ivanova 2010
       5             : 
       6             :   This program is free software; you can redistribute it and/or modify
       7             :   it under the terms of the GNU General Public License as published by
       8             :   the Free Software Foundation; either version 3 of the License, or
       9             :   (at your option) any later version.
      10             : 
      11             :   This program is distributed in the hope that it will be useful,
      12             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :   GNU General Public License for more details.
      15             : 
      16             :   You should have received a copy of the GNU General Public License
      17             :   along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : /*
      21             :  *  Name: acl_util
      22             :  *
      23             :  *  Component: ldb ACL modules
      24             :  *
      25             :  *  Description: Some auxiliary functions used for access checking
      26             :  *
      27             :  *  Author: Nadezhda Ivanova
      28             :  */
      29             : #include "includes.h"
      30             : #include "ldb_module.h"
      31             : #include "auth/auth.h"
      32             : #include "libcli/security/security.h"
      33             : #include "dsdb/samdb/samdb.h"
      34             : #include "librpc/gen_ndr/ndr_security.h"
      35             : #include "param/param.h"
      36             : #include "dsdb/samdb/ldb_modules/util.h"
      37             : 
      38     8487916 : struct security_token *acl_user_token(struct ldb_module *module)
      39             : {
      40     8487916 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
      41      103406 :         struct auth_session_info *session_info
      42     8487916 :                 = (struct auth_session_info *)ldb_get_opaque(
      43             :                         ldb,
      44             :                         DSDB_SESSION_INFO);
      45     8487916 :         if(!session_info) {
      46           0 :                 return NULL;
      47             :         }
      48     8487908 :         return session_info->security_token;
      49             : }
      50             : 
      51             : /* performs an access check from inside the module stack
      52             :  * given the dn of the object to be checked, the required access
      53             :  * guid is either the guid of the extended right, or NULL
      54             :  */
      55             : 
      56     1462893 : int dsdb_module_check_access_on_dn(struct ldb_module *module,
      57             :                                    TALLOC_CTX *mem_ctx,
      58             :                                    struct ldb_dn *dn,
      59             :                                    uint32_t access_mask,
      60             :                                    const struct GUID *guid,
      61             :                                    struct ldb_request *parent)
      62             : {
      63       83790 :         int ret;
      64       83790 :         struct ldb_result *acl_res;
      65       83790 :         static const char *acl_attrs[] = {
      66             :                 "nTSecurityDescriptor",
      67             :                 "objectSid",
      68             :                 NULL
      69             :         };
      70     1462893 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
      71       83790 :         struct auth_session_info *session_info
      72     1462893 :                 = (struct auth_session_info *)ldb_get_opaque(
      73             :                         ldb,
      74             :                         DSDB_SESSION_INFO);
      75     1462893 :         if(!session_info) {
      76           0 :                 return ldb_operr(ldb);
      77             :         }
      78     1462893 :         ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn,
      79             :                                     acl_attrs,
      80             :                                     DSDB_FLAG_NEXT_MODULE |
      81             :                                     DSDB_FLAG_AS_SYSTEM |
      82             :                                     DSDB_SEARCH_SHOW_RECYCLED,
      83             :                                     parent);
      84     1462893 :         if (ret != LDB_SUCCESS) {
      85         381 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
      86             :                                        "access_check: failed to find object %s\n",
      87             :                                        ldb_dn_get_linearized(dn));
      88         381 :                 return ret;
      89             :         }
      90     1462512 :         return dsdb_check_access_on_dn_internal(ldb, acl_res,
      91             :                                                 mem_ctx,
      92             :                                                 session_info->security_token,
      93             :                                                 dn,
      94             :                                                 access_mask,
      95             :                                                 guid);
      96             : }
      97             : 
      98     6892394 : int acl_check_access_on_attribute_implicit_owner(struct ldb_module *module,
      99             :                                                  TALLOC_CTX *mem_ctx,
     100             :                                                  const struct security_descriptor *sd,
     101             :                                                  const struct dom_sid *rp_sid,
     102             :                                                  uint32_t access_mask,
     103             :                                                  const struct dsdb_attribute *attr,
     104             :                                                  const struct dsdb_class *objectclass,
     105             :                                                  enum implicit_owner_rights implicit_owner_rights)
     106             : {
     107        5032 :         int ret;
     108        5032 :         NTSTATUS status;
     109        5032 :         uint32_t access_granted;
     110     6892394 :         struct object_tree *root = NULL;
     111     6892394 :         struct object_tree *new_node = NULL;
     112     6892394 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     113     6892394 :         struct security_token *token = acl_user_token(module);
     114             : 
     115     6892394 :         if (!insert_in_object_tree(tmp_ctx,
     116             :                                    &objectclass->schemaIDGUID,
     117             :                                    access_mask, NULL,
     118             :                                    &root)) {
     119           0 :                 DEBUG(10, ("acl_search: cannot add to object tree class schemaIDGUID\n"));
     120           0 :                 goto fail;
     121             :         }
     122     6892394 :         new_node = root;
     123             : 
     124     6892394 :         if (!GUID_all_zero(&attr->attributeSecurityGUID)) {
     125     5018340 :                 if (!insert_in_object_tree(tmp_ctx,
     126             :                                            &attr->attributeSecurityGUID,
     127             :                                            access_mask, new_node,
     128             :                                            &new_node)) {
     129           0 :                         DEBUG(10, ("acl_search: cannot add to object tree securityGUID\n"));
     130           0 :                         goto fail;
     131             :                 }
     132             :         }
     133             : 
     134     6892394 :         if (!insert_in_object_tree(tmp_ctx,
     135             :                                    &attr->schemaIDGUID,
     136             :                                    access_mask, new_node,
     137             :                                    &new_node)) {
     138           0 :                 DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n"));
     139           0 :                 goto fail;
     140             :         }
     141             : 
     142     6892394 :         status = sec_access_check_ds_implicit_owner(sd, token,
     143             :                                                     access_mask,
     144             :                                                     &access_granted,
     145             :                                                     root,
     146             :                                                     rp_sid,
     147             :                                                     implicit_owner_rights);
     148     6892394 :         if (!NT_STATUS_IS_OK(status)) {
     149       34085 :                 ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
     150             :         }
     151             :         else {
     152     6858309 :                 ret = LDB_SUCCESS;
     153             :         }
     154     6892394 :         talloc_free(tmp_ctx);
     155     6892394 :         return ret;
     156           0 : fail:
     157           0 :         talloc_free(tmp_ctx);
     158           0 :         return ldb_operr(ldb_module_get_ctx(module));
     159             : }
     160             : 
     161      113860 : int acl_check_access_on_attribute(struct ldb_module *module,
     162             :                                   TALLOC_CTX *mem_ctx,
     163             :                                   struct security_descriptor *sd,
     164             :                                   struct dom_sid *rp_sid,
     165             :                                   uint32_t access_mask,
     166             :                                   const struct dsdb_attribute *attr,
     167             :                                   const struct dsdb_class *objectclass)
     168             : {
     169      113860 :         return acl_check_access_on_attribute_implicit_owner(module,
     170             :                                                             mem_ctx,
     171             :                                                             sd,
     172             :                                                             rp_sid,
     173             :                                                             access_mask,
     174             :                                                             attr,
     175             :                                                             objectclass,
     176             :                                                             IMPLICIT_OWNER_READ_CONTROL_RIGHTS);
     177             : }
     178             : 
     179       42579 : int acl_check_access_on_objectclass(struct ldb_module *module,
     180             :                                     TALLOC_CTX *mem_ctx,
     181             :                                     struct security_descriptor *sd,
     182             :                                     struct dom_sid *rp_sid,
     183             :                                     uint32_t access_mask,
     184             :                                     const struct dsdb_class *objectclass)
     185             : {
     186         108 :         int ret;
     187         108 :         NTSTATUS status;
     188         108 :         uint32_t access_granted;
     189       42579 :         struct object_tree *root = NULL;
     190       42579 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     191       42579 :         struct security_token *token = acl_user_token(module);
     192             : 
     193       42579 :         if (!insert_in_object_tree(tmp_ctx,
     194             :                                    &objectclass->schemaIDGUID,
     195             :                                    access_mask, NULL,
     196             :                                    &root)) {
     197           0 :                 DEBUG(10, ("acl_search: cannot add to object tree class schemaIDGUID\n"));
     198           0 :                 goto fail;
     199             :         }
     200             : 
     201       42579 :         status = sec_access_check_ds(sd, token,
     202             :                                      access_mask,
     203             :                                      &access_granted,
     204             :                                      root,
     205             :                                      rp_sid);
     206       42579 :         if (!NT_STATUS_IS_OK(status)) {
     207        1987 :                 ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
     208             :         } else {
     209       40592 :                 ret = LDB_SUCCESS;
     210             :         }
     211       42579 :         talloc_free(tmp_ctx);
     212       42579 :         return ret;
     213           0 : fail:
     214           0 :         talloc_free(tmp_ctx);
     215           0 :         return ldb_operr(ldb_module_get_ctx(module));
     216             : }
     217             : 
     218             : /* checks for validated writes */
     219       21181 : int acl_check_extended_right(TALLOC_CTX *mem_ctx,
     220             :                              struct ldb_module *module,
     221             :                              struct ldb_request *req,
     222             :                              const struct dsdb_class *objectclass,
     223             :                              struct security_descriptor *sd,
     224             :                              struct security_token *token,
     225             :                              const char *ext_right,
     226             :                              uint32_t right_type,
     227             :                              struct dom_sid *sid)
     228             : {
     229         246 :         struct GUID right;
     230         246 :         NTSTATUS status;
     231         246 :         uint32_t access_granted;
     232       21181 :         struct object_tree *root = NULL;
     233       21181 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     234         246 :         static const char *no_attrs[] = { NULL };
     235       21181 :         struct ldb_result *extended_rights_res = NULL;
     236       21181 :         struct ldb_dn *extended_rights_dn = NULL;
     237       21181 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     238       21181 :         int ret = 0;
     239             : 
     240             :         /*
     241             :          * Find the extended right and check if applies to
     242             :          * the objectclass of the object
     243             :          */
     244       21181 :         extended_rights_dn = samdb_extended_rights_dn(ldb, req);
     245       21181 :         if (!extended_rights_dn) {
     246           0 :                 ldb_set_errstring(ldb,
     247             :                         "access_check: CN=Extended-Rights dn could not be generated!");
     248           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     249             :         }
     250             : 
     251             :         /* Note: we are checking only the structural object class. */
     252       21181 :         ret = dsdb_module_search(module, req, &extended_rights_res,
     253             :                                  extended_rights_dn, LDB_SCOPE_ONELEVEL,
     254             :                                  no_attrs,
     255             :                                  DSDB_FLAG_NEXT_MODULE |
     256             :                                  DSDB_FLAG_AS_SYSTEM,
     257             :                                  req,
     258             :                                  "(&(rightsGuid=%s)(appliesTo=%s))",
     259             :                                  ext_right,
     260             :                                  GUID_string(tmp_ctx,
     261             :                                              &(objectclass->schemaIDGUID)));
     262             : 
     263       21181 :         if (ret != LDB_SUCCESS) {
     264           0 :                 return ret;
     265       21181 :         } else if (extended_rights_res->count == 0 ) {
     266          48 :                 ldb_debug(ldb, LDB_DEBUG_TRACE,
     267             :                           "acl_check_extended_right: Could not find appliesTo for %s\n",
     268             :                           ext_right);
     269          48 :                 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
     270             :         }
     271             : 
     272       21133 :         GUID_from_string(ext_right, &right);
     273             : 
     274       21133 :         if (!insert_in_object_tree(tmp_ctx, &right, right_type,
     275             :                                    NULL, &root)) {
     276           0 :                 DEBUG(10, ("acl_ext_right: cannot add to object tree\n"));
     277           0 :                 talloc_free(tmp_ctx);
     278           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     279             :         }
     280       21133 :         status = sec_access_check_ds(sd, token,
     281             :                                      right_type,
     282             :                                      &access_granted,
     283             :                                      root,
     284             :                                      sid);
     285             : 
     286       21133 :         if (!NT_STATUS_IS_OK(status)) {
     287         331 :                 talloc_free(tmp_ctx);
     288         331 :                 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
     289             :         }
     290       20802 :         talloc_free(tmp_ctx);
     291       20802 :         return LDB_SUCCESS;
     292             : }
     293             : 
     294           0 : const char *acl_user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module)
     295             : {
     296           0 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     297           0 :         struct auth_session_info *session_info
     298           0 :                 = (struct auth_session_info *)ldb_get_opaque(
     299             :                         ldb,
     300             :                         DSDB_SESSION_INFO);
     301           0 :         if (!session_info) {
     302           0 :                 return "UNKNOWN (NULL)";
     303             :         }
     304             : 
     305           0 :         return talloc_asprintf(mem_ctx, "%s\\%s",
     306           0 :                                session_info->info->domain_name,
     307           0 :                                session_info->info->account_name);
     308             : }
     309             : 
     310    32077030 : uint32_t dsdb_request_sd_flags(struct ldb_request *req, bool *explicit)
     311             : {
     312     1754885 :         struct ldb_control *sd_control;
     313    32077030 :         uint32_t sd_flags = 0;
     314             : 
     315    32077030 :         if (explicit) {
     316    31506347 :                 *explicit = false;
     317             :         }
     318             : 
     319    32077030 :         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
     320    32077030 :         if (sd_control != NULL && sd_control->data != NULL) {
     321     1341203 :                 struct ldb_sd_flags_control *sdctr = talloc_get_type_abort(sd_control->data, struct ldb_sd_flags_control);
     322             : 
     323     1341203 :                 sd_flags = sdctr->secinfo_flags;
     324             : 
     325     1341203 :                 if (explicit) {
     326     1319830 :                         *explicit = true;
     327             :                 }
     328             : 
     329             :                 /* mark it as handled */
     330     1341203 :                 sd_control->critical = 0;
     331             :         }
     332             : 
     333             :         /* we only care for the last 4 bits */
     334    32077030 :         sd_flags &= 0x0000000F;
     335             : 
     336             :         /*
     337             :          * MS-ADTS 3.1.1.3.4.1.11 says that no bits
     338             :          * equals all 4 bits
     339             :          */
     340    32077030 :         if (sd_flags == 0) {
     341    30735881 :                 sd_flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_SACL;
     342             :         }
     343             : 
     344    32077030 :         return sd_flags;
     345             : }
     346             : 
     347      368480 : int dsdb_module_schedule_sd_propagation(struct ldb_module *module,
     348             :                                         struct ldb_dn *nc_root,
     349             :                                         struct GUID guid,
     350             :                                         struct GUID parent_guid,
     351             :                                         bool include_self)
     352             : {
     353      368480 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     354         352 :         struct dsdb_extended_sec_desc_propagation_op *op;
     355         352 :         int ret;
     356             : 
     357      368480 :         op = talloc_zero(module, struct dsdb_extended_sec_desc_propagation_op);
     358      368480 :         if (op == NULL) {
     359           0 :                 return ldb_oom(ldb);
     360             :         }
     361             : 
     362      368480 :         op->nc_root = nc_root;
     363      368480 :         op->guid = guid;
     364      368480 :         op->include_self = include_self;
     365      368480 :         op->parent_guid = parent_guid;
     366             : 
     367      368480 :         ret = dsdb_module_extended(module, op, NULL,
     368             :                                    DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID,
     369             :                                    op,
     370             :                                    DSDB_FLAG_TOP_MODULE |
     371             :                                    DSDB_FLAG_AS_SYSTEM |
     372             :                                    DSDB_FLAG_TRUSTED,
     373             :                                    NULL);
     374      368480 :         TALLOC_FREE(op);
     375      368480 :         return ret;
     376             : }

Generated by: LCOV version 1.14