lib: Remove unused parmlist code
[Samba.git] / libcli / security / security_descriptor.c
blob0a2bb952b0eb3ec6ae53ad5601adfb87da4e2d80
1 /*
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/>.
22 #include "includes.h"
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);
33 if (!sd) {
34 return NULL;
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;
44 sd->owner_sid = NULL;
45 sd->group_sid = NULL;
46 sd->sacl = NULL;
47 sd->dacl = NULL;
49 return sd;
52 struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
53 const struct security_acl *oacl)
55 struct security_acl *nacl;
57 if (oacl == NULL) {
58 return NULL;
61 nacl = talloc (mem_ctx, struct security_acl);
62 if (nacl == NULL) {
63 return NULL;
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)) {
68 goto failed;
71 nacl->revision = oacl->revision;
72 nacl->size = oacl->size;
73 nacl->num_aces = oacl->num_aces;
75 return nacl;
77 failed:
78 talloc_free (nacl);
79 return NULL;
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;
88 uint32_t i;
90 if (!acl1 && !acl2)
91 return NULL;
93 if (!acl1){
94 nacl = security_acl_dup(mem_ctx, acl2);
95 return nacl;
98 if (!acl2){
99 nacl = security_acl_dup(mem_ctx, acl1);
100 return nacl;
103 nacl = talloc (mem_ctx, struct security_acl);
104 if (nacl == NULL) {
105 return NULL;
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)
113 return nacl;
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)) {
117 goto failed;
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];
125 return nacl;
127 failed:
128 talloc_free (nacl);
129 return NULL;
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);
142 if (!nsd) {
143 return NULL;
146 if (osd->owner_sid) {
147 nsd->owner_sid = dom_sid_dup(nsd, osd->owner_sid);
148 if (nsd->owner_sid == NULL) {
149 goto failed;
153 if (osd->group_sid) {
154 nsd->group_sid = dom_sid_dup(nsd, osd->group_sid);
155 if (nsd->group_sid == NULL) {
156 goto failed;
160 if (osd->sacl) {
161 nsd->sacl = security_acl_dup(nsd, osd->sacl);
162 if (nsd->sacl == NULL) {
163 goto failed;
167 if (osd->dacl) {
168 nsd->dacl = security_acl_dup(nsd, osd->dacl);
169 if (nsd->dacl == NULL) {
170 goto failed;
174 nsd->revision = osd->revision;
175 nsd->type = osd->type;
177 return nsd;
179 failed:
180 talloc_free(nsd);
182 return NULL;
185 NTSTATUS security_descriptor_for_client(TALLOC_CTX *mem_ctx,
186 const struct security_descriptor *ssd,
187 uint32_t sec_info,
188 uint32_t access_granted,
189 struct security_descriptor **_csd)
191 struct security_descriptor *csd = NULL;
192 uint32_t access_required = 0;
194 *_csd = NULL;
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;
211 * make a copy...
213 csd = security_descriptor_copy(mem_ctx, ssd);
214 if (csd == NULL) {
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);
232 csd->type &= ~(
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);
242 csd->type &= ~(
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);
251 *_csd = csd;
252 return NT_STATUS_OK;
256 add an ACE to an ACL of a security_descriptor
259 static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
260 bool add_to_sacl,
261 const struct security_ace *ace)
263 struct security_acl *acl = NULL;
265 if (add_to_sacl) {
266 acl = sd->sacl;
267 } else {
268 acl = sd->dacl;
271 if (acl == NULL) {
272 acl = talloc(sd, struct security_acl);
273 if (acl == NULL) {
274 return NT_STATUS_NO_MEMORY;
276 acl->revision = SECURITY_ACL_REVISION_NT4;
277 acl->size = 0;
278 acl->num_aces = 0;
279 acl->aces = NULL;
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;
296 break;
297 default:
298 break;
301 acl->num_aces++;
303 if (add_to_sacl) {
304 sd->sacl = acl;
305 sd->type |= SEC_DESC_SACL_PRESENT;
306 } else {
307 sd->dacl = acl;
308 sd->type |= SEC_DESC_DACL_PRESENT;
311 return NT_STATUS_OK;
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
336 security_descriptor
339 static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd,
340 bool sacl_del,
341 const struct dom_sid *trustee)
343 uint32_t i;
344 bool found = false;
345 struct security_acl *acl = NULL;
347 if (sacl_del) {
348 acl = sd->sacl;
349 } else {
350 acl = sd->dacl;
353 if (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)));
362 acl->num_aces--;
363 if (acl->num_aces == 0) {
364 acl->aces = NULL;
366 found = true;
370 if (!found) {
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;
383 return NT_STATUS_OK;
384 default:
385 break; /* only for the switch statement */
389 return NT_STATUS_OK;
393 delete the ACE corresponding to the given trustee in the DACL of a
394 security_descriptor
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
405 security_descriptor
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)
420 if (ace1 == ace2) {
421 return true;
423 if ((ace1 == NULL) || (ace2 == NULL)) {
424 return false;
426 if (ace1->type != ace2->type) {
427 return false;
429 if (ace1->flags != ace2->flags) {
430 return false;
432 if (ace1->access_mask != ace2->access_mask) {
433 return false;
435 if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) {
436 return false;
439 return true;
444 compare two security acl structures
446 bool security_acl_equal(const struct security_acl *acl1,
447 const struct security_acl *acl2)
449 uint32_t i;
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;
459 return true;
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;
478 return true;
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,
487 uint32_t mask)
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;
499 return true;
503 static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd,
504 bool add_ace_to_sacl,
505 va_list ap)
507 const char *sidstr;
509 while ((sidstr = va_arg(ap, const char *))) {
510 struct dom_sid *sid;
511 struct security_ace *ace = talloc_zero(sd, struct security_ace);
512 NTSTATUS status;
514 if (ace == NULL) {
515 talloc_free(sd);
516 return NULL;
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);
522 if (sid == NULL) {
523 talloc_free(sd);
524 return NULL;
526 ace->trustee = *sid;
527 if (add_ace_to_sacl) {
528 status = security_descriptor_sacl_add(sd, ace);
529 } else {
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)) {
534 talloc_free(sd);
535 return NULL;
539 return sd;
542 struct security_descriptor *security_descriptor_append(struct security_descriptor *sd,
543 ...)
545 va_list ap;
547 va_start(ap, sd);
548 sd = security_descriptor_appendv(sd, false, ap);
549 va_end(ap);
551 return sd;
554 static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx,
555 uint16_t sd_type,
556 const char *owner_sid,
557 const char *group_sid,
558 bool add_ace_to_sacl,
559 va_list ap)
561 struct security_descriptor *sd;
563 sd = security_descriptor_initialise(mem_ctx);
564 if (sd == NULL) {
565 return NULL;
568 sd->type |= sd_type;
570 if (owner_sid) {
571 sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid);
572 if (sd->owner_sid == NULL) {
573 talloc_free(sd);
574 return NULL;
577 if (group_sid) {
578 sd->group_sid = dom_sid_parse_talloc(sd, group_sid);
579 if (sd->group_sid == NULL) {
580 talloc_free(sd);
581 return 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,
599 sd_type_flags,
600 mysid,
601 mygroup,
602 SID_NT_AUTHENTICATED_USERS,
603 SEC_ACE_TYPE_ACCESS_ALLOWED,
604 SEC_FILE_ALL,
605 SEC_ACE_FLAG_OBJECT_INHERIT,
606 NULL);
607 that would create a sd with one DACL ACE
610 struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx,
611 uint16_t sd_type,
612 const char *owner_sid,
613 const char *group_sid,
614 ...)
616 struct security_descriptor *sd = NULL;
617 va_list ap;
618 va_start(ap, group_sid);
619 sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
620 group_sid, false, ap);
621 va_end(ap);
623 return sd;
626 struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx,
627 uint16_t sd_type,
628 const char *owner_sid,
629 const char *group_sid,
630 ...)
632 struct security_descriptor *sd = NULL;
633 va_list ap;
634 va_start(ap, group_sid);
635 sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
636 group_sid, true, ap);
637 va_end(ap);
639 return sd;
642 struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx,
643 const char *sid_str,
644 enum security_ace_type type,
645 uint32_t access_mask,
646 uint8_t flags)
649 struct security_ace *ace;
650 bool ok;
652 ace = talloc_zero(mem_ctx, struct security_ace);
653 if (ace == NULL) {
654 return NULL;
657 ok = dom_sid_parse(sid_str, &ace->trustee);
658 if (!ok) {
659 talloc_free(ace);
660 return NULL;
662 ace->type = type;
663 ace->access_mask = access_mask;
664 ace->flags = flags;
666 return ace;
669 /*******************************************************************
670 Check for MS NFS ACEs in a sd
671 *******************************************************************/
672 bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd)
674 int i;
676 if (psd->dacl == NULL) {
677 return false;
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) {
684 return true;
688 return false;