source: vendor/current/libcli/security/access_check.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 14.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
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
9
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.
14
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.
19
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/>.
22*/
23
24#include "includes.h"
25#include "libcli/security/security.h"
26
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. */
31
32void se_map_generic(uint32_t *access_mask, const struct generic_mapping *mapping)
33{
34 uint32_t old_mask = *access_mask;
35
36 if (*access_mask & GENERIC_READ_ACCESS) {
37 *access_mask &= ~GENERIC_READ_ACCESS;
38 *access_mask |= mapping->generic_read;
39 }
40
41 if (*access_mask & GENERIC_WRITE_ACCESS) {
42 *access_mask &= ~GENERIC_WRITE_ACCESS;
43 *access_mask |= mapping->generic_write;
44 }
45
46 if (*access_mask & GENERIC_EXECUTE_ACCESS) {
47 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
48 *access_mask |= mapping->generic_execute;
49 }
50
51 if (*access_mask & GENERIC_ALL_ACCESS) {
52 *access_mask &= ~GENERIC_ALL_ACCESS;
53 *access_mask |= mapping->generic_all;
54 }
55
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));
59 }
60}
61
62/* Map generic access rights to object specific rights for all the ACE's
63 * in a security_acl.
64 */
65
66void security_acl_map_generic(struct security_acl *sa,
67 const struct generic_mapping *mapping)
68{
69 unsigned int i;
70
71 if (!sa) {
72 return;
73 }
74
75 for (i = 0; i < sa->num_aces; i++) {
76 se_map_generic(&sa->aces[i].access_mask, mapping);
77 }
78}
79
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. */
84
85void se_map_standard(uint32_t *access_mask, const struct standard_mapping *mapping)
86{
87 uint32_t old_mask = *access_mask;
88
89 if (*access_mask & SEC_STD_READ_CONTROL) {
90 *access_mask &= ~SEC_STD_READ_CONTROL;
91 *access_mask |= mapping->std_read;
92 }
93
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;
97 }
98
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));
102 }
103}
104
105/*
106 perform a SEC_FLAG_MAXIMUM_ALLOWED access check
107*/
108static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
109 const struct security_token *token)
110{
111 uint32_t denied = 0, granted = 0;
112 unsigned i;
113
114 if (security_token_has_sid(token, sd->owner_sid)) {
115 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
116 }
117
118 if (sd->dacl == NULL) {
119 return granted & ~denied;
120 }
121
122 for (i = 0;i<sd->dacl->num_aces; i++) {
123 struct security_ace *ace = &sd->dacl->aces[i];
124
125 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
126 continue;
127 }
128
129 if (!security_token_has_sid(token, &ace->trustee)) {
130 continue;
131 }
132
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;
143 }
144 }
145
146 return granted & ~denied;
147}
148
149/*
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.
153*/
154NTSTATUS se_access_check(const struct security_descriptor *sd,
155 const struct security_token *token,
156 uint32_t access_desired,
157 uint32_t *access_granted)
158{
159 uint32_t i;
160 uint32_t bits_remaining;
161 uint32_t explicitly_denied_bits = 0;
162 /*
163 * Up until Windows Server 2008, owner always had these rights. Now
164 * we have to use Owner Rights perms if they are on the file.
165 *
166 * In addition we have to accumulate these bits and apply them
167 * correctly. See bug #8795
168 */
169 uint32_t owner_rights_allowed = 0;
170 uint32_t owner_rights_denied = 0;
171 bool owner_rights_default = true;
172
173 *access_granted = access_desired;
174 bits_remaining = access_desired;
175
176 /* handle the maximum allowed flag */
177 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
178 uint32_t orig_access_desired = access_desired;
179
180 access_desired |= access_check_max_allowed(sd, token);
181 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
182 *access_granted = access_desired;
183 bits_remaining = access_desired;
184
185 DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n",
186 orig_access_desired,
187 *access_granted,
188 bits_remaining));
189 }
190
191 /* a NULL dacl allows access */
192 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
193 *access_granted = access_desired;
194 return NT_STATUS_OK;
195 }
196
197 if (sd->dacl == NULL) {
198 goto done;
199 }
200
201 /* check each ace in turn. */
202 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
203 struct security_ace *ace = &sd->dacl->aces[i];
204
205 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
206 continue;
207 }
208
209 /*
210 * We need the Owner Rights permissions to ensure we
211 * give or deny the correct permissions to the owner. Replace
212 * owner_rights with the perms here if it is present.
213 *
214 * We don't care if we are not the owner because that is taken
215 * care of below when we check if our token has the owner SID.
216 *
217 */
218 if (dom_sid_equal(&ace->trustee, &global_sid_Owner_Rights)) {
219 if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
220 owner_rights_allowed |= ace->access_mask;
221 owner_rights_default = false;
222 } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
223 owner_rights_denied |= ace->access_mask;
224 owner_rights_default = false;
225 }
226 continue;
227 }
228
229 if (!security_token_has_sid(token, &ace->trustee)) {
230 continue;
231 }
232
233 switch (ace->type) {
234 case SEC_ACE_TYPE_ACCESS_ALLOWED:
235 bits_remaining &= ~ace->access_mask;
236 break;
237 case SEC_ACE_TYPE_ACCESS_DENIED:
238 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
239 explicitly_denied_bits |= (bits_remaining & ace->access_mask);
240 break;
241 default: /* Other ACE types not handled/supported */
242 break;
243 }
244 }
245
246 /* Explicitly denied bits always override */
247 bits_remaining |= explicitly_denied_bits;
248
249 /* The owner always gets owner rights as defined above. */
250 if (security_token_has_sid(token, sd->owner_sid)) {
251 if (owner_rights_default) {
252 /*
253 * Just remove them, no need to check if they are
254 * there.
255 */
256 bits_remaining &= ~(SEC_STD_WRITE_DAC |
257 SEC_STD_READ_CONTROL);
258 } else {
259 bits_remaining &= ~owner_rights_allowed;
260 bits_remaining |= owner_rights_denied;
261 }
262 }
263
264 /*
265 * We check privileges here because they override even DENY entries.
266 */
267
268 /* Does the user have the privilege to gain SEC_PRIV_SECURITY? */
269 if (bits_remaining & SEC_FLAG_SYSTEM_SECURITY) {
270 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
271 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
272 } else {
273 return NT_STATUS_PRIVILEGE_NOT_HELD;
274 }
275 }
276
277 if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
278 security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
279 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
280 }
281
282done:
283 if (bits_remaining != 0) {
284 *access_granted = bits_remaining;
285 return NT_STATUS_ACCESS_DENIED;
286 }
287
288 return NT_STATUS_OK;
289}
290
291/*
292 The main entry point for access checking FOR THE FILE SERVER ONLY !
293 If returning ACCESS_DENIED this function returns the denied bits in
294 the uint32_t pointed to by the access_granted pointer.
295*/
296NTSTATUS se_file_access_check(const struct security_descriptor *sd,
297 const struct security_token *token,
298 bool priv_open_requested,
299 uint32_t access_desired,
300 uint32_t *access_granted)
301{
302 uint32_t bits_remaining;
303 NTSTATUS status;
304
305 if (!priv_open_requested) {
306 /* Fall back to generic se_access_check(). */
307 return se_access_check(sd,
308 token,
309 access_desired,
310 access_granted);
311 }
312
313 /*
314 * We need to handle the maximum allowed flag
315 * outside of se_access_check(), as we need to
316 * add in the access allowed by the privileges
317 * as well.
318 */
319
320 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
321 uint32_t orig_access_desired = access_desired;
322
323 access_desired |= access_check_max_allowed(sd, token);
324 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
325
326 if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
327 access_desired |= SEC_RIGHTS_PRIV_BACKUP;
328 }
329
330 if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
331 access_desired |= SEC_RIGHTS_PRIV_RESTORE;
332 }
333
334 DEBUG(10,("se_file_access_check: MAX desired = 0x%x "
335 "mapped to 0x%x\n",
336 orig_access_desired,
337 access_desired));
338 }
339
340 status = se_access_check(sd,
341 token,
342 access_desired,
343 access_granted);
344
345 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
346 return status;
347 }
348
349 bits_remaining = *access_granted;
350
351 /* Check if we should override with privileges. */
352 if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
353 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
354 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
355 }
356 if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
357 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
358 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
359 }
360 if (bits_remaining != 0) {
361 *access_granted = bits_remaining;
362 return NT_STATUS_ACCESS_DENIED;
363 }
364
365 return NT_STATUS_OK;
366}
367
368static const struct GUID *get_ace_object_type(struct security_ace *ace)
369{
370 if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
371 return &ace->object.object.type.type;
372 }
373
374 return NULL;
375}
376
377/**
378 * @brief Perform directoryservice (DS) related access checks for a given user
379 *
380 * Perform DS access checks for the user represented by its security_token, on
381 * the provided security descriptor. If an tree associating GUID and access
382 * required is provided then object access (OA) are checked as well. *
383 * @param[in] sd The security descritor against which the required
384 * access are requested
385 *
386 * @param[in] token The security_token associated with the user to
387 * test
388 *
389 * @param[in] access_desired A bitfield of rights that must be granted for the
390 * given user in the specified SD.
391 *
392 * If one
393 * of the entry in the tree grants all the requested rights for the given GUID
394 * FIXME
395 * tree can be null if not null it's the
396 * Lots of code duplication, it will ve united in just one
397 * function eventually */
398
399NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
400 const struct security_token *token,
401 uint32_t access_desired,
402 uint32_t *access_granted,
403 struct object_tree *tree,
404 struct dom_sid *replace_sid)
405{
406 uint32_t i;
407 uint32_t bits_remaining;
408 struct object_tree *node;
409 const struct GUID *type;
410 struct dom_sid self_sid;
411
412 dom_sid_parse(SID_NT_SELF, &self_sid);
413
414 *access_granted = access_desired;
415 bits_remaining = access_desired;
416
417 /* handle the maximum allowed flag */
418 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
419 access_desired |= access_check_max_allowed(sd, token);
420 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
421 *access_granted = access_desired;
422 bits_remaining = access_desired;
423 }
424
425 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
426 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
427 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
428 } else {
429 return NT_STATUS_PRIVILEGE_NOT_HELD;
430 }
431 }
432
433 /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
434 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
435 security_token_has_sid(token, sd->owner_sid)) {
436 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
437 }
438
439 /* SEC_PRIV_TAKE_OWNERSHIP grants SEC_STD_WRITE_OWNER */
440 if ((bits_remaining & (SEC_STD_WRITE_OWNER)) &&
441 security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
442 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
443 }
444
445 /* a NULL dacl allows access */
446 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
447 *access_granted = access_desired;
448 return NT_STATUS_OK;
449 }
450
451 if (sd->dacl == NULL) {
452 goto done;
453 }
454
455 /* check each ace in turn. */
456 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
457 struct dom_sid *trustee;
458 struct security_ace *ace = &sd->dacl->aces[i];
459
460 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
461 continue;
462 }
463
464 if (dom_sid_equal(&ace->trustee, &self_sid) && replace_sid) {
465 trustee = replace_sid;
466 } else {
467 trustee = &ace->trustee;
468 }
469
470 if (!security_token_has_sid(token, trustee)) {
471 continue;
472 }
473
474 switch (ace->type) {
475 case SEC_ACE_TYPE_ACCESS_ALLOWED:
476 if (tree) {
477 object_tree_modify_access(tree, ace->access_mask);
478 }
479
480 bits_remaining &= ~ace->access_mask;
481 break;
482 case SEC_ACE_TYPE_ACCESS_DENIED:
483 if (bits_remaining & ace->access_mask) {
484 return NT_STATUS_ACCESS_DENIED;
485 }
486 break;
487 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
488 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
489 /*
490 * check only in case we have provided a tree,
491 * the ACE has an object type and that type
492 * is in the tree
493 */
494 type = get_ace_object_type(ace);
495
496 if (!tree) {
497 continue;
498 }
499
500 if (!type) {
501 node = tree;
502 } else {
503 if (!(node = get_object_tree_by_GUID(tree, type))) {
504 continue;
505 }
506 }
507
508 if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
509 object_tree_modify_access(node, ace->access_mask);
510 if (node->remaining_access == 0) {
511 return NT_STATUS_OK;
512 }
513 } else {
514 if (node->remaining_access & ace->access_mask){
515 return NT_STATUS_ACCESS_DENIED;
516 }
517 }
518 break;
519 default: /* Other ACE types not handled/supported */
520 break;
521 }
522 }
523
524done:
525 if (bits_remaining != 0) {
526 return NT_STATUS_ACCESS_DENIED;
527 }
528
529 return NT_STATUS_OK;
530}
Note: See TracBrowser for help on using the repository browser.