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 (!sid_active_in_token(&ace->trustee, token)) {
67 case SEC_ACE_TYPE_ACCESS_ALLOWED:
68 granted |= ace->access_mask;
70 case SEC_ACE_TYPE_ACCESS_DENIED:
71 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
72 denied |= ace->access_mask;
77 return granted & ~denied;
81 the main entry point for access checking.
83 NTSTATUS sec_access_check(const struct security_descriptor *sd,
84 const struct security_token *token,
85 uint32_t access_desired,
86 uint32_t *access_granted)
89 uint32_t bits_remaining;
91 *access_granted = access_desired;
92 bits_remaining = access_desired;
94 /* handle the maximum allowed flag */
95 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
96 access_desired |= access_check_max_allowed(sd, token);
97 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
98 *access_granted = access_desired;
99 bits_remaining = access_desired & ~SEC_STD_DELETE;
102 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
103 if (sec_privilege_check(token, SEC_PRIV_SECURITY)) {
104 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
106 return NT_STATUS_ACCESS_DENIED;
110 /* dacl not present allows access */
111 if (!(sd->type & SEC_DESC_DACL_PRESENT)) {
112 *access_granted = access_desired;
116 /* empty dacl denies access */
117 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
118 return NT_STATUS_ACCESS_DENIED;
121 /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */
122 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
123 sid_active_in_token(sd->owner_sid, token)) {
124 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
126 if ((bits_remaining & SEC_STD_DELETE) &&
127 sec_privilege_check(token, SEC_PRIV_RESTORE)) {
128 bits_remaining &= ~SEC_STD_DELETE;
131 /* check each ace in turn. */
132 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
133 struct security_ace *ace = &sd->dacl->aces[i];
135 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
139 if (!sid_active_in_token(&ace->trustee, token)) {
144 case SEC_ACE_TYPE_ACCESS_ALLOWED:
145 bits_remaining &= ~ace->access_mask;
147 case SEC_ACE_TYPE_ACCESS_DENIED:
148 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
149 if (bits_remaining & ace->access_mask) {
150 return NT_STATUS_ACCESS_DENIED;
156 if (bits_remaining != 0) {
157 return NT_STATUS_ACCESS_DENIED;