LCOV - code coverage report
Current view: top level - libcli/security - access_check.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 217 247 87.9 %
Date: 2024-06-13 04:01:37 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Copyright (C) Andrew Tridgell 2004
       5             :    Copyright (C) Gerald Carter 2005
       6             :    Copyright (C) Volker Lendecke 2007
       7             :    Copyright (C) Jeremy Allison 2008
       8             :    Copyright (C) Andrew Bartlett 2010
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "libcli/security/security.h"
      26             : 
      27             : /* Map generic access rights to object specific rights.  This technique is
      28             :    used to give meaning to assigning read, write, execute and all access to
      29             :    objects.  Each type of object has its own mapping of generic to object
      30             :    specific access rights. */
      31             : 
      32       62680 : void se_map_generic(uint32_t *access_mask, const struct generic_mapping *mapping)
      33             : {
      34       62680 :         uint32_t old_mask = *access_mask;
      35             : 
      36       62680 :         if (*access_mask & GENERIC_READ_ACCESS) {
      37         108 :                 *access_mask &= ~GENERIC_READ_ACCESS;
      38         108 :                 *access_mask |= mapping->generic_read;
      39             :         }
      40             : 
      41       62680 :         if (*access_mask & GENERIC_WRITE_ACCESS) {
      42           2 :                 *access_mask &= ~GENERIC_WRITE_ACCESS;
      43           2 :                 *access_mask |= mapping->generic_write;
      44             :         }
      45             : 
      46       62680 :         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
      47         106 :                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
      48         106 :                 *access_mask |= mapping->generic_execute;
      49             :         }
      50             : 
      51       62680 :         if (*access_mask & GENERIC_ALL_ACCESS) {
      52         111 :                 *access_mask &= ~GENERIC_ALL_ACCESS;
      53         111 :                 *access_mask |= mapping->generic_all;
      54             :         }
      55             : 
      56       62680 :         if (old_mask != *access_mask) {
      57         116 :                 DEBUG(10, ("se_map_generic(): mapped mask 0x%08x to 0x%08x\n",
      58             :                            old_mask, *access_mask));
      59             :         }
      60       62680 : }
      61             : 
      62             : /* Map generic access rights to object specific rights for all the ACE's
      63             :  * in a security_acl.
      64             :  */
      65             : 
      66        3188 : void security_acl_map_generic(struct security_acl *sa,
      67             :                                 const struct generic_mapping *mapping)
      68             : {
      69             :         unsigned int i;
      70             : 
      71        3188 :         if (!sa) {
      72           0 :                 return;
      73             :         }
      74             : 
      75       31672 :         for (i = 0; i < sa->num_aces; i++) {
      76       28484 :                 se_map_generic(&sa->aces[i].access_mask, mapping);
      77             :         }
      78             : }
      79             : 
      80             : /* Map standard access rights to object specific rights.  This technique is
      81             :    used to give meaning to assigning read, write, execute and all access to
      82             :    objects.  Each type of object has its own mapping of standard to object
      83             :    specific access rights. */
      84             : 
      85           2 : void se_map_standard(uint32_t *access_mask, const struct standard_mapping *mapping)
      86             : {
      87           2 :         uint32_t old_mask = *access_mask;
      88             : 
      89           2 :         if (*access_mask & SEC_STD_READ_CONTROL) {
      90           0 :                 *access_mask &= ~SEC_STD_READ_CONTROL;
      91           0 :                 *access_mask |= mapping->std_read;
      92             :         }
      93             : 
      94           2 :         if (*access_mask & (SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE)) {
      95           0 :                 *access_mask &= ~(SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE);
      96           0 :                 *access_mask |= mapping->std_all;
      97             :         }
      98             : 
      99           2 :         if (old_mask != *access_mask) {
     100           0 :                 DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
     101             :                            old_mask, *access_mask));
     102             :         }
     103           2 : }
     104             : 
     105             : /*
     106             :   perform a SEC_FLAG_MAXIMUM_ALLOWED access check
     107             : */
     108       15959 : static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
     109             :                                         const struct security_token *token)
     110             : {
     111       15959 :         uint32_t denied = 0, granted = 0;
     112       15959 :         bool am_owner = false;
     113       15959 :         bool have_owner_rights_ace = false;
     114             :         unsigned i;
     115             : 
     116       15959 :         if (sd->dacl == NULL) {
     117           0 :                 if (security_token_has_sid(token, sd->owner_sid)) {
     118           0 :                         granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
     119             :                 }
     120           0 :                 return granted;
     121             :         }
     122             : 
     123       15959 :         if (security_token_has_sid(token, sd->owner_sid)) {
     124             :                 /*
     125             :                  * Check for explicit owner rights: if there are none, we remove
     126             :                  * the default owner right SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL
     127             :                  * from remaining_access. Otherwise we just process the
     128             :                  * explicitly granted rights when processing the ACEs.
     129             :                  */
     130        2293 :                 am_owner = true;
     131             : 
     132       22735 :                 for (i=0; i < sd->dacl->num_aces; i++) {
     133       20442 :                         struct security_ace *ace = &sd->dacl->aces[i];
     134             : 
     135       20442 :                         if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
     136           9 :                                 continue;
     137             :                         }
     138             : 
     139       20433 :                         have_owner_rights_ace = dom_sid_equal(
     140       20433 :                                 &ace->trustee, &global_sid_Owner_Rights);
     141       20433 :                         if (have_owner_rights_ace) {
     142           0 :                                 break;
     143             :                         }
     144             :                 }
     145             :         }
     146             : 
     147       15959 :         if (am_owner && !have_owner_rights_ace) {
     148        2293 :                 granted |= SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL;
     149             :         }
     150             : 
     151       50347 :         for (i = 0;i<sd->dacl->num_aces; i++) {
     152       34388 :                 struct security_ace *ace = &sd->dacl->aces[i];
     153       34388 :                 bool is_owner_rights_ace = false;
     154             : 
     155       34388 :                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
     156           9 :                         continue;
     157             :                 }
     158             : 
     159       34379 :                 if (am_owner) {
     160       20433 :                         is_owner_rights_ace = dom_sid_equal(
     161       20433 :                                 &ace->trustee, &global_sid_Owner_Rights);
     162             :                 }
     163             : 
     164       57100 :                 if (!is_owner_rights_ace &&
     165       34379 :                     !security_token_has_sid(token, &ace->trustee))
     166             :                 {
     167       17282 :                         continue;
     168             :                 }
     169             : 
     170       17097 :                 switch (ace->type) {
     171       17088 :                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
     172       17088 :                         granted |= ace->access_mask;
     173       17088 :                         break;
     174           0 :                 case SEC_ACE_TYPE_ACCESS_DENIED:
     175             :                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
     176           0 :                         denied |= ~granted & ace->access_mask;
     177           0 :                         break;
     178           9 :                 default:        /* Other ACE types not handled/supported */
     179           9 :                         break;
     180             :                 }
     181             :         }
     182             : 
     183       15959 :         return granted & ~denied;
     184             : }
     185             : 
     186             : /*
     187             :   The main entry point for access checking. If returning ACCESS_DENIED
     188             :   this function returns the denied bits in the uint32_t pointed
     189             :   to by the access_granted pointer.
     190             : */
     191       22212 : NTSTATUS se_access_check(const struct security_descriptor *sd,
     192             :                           const struct security_token *token,
     193             :                           uint32_t access_desired,
     194             :                           uint32_t *access_granted)
     195             : {
     196             :         uint32_t i;
     197             :         uint32_t bits_remaining;
     198       22212 :         uint32_t explicitly_denied_bits = 0;
     199       22212 :         bool am_owner = false;
     200       22212 :         bool have_owner_rights_ace = false;
     201             : 
     202       22212 :         *access_granted = access_desired;
     203       22212 :         bits_remaining = access_desired;
     204             : 
     205             :         /* handle the maximum allowed flag */
     206       22212 :         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
     207        2340 :                 uint32_t orig_access_desired = access_desired;
     208             : 
     209        2340 :                 access_desired |= access_check_max_allowed(sd, token);
     210        2340 :                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
     211        2340 :                 *access_granted = access_desired;
     212        2340 :                 bits_remaining = access_desired;
     213             : 
     214        2340 :                 DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n",
     215             :                         orig_access_desired,
     216             :                         *access_granted,
     217             :                         bits_remaining));
     218             :         }
     219             : 
     220             :         /* a NULL dacl allows access */
     221       22212 :         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
     222          18 :                 *access_granted = access_desired;
     223          18 :                 return NT_STATUS_OK;
     224             :         }
     225             : 
     226       22194 :         if (sd->dacl == NULL) {
     227           0 :                 goto done;
     228             :         }
     229             : 
     230       22194 :         if (security_token_has_sid(token, sd->owner_sid)) {
     231             :                 /*
     232             :                  * Check for explicit owner rights: if there are none, we remove
     233             :                  * the default owner right SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL
     234             :                  * from remaining_access. Otherwise we just process the
     235             :                  * explicitly granted rights when processing the ACEs.
     236             :                  */
     237        6705 :                 am_owner = true;
     238             : 
     239       56425 :                 for (i=0; i < sd->dacl->num_aces; i++) {
     240       49720 :                         struct security_ace *ace = &sd->dacl->aces[i];
     241             : 
     242       49720 :                         if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
     243        4537 :                                 continue;
     244             :                         }
     245             : 
     246       45183 :                         have_owner_rights_ace = dom_sid_equal(
     247       45183 :                                 &ace->trustee, &global_sid_Owner_Rights);
     248       45183 :                         if (have_owner_rights_ace) {
     249           0 :                                 break;
     250             :                         }
     251             :                 }
     252             :         }
     253       22194 :         if (am_owner && !have_owner_rights_ace) {
     254        6705 :                 bits_remaining &= ~(SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL);
     255             :         }
     256             : 
     257             :         /* check each ace in turn. */
     258       50906 :         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
     259       28712 :                 struct security_ace *ace = &sd->dacl->aces[i];
     260       28712 :                 bool is_owner_rights_ace = false;
     261             : 
     262       28712 :                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
     263         446 :                         continue;
     264             :                 }
     265             : 
     266       28266 :                 if (am_owner) {
     267        9587 :                         is_owner_rights_ace = dom_sid_equal(
     268        9587 :                                 &ace->trustee, &global_sid_Owner_Rights);
     269             :                 }
     270             : 
     271       48974 :                 if (!is_owner_rights_ace &&
     272       28266 :                     !security_token_has_sid(token, &ace->trustee))
     273             :                 {
     274        7433 :                         continue;
     275             :                 }
     276             : 
     277       20833 :                 switch (ace->type) {
     278       20721 :                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
     279       20721 :                         bits_remaining &= ~ace->access_mask;
     280       20721 :                         break;
     281           0 :                 case SEC_ACE_TYPE_ACCESS_DENIED:
     282             :                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
     283           0 :                         explicitly_denied_bits |= (bits_remaining & ace->access_mask);
     284           0 :                         break;
     285         112 :                 default:        /* Other ACE types not handled/supported */
     286         112 :                         break;
     287             :                 }
     288             :         }
     289             : 
     290             :         /* Explicitly denied bits always override */
     291       22194 :         bits_remaining |= explicitly_denied_bits;
     292             : 
     293             :         /*
     294             :          * We check privileges here because they override even DENY entries.
     295             :          */
     296             : 
     297             :         /* Does the user have the privilege to gain SEC_PRIV_SECURITY? */
     298       22194 :         if (bits_remaining & SEC_FLAG_SYSTEM_SECURITY) {
     299        8373 :                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
     300        8373 :                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
     301             :                 } else {
     302           0 :                         return NT_STATUS_PRIVILEGE_NOT_HELD;
     303             :                 }
     304             :         }
     305             : 
     306       23455 :         if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
     307        1261 :              security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
     308        1259 :                 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
     309             :         }
     310             : 
     311       37017 : done:
     312       22194 :         if (bits_remaining != 0) {
     313        1326 :                 *access_granted = bits_remaining;
     314        1326 :                 return NT_STATUS_ACCESS_DENIED;
     315             :         }
     316             : 
     317       20868 :         return NT_STATUS_OK;
     318             : }
     319             : 
     320             : /*
     321             :   The main entry point for access checking FOR THE FILE SERVER ONLY !
     322             :   If returning ACCESS_DENIED this function returns the denied bits in
     323             :   the uint32_t pointed to by the access_granted pointer.
     324             : */
     325       17108 : NTSTATUS se_file_access_check(const struct security_descriptor *sd,
     326             :                           const struct security_token *token,
     327             :                           bool priv_open_requested,
     328             :                           uint32_t access_desired,
     329             :                           uint32_t *access_granted)
     330             : {
     331             :         uint32_t bits_remaining;
     332             :         NTSTATUS status;
     333             : 
     334       17108 :         if (!priv_open_requested) {
     335             :                 /* Fall back to generic se_access_check(). */
     336        3489 :                 return se_access_check(sd,
     337             :                                 token,
     338             :                                 access_desired,
     339             :                                 access_granted);
     340             :         }
     341             : 
     342             :         /*
     343             :          * We need to handle the maximum allowed flag
     344             :          * outside of se_access_check(), as we need to
     345             :          * add in the access allowed by the privileges
     346             :          * as well.
     347             :          */
     348             : 
     349       13619 :         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
     350       13619 :                 uint32_t orig_access_desired = access_desired;
     351             : 
     352       13619 :                 access_desired |= access_check_max_allowed(sd, token);
     353       13619 :                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
     354             : 
     355       13619 :                 if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
     356        8215 :                         access_desired |= SEC_RIGHTS_PRIV_BACKUP;
     357             :                 }
     358             : 
     359       13619 :                 if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
     360        8215 :                         access_desired |= SEC_RIGHTS_PRIV_RESTORE;
     361             :                 }
     362             : 
     363       13619 :                 DEBUG(10,("se_file_access_check: MAX desired = 0x%x "
     364             :                         "mapped to 0x%x\n",
     365             :                         orig_access_desired,
     366             :                         access_desired));
     367             :         }
     368             : 
     369       13619 :         status = se_access_check(sd,
     370             :                                 token,
     371             :                                 access_desired,
     372             :                                 access_granted);
     373             : 
     374       13619 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     375       12448 :                 return status;
     376             :         }
     377             : 
     378        1171 :         bits_remaining = *access_granted;
     379             : 
     380             :         /* Check if we should override with privileges. */
     381        2342 :         if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
     382        1171 :             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
     383        1171 :                 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
     384             :         }
     385        2342 :         if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
     386        1171 :             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
     387        1171 :                 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
     388             :         }
     389        1171 :         if (bits_remaining != 0) {
     390           0 :                 *access_granted = bits_remaining;
     391           0 :                 return NT_STATUS_ACCESS_DENIED;
     392             :         }
     393             : 
     394        1171 :         return NT_STATUS_OK;
     395             : }
     396             : 
     397     5025340 : static const struct GUID *get_ace_object_type(const struct security_ace *ace)
     398             : {
     399     5025340 :         if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
     400     4753827 :                 return &ace->object.object.type.type;
     401             :         }
     402             : 
     403      271513 :         return NULL;
     404             : }
     405             : 
     406             : /**
     407             :  * Evaluates access rights specified in a object-specific ACE for an AD object.
     408             :  * This logic corresponds to MS-ADTS 5.1.3.3.3 Checking Object-Specific Access.
     409             :  * @param[in] ace - the ACE being processed
     410             :  * @param[in/out] tree - remaining_access gets updated for the tree
     411             :  * @param[out] grant_access - set to true if the ACE grants sufficient access
     412             :  *                            rights to the object/attribute
     413             :  * @returns NT_STATUS_OK, unless access was denied
     414             :  */
     415     5694376 : static NTSTATUS check_object_specific_access(const struct security_ace *ace,
     416             :                                              struct object_tree *tree,
     417             :                                              bool *grant_access)
     418             : {
     419     5694376 :         struct object_tree *node = NULL;
     420     5694376 :         const struct GUID *type = NULL;
     421             : 
     422     5694376 :         *grant_access = false;
     423             : 
     424             :         /* if no tree was supplied, we can't do object-specific access checks */
     425     5694376 :         if (!tree) {
     426      669036 :                 return NT_STATUS_OK;
     427             :         }
     428             : 
     429             :         /* Get the ObjectType GUID this ACE applies to */
     430     5025340 :         type = get_ace_object_type(ace);
     431             : 
     432             :         /*
     433             :          * If the ACE doesn't have a type, then apply it to the whole tree, i.e.
     434             :          * treat 'OA' ACEs as 'A' and 'OD' as 'D'
     435             :          */
     436     5025340 :         if (!type) {
     437      271513 :                 node = tree;
     438             :         } else {
     439             : 
     440             :                 /* skip it if the ACE's ObjectType GUID is not in the tree */
     441     4753827 :                 node = get_object_tree_by_GUID(tree, type);
     442     4753827 :                 if (!node) {
     443     4098192 :                         return NT_STATUS_OK;
     444             :                 }
     445             :         }
     446             : 
     447      927148 :         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
     448             : 
     449             :                 /* apply the access rights to this node, and any children */
     450      926569 :                 object_tree_modify_access(node, ace->access_mask);
     451             : 
     452             :                 /*
     453             :                  * Currently all nodes in the tree request the same access mask,
     454             :                  * so we can use any node to check if processing this ACE now
     455             :                  * means the requested access has been granted
     456             :                  */
     457      926569 :                 if (node->remaining_access == 0) {
     458      914419 :                         *grant_access = true;
     459      914419 :                         return NT_STATUS_OK;
     460             :                 }
     461             : 
     462             :                 /*
     463             :                  * As per 5.1.3.3.4 Checking Control Access Right-Based Access,
     464             :                  * if the CONTROL_ACCESS right is present, then we can grant
     465             :                  * access and stop any further access checks
     466             :                  */
     467       12150 :                 if (ace->access_mask & SEC_ADS_CONTROL_ACCESS) {
     468         894 :                         *grant_access = true;
     469         894 :                         return NT_STATUS_OK;
     470             :                 }
     471             :         } else {
     472             : 
     473             :                 /* this ACE denies access to the requested object/attribute */
     474         579 :                 if (node->remaining_access & ace->access_mask){
     475         552 :                         return NT_STATUS_ACCESS_DENIED;
     476             :                 }
     477             :         }
     478       11283 :         return NT_STATUS_OK;
     479             : }
     480             : 
     481             : /**
     482             :  * @brief Perform directoryservice (DS) related access checks for a given user
     483             :  *
     484             :  * Perform DS access checks for the user represented by its security_token, on
     485             :  * the provided security descriptor. If an tree associating GUID and access
     486             :  * required is provided then object access (OA) are checked as well. *
     487             :  * @param[in]   sd             The security descritor against which the required
     488             :  *                             access are requested
     489             :  *
     490             :  * @param[in]   token          The security_token associated with the user to
     491             :  *                             test
     492             :  *
     493             :  * @param[in]   access_desired A bitfield of rights that must be granted for the
     494             :  *                             given user in the specified SD.
     495             :  *
     496             :  * If one
     497             :  * of the entry in the tree grants all the requested rights for the given GUID
     498             :  * FIXME
     499             :  * tree can be null if not null it's the
     500             :  * Lots of code duplication, it will be united in just one
     501             :  * function eventually */
     502             : 
     503     7384148 : NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
     504             :                              const struct security_token *token,
     505             :                              uint32_t access_desired,
     506             :                              uint32_t *access_granted,
     507             :                              struct object_tree *tree,
     508             :                              const struct dom_sid *replace_sid)
     509             : {
     510             :         uint32_t i;
     511             :         uint32_t bits_remaining;
     512             :         struct dom_sid self_sid;
     513             : 
     514     7384148 :         dom_sid_parse(SID_NT_SELF, &self_sid);
     515             : 
     516     7384148 :         *access_granted = access_desired;
     517     7384148 :         bits_remaining = access_desired;
     518             : 
     519             :         /* handle the maximum allowed flag */
     520     7384148 :         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
     521           0 :                 access_desired |= access_check_max_allowed(sd, token);
     522           0 :                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
     523           0 :                 *access_granted = access_desired;
     524           0 :                 bits_remaining = access_desired;
     525             :         }
     526             : 
     527     7384148 :         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
     528       31733 :                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
     529       31307 :                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
     530             :                 } else {
     531         426 :                         return NT_STATUS_PRIVILEGE_NOT_HELD;
     532             :                 }
     533             :         }
     534             : 
     535             :         /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
     536     7429151 :         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
     537       45429 :             security_token_has_sid(token, sd->owner_sid)) {
     538       44529 :                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
     539             :         }
     540             : 
     541             :         /* SEC_PRIV_TAKE_OWNERSHIP grants SEC_STD_WRITE_OWNER */
     542     7395142 :         if ((bits_remaining & (SEC_STD_WRITE_OWNER)) &&
     543       11420 :             security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
     544       11390 :                 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
     545             :         }
     546             : 
     547             :         /* a NULL dacl allows access */
     548     7383722 :         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
     549           0 :                 *access_granted = access_desired;
     550           0 :                 return NT_STATUS_OK;
     551             :         }
     552             : 
     553     7383722 :         if (sd->dacl == NULL) {
     554           0 :                 goto done;
     555             :         }
     556             : 
     557             :         /* check each ace in turn. */
     558    73228915 :         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
     559             :                 const struct dom_sid *trustee;
     560    34241552 :                 const struct security_ace *ace = &sd->dacl->aces[i];
     561             :                 NTSTATUS status;
     562    34241552 :                 bool grant_access = false;
     563             : 
     564    34241552 :                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
     565    25125774 :                         continue;
     566             :                 }
     567             : 
     568    29683298 :                 if (dom_sid_equal(&ace->trustee, &self_sid) && replace_sid) {
     569     6321584 :                         trustee = replace_sid;
     570             :                 } else {
     571    23361714 :                         trustee = &ace->trustee;
     572             :                 }
     573             : 
     574    29683298 :                 if (!security_token_has_sid(token, trustee)) {
     575    16354088 :                         continue;
     576             :                 }
     577             : 
     578    13329210 :                 switch (ace->type) {
     579     7603001 :                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
     580     7603001 :                         if (tree) {
     581     6826171 :                                 object_tree_modify_access(tree, ace->access_mask);
     582             :                         }
     583             : 
     584     7603001 :                         bits_remaining &= ~ace->access_mask;
     585     7603001 :                         break;
     586       31833 :                 case SEC_ACE_TYPE_ACCESS_DENIED:
     587       31833 :                         if (bits_remaining & ace->access_mask) {
     588      937800 :                                 return NT_STATUS_ACCESS_DENIED;
     589             :                         }
     590       16375 :                         break;
     591     5694376 :                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
     592             :                 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
     593     5694376 :                         status = check_object_specific_access(ace, tree,
     594             :                                                               &grant_access);
     595             : 
     596     5694376 :                         if (!NT_STATUS_IS_OK(status)) {
     597         552 :                                 return status;
     598             :                         }
     599             : 
     600     5693824 :                         if (grant_access) {
     601      915313 :                                 return NT_STATUS_OK;
     602             :                         }
     603     4778511 :                         break;
     604           0 :                 default:        /* Other ACE types not handled/supported */
     605           0 :                         break;
     606             :                 }
     607             :         }
     608             : 
     609     6452399 : done:
     610     6452399 :         if (bits_remaining != 0) {
     611       64129 :                 return NT_STATUS_ACCESS_DENIED;
     612             :         }
     613             : 
     614     6388270 :         return NT_STATUS_OK;
     615             : }

Generated by: LCOV version 1.13