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 | SEC_STD_DELETE;
56 for (i = 0;i<sd->dacl->num_aces; i++) {
57 struct security_ace *ace = &sd->dacl->aces[i];
59 if (!sid_active_in_token(&ace->trustee, token)) {
64 case SEC_ACE_TYPE_ACCESS_ALLOWED:
65 granted |= ace->access_mask;
67 case SEC_ACE_TYPE_ACCESS_DENIED:
68 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
69 denied |= ace->access_mask;
74 return granted & ~denied;
78 the main entry point for access checking.
80 NTSTATUS sec_access_check(const struct security_descriptor *sd,
81 const struct security_token *token,
82 uint32_t access_desired,
83 uint32_t *access_granted)
86 uint32_t bits_remaining;
88 *access_granted = access_desired;
89 bits_remaining = access_desired;
91 /* handle the maximum allowed flag */
92 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
93 access_desired |= access_check_max_allowed(sd, token);
94 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
95 *access_granted = access_desired;
96 bits_remaining = access_desired & ~SEC_STD_DELETE;
100 /* this is where we should check for the "system security" privilege, once we
101 move to the full security_token and not just the nt_user_token */
102 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
103 if (privilege_in_token(SE_PRIVILEGE_SYSTEM_SECURITY, token)) {
104 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
106 return NT_STATUS_ACCESS_DENIED;
111 /* dacl not present allows access */
112 if (!(sd->type & SEC_DESC_DACL_PRESENT)) {
113 *access_granted = access_desired;
117 /* empty dacl denies access */
118 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
119 return NT_STATUS_ACCESS_DENIED;
122 /* the owner always gets SEC_STD_WRITE_DAC & SEC_STD_READ_CONTROL */
123 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
124 sid_active_in_token(sd->owner_sid, token)) {
125 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
128 /* check each ace in turn. */
129 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
130 struct security_ace *ace = &sd->dacl->aces[i];
132 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
136 if (!sid_active_in_token(&ace->trustee, token)) {
141 case SEC_ACE_TYPE_ACCESS_ALLOWED:
142 bits_remaining &= ~ace->access_mask;
144 case SEC_ACE_TYPE_ACCESS_DENIED:
145 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
146 if (bits_remaining & ace->access_mask) {
147 return NT_STATUS_ACCESS_DENIED;
153 if (bits_remaining != 0) {
154 return NT_STATUS_ACCESS_DENIED;