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 4667001 : struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx)
30 : {
31 366249 : struct security_descriptor *sd;
32 :
33 4667001 : sd = talloc(mem_ctx, struct security_descriptor);
34 4667001 : if (!sd) {
35 0 : return NULL;
36 : }
37 :
38 4667001 : 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 4667001 : sd->type = SEC_DESC_SELF_RELATIVE;
44 :
45 4667001 : sd->owner_sid = NULL;
46 4667001 : sd->group_sid = NULL;
47 4667001 : sd->sacl = NULL;
48 4667001 : sd->dacl = NULL;
49 :
50 4667001 : return sd;
51 : }
52 :
53 12111732 : struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
54 : const struct security_acl *oacl)
55 : {
56 873953 : struct security_acl *nacl;
57 :
58 12111732 : if (oacl == NULL) {
59 1027847 : return NULL;
60 : }
61 :
62 10942412 : if (oacl->aces == NULL && oacl->num_aces > 0) {
63 0 : return NULL;
64 : }
65 :
66 10942412 : nacl = talloc (mem_ctx, struct security_acl);
67 10942412 : if (nacl == NULL) {
68 0 : return NULL;
69 : }
70 :
71 10942412 : *nacl = (struct security_acl) {
72 10942412 : .revision = oacl->revision,
73 10942412 : .size = oacl->size,
74 10942412 : .num_aces = oacl->num_aces,
75 : };
76 10942412 : if (nacl->num_aces == 0) {
77 2063350 : return nacl;
78 : }
79 :
80 8712397 : nacl->aces = (struct security_ace *)talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces);
81 8712397 : if (nacl->aces == NULL) {
82 0 : goto failed;
83 : }
84 :
85 8146582 : return nacl;
86 :
87 0 : failed:
88 0 : talloc_free (nacl);
89 0 : return NULL;
90 :
91 : }
92 :
93 4320970 : struct security_acl *security_acl_concatenate(TALLOC_CTX *mem_ctx,
94 : const struct security_acl *acl1,
95 : const struct security_acl *acl2)
96 : {
97 415562 : struct security_acl *nacl;
98 415562 : uint32_t i;
99 :
100 4320970 : if (!acl1 && !acl2)
101 656469 : return NULL;
102 :
103 3556599 : if (!acl1){
104 217805 : nacl = security_acl_dup(mem_ctx, acl2);
105 217805 : return nacl;
106 : }
107 :
108 3338794 : if (!acl2){
109 48822 : nacl = security_acl_dup(mem_ctx, acl1);
110 48822 : return nacl;
111 : }
112 :
113 3289972 : nacl = talloc (mem_ctx, struct security_acl);
114 3289972 : if (nacl == NULL) {
115 0 : return NULL;
116 : }
117 :
118 3289972 : nacl->revision = acl1->revision;
119 3289972 : nacl->size = acl1->size + acl2->size;
120 3289972 : nacl->num_aces = acl1->num_aces + acl2->num_aces;
121 :
122 3289972 : if (nacl->num_aces == 0)
123 0 : return nacl;
124 :
125 3289972 : nacl->aces = (struct security_ace *)talloc_array (mem_ctx, struct security_ace, acl1->num_aces+acl2->num_aces);
126 3289972 : if ((nacl->aces == NULL) && (nacl->num_aces > 0)) {
127 0 : goto failed;
128 : }
129 :
130 8651041 : for (i = 0; i < acl1->num_aces; i++)
131 5361069 : nacl->aces[i] = acl1->aces[i];
132 17982762 : for (i = 0; i < acl2->num_aces; i++)
133 14692790 : nacl->aces[i + acl1->num_aces] = acl2->aces[i];
134 :
135 2996836 : 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 169720 : 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 169720 : nsd = talloc_zero(mem_ctx, struct security_descriptor);
152 169720 : if (!nsd) {
153 0 : return NULL;
154 : }
155 :
156 169720 : if (osd->owner_sid) {
157 168716 : nsd->owner_sid = dom_sid_dup(nsd, osd->owner_sid);
158 168716 : if (nsd->owner_sid == NULL) {
159 0 : goto failed;
160 : }
161 : }
162 :
163 169720 : if (osd->group_sid) {
164 160343 : nsd->group_sid = dom_sid_dup(nsd, osd->group_sid);
165 160343 : if (nsd->group_sid == NULL) {
166 0 : goto failed;
167 : }
168 : }
169 :
170 169720 : 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 169720 : if (osd->dacl) {
178 169700 : nsd->dacl = security_acl_dup(nsd, osd->dacl);
179 169700 : if (nsd->dacl == NULL) {
180 0 : goto failed;
181 : }
182 : }
183 :
184 169720 : nsd->revision = osd->revision;
185 169720 : nsd->type = osd->type;
186 :
187 169720 : 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 895877 : 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 895877 : struct security_acl *acl = NULL;
275 145594 : ssize_t idx;
276 :
277 895877 : if (add_to_sacl) {
278 7337 : acl = sd->sacl;
279 : } else {
280 888540 : acl = sd->dacl;
281 : }
282 :
283 895877 : if (acl == NULL) {
284 237588 : acl = talloc(sd, struct security_acl);
285 237588 : if (acl == NULL) {
286 0 : return NT_STATUS_NO_MEMORY;
287 : }
288 237588 : acl->revision = SECURITY_ACL_REVISION_NT4;
289 237588 : acl->size = 0;
290 237588 : acl->num_aces = 0;
291 237588 : acl->aces = NULL;
292 : }
293 :
294 895877 : if (_idx < 0) {
295 891089 : idx = (acl->num_aces + 1) + _idx;
296 : } else {
297 4788 : idx = _idx;
298 : }
299 :
300 895877 : if (idx < 0) {
301 0 : return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
302 895877 : } else if (idx > acl->num_aces) {
303 0 : return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
304 : }
305 :
306 895877 : acl->aces = talloc_realloc(acl, acl->aces,
307 : struct security_ace, acl->num_aces+1);
308 895877 : if (acl->aces == NULL) {
309 0 : return NT_STATUS_NO_MEMORY;
310 : }
311 :
312 895877 : ARRAY_INSERT_ELEMENT(acl->aces, acl->num_aces, *ace, idx);
313 895877 : acl->num_aces++;
314 :
315 895877 : if (sec_ace_object(acl->aces[idx].type)) {
316 123527 : acl->revision = SECURITY_ACL_REVISION_ADS;
317 : }
318 :
319 895877 : if (add_to_sacl) {
320 7337 : sd->sacl = acl;
321 7337 : sd->type |= SEC_DESC_SACL_PRESENT;
322 : } else {
323 888540 : sd->dacl = acl;
324 888540 : sd->type |= SEC_DESC_DACL_PRESENT;
325 : }
326 :
327 895877 : 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 26582 : NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
359 : const struct security_ace *ace)
360 : {
361 26582 : 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 861958 : NTSTATUS security_descriptor_dacl_insert(struct security_descriptor *sd,
372 : const struct security_ace *ace,
373 : ssize_t idx)
374 : {
375 861958 : 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 110835 : 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 110835 : bool found = false;
461 110835 : struct security_acl *acl = NULL;
462 :
463 110835 : if (sacl_del) {
464 0 : acl = sd->sacl;
465 : } else {
466 110835 : acl = sd->dacl;
467 : }
468 :
469 110835 : if (acl == NULL) {
470 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
471 : }
472 :
473 3305466 : for (i=0;i<acl->num_aces;i++) {
474 3194631 : if (security_ace_equal(ace, &acl->aces[i])) {
475 110835 : ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
476 110835 : acl->num_aces--;
477 110835 : if (acl->num_aces == 0) {
478 0 : acl->aces = NULL;
479 : }
480 110835 : found = true;
481 110835 : i--;
482 : }
483 : }
484 :
485 110835 : if (!found) {
486 9 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
487 : }
488 :
489 110826 : acl->revision = SECURITY_ACL_REVISION_NT4;
490 :
491 408411 : for (i=0;i<acl->num_aces;i++) {
492 407683 : if (sec_ace_object(acl->aces[i].type)) {
493 110098 : acl->revision = SECURITY_ACL_REVISION_ADS;
494 110098 : break;
495 : }
496 : }
497 :
498 110826 : return NT_STATUS_OK;
499 : }
500 :
501 110835 : NTSTATUS security_descriptor_dacl_del_ace(struct security_descriptor *sd,
502 : const struct security_ace *ace)
503 : {
504 110835 : 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 392721 : static bool security_ace_object_equal(const struct security_ace_object *object1,
514 : const struct security_ace_object *object2)
515 : {
516 392721 : if (object1 == object2) {
517 0 : return true;
518 : }
519 392721 : if ((object1 == NULL) || (object2 == NULL)) {
520 0 : return false;
521 : }
522 392721 : if (object1->flags != object2->flags) {
523 856 : return false;
524 : }
525 391865 : if (object1->flags & SEC_ACE_OBJECT_TYPE_PRESENT
526 368945 : && !GUID_equal(&object1->type.type, &object2->type.type)) {
527 239249 : return false;
528 : }
529 150700 : if (object1->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
530 125570 : && !GUID_equal(&object1->inherited_type.inherited_type,
531 : &object2->inherited_type.inherited_type)) {
532 31629 : return false;
533 : }
534 :
535 106602 : 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 3979094 : bool security_ace_equal(const struct security_ace *ace1,
629 : const struct security_ace *ace2)
630 : {
631 3979094 : if (ace1 == ace2) {
632 0 : return true;
633 : }
634 3979094 : if ((ace1 == NULL) || (ace2 == NULL)) {
635 0 : return false;
636 : }
637 3979094 : if (ace1->type != ace2->type) {
638 964011 : return false;
639 : }
640 3006371 : if (ace1->flags != ace2->flags) {
641 1704251 : return false;
642 : }
643 1291478 : if (ace1->access_mask != ace2->access_mask) {
644 680826 : return false;
645 : }
646 620409 : if (sec_ace_object(ace1->type) &&
647 392721 : !security_ace_object_equal(&ace1->object.object,
648 : &ace2->object.object))
649 : {
650 271492 : return false;
651 : }
652 332132 : if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) {
653 160862 : return false;
654 : }
655 :
656 170553 : if (sec_ace_callback(ace1->type)) {
657 427 : if (data_blob_cmp(&ace1->coda.conditions, &ace2->coda.conditions) != 0) {
658 0 : return false;
659 : }
660 170126 : } 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 128941 : return true;
671 : }
672 :
673 :
674 : /*
675 : compare two security acl structures
676 : */
677 35119 : bool security_acl_equal(const struct security_acl *acl1,
678 : const struct security_acl *acl2)
679 : {
680 15569 : uint32_t i;
681 :
682 35119 : if (acl1 == acl2) return true;
683 21672 : if (!acl1 || !acl2) return false;
684 21666 : if (acl1->revision != acl2->revision) return false;
685 21263 : if (acl1->num_aces != acl2->num_aces) return false;
686 :
687 76133 : for (i=0;i<acl1->num_aces;i++) {
688 55676 : if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return false;
689 : }
690 8820 : return true;
691 : }
692 :
693 : /*
694 : compare two security descriptors.
695 : */
696 18996 : bool security_descriptor_equal(const struct security_descriptor *sd1,
697 : const struct security_descriptor *sd2)
698 : {
699 18996 : if (sd1 == sd2) return true;
700 18996 : if (!sd1 || !sd2) return false;
701 18996 : if (sd1->revision != sd2->revision) return false;
702 18996 : if (sd1->type != sd2->type) return false;
703 :
704 17533 : if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
705 17343 : if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
706 17343 : if (!security_acl_equal(sd1->sacl, sd2->sacl)) return false;
707 17226 : if (!security_acl_equal(sd1->dacl, sd2->dacl)) return false;
708 :
709 8402 : 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 2384 : 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 5664 : while ((sidstr = va_arg(ap, const char *))) {
741 5 : struct dom_sid *sid;
742 3280 : struct security_ace *ace = talloc_zero(sd, struct security_ace);
743 5 : NTSTATUS status;
744 :
745 3280 : if (ace == NULL) {
746 0 : talloc_free(sd);
747 0 : return NULL;
748 : }
749 3280 : ace->type = va_arg(ap, unsigned int);
750 3280 : ace->access_mask = va_arg(ap, unsigned int);
751 3280 : ace->flags = va_arg(ap, unsigned int);
752 3280 : sid = dom_sid_parse_talloc(ace, sidstr);
753 3280 : if (sid == NULL) {
754 0 : talloc_free(sd);
755 0 : return NULL;
756 : }
757 3280 : ace->trustee = *sid;
758 3280 : if (add_ace_to_sacl) {
759 2 : status = security_descriptor_sacl_add(sd, ace);
760 : } else {
761 3278 : status = security_descriptor_dacl_add(sd, ace);
762 : }
763 : /* TODO: check: would talloc_free(ace) here be correct? */
764 3280 : if (!NT_STATUS_IS_OK(status)) {
765 0 : talloc_free(sd);
766 0 : return NULL;
767 : }
768 : }
769 :
770 2379 : return sd;
771 : }
772 :
773 2384 : 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 2384 : sd = security_descriptor_initialise(mem_ctx);
783 2384 : if (sd == NULL) {
784 0 : return NULL;
785 : }
786 :
787 2384 : sd->type |= sd_type;
788 :
789 2384 : 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 2384 : 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 2384 : 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 2382 : 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 2382 : struct security_descriptor *sd = NULL;
836 5 : va_list ap;
837 2382 : va_start(ap, group_sid);
838 2382 : sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
839 : group_sid, false, ap);
840 2382 : va_end(ap);
841 :
842 2382 : 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 318311 : bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd)
892 : {
893 883 : uint32_t i;
894 :
895 318311 : if (psd->dacl == NULL) {
896 54 : return false;
897 : }
898 :
899 1318662 : for (i = 0; i < psd->dacl->num_aces; i++) {
900 1000405 : if (dom_sid_compare_domain(
901 : &global_sid_Unix_NFS,
902 1000405 : &psd->dacl->aces[i].trustee) == 0) {
903 0 : return true;
904 : }
905 : }
906 :
907 317374 : return false;
908 : }
|