Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : security descriptor utility functions
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 "replace.h"
23 : #include "libcli/security/security.h"
24 : #include "librpc/ndr/libndr.h"
25 :
26 : /*
27 : return a blank security descriptor (no owners, dacl or sacl)
28 : */
29 4667966 : struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx)
30 : {
31 366295 : struct security_descriptor *sd;
32 :
33 4667966 : sd = talloc(mem_ctx, struct security_descriptor);
34 4667966 : if (!sd) {
35 0 : return NULL;
36 : }
37 :
38 4667966 : sd->revision = SD_REVISION;
39 : /* we mark as self relative, even though it isn't while it remains
40 : a pointer in memory because this simplifies the ndr code later.
41 : All SDs that we store/emit are in fact SELF_RELATIVE
42 : */
43 4667966 : sd->type = SEC_DESC_SELF_RELATIVE;
44 :
45 4667966 : sd->owner_sid = NULL;
46 4667966 : sd->group_sid = NULL;
47 4667966 : sd->sacl = NULL;
48 4667966 : sd->dacl = NULL;
49 :
50 4667966 : return sd;
51 : }
52 :
53 12117506 : struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
54 : const struct security_acl *oacl)
55 : {
56 874087 : struct security_acl *nacl;
57 :
58 12117506 : if (oacl == NULL) {
59 1031359 : return NULL;
60 : }
61 :
62 10944629 : if (oacl->aces == NULL && oacl->num_aces > 0) {
63 0 : return NULL;
64 : }
65 :
66 10944629 : nacl = talloc (mem_ctx, struct security_acl);
67 10944629 : if (nacl == NULL) {
68 0 : return NULL;
69 : }
70 :
71 10944629 : *nacl = (struct security_acl) {
72 10944629 : .revision = oacl->revision,
73 10944629 : .size = oacl->size,
74 10944629 : .num_aces = oacl->num_aces,
75 : };
76 10944629 : if (nacl->num_aces == 0) {
77 2058819 : return nacl;
78 : }
79 :
80 8719145 : nacl->aces = (struct security_ace *)talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces);
81 8719145 : if (nacl->aces == NULL) {
82 0 : goto failed;
83 : }
84 :
85 8153241 : return nacl;
86 :
87 0 : failed:
88 0 : talloc_free (nacl);
89 0 : return NULL;
90 :
91 : }
92 :
93 4317308 : struct security_acl *security_acl_concatenate(TALLOC_CTX *mem_ctx,
94 : const struct security_acl *acl1,
95 : const struct security_acl *acl2)
96 : {
97 415650 : struct security_acl *nacl;
98 415650 : uint32_t i;
99 :
100 4317308 : if (!acl1 && !acl2)
101 656708 : return NULL;
102 :
103 3552654 : if (!acl1){
104 218413 : nacl = security_acl_dup(mem_ctx, acl2);
105 218413 : return nacl;
106 : }
107 :
108 3334241 : if (!acl2){
109 48246 : nacl = security_acl_dup(mem_ctx, acl1);
110 48246 : return nacl;
111 : }
112 :
113 3285995 : nacl = talloc (mem_ctx, struct security_acl);
114 3285995 : if (nacl == NULL) {
115 0 : return NULL;
116 : }
117 :
118 3285995 : nacl->revision = acl1->revision;
119 3285995 : nacl->size = acl1->size + acl2->size;
120 3285995 : nacl->num_aces = acl1->num_aces + acl2->num_aces;
121 :
122 3285995 : if (nacl->num_aces == 0)
123 0 : return nacl;
124 :
125 3285995 : nacl->aces = (struct security_ace *)talloc_array (mem_ctx, struct security_ace, acl1->num_aces+acl2->num_aces);
126 3285995 : if ((nacl->aces == NULL) && (nacl->num_aces > 0)) {
127 0 : goto failed;
128 : }
129 :
130 8656484 : for (i = 0; i < acl1->num_aces; i++)
131 5370489 : nacl->aces[i] = acl1->aces[i];
132 17976671 : for (i = 0; i < acl2->num_aces; i++)
133 14690676 : nacl->aces[i + acl1->num_aces] = acl2->aces[i];
134 :
135 2992815 : return nacl;
136 :
137 0 : failed:
138 0 : talloc_free (nacl);
139 0 : return NULL;
140 :
141 : }
142 :
143 : /*
144 : talloc and copy a security descriptor
145 : */
146 169727 : struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx,
147 : const struct security_descriptor *osd)
148 : {
149 464 : struct security_descriptor *nsd;
150 :
151 169727 : nsd = talloc_zero(mem_ctx, struct security_descriptor);
152 169727 : if (!nsd) {
153 0 : return NULL;
154 : }
155 :
156 169727 : if (osd->owner_sid) {
157 168717 : nsd->owner_sid = dom_sid_dup(nsd, osd->owner_sid);
158 168717 : if (nsd->owner_sid == NULL) {
159 0 : goto failed;
160 : }
161 : }
162 :
163 169727 : if (osd->group_sid) {
164 160344 : nsd->group_sid = dom_sid_dup(nsd, osd->group_sid);
165 160344 : if (nsd->group_sid == NULL) {
166 0 : goto failed;
167 : }
168 : }
169 :
170 169727 : if (osd->sacl) {
171 52 : nsd->sacl = security_acl_dup(nsd, osd->sacl);
172 52 : if (nsd->sacl == NULL) {
173 0 : goto failed;
174 : }
175 : }
176 :
177 169727 : if (osd->dacl) {
178 169707 : nsd->dacl = security_acl_dup(nsd, osd->dacl);
179 169707 : if (nsd->dacl == NULL) {
180 0 : goto failed;
181 : }
182 : }
183 :
184 169727 : nsd->revision = osd->revision;
185 169727 : nsd->type = osd->type;
186 :
187 169727 : return nsd;
188 :
189 0 : failed:
190 0 : talloc_free(nsd);
191 :
192 0 : return NULL;
193 : }
194 :
195 48 : NTSTATUS security_descriptor_for_client(TALLOC_CTX *mem_ctx,
196 : const struct security_descriptor *ssd,
197 : uint32_t sec_info,
198 : uint32_t access_granted,
199 : struct security_descriptor **_csd)
200 : {
201 48 : struct security_descriptor *csd = NULL;
202 48 : uint32_t access_required = 0;
203 :
204 48 : *_csd = NULL;
205 :
206 48 : if (sec_info & (SECINFO_OWNER|SECINFO_GROUP)) {
207 0 : access_required |= SEC_STD_READ_CONTROL;
208 : }
209 48 : if (sec_info & SECINFO_DACL) {
210 0 : access_required |= SEC_STD_READ_CONTROL;
211 : }
212 48 : if (sec_info & SECINFO_SACL) {
213 0 : access_required |= SEC_FLAG_SYSTEM_SECURITY;
214 : }
215 :
216 48 : if (access_required & (~access_granted)) {
217 0 : return NT_STATUS_ACCESS_DENIED;
218 : }
219 :
220 : /*
221 : * make a copy...
222 : */
223 48 : csd = security_descriptor_copy(mem_ctx, ssd);
224 48 : if (csd == NULL) {
225 0 : return NT_STATUS_NO_MEMORY;
226 : }
227 :
228 : /*
229 : * ... and remove everything not wanted
230 : */
231 :
232 48 : if (!(sec_info & SECINFO_OWNER)) {
233 48 : TALLOC_FREE(csd->owner_sid);
234 48 : csd->type &= ~SEC_DESC_OWNER_DEFAULTED;
235 : }
236 48 : if (!(sec_info & SECINFO_GROUP)) {
237 48 : TALLOC_FREE(csd->group_sid);
238 48 : csd->type &= ~SEC_DESC_GROUP_DEFAULTED;
239 : }
240 48 : if (!(sec_info & SECINFO_DACL)) {
241 48 : TALLOC_FREE(csd->dacl);
242 48 : csd->type &= ~(
243 : SEC_DESC_DACL_PRESENT |
244 : SEC_DESC_DACL_DEFAULTED|
245 : SEC_DESC_DACL_AUTO_INHERIT_REQ |
246 : SEC_DESC_DACL_AUTO_INHERITED |
247 : SEC_DESC_DACL_PROTECTED |
248 : SEC_DESC_DACL_TRUSTED);
249 : }
250 48 : if (!(sec_info & SECINFO_SACL)) {
251 48 : TALLOC_FREE(csd->sacl);
252 48 : csd->type &= ~(
253 : SEC_DESC_SACL_PRESENT |
254 : SEC_DESC_SACL_DEFAULTED |
255 : SEC_DESC_SACL_AUTO_INHERIT_REQ |
256 : SEC_DESC_SACL_AUTO_INHERITED |
257 : SEC_DESC_SACL_PROTECTED |
258 : SEC_DESC_SERVER_SECURITY);
259 : }
260 :
261 48 : *_csd = csd;
262 48 : return NT_STATUS_OK;
263 : }
264 :
265 : /*
266 : add an ACE to an ACL of a security_descriptor
267 : */
268 :
269 896115 : static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
270 : bool add_to_sacl,
271 : const struct security_ace *ace,
272 : ssize_t _idx)
273 : {
274 896115 : struct security_acl *acl = NULL;
275 145597 : ssize_t idx;
276 :
277 896115 : if (add_to_sacl) {
278 7337 : acl = sd->sacl;
279 : } else {
280 888778 : acl = sd->dacl;
281 : }
282 :
283 896115 : if (acl == NULL) {
284 237639 : acl = talloc(sd, struct security_acl);
285 237639 : if (acl == NULL) {
286 0 : return NT_STATUS_NO_MEMORY;
287 : }
288 237639 : acl->revision = SECURITY_ACL_REVISION_NT4;
289 237639 : acl->size = 0;
290 237639 : acl->num_aces = 0;
291 237639 : acl->aces = NULL;
292 : }
293 :
294 896115 : if (_idx < 0) {
295 891326 : idx = (acl->num_aces + 1) + _idx;
296 : } else {
297 4789 : idx = _idx;
298 : }
299 :
300 896115 : if (idx < 0) {
301 0 : return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
302 896115 : } else if (idx > acl->num_aces) {
303 0 : return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
304 : }
305 :
306 896115 : acl->aces = talloc_realloc(acl, acl->aces,
307 : struct security_ace, acl->num_aces+1);
308 896115 : if (acl->aces == NULL) {
309 0 : return NT_STATUS_NO_MEMORY;
310 : }
311 :
312 896115 : ARRAY_INSERT_ELEMENT(acl->aces, acl->num_aces, *ace, idx);
313 896115 : acl->num_aces++;
314 :
315 896115 : if (sec_ace_object(acl->aces[idx].type)) {
316 123607 : acl->revision = SECURITY_ACL_REVISION_ADS;
317 : }
318 :
319 896115 : if (add_to_sacl) {
320 7337 : sd->sacl = acl;
321 7337 : sd->type |= SEC_DESC_SACL_PRESENT;
322 : } else {
323 888778 : sd->dacl = acl;
324 888778 : sd->type |= SEC_DESC_DACL_PRESENT;
325 : }
326 :
327 896115 : return NT_STATUS_OK;
328 : }
329 :
330 : /*
331 : add an ACE to the SACL of a security_descriptor
332 : */
333 :
334 2 : NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
335 : const struct security_ace *ace)
336 : {
337 2 : return security_descriptor_acl_add(sd, true, ace, -1);
338 : }
339 :
340 : /*
341 : insert an ACE at a given index to the SACL of a security_descriptor
342 :
343 : idx can be negative, which means it's related to the new size from the
344 : end, so -1 means the ace is appended at the end.
345 : */
346 :
347 7335 : NTSTATUS security_descriptor_sacl_insert(struct security_descriptor *sd,
348 : const struct security_ace *ace,
349 : ssize_t idx)
350 : {
351 7335 : return security_descriptor_acl_add(sd, true, ace, idx);
352 : }
353 :
354 : /*
355 : add an ACE to the DACL of a security_descriptor
356 : */
357 :
358 26586 : NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
359 : const struct security_ace *ace)
360 : {
361 26586 : return security_descriptor_acl_add(sd, false, ace, -1);
362 : }
363 :
364 : /*
365 : insert an ACE at a given index to the DACL of a security_descriptor
366 :
367 : idx can be negative, which means it's related to the new size from the
368 : end, so -1 means the ace is appended at the end.
369 : */
370 :
371 862192 : NTSTATUS security_descriptor_dacl_insert(struct security_descriptor *sd,
372 : const struct security_ace *ace,
373 : ssize_t idx)
374 : {
375 862192 : return security_descriptor_acl_add(sd, false, ace, idx);
376 : }
377 :
378 : /*
379 : delete the ACE corresponding to the given trustee in an ACL of a
380 : security_descriptor
381 : */
382 :
383 32 : static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd,
384 : bool sacl_del,
385 : const struct dom_sid *trustee)
386 : {
387 0 : uint32_t i;
388 32 : bool found = false;
389 32 : struct security_acl *acl = NULL;
390 :
391 32 : if (sacl_del) {
392 0 : acl = sd->sacl;
393 : } else {
394 32 : acl = sd->dacl;
395 : }
396 :
397 32 : if (acl == NULL) {
398 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
399 : }
400 :
401 : /* there can be multiple ace's for one trustee */
402 198 : for (i=0;i<acl->num_aces;i++) {
403 166 : if (dom_sid_equal(trustee, &acl->aces[i].trustee)) {
404 80 : ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
405 80 : acl->num_aces--;
406 80 : if (acl->num_aces == 0) {
407 0 : acl->aces = NULL;
408 : }
409 80 : found = true;
410 80 : --i;
411 : }
412 : }
413 :
414 32 : if (!found) {
415 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
416 : }
417 :
418 32 : acl->revision = SECURITY_ACL_REVISION_NT4;
419 :
420 118 : for (i=0;i<acl->num_aces;i++) {
421 86 : if (sec_ace_object(acl->aces[i].type)) {
422 0 : acl->revision = SECURITY_ACL_REVISION_ADS;
423 0 : break;
424 : }
425 : }
426 :
427 32 : return NT_STATUS_OK;
428 : }
429 :
430 : /*
431 : delete the ACE corresponding to the given trustee in the DACL of a
432 : security_descriptor
433 : */
434 :
435 32 : NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
436 : const struct dom_sid *trustee)
437 : {
438 32 : return security_descriptor_acl_del(sd, false, trustee);
439 : }
440 :
441 : /*
442 : delete the ACE corresponding to the given trustee in the SACL of a
443 : security_descriptor
444 : */
445 :
446 0 : NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
447 : const struct dom_sid *trustee)
448 : {
449 0 : return security_descriptor_acl_del(sd, true, trustee);
450 : }
451 :
452 : /*
453 : delete the given ACE in the SACL or DACL of a security_descriptor
454 : */
455 110854 : static NTSTATUS security_descriptor_acl_del_ace(struct security_descriptor *sd,
456 : bool sacl_del,
457 : const struct security_ace *ace)
458 : {
459 594 : uint32_t i;
460 110854 : bool found = false;
461 110854 : struct security_acl *acl = NULL;
462 :
463 110854 : if (sacl_del) {
464 0 : acl = sd->sacl;
465 : } else {
466 110854 : acl = sd->dacl;
467 : }
468 :
469 110854 : if (acl == NULL) {
470 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
471 : }
472 :
473 3306421 : for (i=0;i<acl->num_aces;i++) {
474 3195567 : if (security_ace_equal(ace, &acl->aces[i])) {
475 110854 : ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
476 110854 : acl->num_aces--;
477 110854 : if (acl->num_aces == 0) {
478 0 : acl->aces = NULL;
479 : }
480 110854 : found = true;
481 110854 : i--;
482 : }
483 : }
484 :
485 110854 : if (!found) {
486 9 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
487 : }
488 :
489 110845 : acl->revision = SECURITY_ACL_REVISION_NT4;
490 :
491 408502 : for (i=0;i<acl->num_aces;i++) {
492 407781 : if (sec_ace_object(acl->aces[i].type)) {
493 110124 : acl->revision = SECURITY_ACL_REVISION_ADS;
494 110124 : break;
495 : }
496 : }
497 :
498 110845 : return NT_STATUS_OK;
499 : }
500 :
501 110854 : NTSTATUS security_descriptor_dacl_del_ace(struct security_descriptor *sd,
502 : const struct security_ace *ace)
503 : {
504 110854 : return security_descriptor_acl_del_ace(sd, false, ace);
505 : }
506 :
507 0 : NTSTATUS security_descriptor_sacl_del_ace(struct security_descriptor *sd,
508 : const struct security_ace *ace)
509 : {
510 0 : return security_descriptor_acl_del_ace(sd, true, ace);
511 : }
512 :
513 392783 : static bool security_ace_object_equal(const struct security_ace_object *object1,
514 : const struct security_ace_object *object2)
515 : {
516 392783 : if (object1 == object2) {
517 0 : return true;
518 : }
519 392783 : if ((object1 == NULL) || (object2 == NULL)) {
520 0 : return false;
521 : }
522 392783 : if (object1->flags != object2->flags) {
523 856 : return false;
524 : }
525 391927 : if (object1->flags & SEC_ACE_OBJECT_TYPE_PRESENT
526 369003 : && !GUID_equal(&object1->type.type, &object2->type.type)) {
527 239284 : return false;
528 : }
529 150727 : if (object1->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
530 125592 : && !GUID_equal(&object1->inherited_type.inherited_type,
531 : &object2->inherited_type.inherited_type)) {
532 31631 : return false;
533 : }
534 :
535 106627 : return true;
536 : }
537 :
538 :
539 83 : static bool security_ace_claim_equal(const struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *claim1,
540 : const struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *claim2)
541 : {
542 83 : uint32_t i;
543 :
544 83 : if (claim1 == claim2) {
545 0 : return true;
546 : }
547 83 : if (claim1 == NULL || claim2 == NULL) {
548 0 : return false;
549 : }
550 83 : if (claim1->name != NULL && claim2->name != NULL) {
551 83 : if (strcasecmp_m(claim1->name, claim2->name) != 0) {
552 0 : return false;
553 : }
554 0 : } else if (claim1->name != NULL || claim2->name != NULL) {
555 0 : return false;
556 : }
557 83 : if (claim1->value_type != claim2->value_type) {
558 0 : return false;
559 : }
560 83 : if (claim1->flags != claim2->flags) {
561 0 : return false;
562 : }
563 83 : if (claim1->value_count != claim2->value_count) {
564 0 : return false;
565 : }
566 1070 : for (i = 0; i < claim1->value_count; ++i) {
567 987 : const union claim_values *values1 = claim1->values;
568 987 : const union claim_values *values2 = claim2->values;
569 :
570 987 : switch (claim1->value_type) {
571 128 : case CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64:
572 128 : if (values1[i].int_value != NULL && values2[i].int_value != NULL) {
573 128 : if (*values1[i].int_value != *values2[i].int_value) {
574 0 : return false;
575 : }
576 0 : } else if (values1[i].int_value != NULL || values2[i].int_value != NULL) {
577 0 : return false;
578 : }
579 0 : break;
580 349 : case CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64:
581 : case CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN:
582 349 : if (values1[i].uint_value != NULL && values2[i].uint_value != NULL) {
583 349 : if (*values1[i].uint_value != *values2[i].uint_value) {
584 0 : return false;
585 : }
586 0 : } else if (values1[i].uint_value != NULL || values2[i].uint_value != NULL) {
587 0 : return false;
588 : }
589 0 : break;
590 27 : case CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING:
591 27 : if (values1[i].string_value != NULL && values2[i].string_value != NULL) {
592 27 : if (strcasecmp_m(values1[i].string_value, values2[i].string_value) != 0) {
593 0 : return false;
594 : }
595 0 : } else if (values1[i].string_value != NULL || values2[i].string_value != NULL) {
596 0 : return false;
597 : }
598 0 : break;
599 0 : case CLAIM_SECURITY_ATTRIBUTE_TYPE_SID:
600 0 : if (values1[i].sid_value != NULL && values2[i].sid_value != NULL) {
601 0 : if (data_blob_cmp(values1[i].sid_value, values2[i].sid_value) != 0) {
602 0 : return false;
603 : }
604 0 : } else if (values1[i].sid_value != NULL || values2[i].sid_value != NULL) {
605 0 : return false;
606 : }
607 0 : break;
608 483 : case CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING:
609 483 : if (values1[i].octet_value != NULL && values2[i].octet_value != NULL) {
610 483 : if (data_blob_cmp(values1[i].octet_value, values2[i].octet_value) != 0) {
611 0 : return false;
612 : }
613 0 : } else if (values1[i].octet_value != NULL || values2[i].octet_value != NULL) {
614 0 : return false;
615 : }
616 0 : break;
617 0 : default:
618 0 : break;
619 : }
620 : }
621 :
622 0 : return true;
623 : }
624 :
625 : /*
626 : compare two security ace structures
627 : */
628 3980037 : bool security_ace_equal(const struct security_ace *ace1,
629 : const struct security_ace *ace2)
630 : {
631 3980037 : if (ace1 == ace2) {
632 3 : return true;
633 : }
634 3980034 : if ((ace1 == NULL) || (ace2 == NULL)) {
635 0 : return false;
636 : }
637 3980034 : if (ace1->type != ace2->type) {
638 964256 : return false;
639 : }
640 3007066 : if (ace1->flags != ace2->flags) {
641 1704815 : return false;
642 : }
643 1291609 : if (ace1->access_mask != ace2->access_mask) {
644 680896 : return false;
645 : }
646 620470 : if (sec_ace_object(ace1->type) &&
647 392783 : !security_ace_object_equal(&ace1->object.object,
648 : &ace2->object.object))
649 : {
650 271529 : return false;
651 : }
652 332156 : if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) {
653 160864 : return false;
654 : }
655 :
656 170575 : if (sec_ace_callback(ace1->type)) {
657 433 : if (data_blob_cmp(&ace1->coda.conditions, &ace2->coda.conditions) != 0) {
658 0 : return false;
659 : }
660 170142 : } else if (sec_ace_resource(ace1->type)) {
661 83 : if (!security_ace_claim_equal(&ace1->coda.claim, &ace2->coda.claim)) {
662 0 : return false;
663 : }
664 : } else {
665 : /*
666 : * Don’t require ace1->coda.ignored to match ace2->coda.ignored.
667 : */
668 : }
669 :
670 128963 : return true;
671 : }
672 :
673 :
674 : /*
675 : compare two security acl structures
676 : */
677 35151 : bool security_acl_equal(const struct security_acl *acl1,
678 : const struct security_acl *acl2)
679 : {
680 15569 : uint32_t i;
681 :
682 35151 : if (acl1 == acl2) return true;
683 21688 : if (!acl1 || !acl2) return false;
684 21682 : if (acl1->revision != acl2->revision) return false;
685 21276 : if (acl1->num_aces != acl2->num_aces) return false;
686 :
687 76146 : for (i=0;i<acl1->num_aces;i++) {
688 55683 : if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return false;
689 : }
690 8826 : return true;
691 : }
692 :
693 : /*
694 : compare two security descriptors.
695 : */
696 19012 : bool security_descriptor_equal(const struct security_descriptor *sd1,
697 : const struct security_descriptor *sd2)
698 : {
699 19012 : if (sd1 == sd2) return true;
700 19012 : if (!sd1 || !sd2) return false;
701 19012 : if (sd1->revision != sd2->revision) return false;
702 19012 : if (sd1->type != sd2->type) return false;
703 :
704 17549 : if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
705 17359 : if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
706 17359 : if (!security_acl_equal(sd1->sacl, sd2->sacl)) return false;
707 17242 : if (!security_acl_equal(sd1->dacl, sd2->dacl)) return false;
708 :
709 8408 : return true;
710 : }
711 :
712 : /*
713 : compare two security descriptors, but allow certain (missing) parts
714 : to be masked out of the comparison
715 : */
716 0 : bool security_descriptor_mask_equal(const struct security_descriptor *sd1,
717 : const struct security_descriptor *sd2,
718 : uint32_t mask)
719 : {
720 0 : if (sd1 == sd2) return true;
721 0 : if (!sd1 || !sd2) return false;
722 0 : if (sd1->revision != sd2->revision) return false;
723 0 : if ((sd1->type & mask) != (sd2->type & mask)) return false;
724 :
725 0 : if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
726 0 : if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
727 0 : if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return false;
728 0 : if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return false;
729 :
730 0 : return true;
731 : }
732 :
733 :
734 2388 : static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd,
735 : bool add_ace_to_sacl,
736 : va_list ap)
737 : {
738 5 : const char *sidstr;
739 :
740 5672 : while ((sidstr = va_arg(ap, const char *))) {
741 5 : struct dom_sid *sid;
742 3284 : struct security_ace *ace = talloc_zero(sd, struct security_ace);
743 5 : NTSTATUS status;
744 :
745 3284 : if (ace == NULL) {
746 0 : talloc_free(sd);
747 0 : return NULL;
748 : }
749 3284 : ace->type = va_arg(ap, unsigned int);
750 3284 : ace->access_mask = va_arg(ap, unsigned int);
751 3284 : ace->flags = va_arg(ap, unsigned int);
752 3284 : sid = dom_sid_parse_talloc(ace, sidstr);
753 3284 : if (sid == NULL) {
754 0 : talloc_free(sd);
755 0 : return NULL;
756 : }
757 3284 : ace->trustee = *sid;
758 3284 : if (add_ace_to_sacl) {
759 2 : status = security_descriptor_sacl_add(sd, ace);
760 : } else {
761 3282 : status = security_descriptor_dacl_add(sd, ace);
762 : }
763 : /* TODO: check: would talloc_free(ace) here be correct? */
764 3284 : if (!NT_STATUS_IS_OK(status)) {
765 0 : talloc_free(sd);
766 0 : return NULL;
767 : }
768 : }
769 :
770 2383 : return sd;
771 : }
772 :
773 2388 : static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx,
774 : uint16_t sd_type,
775 : const char *owner_sid,
776 : const char *group_sid,
777 : bool add_ace_to_sacl,
778 : va_list ap)
779 : {
780 5 : struct security_descriptor *sd;
781 :
782 2388 : sd = security_descriptor_initialise(mem_ctx);
783 2388 : if (sd == NULL) {
784 0 : return NULL;
785 : }
786 :
787 2388 : sd->type |= sd_type;
788 :
789 2388 : if (owner_sid) {
790 1342 : sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid);
791 1342 : if (sd->owner_sid == NULL) {
792 0 : talloc_free(sd);
793 0 : return NULL;
794 : }
795 : }
796 2388 : if (group_sid) {
797 69 : sd->group_sid = dom_sid_parse_talloc(sd, group_sid);
798 69 : if (sd->group_sid == NULL) {
799 0 : talloc_free(sd);
800 0 : return NULL;
801 : }
802 : }
803 :
804 2388 : return security_descriptor_appendv(sd, add_ace_to_sacl, ap);
805 : }
806 :
807 : /*
808 : create a security descriptor using string SIDs. This is used by the
809 : torture code to allow the easy creation of complex ACLs
810 : This is a varargs function. The list of DACL ACEs ends with a NULL sid.
811 :
812 : Each ACE contains a set of 4 parameters:
813 : SID, ACCESS_TYPE, MASK, FLAGS
814 :
815 : a typical call would be:
816 :
817 : sd = security_descriptor_dacl_create(mem_ctx,
818 : sd_type_flags,
819 : mysid,
820 : mygroup,
821 : SID_NT_AUTHENTICATED_USERS,
822 : SEC_ACE_TYPE_ACCESS_ALLOWED,
823 : SEC_FILE_ALL,
824 : SEC_ACE_FLAG_OBJECT_INHERIT,
825 : NULL);
826 : that would create a sd with one DACL ACE
827 : */
828 :
829 2386 : struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx,
830 : uint16_t sd_type,
831 : const char *owner_sid,
832 : const char *group_sid,
833 : ...)
834 : {
835 2386 : struct security_descriptor *sd = NULL;
836 5 : va_list ap;
837 2386 : va_start(ap, group_sid);
838 2386 : sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
839 : group_sid, false, ap);
840 2386 : va_end(ap);
841 :
842 2386 : return sd;
843 : }
844 :
845 2 : struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx,
846 : uint16_t sd_type,
847 : const char *owner_sid,
848 : const char *group_sid,
849 : ...)
850 : {
851 2 : struct security_descriptor *sd = NULL;
852 0 : va_list ap;
853 2 : va_start(ap, group_sid);
854 2 : sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
855 : group_sid, true, ap);
856 2 : va_end(ap);
857 :
858 2 : return sd;
859 : }
860 :
861 4 : struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx,
862 : const char *sid_str,
863 : enum security_ace_type type,
864 : uint32_t access_mask,
865 : uint8_t flags)
866 :
867 : {
868 0 : struct security_ace *ace;
869 0 : bool ok;
870 :
871 4 : ace = talloc_zero(mem_ctx, struct security_ace);
872 4 : if (ace == NULL) {
873 0 : return NULL;
874 : }
875 :
876 4 : ok = dom_sid_parse(sid_str, &ace->trustee);
877 4 : if (!ok) {
878 0 : talloc_free(ace);
879 0 : return NULL;
880 : }
881 4 : ace->type = type;
882 4 : ace->access_mask = access_mask;
883 4 : ace->flags = flags;
884 :
885 4 : return ace;
886 : }
887 :
888 : /*******************************************************************
889 : Check for MS NFS ACEs in a sd
890 : *******************************************************************/
891 318313 : bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd)
892 : {
893 883 : uint32_t i;
894 :
895 318313 : if (psd->dacl == NULL) {
896 54 : return false;
897 : }
898 :
899 1318654 : for (i = 0; i < psd->dacl->num_aces; i++) {
900 1000395 : if (dom_sid_compare_domain(
901 : &global_sid_Unix_NFS,
902 1000395 : &psd->dacl->aces[i].trustee) == 0) {
903 0 : return true;
904 : }
905 : }
906 :
907 317376 : return false;
908 : }
|