s3: Fix some blank line endings
[Samba/gebeck_regimport.git] / libcli / security / access_check.c
bloba9b618f577b2a1ab1cd1f6a8a93cfde78f2ecdf1
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Gerald Carter 2005
6 Copyright (C) Volker Lendecke 2007
7 Copyright (C) Jeremy Allison 2008
8 Copyright (C) Andrew Bartlett 2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "libcli/security/security.h"
27 /* Map generic access rights to object specific rights. This technique is
28 used to give meaning to assigning read, write, execute and all access to
29 objects. Each type of object has its own mapping of generic to object
30 specific access rights. */
32 void se_map_generic(uint32_t *access_mask, const struct generic_mapping *mapping)
34 uint32_t old_mask = *access_mask;
36 if (*access_mask & GENERIC_READ_ACCESS) {
37 *access_mask &= ~GENERIC_READ_ACCESS;
38 *access_mask |= mapping->generic_read;
41 if (*access_mask & GENERIC_WRITE_ACCESS) {
42 *access_mask &= ~GENERIC_WRITE_ACCESS;
43 *access_mask |= mapping->generic_write;
46 if (*access_mask & GENERIC_EXECUTE_ACCESS) {
47 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
48 *access_mask |= mapping->generic_execute;
51 if (*access_mask & GENERIC_ALL_ACCESS) {
52 *access_mask &= ~GENERIC_ALL_ACCESS;
53 *access_mask |= mapping->generic_all;
56 if (old_mask != *access_mask) {
57 DEBUG(10, ("se_map_generic(): mapped mask 0x%08x to 0x%08x\n",
58 old_mask, *access_mask));
62 /* Map generic access rights to object specific rights for all the ACE's
63 * in a security_acl.
66 void security_acl_map_generic(struct security_acl *sa,
67 const struct generic_mapping *mapping)
69 unsigned int i;
71 if (!sa) {
72 return;
75 for (i = 0; i < sa->num_aces; i++) {
76 se_map_generic(&sa->aces[i].access_mask, mapping);
80 /* Map standard access rights to object specific rights. This technique is
81 used to give meaning to assigning read, write, execute and all access to
82 objects. Each type of object has its own mapping of standard to object
83 specific access rights. */
85 void se_map_standard(uint32_t *access_mask, const struct standard_mapping *mapping)
87 uint32_t old_mask = *access_mask;
89 if (*access_mask & SEC_STD_READ_CONTROL) {
90 *access_mask &= ~SEC_STD_READ_CONTROL;
91 *access_mask |= mapping->std_read;
94 if (*access_mask & (SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE)) {
95 *access_mask &= ~(SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE);
96 *access_mask |= mapping->std_all;
99 if (old_mask != *access_mask) {
100 DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
101 old_mask, *access_mask));
106 perform a SEC_FLAG_MAXIMUM_ALLOWED access check
108 static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
109 const struct security_token *token)
111 uint32_t denied = 0, granted = 0;
112 unsigned i;
114 if (security_token_has_sid(token, sd->owner_sid)) {
115 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
118 if (sd->dacl == NULL) {
119 return granted & ~denied;
122 for (i = 0;i<sd->dacl->num_aces; i++) {
123 struct security_ace *ace = &sd->dacl->aces[i];
125 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
126 continue;
129 if (!security_token_has_sid(token, &ace->trustee)) {
130 continue;
133 switch (ace->type) {
134 case SEC_ACE_TYPE_ACCESS_ALLOWED:
135 granted |= ace->access_mask;
136 break;
137 case SEC_ACE_TYPE_ACCESS_DENIED:
138 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
139 denied |= ace->access_mask;
140 break;
141 default: /* Other ACE types not handled/supported */
142 break;
146 return granted & ~denied;
150 The main entry point for access checking. If returning ACCESS_DENIED
151 this function returns the denied bits in the uint32_t pointed
152 to by the access_granted pointer.
154 NTSTATUS se_access_check(const struct security_descriptor *sd,
155 const struct security_token *token,
156 uint32_t access_desired,
157 uint32_t *access_granted)
159 uint32_t i;
160 uint32_t bits_remaining;
161 uint32_t explicitly_denied_bits = 0;
163 *access_granted = access_desired;
164 bits_remaining = access_desired;
166 /* handle the maximum allowed flag */
167 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
168 uint32_t orig_access_desired = access_desired;
170 access_desired |= access_check_max_allowed(sd, token);
171 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
172 *access_granted = access_desired;
173 bits_remaining = access_desired;
175 DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n",
176 orig_access_desired,
177 *access_granted,
178 bits_remaining));
181 /* s3 had this with #if 0 previously. To be sure the merge
182 doesn't change any behaviour, we have the above #if check
183 on _SAMBA_BUILD_. */
184 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
185 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
186 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
187 } else {
188 return NT_STATUS_PRIVILEGE_NOT_HELD;
192 /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
193 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
194 security_token_has_sid(token, sd->owner_sid)) {
195 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
198 /* TODO: remove this, as it is file server specific */
199 if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
200 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
201 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
203 if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
204 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
205 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
208 if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
209 security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
210 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
213 /* a NULL dacl allows access */
214 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
215 *access_granted = access_desired;
216 return NT_STATUS_OK;
219 if (sd->dacl == NULL) {
220 goto done;
223 /* check each ace in turn. */
224 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
225 struct security_ace *ace = &sd->dacl->aces[i];
227 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
228 continue;
231 if (!security_token_has_sid(token, &ace->trustee)) {
232 continue;
235 switch (ace->type) {
236 case SEC_ACE_TYPE_ACCESS_ALLOWED:
237 bits_remaining &= ~ace->access_mask;
238 break;
239 case SEC_ACE_TYPE_ACCESS_DENIED:
240 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
241 explicitly_denied_bits |= (bits_remaining & ace->access_mask);
242 break;
243 default: /* Other ACE types not handled/supported */
244 break;
248 bits_remaining |= explicitly_denied_bits;
250 done:
251 if (bits_remaining != 0) {
252 *access_granted = bits_remaining;
253 return NT_STATUS_ACCESS_DENIED;
256 return NT_STATUS_OK;
260 static const struct GUID *get_ace_object_type(struct security_ace *ace)
262 struct GUID *type;
264 if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
265 type = &ace->object.object.type.type;
266 else if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)
267 type = &ace->object.object.inherited_type.inherited_type; /* This doesn't look right. Is something wrong with the IDL? */
268 else
269 type = NULL;
271 return type;
275 /* modified access check for the purposes of DS security
276 * Lots of code duplication, it will ve united in just one
277 * function eventually */
279 NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
280 const struct security_token *token,
281 uint32_t access_desired,
282 uint32_t *access_granted,
283 struct object_tree *tree,
284 struct dom_sid *replace_sid)
286 uint32_t i;
287 uint32_t bits_remaining;
288 struct object_tree *node;
289 const struct GUID *type;
290 struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF);
292 *access_granted = access_desired;
293 bits_remaining = access_desired;
295 /* handle the maximum allowed flag */
296 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
297 access_desired |= access_check_max_allowed(sd, token);
298 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
299 *access_granted = access_desired;
300 bits_remaining = access_desired;
303 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
304 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
305 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
306 } else {
307 talloc_free(ps_sid);
308 return NT_STATUS_PRIVILEGE_NOT_HELD;
312 /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
313 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
314 security_token_has_sid(token, sd->owner_sid)) {
315 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
318 /* TODO: remove this, as it is file server specific */
319 if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
320 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
321 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
323 if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
324 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
325 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
328 /* a NULL dacl allows access */
329 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
330 *access_granted = access_desired;
331 talloc_free(ps_sid);
332 return NT_STATUS_OK;
335 if (sd->dacl == NULL) {
336 goto done;
339 /* check each ace in turn. */
340 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
341 struct dom_sid *trustee;
342 struct security_ace *ace = &sd->dacl->aces[i];
344 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
345 continue;
347 if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) {
348 trustee = replace_sid;
350 else
352 trustee = &ace->trustee;
354 if (!security_token_has_sid(token, trustee)) {
355 continue;
358 switch (ace->type) {
359 case SEC_ACE_TYPE_ACCESS_ALLOWED:
360 if (tree)
361 object_tree_modify_access(tree, ace->access_mask);
363 bits_remaining &= ~ace->access_mask;
364 break;
365 case SEC_ACE_TYPE_ACCESS_DENIED:
366 if (bits_remaining & ace->access_mask) {
367 talloc_free(ps_sid);
368 return NT_STATUS_ACCESS_DENIED;
370 break;
371 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
372 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
373 /* check only in case we have provided a tree,
374 * the ACE has an object type and that type
375 * is in the tree */
376 type = get_ace_object_type(ace);
378 if (!tree)
379 continue;
381 if (!type)
382 node = tree;
383 else
384 if (!(node = get_object_tree_by_GUID(tree, type)))
385 continue;
387 if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
388 object_tree_modify_access(node, ace->access_mask);
389 if (node->remaining_access == 0) {
390 talloc_free(ps_sid);
391 return NT_STATUS_OK;
393 } else {
394 if (node->remaining_access & ace->access_mask){
395 talloc_free(ps_sid);
396 return NT_STATUS_ACCESS_DENIED;
399 break;
400 default: /* Other ACE types not handled/supported */
401 break;
405 done:
406 talloc_free(ps_sid);
407 if (bits_remaining != 0) {
408 return NT_STATUS_ACCESS_DENIED;
411 return NT_STATUS_OK;