2 Unix SMB/CIFS implementation.
4 security descriptor utility functions
6 Copyright (C) Andrew Tridgell 2004
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.
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.
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/>.
23 #include "libcli/security/security.h"
24 #include "librpc/ndr/libndr.h"
27 return a blank security descriptor (no owners, dacl or sacl)
29 struct security_descriptor
*security_descriptor_initialise(TALLOC_CTX
*mem_ctx
)
31 struct security_descriptor
*sd
;
33 sd
= talloc(mem_ctx
, struct security_descriptor
);
37 *sd
= (struct security_descriptor
){
38 .revision
= SD_REVISION
,
41 * we mark as self relative, even though it isn't
42 * while it remains a pointer in memory because this
43 * simplifies the ndr code later. All SDs that we
44 * store/emit are in fact SELF_RELATIVE
46 .type
= SEC_DESC_SELF_RELATIVE
,
52 struct security_acl
*security_acl_dup(TALLOC_CTX
*mem_ctx
,
53 const struct security_acl
*oacl
)
55 struct security_acl
*nacl
;
61 if (oacl
->aces
== NULL
&& oacl
->num_aces
> 0) {
65 nacl
= talloc (mem_ctx
, struct security_acl
);
70 *nacl
= (struct security_acl
) {
71 .revision
= oacl
->revision
,
73 .num_aces
= oacl
->num_aces
,
75 if (nacl
->num_aces
== 0) {
79 nacl
->aces
= (struct security_ace
*)talloc_memdup (nacl
, oacl
->aces
, sizeof(struct security_ace
) * oacl
->num_aces
);
80 if (nacl
->aces
== NULL
) {
92 struct security_acl
*security_acl_concatenate(TALLOC_CTX
*mem_ctx
,
93 const struct security_acl
*acl1
,
94 const struct security_acl
*acl2
)
96 struct security_acl
*nacl
;
103 nacl
= security_acl_dup(mem_ctx
, acl2
);
108 nacl
= security_acl_dup(mem_ctx
, acl1
);
112 nacl
= talloc (mem_ctx
, struct security_acl
);
117 nacl
->revision
= acl1
->revision
;
118 nacl
->size
= acl1
->size
+ acl2
->size
;
119 nacl
->num_aces
= acl1
->num_aces
+ acl2
->num_aces
;
121 if (nacl
->num_aces
== 0)
124 nacl
->aces
= (struct security_ace
*)talloc_array (mem_ctx
, struct security_ace
, acl1
->num_aces
+acl2
->num_aces
);
125 if ((nacl
->aces
== NULL
) && (nacl
->num_aces
> 0)) {
129 for (i
= 0; i
< acl1
->num_aces
; i
++)
130 nacl
->aces
[i
] = acl1
->aces
[i
];
131 for (i
= 0; i
< acl2
->num_aces
; i
++)
132 nacl
->aces
[i
+ acl1
->num_aces
] = acl2
->aces
[i
];
143 talloc and copy a security descriptor
145 struct security_descriptor
*security_descriptor_copy(TALLOC_CTX
*mem_ctx
,
146 const struct security_descriptor
*osd
)
148 struct security_descriptor
*nsd
;
150 nsd
= talloc_zero(mem_ctx
, struct security_descriptor
);
155 if (osd
->owner_sid
) {
156 nsd
->owner_sid
= dom_sid_dup(nsd
, osd
->owner_sid
);
157 if (nsd
->owner_sid
== NULL
) {
162 if (osd
->group_sid
) {
163 nsd
->group_sid
= dom_sid_dup(nsd
, osd
->group_sid
);
164 if (nsd
->group_sid
== NULL
) {
170 nsd
->sacl
= security_acl_dup(nsd
, osd
->sacl
);
171 if (nsd
->sacl
== NULL
) {
177 nsd
->dacl
= security_acl_dup(nsd
, osd
->dacl
);
178 if (nsd
->dacl
== NULL
) {
183 nsd
->revision
= osd
->revision
;
184 nsd
->type
= osd
->type
;
194 NTSTATUS
security_descriptor_for_client(TALLOC_CTX
*mem_ctx
,
195 const struct security_descriptor
*ssd
,
197 uint32_t access_granted
,
198 struct security_descriptor
**_csd
)
200 struct security_descriptor
*csd
= NULL
;
201 uint32_t access_required
= 0;
205 if (sec_info
& (SECINFO_OWNER
|SECINFO_GROUP
)) {
206 access_required
|= SEC_STD_READ_CONTROL
;
208 if (sec_info
& SECINFO_DACL
) {
209 access_required
|= SEC_STD_READ_CONTROL
;
211 if (sec_info
& SECINFO_SACL
) {
212 access_required
|= SEC_FLAG_SYSTEM_SECURITY
;
215 if (access_required
& (~access_granted
)) {
216 return NT_STATUS_ACCESS_DENIED
;
222 csd
= security_descriptor_copy(mem_ctx
, ssd
);
224 return NT_STATUS_NO_MEMORY
;
228 * ... and remove everything not wanted
231 if (!(sec_info
& SECINFO_OWNER
)) {
232 TALLOC_FREE(csd
->owner_sid
);
233 csd
->type
&= ~SEC_DESC_OWNER_DEFAULTED
;
235 if (!(sec_info
& SECINFO_GROUP
)) {
236 TALLOC_FREE(csd
->group_sid
);
237 csd
->type
&= ~SEC_DESC_GROUP_DEFAULTED
;
239 if (!(sec_info
& SECINFO_DACL
)) {
240 TALLOC_FREE(csd
->dacl
);
242 SEC_DESC_DACL_PRESENT
|
243 SEC_DESC_DACL_DEFAULTED
|
244 SEC_DESC_DACL_AUTO_INHERIT_REQ
|
245 SEC_DESC_DACL_AUTO_INHERITED
|
246 SEC_DESC_DACL_PROTECTED
|
247 SEC_DESC_DACL_TRUSTED
);
249 if (!(sec_info
& SECINFO_SACL
)) {
250 TALLOC_FREE(csd
->sacl
);
252 SEC_DESC_SACL_PRESENT
|
253 SEC_DESC_SACL_DEFAULTED
|
254 SEC_DESC_SACL_AUTO_INHERIT_REQ
|
255 SEC_DESC_SACL_AUTO_INHERITED
|
256 SEC_DESC_SACL_PROTECTED
|
257 SEC_DESC_SERVER_SECURITY
);
265 add an ACE to an ACL of a security_descriptor
268 static NTSTATUS
security_descriptor_acl_add(struct security_descriptor
*sd
,
270 const struct security_ace
*ace
,
273 struct security_acl
*acl
= NULL
;
283 acl
= talloc(sd
, struct security_acl
);
285 return NT_STATUS_NO_MEMORY
;
287 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
294 idx
= (acl
->num_aces
+ 1) + _idx
;
300 return NT_STATUS_ARRAY_BOUNDS_EXCEEDED
;
301 } else if (idx
> acl
->num_aces
) {
302 return NT_STATUS_ARRAY_BOUNDS_EXCEEDED
;
305 acl
->aces
= talloc_realloc(acl
, acl
->aces
,
306 struct security_ace
, acl
->num_aces
+1);
307 if (acl
->aces
== NULL
) {
308 return NT_STATUS_NO_MEMORY
;
311 ARRAY_INSERT_ELEMENT(acl
->aces
, acl
->num_aces
, *ace
, idx
);
314 if (sec_ace_object(acl
->aces
[idx
].type
)) {
315 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
320 sd
->type
|= SEC_DESC_SACL_PRESENT
;
323 sd
->type
|= SEC_DESC_DACL_PRESENT
;
330 add an ACE to the SACL of a security_descriptor
333 NTSTATUS
security_descriptor_sacl_add(struct security_descriptor
*sd
,
334 const struct security_ace
*ace
)
336 return security_descriptor_acl_add(sd
, true, ace
, -1);
340 insert an ACE at a given index to the SACL of a security_descriptor
342 idx can be negative, which means it's related to the new size from the
343 end, so -1 means the ace is appended at the end.
346 NTSTATUS
security_descriptor_sacl_insert(struct security_descriptor
*sd
,
347 const struct security_ace
*ace
,
350 return security_descriptor_acl_add(sd
, true, ace
, idx
);
354 add an ACE to the DACL of a security_descriptor
357 NTSTATUS
security_descriptor_dacl_add(struct security_descriptor
*sd
,
358 const struct security_ace
*ace
)
360 return security_descriptor_acl_add(sd
, false, ace
, -1);
364 insert an ACE at a given index to the DACL of a security_descriptor
366 idx can be negative, which means it's related to the new size from the
367 end, so -1 means the ace is appended at the end.
370 NTSTATUS
security_descriptor_dacl_insert(struct security_descriptor
*sd
,
371 const struct security_ace
*ace
,
374 return security_descriptor_acl_add(sd
, false, ace
, idx
);
378 delete the ACE corresponding to the given trustee in an ACL of a
382 static NTSTATUS
security_descriptor_acl_del(struct security_descriptor
*sd
,
384 const struct dom_sid
*trustee
)
388 struct security_acl
*acl
= NULL
;
397 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
400 /* there can be multiple ace's for one trustee */
404 while (i
<acl
->num_aces
) {
405 if (dom_sid_equal(trustee
, &acl
->aces
[i
].trustee
)) {
406 ARRAY_DEL_ELEMENT(acl
->aces
, i
, acl
->num_aces
);
408 if (acl
->num_aces
== 0) {
418 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
421 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
423 for (i
=0;i
<acl
->num_aces
;i
++) {
424 if (sec_ace_object(acl
->aces
[i
].type
)) {
425 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
434 delete the ACE corresponding to the given trustee in the DACL of a
438 NTSTATUS
security_descriptor_dacl_del(struct security_descriptor
*sd
,
439 const struct dom_sid
*trustee
)
441 return security_descriptor_acl_del(sd
, false, trustee
);
445 delete the ACE corresponding to the given trustee in the SACL of a
449 NTSTATUS
security_descriptor_sacl_del(struct security_descriptor
*sd
,
450 const struct dom_sid
*trustee
)
452 return security_descriptor_acl_del(sd
, true, trustee
);
456 delete the given ACE in the SACL or DACL of a security_descriptor
458 static NTSTATUS
security_descriptor_acl_del_ace(struct security_descriptor
*sd
,
460 const struct security_ace
*ace
)
464 struct security_acl
*acl
= NULL
;
473 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
476 for (i
=0;i
<acl
->num_aces
;i
++) {
477 if (security_ace_equal(ace
, &acl
->aces
[i
])) {
478 ARRAY_DEL_ELEMENT(acl
->aces
, i
, acl
->num_aces
);
480 if (acl
->num_aces
== 0) {
489 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
492 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
494 for (i
=0;i
<acl
->num_aces
;i
++) {
495 if (sec_ace_object(acl
->aces
[i
].type
)) {
496 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
504 NTSTATUS
security_descriptor_dacl_del_ace(struct security_descriptor
*sd
,
505 const struct security_ace
*ace
)
507 return security_descriptor_acl_del_ace(sd
, false, ace
);
510 NTSTATUS
security_descriptor_sacl_del_ace(struct security_descriptor
*sd
,
511 const struct security_ace
*ace
)
513 return security_descriptor_acl_del_ace(sd
, true, ace
);
516 static bool security_ace_object_equal(const struct security_ace_object
*object1
,
517 const struct security_ace_object
*object2
)
519 if (object1
== object2
) {
522 if ((object1
== NULL
) || (object2
== NULL
)) {
525 if (object1
->flags
!= object2
->flags
) {
528 if (object1
->flags
& SEC_ACE_OBJECT_TYPE_PRESENT
529 && !GUID_equal(&object1
->type
.type
, &object2
->type
.type
)) {
532 if (object1
->flags
& SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
533 && !GUID_equal(&object1
->inherited_type
.inherited_type
,
534 &object2
->inherited_type
.inherited_type
)) {
542 static bool security_ace_claim_equal(const struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1
*claim1
,
543 const struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1
*claim2
)
547 if (claim1
== claim2
) {
550 if (claim1
== NULL
|| claim2
== NULL
) {
553 if (claim1
->name
!= NULL
&& claim2
->name
!= NULL
) {
554 if (strcasecmp_m(claim1
->name
, claim2
->name
) != 0) {
557 } else if (claim1
->name
!= NULL
|| claim2
->name
!= NULL
) {
560 if (claim1
->value_type
!= claim2
->value_type
) {
563 if (claim1
->flags
!= claim2
->flags
) {
566 if (claim1
->value_count
!= claim2
->value_count
) {
569 for (i
= 0; i
< claim1
->value_count
; ++i
) {
570 const union claim_values
*values1
= claim1
->values
;
571 const union claim_values
*values2
= claim2
->values
;
573 switch (claim1
->value_type
) {
574 case CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64
:
575 if (values1
[i
].int_value
!= NULL
&& values2
[i
].int_value
!= NULL
) {
576 if (*values1
[i
].int_value
!= *values2
[i
].int_value
) {
579 } else if (values1
[i
].int_value
!= NULL
|| values2
[i
].int_value
!= NULL
) {
583 case CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64
:
584 case CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN
:
585 if (values1
[i
].uint_value
!= NULL
&& values2
[i
].uint_value
!= NULL
) {
586 if (*values1
[i
].uint_value
!= *values2
[i
].uint_value
) {
589 } else if (values1
[i
].uint_value
!= NULL
|| values2
[i
].uint_value
!= NULL
) {
593 case CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING
:
594 if (values1
[i
].string_value
!= NULL
&& values2
[i
].string_value
!= NULL
) {
595 if (strcasecmp_m(values1
[i
].string_value
, values2
[i
].string_value
) != 0) {
598 } else if (values1
[i
].string_value
!= NULL
|| values2
[i
].string_value
!= NULL
) {
602 case CLAIM_SECURITY_ATTRIBUTE_TYPE_SID
:
603 if (values1
[i
].sid_value
!= NULL
&& values2
[i
].sid_value
!= NULL
) {
604 if (data_blob_cmp(values1
[i
].sid_value
, values2
[i
].sid_value
) != 0) {
607 } else if (values1
[i
].sid_value
!= NULL
|| values2
[i
].sid_value
!= NULL
) {
611 case CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING
:
612 if (values1
[i
].octet_value
!= NULL
&& values2
[i
].octet_value
!= NULL
) {
613 if (data_blob_cmp(values1
[i
].octet_value
, values2
[i
].octet_value
) != 0) {
616 } else if (values1
[i
].octet_value
!= NULL
|| values2
[i
].octet_value
!= NULL
) {
629 compare two security ace structures
631 bool security_ace_equal(const struct security_ace
*ace1
,
632 const struct security_ace
*ace2
)
637 if ((ace1
== NULL
) || (ace2
== NULL
)) {
640 if (ace1
->type
!= ace2
->type
) {
643 if (ace1
->flags
!= ace2
->flags
) {
646 if (ace1
->access_mask
!= ace2
->access_mask
) {
649 if (sec_ace_object(ace1
->type
) &&
650 !security_ace_object_equal(&ace1
->object
.object
,
651 &ace2
->object
.object
))
655 if (!dom_sid_equal(&ace1
->trustee
, &ace2
->trustee
)) {
659 if (sec_ace_callback(ace1
->type
)) {
660 if (data_blob_cmp(&ace1
->coda
.conditions
, &ace2
->coda
.conditions
) != 0) {
663 } else if (sec_ace_resource(ace1
->type
)) {
664 if (!security_ace_claim_equal(&ace1
->coda
.claim
, &ace2
->coda
.claim
)) {
669 * Don’t require ace1->coda.ignored to match ace2->coda.ignored.
678 compare two security acl structures
680 bool security_acl_equal(const struct security_acl
*acl1
,
681 const struct security_acl
*acl2
)
685 if (acl1
== acl2
) return true;
686 if (!acl1
|| !acl2
) return false;
687 if (acl1
->revision
!= acl2
->revision
) return false;
688 if (acl1
->num_aces
!= acl2
->num_aces
) return false;
690 for (i
=0;i
<acl1
->num_aces
;i
++) {
691 if (!security_ace_equal(&acl1
->aces
[i
], &acl2
->aces
[i
])) return false;
697 compare two security descriptors.
699 bool security_descriptor_equal(const struct security_descriptor
*sd1
,
700 const struct security_descriptor
*sd2
)
702 if (sd1
== sd2
) return true;
703 if (!sd1
|| !sd2
) return false;
704 if (sd1
->revision
!= sd2
->revision
) return false;
705 if (sd1
->type
!= sd2
->type
) return false;
707 if (!dom_sid_equal(sd1
->owner_sid
, sd2
->owner_sid
)) return false;
708 if (!dom_sid_equal(sd1
->group_sid
, sd2
->group_sid
)) return false;
709 if (!security_acl_equal(sd1
->sacl
, sd2
->sacl
)) return false;
710 if (!security_acl_equal(sd1
->dacl
, sd2
->dacl
)) return false;
716 compare two security descriptors, but allow certain (missing) parts
717 to be masked out of the comparison
719 bool security_descriptor_mask_equal(const struct security_descriptor
*sd1
,
720 const struct security_descriptor
*sd2
,
723 if (sd1
== sd2
) return true;
724 if (!sd1
|| !sd2
) return false;
725 if (sd1
->revision
!= sd2
->revision
) return false;
726 if ((sd1
->type
& mask
) != (sd2
->type
& mask
)) return false;
728 if (!dom_sid_equal(sd1
->owner_sid
, sd2
->owner_sid
)) return false;
729 if (!dom_sid_equal(sd1
->group_sid
, sd2
->group_sid
)) return false;
730 if ((mask
& SEC_DESC_DACL_PRESENT
) && !security_acl_equal(sd1
->dacl
, sd2
->dacl
)) return false;
731 if ((mask
& SEC_DESC_SACL_PRESENT
) && !security_acl_equal(sd1
->sacl
, sd2
->sacl
)) return false;
737 static struct security_descriptor
*security_descriptor_appendv(struct security_descriptor
*sd
,
738 bool add_ace_to_sacl
,
743 while ((sidstr
= va_arg(ap
, const char *))) {
745 struct security_ace
*ace
= talloc_zero(sd
, struct security_ace
);
752 ace
->type
= va_arg(ap
, unsigned int);
753 ace
->access_mask
= va_arg(ap
, unsigned int);
754 ace
->flags
= va_arg(ap
, unsigned int);
755 sid
= dom_sid_parse_talloc(ace
, sidstr
);
761 if (add_ace_to_sacl
) {
762 status
= security_descriptor_sacl_add(sd
, ace
);
764 status
= security_descriptor_dacl_add(sd
, ace
);
766 /* TODO: check: would talloc_free(ace) here be correct? */
767 if (!NT_STATUS_IS_OK(status
)) {
776 static struct security_descriptor
*security_descriptor_createv(TALLOC_CTX
*mem_ctx
,
778 const char *owner_sid
,
779 const char *group_sid
,
780 bool add_ace_to_sacl
,
783 struct security_descriptor
*sd
;
785 sd
= security_descriptor_initialise(mem_ctx
);
793 sd
->owner_sid
= dom_sid_parse_talloc(sd
, owner_sid
);
794 if (sd
->owner_sid
== NULL
) {
800 sd
->group_sid
= dom_sid_parse_talloc(sd
, group_sid
);
801 if (sd
->group_sid
== NULL
) {
807 return security_descriptor_appendv(sd
, add_ace_to_sacl
, ap
);
811 create a security descriptor using string SIDs. This is used by the
812 torture code to allow the easy creation of complex ACLs
813 This is a varargs function. The list of DACL ACEs ends with a NULL sid.
815 Each ACE contains a set of 4 parameters:
816 SID, ACCESS_TYPE, MASK, FLAGS
818 a typical call would be:
820 sd = security_descriptor_dacl_create(mem_ctx,
824 SID_NT_AUTHENTICATED_USERS,
825 SEC_ACE_TYPE_ACCESS_ALLOWED,
827 SEC_ACE_FLAG_OBJECT_INHERIT,
829 that would create a sd with one DACL ACE
832 struct security_descriptor
*security_descriptor_dacl_create(TALLOC_CTX
*mem_ctx
,
834 const char *owner_sid
,
835 const char *group_sid
,
838 struct security_descriptor
*sd
= NULL
;
840 va_start(ap
, group_sid
);
841 sd
= security_descriptor_createv(mem_ctx
, sd_type
, owner_sid
,
842 group_sid
, false, ap
);
848 struct security_descriptor
*security_descriptor_sacl_create(TALLOC_CTX
*mem_ctx
,
850 const char *owner_sid
,
851 const char *group_sid
,
854 struct security_descriptor
*sd
= NULL
;
856 va_start(ap
, group_sid
);
857 sd
= security_descriptor_createv(mem_ctx
, sd_type
, owner_sid
,
858 group_sid
, true, ap
);
864 struct security_ace
*security_ace_create(TALLOC_CTX
*mem_ctx
,
866 enum security_ace_type type
,
867 uint32_t access_mask
,
871 struct security_ace
*ace
;
874 ace
= talloc_zero(mem_ctx
, struct security_ace
);
879 ok
= dom_sid_parse(sid_str
, &ace
->trustee
);
885 ace
->access_mask
= access_mask
;
891 /*******************************************************************
892 Check for MS NFS ACEs in a sd
893 *******************************************************************/
894 bool security_descriptor_with_ms_nfs(const struct security_descriptor
*psd
)
898 if (psd
->dacl
== NULL
) {
902 for (i
= 0; i
< psd
->dacl
->num_aces
; i
++) {
903 if (dom_sid_compare_domain(
904 &global_sid_Unix_NFS
,
905 &psd
->dacl
->aces
[i
].trustee
) == 0) {