2 Unix SMB/CIFS implementation.
4 security descriptror 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"
26 return a blank security descriptor (no owners, dacl or sacl)
28 struct security_descriptor
*security_descriptor_initialise(TALLOC_CTX
*mem_ctx
)
30 struct security_descriptor
*sd
;
32 sd
= talloc(mem_ctx
, struct security_descriptor
);
37 sd
->revision
= SD_REVISION
;
38 /* we mark as self relative, even though it isn't while it remains
39 a pointer in memory because this simplifies the ndr code later.
40 All SDs that we store/emit are in fact SELF_RELATIVE
42 sd
->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 nacl
= talloc (mem_ctx
, struct security_acl
);
66 nacl
->aces
= (struct security_ace
*)talloc_memdup (nacl
, oacl
->aces
, sizeof(struct security_ace
) * oacl
->num_aces
);
67 if ((nacl
->aces
== NULL
) && (oacl
->num_aces
> 0)) {
71 nacl
->revision
= oacl
->revision
;
72 nacl
->size
= oacl
->size
;
73 nacl
->num_aces
= oacl
->num_aces
;
83 struct security_acl
*security_acl_concatenate(TALLOC_CTX
*mem_ctx
,
84 const struct security_acl
*acl1
,
85 const struct security_acl
*acl2
)
87 struct security_acl
*nacl
;
94 nacl
= security_acl_dup(mem_ctx
, acl2
);
99 nacl
= security_acl_dup(mem_ctx
, acl1
);
103 nacl
= talloc (mem_ctx
, struct security_acl
);
108 nacl
->revision
= acl1
->revision
;
109 nacl
->size
= acl1
->size
+ acl2
->size
;
110 nacl
->num_aces
= acl1
->num_aces
+ acl2
->num_aces
;
112 if (nacl
->num_aces
== 0)
115 nacl
->aces
= (struct security_ace
*)talloc_array (mem_ctx
, struct security_ace
, acl1
->num_aces
+acl2
->num_aces
);
116 if ((nacl
->aces
== NULL
) && (nacl
->num_aces
> 0)) {
120 for (i
= 0; i
< acl1
->num_aces
; i
++)
121 nacl
->aces
[i
] = acl1
->aces
[i
];
122 for (i
= 0; i
< acl2
->num_aces
; i
++)
123 nacl
->aces
[i
+ acl1
->num_aces
] = acl2
->aces
[i
];
134 talloc and copy a security descriptor
136 struct security_descriptor
*security_descriptor_copy(TALLOC_CTX
*mem_ctx
,
137 const struct security_descriptor
*osd
)
139 struct security_descriptor
*nsd
;
141 nsd
= talloc_zero(mem_ctx
, struct security_descriptor
);
146 if (osd
->owner_sid
) {
147 nsd
->owner_sid
= dom_sid_dup(nsd
, osd
->owner_sid
);
148 if (nsd
->owner_sid
== NULL
) {
153 if (osd
->group_sid
) {
154 nsd
->group_sid
= dom_sid_dup(nsd
, osd
->group_sid
);
155 if (nsd
->group_sid
== NULL
) {
161 nsd
->sacl
= security_acl_dup(nsd
, osd
->sacl
);
162 if (nsd
->sacl
== NULL
) {
168 nsd
->dacl
= security_acl_dup(nsd
, osd
->dacl
);
169 if (nsd
->dacl
== NULL
) {
174 nsd
->revision
= osd
->revision
;
175 nsd
->type
= osd
->type
;
185 NTSTATUS
security_descriptor_for_client(TALLOC_CTX
*mem_ctx
,
186 const struct security_descriptor
*ssd
,
188 uint32_t access_granted
,
189 struct security_descriptor
**_csd
)
191 struct security_descriptor
*csd
= NULL
;
192 uint32_t access_required
= 0;
196 if (sec_info
& (SECINFO_OWNER
|SECINFO_GROUP
)) {
197 access_required
|= SEC_STD_READ_CONTROL
;
199 if (sec_info
& SECINFO_DACL
) {
200 access_required
|= SEC_STD_READ_CONTROL
;
202 if (sec_info
& SECINFO_SACL
) {
203 access_required
|= SEC_FLAG_SYSTEM_SECURITY
;
206 if (access_required
& (~access_granted
)) {
207 return NT_STATUS_ACCESS_DENIED
;
213 csd
= security_descriptor_copy(mem_ctx
, ssd
);
215 return NT_STATUS_NO_MEMORY
;
219 * ... and remove everthing not wanted
222 if (!(sec_info
& SECINFO_OWNER
)) {
223 TALLOC_FREE(csd
->owner_sid
);
224 csd
->type
&= ~SEC_DESC_OWNER_DEFAULTED
;
226 if (!(sec_info
& SECINFO_GROUP
)) {
227 TALLOC_FREE(csd
->group_sid
);
228 csd
->type
&= ~SEC_DESC_GROUP_DEFAULTED
;
230 if (!(sec_info
& SECINFO_DACL
)) {
231 TALLOC_FREE(csd
->dacl
);
233 SEC_DESC_DACL_PRESENT
|
234 SEC_DESC_DACL_DEFAULTED
|
235 SEC_DESC_DACL_AUTO_INHERIT_REQ
|
236 SEC_DESC_DACL_AUTO_INHERITED
|
237 SEC_DESC_DACL_PROTECTED
|
238 SEC_DESC_DACL_TRUSTED
);
240 if (!(sec_info
& SECINFO_SACL
)) {
241 TALLOC_FREE(csd
->sacl
);
243 SEC_DESC_SACL_PRESENT
|
244 SEC_DESC_SACL_DEFAULTED
|
245 SEC_DESC_SACL_AUTO_INHERIT_REQ
|
246 SEC_DESC_SACL_AUTO_INHERITED
|
247 SEC_DESC_SACL_PROTECTED
|
248 SEC_DESC_SERVER_SECURITY
);
256 add an ACE to an ACL of a security_descriptor
259 static NTSTATUS
security_descriptor_acl_add(struct security_descriptor
*sd
,
261 const struct security_ace
*ace
)
263 struct security_acl
*acl
= NULL
;
272 acl
= talloc(sd
, struct security_acl
);
274 return NT_STATUS_NO_MEMORY
;
276 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
282 acl
->aces
= talloc_realloc(acl
, acl
->aces
,
283 struct security_ace
, acl
->num_aces
+1);
284 if (acl
->aces
== NULL
) {
285 return NT_STATUS_NO_MEMORY
;
288 acl
->aces
[acl
->num_aces
] = *ace
;
290 switch (acl
->aces
[acl
->num_aces
].type
) {
291 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
:
292 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
:
293 case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
:
294 case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT
:
295 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
305 sd
->type
|= SEC_DESC_SACL_PRESENT
;
308 sd
->type
|= SEC_DESC_DACL_PRESENT
;
315 add an ACE to the SACL of a security_descriptor
318 NTSTATUS
security_descriptor_sacl_add(struct security_descriptor
*sd
,
319 const struct security_ace
*ace
)
321 return security_descriptor_acl_add(sd
, true, ace
);
325 add an ACE to the DACL of a security_descriptor
328 NTSTATUS
security_descriptor_dacl_add(struct security_descriptor
*sd
,
329 const struct security_ace
*ace
)
331 return security_descriptor_acl_add(sd
, false, ace
);
335 delete the ACE corresponding to the given trustee in an ACL of a
339 static NTSTATUS
security_descriptor_acl_del(struct security_descriptor
*sd
,
341 const struct dom_sid
*trustee
)
345 struct security_acl
*acl
= NULL
;
354 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
357 /* there can be multiple ace's for one trustee */
358 for (i
=0;i
<acl
->num_aces
;i
++) {
359 if (dom_sid_equal(trustee
, &acl
->aces
[i
].trustee
)) {
360 memmove(&acl
->aces
[i
], &acl
->aces
[i
+1],
361 sizeof(acl
->aces
[i
]) * (acl
->num_aces
- (i
+1)));
363 if (acl
->num_aces
== 0) {
371 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
374 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
376 for (i
=0;i
<acl
->num_aces
;i
++) {
377 switch (acl
->aces
[i
].type
) {
378 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
:
379 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
:
380 case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
:
381 case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT
:
382 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
385 break; /* only for the switch statement */
393 delete the ACE corresponding to the given trustee in the DACL of a
397 NTSTATUS
security_descriptor_dacl_del(struct security_descriptor
*sd
,
398 const struct dom_sid
*trustee
)
400 return security_descriptor_acl_del(sd
, false, trustee
);
404 delete the ACE corresponding to the given trustee in the SACL of a
408 NTSTATUS
security_descriptor_sacl_del(struct security_descriptor
*sd
,
409 const struct dom_sid
*trustee
)
411 return security_descriptor_acl_del(sd
, true, trustee
);
415 compare two security ace structures
417 bool security_ace_equal(const struct security_ace
*ace1
,
418 const struct security_ace
*ace2
)
423 if ((ace1
== NULL
) || (ace2
== NULL
)) {
426 if (ace1
->type
!= ace2
->type
) {
429 if (ace1
->flags
!= ace2
->flags
) {
432 if (ace1
->access_mask
!= ace2
->access_mask
) {
435 if (!dom_sid_equal(&ace1
->trustee
, &ace2
->trustee
)) {
444 compare two security acl structures
446 bool security_acl_equal(const struct security_acl
*acl1
,
447 const struct security_acl
*acl2
)
451 if (acl1
== acl2
) return true;
452 if (!acl1
|| !acl2
) return false;
453 if (acl1
->revision
!= acl2
->revision
) return false;
454 if (acl1
->num_aces
!= acl2
->num_aces
) return false;
456 for (i
=0;i
<acl1
->num_aces
;i
++) {
457 if (!security_ace_equal(&acl1
->aces
[i
], &acl2
->aces
[i
])) return false;
463 compare two security descriptors.
465 bool security_descriptor_equal(const struct security_descriptor
*sd1
,
466 const struct security_descriptor
*sd2
)
468 if (sd1
== sd2
) return true;
469 if (!sd1
|| !sd2
) return false;
470 if (sd1
->revision
!= sd2
->revision
) return false;
471 if (sd1
->type
!= sd2
->type
) return false;
473 if (!dom_sid_equal(sd1
->owner_sid
, sd2
->owner_sid
)) return false;
474 if (!dom_sid_equal(sd1
->group_sid
, sd2
->group_sid
)) return false;
475 if (!security_acl_equal(sd1
->sacl
, sd2
->sacl
)) return false;
476 if (!security_acl_equal(sd1
->dacl
, sd2
->dacl
)) return false;
482 compare two security descriptors, but allow certain (missing) parts
483 to be masked out of the comparison
485 bool security_descriptor_mask_equal(const struct security_descriptor
*sd1
,
486 const struct security_descriptor
*sd2
,
489 if (sd1
== sd2
) return true;
490 if (!sd1
|| !sd2
) return false;
491 if (sd1
->revision
!= sd2
->revision
) return false;
492 if ((sd1
->type
& mask
) != (sd2
->type
& mask
)) return false;
494 if (!dom_sid_equal(sd1
->owner_sid
, sd2
->owner_sid
)) return false;
495 if (!dom_sid_equal(sd1
->group_sid
, sd2
->group_sid
)) return false;
496 if ((mask
& SEC_DESC_DACL_PRESENT
) && !security_acl_equal(sd1
->dacl
, sd2
->dacl
)) return false;
497 if ((mask
& SEC_DESC_SACL_PRESENT
) && !security_acl_equal(sd1
->sacl
, sd2
->sacl
)) return false;
503 static struct security_descriptor
*security_descriptor_appendv(struct security_descriptor
*sd
,
504 bool add_ace_to_sacl
,
509 while ((sidstr
= va_arg(ap
, const char *))) {
511 struct security_ace
*ace
= talloc_zero(sd
, struct security_ace
);
518 ace
->type
= va_arg(ap
, unsigned int);
519 ace
->access_mask
= va_arg(ap
, unsigned int);
520 ace
->flags
= va_arg(ap
, unsigned int);
521 sid
= dom_sid_parse_talloc(ace
, sidstr
);
527 if (add_ace_to_sacl
) {
528 status
= security_descriptor_sacl_add(sd
, ace
);
530 status
= security_descriptor_dacl_add(sd
, ace
);
532 /* TODO: check: would talloc_free(ace) here be correct? */
533 if (!NT_STATUS_IS_OK(status
)) {
542 struct security_descriptor
*security_descriptor_append(struct security_descriptor
*sd
,
548 sd
= security_descriptor_appendv(sd
, false, ap
);
554 static struct security_descriptor
*security_descriptor_createv(TALLOC_CTX
*mem_ctx
,
556 const char *owner_sid
,
557 const char *group_sid
,
558 bool add_ace_to_sacl
,
561 struct security_descriptor
*sd
;
563 sd
= security_descriptor_initialise(mem_ctx
);
571 sd
->owner_sid
= dom_sid_parse_talloc(sd
, owner_sid
);
572 if (sd
->owner_sid
== NULL
) {
578 sd
->group_sid
= dom_sid_parse_talloc(sd
, group_sid
);
579 if (sd
->group_sid
== NULL
) {
585 return security_descriptor_appendv(sd
, add_ace_to_sacl
, ap
);
589 create a security descriptor using string SIDs. This is used by the
590 torture code to allow the easy creation of complex ACLs
591 This is a varargs function. The list of DACL ACEs ends with a NULL sid.
593 Each ACE contains a set of 4 parameters:
594 SID, ACCESS_TYPE, MASK, FLAGS
596 a typical call would be:
598 sd = security_descriptor_dacl_create(mem_ctx,
602 SID_NT_AUTHENTICATED_USERS,
603 SEC_ACE_TYPE_ACCESS_ALLOWED,
605 SEC_ACE_FLAG_OBJECT_INHERIT,
607 that would create a sd with one DACL ACE
610 struct security_descriptor
*security_descriptor_dacl_create(TALLOC_CTX
*mem_ctx
,
612 const char *owner_sid
,
613 const char *group_sid
,
616 struct security_descriptor
*sd
= NULL
;
618 va_start(ap
, group_sid
);
619 sd
= security_descriptor_createv(mem_ctx
, sd_type
, owner_sid
,
620 group_sid
, false, ap
);
626 struct security_descriptor
*security_descriptor_sacl_create(TALLOC_CTX
*mem_ctx
,
628 const char *owner_sid
,
629 const char *group_sid
,
632 struct security_descriptor
*sd
= NULL
;
634 va_start(ap
, group_sid
);
635 sd
= security_descriptor_createv(mem_ctx
, sd_type
, owner_sid
,
636 group_sid
, true, ap
);
642 struct security_ace
*security_ace_create(TALLOC_CTX
*mem_ctx
,
644 enum security_ace_type type
,
645 uint32_t access_mask
,
649 struct security_ace
*ace
;
652 ace
= talloc_zero(mem_ctx
, struct security_ace
);
657 ok
= dom_sid_parse(sid_str
, &ace
->trustee
);
663 ace
->access_mask
= access_mask
;
669 /*******************************************************************
670 Check for MS NFS ACEs in a sd
671 *******************************************************************/
672 bool security_descriptor_with_ms_nfs(const struct security_descriptor
*psd
)
676 if (psd
->dacl
== NULL
) {
680 for (i
= 0; i
< psd
->dacl
->num_aces
; i
++) {
681 if (dom_sid_compare_domain(
682 &global_sid_Unix_NFS
,
683 &psd
->dacl
->aces
[i
].trustee
) == 0) {