2 Unix SMB/CIFS implementation.
4 security access checking routines
6 Copyright (C) Andrew Tridgell 2004
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "librpc/gen_ndr/ndr_security.h"
28 check if a sid is in the supplied token
30 static BOOL sid_active_in_token(const struct dom_sid *sid,
31 const struct security_token *token)
34 for (i=0;i<token->num_sids;i++) {
35 if (dom_sid_equal(sid, token->sids[i])) {
44 perform a SEC_FLAG_MAXIMUM_ALLOWED access check
46 static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
47 const struct security_token *token)
49 uint32_t denied = 0, granted = 0;
52 if (sid_active_in_token(sd->owner_sid, token)) {
53 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
55 if (sec_privilege_check(token, SEC_PRIV_RESTORE)) {
56 granted |= SEC_STD_DELETE;
59 for (i = 0;i<sd->dacl->num_aces; i++) {
60 struct security_ace *ace = &sd->dacl->aces[i];
62 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
66 if (!sid_active_in_token(&ace->trustee, token)) {
71 case SEC_ACE_TYPE_ACCESS_ALLOWED:
72 granted |= ace->access_mask;
74 case SEC_ACE_TYPE_ACCESS_DENIED:
75 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
76 denied |= ace->access_mask;
81 return granted & ~denied;
85 the main entry point for access checking.
87 NTSTATUS sec_access_check(const struct security_descriptor *sd,
88 const struct security_token *token,
89 uint32_t access_desired,
90 uint32_t *access_granted)
93 uint32_t bits_remaining;
95 *access_granted = access_desired;
96 bits_remaining = access_desired;
98 /* handle the maximum allowed flag */
99 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
100 access_desired |= access_check_max_allowed(sd, token);
101 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
102 *access_granted = access_desired;
103 bits_remaining = access_desired & ~SEC_STD_DELETE;
106 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
107 if (sec_privilege_check(token, SEC_PRIV_SECURITY)) {
108 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
110 return NT_STATUS_ACCESS_DENIED;
114 /* dacl not present allows access */
115 if (!(sd->type & SEC_DESC_DACL_PRESENT)) {
116 *access_granted = access_desired;
120 /* empty dacl denies access */
121 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
122 return NT_STATUS_ACCESS_DENIED;
125 /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */
126 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
127 sid_active_in_token(sd->owner_sid, token)) {
128 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
130 if ((bits_remaining & SEC_STD_DELETE) &&
131 sec_privilege_check(token, SEC_PRIV_RESTORE)) {
132 bits_remaining &= ~SEC_STD_DELETE;
135 /* check each ace in turn. */
136 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
137 struct security_ace *ace = &sd->dacl->aces[i];
139 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
143 if (!sid_active_in_token(&ace->trustee, token)) {
148 case SEC_ACE_TYPE_ACCESS_ALLOWED:
149 bits_remaining &= ~ace->access_mask;
151 case SEC_ACE_TYPE_ACCESS_DENIED:
152 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
153 if (bits_remaining & ace->access_mask) {
154 return NT_STATUS_ACCESS_DENIED;
160 if (bits_remaining != 0) {
161 return NT_STATUS_ACCESS_DENIED;