af6a3d6fb3e7bc965032ce8fef3580cbc5cf173b
[ira/wip.git] / source4 / libcli / security / access_check.c
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, 
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, 
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 }