Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : security descriptror 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 "includes.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 1827460 : struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx)
30 : {
31 : struct security_descriptor *sd;
32 :
33 1827460 : sd = talloc(mem_ctx, struct security_descriptor);
34 1827460 : if (!sd) {
35 0 : return NULL;
36 : }
37 :
38 1827460 : 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 1827460 : sd->type = SEC_DESC_SELF_RELATIVE;
44 :
45 1827460 : sd->owner_sid = NULL;
46 1827460 : sd->group_sid = NULL;
47 1827460 : sd->sacl = NULL;
48 1827460 : sd->dacl = NULL;
49 :
50 1827460 : return sd;
51 : }
52 :
53 6095938 : struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
54 : const struct security_acl *oacl)
55 : {
56 : struct security_acl *nacl;
57 :
58 6095938 : if (oacl == NULL) {
59 808321 : return NULL;
60 : }
61 :
62 5287617 : if (oacl->aces == NULL && oacl->num_aces > 0) {
63 0 : return NULL;
64 : }
65 :
66 5287617 : nacl = talloc (mem_ctx, struct security_acl);
67 5287617 : if (nacl == NULL) {
68 0 : return NULL;
69 : }
70 :
71 5287617 : *nacl = (struct security_acl) {
72 5287617 : .revision = oacl->revision,
73 5287617 : .size = oacl->size,
74 5287617 : .num_aces = oacl->num_aces,
75 : };
76 5287617 : if (nacl->num_aces == 0) {
77 942087 : return nacl;
78 : }
79 :
80 4345530 : nacl->aces = (struct security_ace *)talloc_memdup (nacl, oacl->aces, sizeof(struct security_ace) * oacl->num_aces);
81 4345530 : if (nacl->aces == NULL) {
82 0 : goto failed;
83 : }
84 :
85 4345530 : return nacl;
86 :
87 0 : failed:
88 0 : talloc_free (nacl);
89 0 : return NULL;
90 :
91 : }
92 :
93 2305502 : struct security_acl *security_acl_concatenate(TALLOC_CTX *mem_ctx,
94 : const struct security_acl *acl1,
95 : const struct security_acl *acl2)
96 : {
97 : struct security_acl *nacl;
98 : uint32_t i;
99 :
100 2305502 : if (!acl1 && !acl2)
101 492963 : return NULL;
102 :
103 1812539 : if (!acl1){
104 145479 : nacl = security_acl_dup(mem_ctx, acl2);
105 145479 : return nacl;
106 : }
107 :
108 1667060 : if (!acl2){
109 44881 : nacl = security_acl_dup(mem_ctx, acl1);
110 44881 : return nacl;
111 : }
112 :
113 1622179 : nacl = talloc (mem_ctx, struct security_acl);
114 1622179 : if (nacl == NULL) {
115 0 : return NULL;
116 : }
117 :
118 1622179 : nacl->revision = acl1->revision;
119 1622179 : nacl->size = acl1->size + acl2->size;
120 1622179 : nacl->num_aces = acl1->num_aces + acl2->num_aces;
121 :
122 1622179 : if (nacl->num_aces == 0)
123 0 : return nacl;
124 :
125 1622179 : nacl->aces = (struct security_ace *)talloc_array (mem_ctx, struct security_ace, acl1->num_aces+acl2->num_aces);
126 1622179 : if ((nacl->aces == NULL) && (nacl->num_aces > 0)) {
127 0 : goto failed;
128 : }
129 :
130 5182861 : for (i = 0; i < acl1->num_aces; i++)
131 3560682 : nacl->aces[i] = acl1->aces[i];
132 8838246 : for (i = 0; i < acl2->num_aces; i++)
133 7216067 : nacl->aces[i + acl1->num_aces] = acl2->aces[i];
134 :
135 1622179 : 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 2591 : struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx,
147 : const struct security_descriptor *osd)
148 : {
149 : struct security_descriptor *nsd;
150 :
151 2591 : nsd = talloc_zero(mem_ctx, struct security_descriptor);
152 2591 : if (!nsd) {
153 0 : return NULL;
154 : }
155 :
156 2591 : if (osd->owner_sid) {
157 2463 : nsd->owner_sid = dom_sid_dup(nsd, osd->owner_sid);
158 2463 : if (nsd->owner_sid == NULL) {
159 0 : goto failed;
160 : }
161 : }
162 :
163 2591 : if (osd->group_sid) {
164 2394 : nsd->group_sid = dom_sid_dup(nsd, osd->group_sid);
165 2394 : if (nsd->group_sid == NULL) {
166 0 : goto failed;
167 : }
168 : }
169 :
170 2591 : if (osd->sacl) {
171 4 : nsd->sacl = security_acl_dup(nsd, osd->sacl);
172 4 : if (nsd->sacl == NULL) {
173 0 : goto failed;
174 : }
175 : }
176 :
177 2591 : if (osd->dacl) {
178 2589 : nsd->dacl = security_acl_dup(nsd, osd->dacl);
179 2589 : if (nsd->dacl == NULL) {
180 0 : goto failed;
181 : }
182 : }
183 :
184 2591 : nsd->revision = osd->revision;
185 2591 : nsd->type = osd->type;
186 :
187 2591 : return nsd;
188 :
189 0 : failed:
190 0 : talloc_free(nsd);
191 :
192 0 : return NULL;
193 : }
194 :
195 12 : 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 12 : struct security_descriptor *csd = NULL;
202 12 : uint32_t access_required = 0;
203 :
204 12 : *_csd = NULL;
205 :
206 12 : if (sec_info & (SECINFO_OWNER|SECINFO_GROUP)) {
207 0 : access_required |= SEC_STD_READ_CONTROL;
208 : }
209 12 : if (sec_info & SECINFO_DACL) {
210 0 : access_required |= SEC_STD_READ_CONTROL;
211 : }
212 12 : if (sec_info & SECINFO_SACL) {
213 0 : access_required |= SEC_FLAG_SYSTEM_SECURITY;
214 : }
215 :
216 12 : if (access_required & (~access_granted)) {
217 0 : return NT_STATUS_ACCESS_DENIED;
218 : }
219 :
220 : /*
221 : * make a copy...
222 : */
223 12 : csd = security_descriptor_copy(mem_ctx, ssd);
224 12 : if (csd == NULL) {
225 0 : return NT_STATUS_NO_MEMORY;
226 : }
227 :
228 : /*
229 : * ... and remove everthing not wanted
230 : */
231 :
232 12 : if (!(sec_info & SECINFO_OWNER)) {
233 12 : TALLOC_FREE(csd->owner_sid);
234 12 : csd->type &= ~SEC_DESC_OWNER_DEFAULTED;
235 : }
236 12 : if (!(sec_info & SECINFO_GROUP)) {
237 12 : TALLOC_FREE(csd->group_sid);
238 12 : csd->type &= ~SEC_DESC_GROUP_DEFAULTED;
239 : }
240 12 : if (!(sec_info & SECINFO_DACL)) {
241 12 : TALLOC_FREE(csd->dacl);
242 12 : 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 12 : if (!(sec_info & SECINFO_SACL)) {
251 12 : TALLOC_FREE(csd->sacl);
252 12 : 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 12 : *_csd = csd;
262 12 : return NT_STATUS_OK;
263 : }
264 :
265 : /*
266 : add an ACE to an ACL of a security_descriptor
267 : */
268 :
269 557058 : 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 557058 : struct security_acl *acl = NULL;
275 : ssize_t idx;
276 :
277 557058 : if (add_to_sacl) {
278 3636 : acl = sd->sacl;
279 : } else {
280 553422 : acl = sd->dacl;
281 : }
282 :
283 557058 : if (acl == NULL) {
284 150670 : acl = talloc(sd, struct security_acl);
285 150670 : if (acl == NULL) {
286 0 : return NT_STATUS_NO_MEMORY;
287 : }
288 150670 : acl->revision = SECURITY_ACL_REVISION_NT4;
289 150670 : acl->size = 0;
290 150670 : acl->num_aces = 0;
291 150670 : acl->aces = NULL;
292 : }
293 :
294 557058 : if (_idx < 0) {
295 552772 : idx = (acl->num_aces + 1) + _idx;
296 : } else {
297 4286 : idx = _idx;
298 : }
299 :
300 557058 : if (idx < 0) {
301 0 : return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
302 557058 : } else if (idx > acl->num_aces) {
303 0 : return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
304 : }
305 :
306 557058 : acl->aces = talloc_realloc(acl, acl->aces,
307 : struct security_ace, acl->num_aces+1);
308 557058 : if (acl->aces == NULL) {
309 0 : return NT_STATUS_NO_MEMORY;
310 : }
311 :
312 557058 : ARRAY_INSERT_ELEMENT(acl->aces, acl->num_aces, *ace, idx);
313 557058 : acl->num_aces++;
314 :
315 557058 : switch (acl->aces[idx].type) {
316 75717 : case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
317 : case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
318 : case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
319 : case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
320 75717 : acl->revision = SECURITY_ACL_REVISION_ADS;
321 75717 : break;
322 481341 : default:
323 481341 : break;
324 : }
325 :
326 557058 : if (add_to_sacl) {
327 3636 : sd->sacl = acl;
328 3636 : sd->type |= SEC_DESC_SACL_PRESENT;
329 : } else {
330 553422 : sd->dacl = acl;
331 553422 : sd->type |= SEC_DESC_DACL_PRESENT;
332 : }
333 :
334 557058 : return NT_STATUS_OK;
335 : }
336 :
337 : /*
338 : add an ACE to the SACL of a security_descriptor
339 : */
340 :
341 0 : NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
342 : const struct security_ace *ace)
343 : {
344 0 : return security_descriptor_acl_add(sd, true, ace, -1);
345 : }
346 :
347 : /*
348 : insert an ACE at a given index to the SACL of a security_descriptor
349 :
350 : idx can be negative, which means it's related to the new size from the
351 : end, so -1 means the ace is appended at the end.
352 : */
353 :
354 3636 : NTSTATUS security_descriptor_sacl_insert(struct security_descriptor *sd,
355 : const struct security_ace *ace,
356 : ssize_t idx)
357 : {
358 3636 : return security_descriptor_acl_add(sd, true, ace, idx);
359 : }
360 :
361 : /*
362 : add an ACE to the DACL of a security_descriptor
363 : */
364 :
365 6085 : NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
366 : const struct security_ace *ace)
367 : {
368 6085 : return security_descriptor_acl_add(sd, false, ace, -1);
369 : }
370 :
371 : /*
372 : insert an ACE at a given index to the DACL of a security_descriptor
373 :
374 : idx can be negative, which means it's related to the new size from the
375 : end, so -1 means the ace is appended at the end.
376 : */
377 :
378 547337 : NTSTATUS security_descriptor_dacl_insert(struct security_descriptor *sd,
379 : const struct security_ace *ace,
380 : ssize_t idx)
381 : {
382 547337 : return security_descriptor_acl_add(sd, false, ace, idx);
383 : }
384 :
385 : /*
386 : delete the ACE corresponding to the given trustee in an ACL of a
387 : security_descriptor
388 : */
389 :
390 2 : static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd,
391 : bool sacl_del,
392 : const struct dom_sid *trustee)
393 : {
394 : uint32_t i;
395 2 : bool found = false;
396 2 : struct security_acl *acl = NULL;
397 :
398 2 : if (sacl_del) {
399 0 : acl = sd->sacl;
400 : } else {
401 2 : acl = sd->dacl;
402 : }
403 :
404 2 : if (acl == NULL) {
405 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
406 : }
407 :
408 : /* there can be multiple ace's for one trustee */
409 12 : for (i=0;i<acl->num_aces;i++) {
410 10 : if (dom_sid_equal(trustee, &acl->aces[i].trustee)) {
411 2 : ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
412 2 : acl->num_aces--;
413 2 : if (acl->num_aces == 0) {
414 0 : acl->aces = NULL;
415 : }
416 2 : found = true;
417 : }
418 : }
419 :
420 2 : if (!found) {
421 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
422 : }
423 :
424 2 : acl->revision = SECURITY_ACL_REVISION_NT4;
425 :
426 10 : for (i=0;i<acl->num_aces;i++) {
427 8 : switch (acl->aces[i].type) {
428 0 : case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
429 : case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
430 : case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
431 : case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
432 0 : acl->revision = SECURITY_ACL_REVISION_ADS;
433 0 : return NT_STATUS_OK;
434 8 : default:
435 8 : break; /* only for the switch statement */
436 : }
437 : }
438 :
439 2 : return NT_STATUS_OK;
440 : }
441 :
442 : /*
443 : delete the ACE corresponding to the given trustee in the DACL of a
444 : security_descriptor
445 : */
446 :
447 2 : NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
448 : const struct dom_sid *trustee)
449 : {
450 2 : return security_descriptor_acl_del(sd, false, trustee);
451 : }
452 :
453 : /*
454 : delete the ACE corresponding to the given trustee in the SACL of a
455 : security_descriptor
456 : */
457 :
458 0 : NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
459 : const struct dom_sid *trustee)
460 : {
461 0 : return security_descriptor_acl_del(sd, true, trustee);
462 : }
463 :
464 : /*
465 : delete the given ACE in the SACL or DACL of a security_descriptor
466 : */
467 78662 : static NTSTATUS security_descriptor_acl_del_ace(struct security_descriptor *sd,
468 : bool sacl_del,
469 : const struct security_ace *ace)
470 : {
471 : uint32_t i;
472 78662 : bool found = false;
473 78662 : struct security_acl *acl = NULL;
474 :
475 78662 : if (sacl_del) {
476 0 : acl = sd->sacl;
477 : } else {
478 78662 : acl = sd->dacl;
479 : }
480 :
481 78662 : if (acl == NULL) {
482 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
483 : }
484 :
485 2111700 : for (i=0;i<acl->num_aces;i++) {
486 2033038 : if (security_ace_equal(ace, &acl->aces[i])) {
487 78662 : ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
488 78662 : acl->num_aces--;
489 78662 : if (acl->num_aces == 0) {
490 0 : acl->aces = NULL;
491 : }
492 78662 : found = true;
493 78662 : i--;
494 : }
495 : }
496 :
497 78662 : if (!found) {
498 9 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
499 : }
500 :
501 78653 : acl->revision = SECURITY_ACL_REVISION_NT4;
502 :
503 285682 : for (i=0;i<acl->num_aces;i++) {
504 285565 : switch (acl->aces[i].type) {
505 78536 : case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
506 : case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
507 : case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
508 : case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
509 78536 : acl->revision = SECURITY_ACL_REVISION_ADS;
510 78536 : return NT_STATUS_OK;
511 207029 : default:
512 207029 : break; /* only for the switch statement */
513 : }
514 : }
515 :
516 117 : return NT_STATUS_OK;
517 : }
518 :
519 78662 : NTSTATUS security_descriptor_dacl_del_ace(struct security_descriptor *sd,
520 : const struct security_ace *ace)
521 : {
522 78662 : return security_descriptor_acl_del_ace(sd, false, ace);
523 : }
524 :
525 0 : NTSTATUS security_descriptor_sacl_del_ace(struct security_descriptor *sd,
526 : const struct security_ace *ace)
527 : {
528 0 : return security_descriptor_acl_del_ace(sd, true, ace);
529 : }
530 :
531 317710 : static bool security_ace_object_equal(const struct security_ace_object *object1,
532 : const struct security_ace_object *object2)
533 : {
534 317710 : if (object1 == object2) {
535 0 : return true;
536 : }
537 317710 : if ((object1 == NULL) || (object2 == NULL)) {
538 0 : return false;
539 : }
540 317710 : if (object1->flags != object2->flags) {
541 856 : return false;
542 : }
543 316854 : if (object1->flags & SEC_ACE_OBJECT_TYPE_PRESENT
544 296470 : && !GUID_equal(&object1->type.type, &object2->type.type)) {
545 220834 : return false;
546 : }
547 96020 : if (object1->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
548 91604 : && !GUID_equal(&object1->inherited_type.inherited_type,
549 : &object2->inherited_type.inherited_type)) {
550 28820 : return false;
551 : }
552 :
553 67200 : return true;
554 : }
555 :
556 : /*
557 : compare two security ace structures
558 : */
559 2123426 : bool security_ace_equal(const struct security_ace *ace1,
560 : const struct security_ace *ace2)
561 : {
562 2123426 : if (ace1 == ace2) {
563 0 : return true;
564 : }
565 2123426 : if ((ace1 == NULL) || (ace2 == NULL)) {
566 0 : return false;
567 : }
568 2123426 : if (ace1->type != ace2->type) {
569 676025 : return false;
570 : }
571 1447401 : if (ace1->flags != ace2->flags) {
572 949246 : return false;
573 : }
574 498155 : if (ace1->access_mask != ace2->access_mask) {
575 161741 : return false;
576 : }
577 336414 : if ((ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
578 18713 : || ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
579 18704 : || ace1->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
580 18704 : || ace1->type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)
581 317710 : && !security_ace_object_equal(&ace1->object.object,
582 : &ace2->object.object)) {
583 250510 : return false;
584 : }
585 85904 : if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) {
586 5077 : return false;
587 : }
588 :
589 80827 : return true;
590 : }
591 :
592 :
593 : /*
594 : compare two security acl structures
595 : */
596 2236 : bool security_acl_equal(const struct security_acl *acl1,
597 : const struct security_acl *acl2)
598 : {
599 : uint32_t i;
600 :
601 2236 : if (acl1 == acl2) return true;
602 1149 : if (!acl1 || !acl2) return false;
603 1143 : if (acl1->revision != acl2->revision) return false;
604 865 : if (acl1->num_aces != acl2->num_aces) return false;
605 :
606 2133 : for (i=0;i<acl1->num_aces;i++) {
607 1504 : if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return false;
608 : }
609 629 : return true;
610 : }
611 :
612 : /*
613 : compare two security descriptors.
614 : */
615 1310 : bool security_descriptor_equal(const struct security_descriptor *sd1,
616 : const struct security_descriptor *sd2)
617 : {
618 1310 : if (sd1 == sd2) return true;
619 1310 : if (!sd1 || !sd2) return false;
620 1310 : if (sd1->revision != sd2->revision) return false;
621 1310 : if (sd1->type != sd2->type) return false;
622 :
623 1113 : if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
624 1087 : if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
625 1087 : if (!security_acl_equal(sd1->sacl, sd2->sacl)) return false;
626 1087 : if (!security_acl_equal(sd1->dacl, sd2->dacl)) return false;
627 :
628 567 : return true;
629 : }
630 :
631 : /*
632 : compare two security descriptors, but allow certain (missing) parts
633 : to be masked out of the comparison
634 : */
635 0 : bool security_descriptor_mask_equal(const struct security_descriptor *sd1,
636 : const struct security_descriptor *sd2,
637 : uint32_t mask)
638 : {
639 0 : if (sd1 == sd2) return true;
640 0 : if (!sd1 || !sd2) return false;
641 0 : if (sd1->revision != sd2->revision) return false;
642 0 : if ((sd1->type & mask) != (sd2->type & mask)) return false;
643 :
644 0 : if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
645 0 : if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
646 0 : if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return false;
647 0 : if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return false;
648 :
649 0 : return true;
650 : }
651 :
652 :
653 133 : static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd,
654 : bool add_ace_to_sacl,
655 : va_list ap)
656 : {
657 : const char *sidstr;
658 :
659 310 : while ((sidstr = va_arg(ap, const char *))) {
660 : struct dom_sid *sid;
661 177 : struct security_ace *ace = talloc_zero(sd, struct security_ace);
662 : NTSTATUS status;
663 :
664 177 : if (ace == NULL) {
665 0 : talloc_free(sd);
666 0 : return NULL;
667 : }
668 177 : ace->type = va_arg(ap, unsigned int);
669 177 : ace->access_mask = va_arg(ap, unsigned int);
670 177 : ace->flags = va_arg(ap, unsigned int);
671 177 : sid = dom_sid_parse_talloc(ace, sidstr);
672 177 : if (sid == NULL) {
673 0 : talloc_free(sd);
674 0 : return NULL;
675 : }
676 177 : ace->trustee = *sid;
677 177 : if (add_ace_to_sacl) {
678 0 : status = security_descriptor_sacl_add(sd, ace);
679 : } else {
680 177 : status = security_descriptor_dacl_add(sd, ace);
681 : }
682 : /* TODO: check: would talloc_free(ace) here be correct? */
683 177 : if (!NT_STATUS_IS_OK(status)) {
684 0 : talloc_free(sd);
685 0 : return NULL;
686 : }
687 : }
688 :
689 133 : return sd;
690 : }
691 :
692 133 : static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx,
693 : uint16_t sd_type,
694 : const char *owner_sid,
695 : const char *group_sid,
696 : bool add_ace_to_sacl,
697 : va_list ap)
698 : {
699 : struct security_descriptor *sd;
700 :
701 133 : sd = security_descriptor_initialise(mem_ctx);
702 133 : if (sd == NULL) {
703 0 : return NULL;
704 : }
705 :
706 133 : sd->type |= sd_type;
707 :
708 133 : if (owner_sid) {
709 92 : sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid);
710 92 : if (sd->owner_sid == NULL) {
711 0 : talloc_free(sd);
712 0 : return NULL;
713 : }
714 : }
715 133 : if (group_sid) {
716 9 : sd->group_sid = dom_sid_parse_talloc(sd, group_sid);
717 9 : if (sd->group_sid == NULL) {
718 0 : talloc_free(sd);
719 0 : return NULL;
720 : }
721 : }
722 :
723 133 : return security_descriptor_appendv(sd, add_ace_to_sacl, ap);
724 : }
725 :
726 : /*
727 : create a security descriptor using string SIDs. This is used by the
728 : torture code to allow the easy creation of complex ACLs
729 : This is a varargs function. The list of DACL ACEs ends with a NULL sid.
730 :
731 : Each ACE contains a set of 4 parameters:
732 : SID, ACCESS_TYPE, MASK, FLAGS
733 :
734 : a typical call would be:
735 :
736 : sd = security_descriptor_dacl_create(mem_ctx,
737 : sd_type_flags,
738 : mysid,
739 : mygroup,
740 : SID_NT_AUTHENTICATED_USERS,
741 : SEC_ACE_TYPE_ACCESS_ALLOWED,
742 : SEC_FILE_ALL,
743 : SEC_ACE_FLAG_OBJECT_INHERIT,
744 : NULL);
745 : that would create a sd with one DACL ACE
746 : */
747 :
748 133 : struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx,
749 : uint16_t sd_type,
750 : const char *owner_sid,
751 : const char *group_sid,
752 : ...)
753 : {
754 133 : struct security_descriptor *sd = NULL;
755 : va_list ap;
756 133 : va_start(ap, group_sid);
757 133 : sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
758 : group_sid, false, ap);
759 133 : va_end(ap);
760 :
761 133 : return sd;
762 : }
763 :
764 0 : struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx,
765 : uint16_t sd_type,
766 : const char *owner_sid,
767 : const char *group_sid,
768 : ...)
769 : {
770 0 : struct security_descriptor *sd = NULL;
771 : va_list ap;
772 0 : va_start(ap, group_sid);
773 0 : sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
774 : group_sid, true, ap);
775 0 : va_end(ap);
776 :
777 0 : return sd;
778 : }
779 :
780 0 : struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx,
781 : const char *sid_str,
782 : enum security_ace_type type,
783 : uint32_t access_mask,
784 : uint8_t flags)
785 :
786 : {
787 : struct security_ace *ace;
788 : bool ok;
789 :
790 0 : ace = talloc_zero(mem_ctx, struct security_ace);
791 0 : if (ace == NULL) {
792 0 : return NULL;
793 : }
794 :
795 0 : ok = dom_sid_parse(sid_str, &ace->trustee);
796 0 : if (!ok) {
797 0 : talloc_free(ace);
798 0 : return NULL;
799 : }
800 0 : ace->type = type;
801 0 : ace->access_mask = access_mask;
802 0 : ace->flags = flags;
803 :
804 0 : return ace;
805 : }
806 :
807 : /*******************************************************************
808 : Check for MS NFS ACEs in a sd
809 : *******************************************************************/
810 4764 : bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd)
811 : {
812 : uint32_t i;
813 :
814 4764 : if (psd->dacl == NULL) {
815 4 : return false;
816 : }
817 :
818 34248 : for (i = 0; i < psd->dacl->num_aces; i++) {
819 29488 : if (dom_sid_compare_domain(
820 : &global_sid_Unix_NFS,
821 29488 : &psd->dacl->aces[i].trustee) == 0) {
822 0 : return true;
823 : }
824 : }
825 :
826 4760 : return false;
827 : }
|