root/source4/libcli/security/access_check.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. access_check_max_allowed
  2. sec_access_check

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    security access checking routines
   5 
   6    Copyright (C) Andrew Tridgell 2004
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12 
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17 
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "libcli/security/security.h"
  24 
  25 
  26 /*
  27   perform a SEC_FLAG_MAXIMUM_ALLOWED access check
  28 */
  29 static uint32_t access_check_max_allowed(const struct security_descriptor *sd, 
     /* [<][>][^][v][top][bottom][index][help] */
  30                                          const struct security_token *token)
  31 {
  32         uint32_t denied = 0, granted = 0;
  33         unsigned i;
  34         
  35         if (security_token_has_sid(token, sd->owner_sid)) {
  36                 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE;
  37         } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
  38                 granted |= SEC_STD_DELETE;
  39         }
  40 
  41         if (sd->dacl == NULL) {
  42                 return granted & ~denied;
  43         }
  44         
  45         for (i = 0;i<sd->dacl->num_aces; i++) {
  46                 struct security_ace *ace = &sd->dacl->aces[i];
  47 
  48                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
  49                         continue;
  50                 }
  51 
  52                 if (!security_token_has_sid(token, &ace->trustee)) {
  53                         continue;
  54                 }
  55 
  56                 switch (ace->type) {
  57                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
  58                         granted |= ace->access_mask;
  59                         break;
  60                 case SEC_ACE_TYPE_ACCESS_DENIED:
  61                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
  62                         denied |= ace->access_mask;
  63                         break;
  64                 default:        /* Other ACE types not handled/supported */
  65                         break;
  66                 }
  67         }
  68 
  69         return granted & ~denied;
  70 }
  71 
  72 /*
  73   the main entry point for access checking. 
  74 */
  75 NTSTATUS sec_access_check(const struct security_descriptor *sd, 
     /* [<][>][^][v][top][bottom][index][help] */
  76                           const struct security_token *token,
  77                           uint32_t access_desired,
  78                           uint32_t *access_granted)
  79 {
  80         int i;
  81         uint32_t bits_remaining;
  82 
  83         *access_granted = access_desired;
  84         bits_remaining = access_desired;
  85 
  86         /* handle the maximum allowed flag */
  87         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
  88                 access_desired |= access_check_max_allowed(sd, token);
  89                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
  90                 *access_granted = access_desired;
  91                 bits_remaining = access_desired & ~SEC_STD_DELETE;
  92         }
  93 
  94         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
  95                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
  96                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
  97                 } else {
  98                         return NT_STATUS_PRIVILEGE_NOT_HELD;
  99                 }
 100         }
 101 
 102         /* a NULL dacl allows access */
 103         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
 104                 *access_granted = access_desired;
 105                 return NT_STATUS_OK;
 106         }
 107 
 108         /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
 109         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
 110             security_token_has_sid(token, sd->owner_sid)) {
 111                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
 112         }
 113         if ((bits_remaining & SEC_STD_DELETE) &&
 114             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
 115                 bits_remaining &= ~SEC_STD_DELETE;
 116         }
 117 
 118         if (sd->dacl == NULL) {
 119                 goto done;
 120         }
 121 
 122         /* check each ace in turn. */
 123         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
 124                 struct security_ace *ace = &sd->dacl->aces[i];
 125 
 126                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
 127                         continue;
 128                 }
 129 
 130                 if (!security_token_has_sid(token, &ace->trustee)) {
 131                         continue;
 132                 }
 133 
 134                 switch (ace->type) {
 135                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
 136                         bits_remaining &= ~ace->access_mask;
 137                         break;
 138                 case SEC_ACE_TYPE_ACCESS_DENIED:
 139                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
 140                         if (bits_remaining & ace->access_mask) {
 141                                 return NT_STATUS_ACCESS_DENIED;
 142                         }
 143                         break;
 144                 default:        /* Other ACE types not handled/supported */
 145                         break;
 146                 }
 147         }
 148 
 149 done:
 150         if (bits_remaining != 0) {
 151                 return NT_STATUS_ACCESS_DENIED;
 152         }
 153 
 154         return NT_STATUS_OK;
 155 }

/* [<][>][^][v][top][bottom][index][help] */