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_descriptor.h"
24 #include "libcli/security/dom_sid.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
);
38 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
43 sd
->type
= SEC_DESC_SELF_RELATIVE
;
53 struct security_acl
*security_acl_dup(TALLOC_CTX
*mem_ctx
,
54 const struct security_acl
*oacl
)
56 struct security_acl
*nacl
;
58 nacl
= talloc (mem_ctx
, struct security_acl
);
63 nacl
->aces
= (struct security_ace
*)talloc_memdup (nacl
, oacl
->aces
, sizeof(struct security_ace
) * oacl
->num_aces
);
64 if ((nacl
->aces
== NULL
) && (oacl
->num_aces
> 0)) {
68 nacl
->revision
= oacl
->revision
;
69 nacl
->size
= oacl
->size
;
70 nacl
->num_aces
= oacl
->num_aces
;
80 struct security_acl
*security_acl_concatenate(TALLOC_CTX
*mem_ctx
,
81 const struct security_acl
*acl1
,
82 const struct security_acl
*acl2
)
84 struct security_acl
*nacl
;
91 nacl
= security_acl_dup(mem_ctx
, acl2
);
96 nacl
= security_acl_dup(mem_ctx
, acl1
);
100 nacl
= talloc (mem_ctx
, struct security_acl
);
105 nacl
->revision
= acl1
->revision
;
106 nacl
->size
= acl1
->size
+ acl2
->size
;
107 nacl
->num_aces
= acl1
->num_aces
+ acl2
->num_aces
;
109 if (nacl
->num_aces
== 0)
112 nacl
->aces
= (struct security_ace
*)talloc_array (mem_ctx
, struct security_ace
, acl1
->num_aces
+acl2
->num_aces
);
113 if ((nacl
->aces
== NULL
) && (nacl
->num_aces
> 0)) {
117 for (i
= 0; i
< acl1
->num_aces
; i
++)
118 nacl
->aces
[i
] = acl1
->aces
[i
];
119 for (i
= 0; i
< acl2
->num_aces
; i
++)
120 nacl
->aces
[i
+ acl1
->num_aces
] = acl2
->aces
[i
];
131 talloc and copy a security descriptor
133 struct security_descriptor
*security_descriptor_copy(TALLOC_CTX
*mem_ctx
,
134 const struct security_descriptor
*osd
)
136 struct security_descriptor
*nsd
;
138 nsd
= talloc_zero(mem_ctx
, struct security_descriptor
);
143 if (osd
->owner_sid
) {
144 nsd
->owner_sid
= dom_sid_dup(nsd
, osd
->owner_sid
);
145 if (nsd
->owner_sid
== NULL
) {
150 if (osd
->group_sid
) {
151 nsd
->group_sid
= dom_sid_dup(nsd
, osd
->group_sid
);
152 if (nsd
->group_sid
== NULL
) {
158 nsd
->sacl
= security_acl_dup(nsd
, osd
->sacl
);
159 if (nsd
->sacl
== NULL
) {
165 nsd
->dacl
= security_acl_dup(nsd
, osd
->dacl
);
166 if (nsd
->dacl
== NULL
) {
171 nsd
->revision
= osd
->revision
;
172 nsd
->type
= osd
->type
;
183 add an ACE to an ACL of a security_descriptor
186 static NTSTATUS
security_descriptor_acl_add(struct security_descriptor
*sd
,
188 const struct security_ace
*ace
)
190 struct security_acl
*acl
= NULL
;
199 acl
= talloc(sd
, struct security_acl
);
201 return NT_STATUS_NO_MEMORY
;
203 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
209 acl
->aces
= talloc_realloc(acl
, acl
->aces
,
210 struct security_ace
, acl
->num_aces
+1);
211 if (acl
->aces
== NULL
) {
212 return NT_STATUS_NO_MEMORY
;
215 acl
->aces
[acl
->num_aces
] = *ace
;
217 switch (acl
->aces
[acl
->num_aces
].type
) {
218 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
:
219 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
:
220 case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
:
221 case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT
:
222 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
232 sd
->type
|= SEC_DESC_SACL_PRESENT
;
235 sd
->type
|= SEC_DESC_DACL_PRESENT
;
242 add an ACE to the SACL of a security_descriptor
245 NTSTATUS
security_descriptor_sacl_add(struct security_descriptor
*sd
,
246 const struct security_ace
*ace
)
248 return security_descriptor_acl_add(sd
, true, ace
);
252 add an ACE to the DACL of a security_descriptor
255 NTSTATUS
security_descriptor_dacl_add(struct security_descriptor
*sd
,
256 const struct security_ace
*ace
)
258 return security_descriptor_acl_add(sd
, false, ace
);
262 delete the ACE corresponding to the given trustee in an ACL of a
266 static NTSTATUS
security_descriptor_acl_del(struct security_descriptor
*sd
,
268 const struct dom_sid
*trustee
)
272 struct security_acl
*acl
= NULL
;
281 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
284 /* there can be multiple ace's for one trustee */
285 for (i
=0;i
<acl
->num_aces
;i
++) {
286 if (dom_sid_equal(trustee
, &acl
->aces
[i
].trustee
)) {
287 memmove(&acl
->aces
[i
], &acl
->aces
[i
+1],
288 sizeof(acl
->aces
[i
]) * (acl
->num_aces
- (i
+1)));
290 if (acl
->num_aces
== 0) {
298 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
301 acl
->revision
= SECURITY_ACL_REVISION_NT4
;
303 for (i
=0;i
<acl
->num_aces
;i
++) {
304 switch (acl
->aces
[i
].type
) {
305 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
:
306 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
:
307 case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
:
308 case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT
:
309 acl
->revision
= SECURITY_ACL_REVISION_ADS
;
312 break; /* only for the switch statement */
320 delete the ACE corresponding to the given trustee in the DACL of a
324 NTSTATUS
security_descriptor_dacl_del(struct security_descriptor
*sd
,
325 const struct dom_sid
*trustee
)
327 return security_descriptor_acl_del(sd
, false, trustee
);
331 delete the ACE corresponding to the given trustee in the SACL of a
335 NTSTATUS
security_descriptor_sacl_del(struct security_descriptor
*sd
,
336 const struct dom_sid
*trustee
)
338 return security_descriptor_acl_del(sd
, true, trustee
);
342 compare two security ace structures
344 bool security_ace_equal(const struct security_ace
*ace1
,
345 const struct security_ace
*ace2
)
347 if (ace1
== ace2
) return true;
348 if (!ace1
|| !ace2
) return false;
349 if (ace1
->type
!= ace2
->type
) return false;
350 if (ace1
->flags
!= ace2
->flags
) return false;
351 if (ace1
->access_mask
!= ace2
->access_mask
) return false;
352 if (!dom_sid_equal(&ace1
->trustee
, &ace2
->trustee
)) return false;
359 compare two security acl structures
361 bool security_acl_equal(const struct security_acl
*acl1
,
362 const struct security_acl
*acl2
)
366 if (acl1
== acl2
) return true;
367 if (!acl1
|| !acl2
) return false;
368 if (acl1
->revision
!= acl2
->revision
) return false;
369 if (acl1
->num_aces
!= acl2
->num_aces
) return false;
371 for (i
=0;i
<acl1
->num_aces
;i
++) {
372 if (!security_ace_equal(&acl1
->aces
[i
], &acl2
->aces
[i
])) return false;
378 compare two security descriptors.
380 bool security_descriptor_equal(const struct security_descriptor
*sd1
,
381 const struct security_descriptor
*sd2
)
383 if (sd1
== sd2
) return true;
384 if (!sd1
|| !sd2
) return false;
385 if (sd1
->revision
!= sd2
->revision
) return false;
386 if (sd1
->type
!= sd2
->type
) return false;
388 if (!dom_sid_equal(sd1
->owner_sid
, sd2
->owner_sid
)) return false;
389 if (!dom_sid_equal(sd1
->group_sid
, sd2
->group_sid
)) return false;
390 if (!security_acl_equal(sd1
->sacl
, sd2
->sacl
)) return false;
391 if (!security_acl_equal(sd1
->dacl
, sd2
->dacl
)) return false;
397 compare two security descriptors, but allow certain (missing) parts
398 to be masked out of the comparison
400 bool security_descriptor_mask_equal(const struct security_descriptor
*sd1
,
401 const struct security_descriptor
*sd2
,
404 if (sd1
== sd2
) return true;
405 if (!sd1
|| !sd2
) return false;
406 if (sd1
->revision
!= sd2
->revision
) return false;
407 if ((sd1
->type
& mask
) != (sd2
->type
& mask
)) return false;
409 if (!dom_sid_equal(sd1
->owner_sid
, sd2
->owner_sid
)) return false;
410 if (!dom_sid_equal(sd1
->group_sid
, sd2
->group_sid
)) return false;
411 if ((mask
& SEC_DESC_DACL_PRESENT
) && !security_acl_equal(sd1
->dacl
, sd2
->dacl
)) return false;
412 if ((mask
& SEC_DESC_SACL_PRESENT
) && !security_acl_equal(sd1
->sacl
, sd2
->sacl
)) return false;
418 static struct security_descriptor
*security_descriptor_appendv(struct security_descriptor
*sd
,
419 bool add_ace_to_sacl
,
424 while ((sidstr
= va_arg(ap
, const char *))) {
426 struct security_ace
*ace
= talloc_zero(sd
, struct security_ace
);
433 ace
->type
= va_arg(ap
, unsigned int);
434 ace
->access_mask
= va_arg(ap
, unsigned int);
435 ace
->flags
= va_arg(ap
, unsigned int);
436 sid
= dom_sid_parse_talloc(ace
, sidstr
);
442 if (add_ace_to_sacl
) {
443 status
= security_descriptor_sacl_add(sd
, ace
);
445 status
= security_descriptor_dacl_add(sd
, ace
);
447 /* TODO: check: would talloc_free(ace) here be correct? */
448 if (!NT_STATUS_IS_OK(status
)) {
457 struct security_descriptor
*security_descriptor_append(struct security_descriptor
*sd
,
463 sd
= security_descriptor_appendv(sd
, false, ap
);
469 static struct security_descriptor
*security_descriptor_createv(TALLOC_CTX
*mem_ctx
,
471 const char *owner_sid
,
472 const char *group_sid
,
473 bool add_ace_to_sacl
,
476 struct security_descriptor
*sd
;
478 sd
= security_descriptor_initialise(mem_ctx
);
486 sd
->owner_sid
= dom_sid_parse_talloc(sd
, owner_sid
);
487 if (sd
->owner_sid
== NULL
) {
493 sd
->group_sid
= dom_sid_parse_talloc(sd
, group_sid
);
494 if (sd
->group_sid
== NULL
) {
500 return security_descriptor_appendv(sd
, add_ace_to_sacl
, ap
);
504 create a security descriptor using string SIDs. This is used by the
505 torture code to allow the easy creation of complex ACLs
506 This is a varargs function. The list of DACL ACEs ends with a NULL sid.
508 Each ACE contains a set of 4 parameters:
509 SID, ACCESS_TYPE, MASK, FLAGS
511 a typical call would be:
513 sd = security_descriptor_dacl_create(mem_ctx,
517 SID_NT_AUTHENTICATED_USERS,
518 SEC_ACE_TYPE_ACCESS_ALLOWED,
520 SEC_ACE_FLAG_OBJECT_INHERIT,
522 that would create a sd with one DACL ACE
525 struct security_descriptor
*security_descriptor_dacl_create(TALLOC_CTX
*mem_ctx
,
527 const char *owner_sid
,
528 const char *group_sid
,
531 struct security_descriptor
*sd
= NULL
;
533 va_start(ap
, group_sid
);
534 sd
= security_descriptor_createv(mem_ctx
, sd_type
, owner_sid
,
535 group_sid
, false, ap
);
541 struct security_descriptor
*security_descriptor_sacl_create(TALLOC_CTX
*mem_ctx
,
543 const char *owner_sid
,
544 const char *group_sid
,
547 struct security_descriptor
*sd
= NULL
;
549 va_start(ap
, group_sid
);
550 sd
= security_descriptor_createv(mem_ctx
, sd_type
, owner_sid
,
551 group_sid
, true, ap
);
557 struct security_ace
*security_ace_create(TALLOC_CTX
*mem_ctx
,
559 enum security_ace_type type
,
560 uint32_t access_mask
,
565 struct security_ace
*ace
;
567 ace
= talloc_zero(mem_ctx
, struct security_ace
);
572 sid
= dom_sid_parse_talloc(ace
, sid_str
);
580 ace
->access_mask
= access_mask
;