2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1998,
5 * Copyright (C) Jeremy R. Allison 1995-1998
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
7 * Copyright (C) Paul Ashton 1997-1998.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /*******************************************************************
27 Sets up a SEC_ACCESS structure.
28 ********************************************************************/
30 void init_sec_access(SEC_ACCESS *t, uint32 mask)
35 /*******************************************************************
36 Reads or writes a SEC_ACCESS structure.
37 ********************************************************************/
39 BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
44 prs_debug(ps, depth, desc, "sec_io_access");
50 if(!prs_uint32("mask", ps, depth, &(t->mask)))
56 /*******************************************************************
57 Check if ACE has OBJECT type.
58 ********************************************************************/
60 BOOL sec_ace_object(uint8 type)
62 if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
63 type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
64 type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
65 type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
71 /*******************************************************************
72 copy a SEC_ACE structure.
73 ********************************************************************/
74 void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
76 ace_dest->type = ace_src->type;
77 ace_dest->flags = ace_src->flags;
78 ace_dest->size = ace_src->size;
79 ace_dest->info.mask = ace_src->info.mask;
80 ace_dest->obj_flags = ace_src->obj_flags;
81 memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, GUID_SIZE);
82 memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE);
83 sid_copy(&ace_dest->trustee, &ace_src->trustee);
86 /*******************************************************************
87 Sets up a SEC_ACE structure.
88 ********************************************************************/
90 void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
94 t->size = sid_size(sid) + 8;
97 ZERO_STRUCTP(&t->trustee);
98 sid_copy(&t->trustee, sid);
101 /*******************************************************************
102 Reads or writes a SEC_ACE structure.
103 ********************************************************************/
105 BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
108 uint32 offset_ace_size;
113 prs_debug(ps, depth, desc, "sec_io_ace");
119 old_offset = prs_offset(ps);
121 if(!prs_uint8("type ", ps, depth, &psa->type))
124 if(!prs_uint8("flags", ps, depth, &psa->flags))
127 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
130 if(!sec_io_access("info ", &psa->info, ps, depth))
136 /* check whether object access is present */
137 if (!sec_ace_object(psa->type)) {
138 if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
141 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
144 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
145 if (!prs_uint8s(False, "obj_guid", ps, depth, psa->obj_guid.info, GUID_SIZE))
148 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
149 if (!prs_uint8s(False, "inh_guid", ps, depth, psa->inh_guid.info, GUID_SIZE))
152 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
156 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
161 /*******************************************************************
162 adds new SID with its permissions to ACE list
163 ********************************************************************/
165 NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid, uint32 mask)
169 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
173 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
174 return NT_STATUS_NO_MEMORY;
176 for (i = 0; i < *num - 1; i ++)
177 sec_ace_copy(&(*new)[i], &old[i]);
181 (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
182 (*new)[i].info.mask = mask;
183 sid_copy(&(*new)[i].trustee, sid);
187 /*******************************************************************
188 modify SID's permissions at ACL
189 ********************************************************************/
191 NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
195 if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
197 for (i = 0; i < num; i ++) {
198 if (sid_compare(&ace[i].trustee, sid) == 0) {
199 ace[i].info.mask = mask;
203 return NT_STATUS_NOT_FOUND;
206 /*******************************************************************
208 ********************************************************************/
210 NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid)
215 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
217 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
218 return NT_STATUS_NO_MEMORY;
220 for (i = 0; i < *num; i ++) {
221 if (sid_compare(&old[i].trustee, sid) != 0)
222 sec_ace_copy(&(*new)[i], &old[i]);
227 return NT_STATUS_NOT_FOUND;
234 /*******************************************************************
235 Create a SEC_ACL structure.
236 ********************************************************************/
238 SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
243 if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
246 dst->revision = revision;
247 dst->num_aces = num_aces;
248 dst->size = SEC_ACL_HEADER_SIZE;
250 /* Now we need to return a non-NULL address for the ace list even
251 if the number of aces required is zero. This is because there
252 is a distinct difference between a NULL ace and an ace with zero
253 entries in it. This is achieved by checking that num_aces is a
257 ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
262 for (i = 0; i < num_aces; i++) {
263 dst->ace[i] = ace_list[i]; /* Structure copy. */
264 dst->size += ace_list[i].size;
270 /*******************************************************************
271 Duplicate a SEC_ACL structure.
272 ********************************************************************/
274 SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
279 return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
282 /*******************************************************************
283 Reads or writes a SEC_ACL structure.
285 First of the xx_io_xx functions that allocates its data structures
286 for you as it reads them.
287 ********************************************************************/
289 BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
293 uint32 offset_acl_size;
301 if(UNMARSHALLING(ps) && psa == NULL) {
303 * This is a read and we must allocate the stuct to read into.
305 if((psa = (SEC_ACL *)prs_alloc_mem(ps, sizeof(SEC_ACL))) == NULL)
310 prs_debug(ps, depth, desc, "sec_io_acl");
316 old_offset = prs_offset(ps);
318 if(!prs_uint16("revision", ps, depth, &psa->revision))
321 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
324 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
327 if (UNMARSHALLING(ps)) {
329 * Even if the num_aces is zero, allocate memory as there's a difference
330 * between a non-present DACL (allow all access) and a DACL with no ACE's
333 if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * (psa->num_aces+1))) == NULL)
337 for (i = 0; i < psa->num_aces; i++) {
339 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
340 if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
347 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
353 /*******************************************************************
354 Works out the linearization size of a SEC_DESC.
355 ********************************************************************/
357 size_t sec_desc_size(SEC_DESC *psd)
363 offset = SEC_DESC_HEADER_SIZE;
365 if (psd->owner_sid != NULL)
366 offset += ((sid_size(psd->owner_sid) + 3) & ~3);
368 if (psd->grp_sid != NULL)
369 offset += ((sid_size(psd->grp_sid) + 3) & ~3);
371 if (psd->sacl != NULL)
372 offset += ((psd->sacl->size + 3) & ~3);
374 if (psd->dacl != NULL)
375 offset += ((psd->dacl->size + 3) & ~3);
380 /*******************************************************************
381 Compares two SEC_ACE structures
382 ********************************************************************/
384 BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
388 if (!s1 && !s2) return True;
390 /* Check top level stuff */
392 if (s1->type != s2->type || s1->flags != s2->flags ||
393 s1->info.mask != s2->info.mask) {
399 if (!sid_equal(&s1->trustee, &s2->trustee)) {
406 /*******************************************************************
407 Compares two SEC_ACL structures
408 ********************************************************************/
410 BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
416 if (!s1 && !s2) return True;
417 if (!s1 || !s2) return False;
419 /* Check top level stuff */
421 if (s1->revision != s2->revision) {
422 DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
423 s1->revision, s2->revision));
427 if (s1->num_aces != s2->num_aces) {
428 DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
429 s1->revision, s2->revision));
433 /* The ACEs could be in any order so check each ACE in s1 against
436 for (i = 0; i < s1->num_aces; i++) {
439 for (j = 0; j < s2->num_aces; j++) {
440 if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
446 if (!found) return False;
452 /*******************************************************************
453 Compares two SEC_DESC structures
454 ********************************************************************/
456 BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
464 /* Check top level stuff */
466 if (s1->revision != s2->revision) {
467 DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
468 s1->revision, s2->revision));
472 if (s1->type!= s2->type) {
473 DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
474 s1->type, s2->type));
478 /* Check owner and group */
480 if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
483 sid_to_string(str1, s1->owner_sid);
484 sid_to_string(str2, s2->owner_sid);
486 DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
491 if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
494 sid_to_string(str1, s1->grp_sid);
495 sid_to_string(str2, s2->grp_sid);
497 DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
502 /* Check ACLs present in one but not the other */
504 if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
505 (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
506 DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
510 /* Sigh - we have to do it the hard way by iterating over all
511 the ACEs in the ACLs */
513 if (!sec_acl_equal(s1->dacl, s2->dacl) ||
514 !sec_acl_equal(s1->sacl, s2->sacl)) {
515 DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
520 DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
524 /*******************************************************************
525 Merge part of security descriptor old_sec in to the empty sections of
526 security descriptor new_sec.
527 ********************************************************************/
529 SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
531 DOM_SID *owner_sid, *group_sid;
532 SEC_DESC_BUF *return_sdb;
533 SEC_ACL *dacl, *sacl;
534 SEC_DESC *psd = NULL;
538 /* Copy over owner and group sids. There seems to be no flag for
539 this so just check the pointer values. */
541 owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
542 old_sdb->sec->owner_sid;
544 group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
545 old_sdb->sec->grp_sid;
547 secdesc_type = new_sdb->sec->type;
549 /* Ignore changes to the system ACL. This has the effect of making
550 changes through the security tab audit button not sticking.
551 Perhaps in future Samba could implement these settings somehow. */
554 secdesc_type &= ~SEC_DESC_SACL_PRESENT;
556 /* Copy across discretionary ACL */
558 if (secdesc_type & SEC_DESC_DACL_PRESENT) {
559 dacl = new_sdb->sec->dacl;
561 dacl = old_sdb->sec->dacl;
564 /* Create new security descriptor from bits */
566 psd = make_sec_desc(ctx, new_sdb->sec->revision,
567 owner_sid, group_sid, sacl, dacl, &secdesc_size);
569 return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
574 /*******************************************************************
575 Tallocs a duplicate SID.
576 ********************************************************************/
578 static DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
585 if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
592 /*******************************************************************
593 Creates a SEC_DESC structure
594 ********************************************************************/
596 SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
597 DOM_SID *owner_sid, DOM_SID *grp_sid,
598 SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
602 uint32 offset_sid = SEC_DESC_HEADER_SIZE;
603 uint32 offset_acl = 0;
607 if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
610 dst->revision = revision;
611 dst->type = SEC_DESC_SELF_RELATIVE;
613 if (sacl) dst->type |= SEC_DESC_SACL_PRESENT;
614 if (dacl) dst->type |= SEC_DESC_DACL_PRESENT;
616 dst->off_owner_sid = 0;
617 dst->off_grp_sid = 0;
621 if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
624 if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
627 if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
630 if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
636 * Work out the linearization sizes.
638 if (dst->owner_sid != NULL) {
641 offset = SEC_DESC_HEADER_SIZE;
643 offset += ((sid_size(dst->owner_sid) + 3) & ~3);
646 if (dst->grp_sid != NULL) {
649 offset = SEC_DESC_HEADER_SIZE;
651 offset += ((sid_size(dst->grp_sid) + 3) & ~3);
654 if (dst->sacl != NULL) {
656 offset_acl = SEC_DESC_HEADER_SIZE;
658 dst->off_sacl = offset_acl;
659 offset_acl += ((dst->sacl->size + 3) & ~3);
660 offset += dst->sacl->size;
661 offset_sid += dst->sacl->size;
664 if (dst->dacl != NULL) {
667 offset_acl = SEC_DESC_HEADER_SIZE;
669 dst->off_dacl = offset_acl;
670 offset_acl += ((dst->dacl->size + 3) & ~3);
671 offset += dst->dacl->size;
672 offset_sid += dst->dacl->size;
675 *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset);
677 if (dst->owner_sid != NULL) {
678 dst->off_owner_sid = offset_sid;
679 dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid);
682 if (dst->grp_sid != NULL)
683 dst->off_grp_sid = offset_sid;
693 /*******************************************************************
694 Duplicate a SEC_DESC structure.
695 ********************************************************************/
697 SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src)
704 return make_sec_desc( ctx, src->revision,
705 src->owner_sid, src->grp_sid, src->sacl,
709 /*******************************************************************
710 Creates a SEC_DESC structure with typical defaults.
711 ********************************************************************/
713 SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
714 SEC_ACL *dacl, size_t *sd_size)
716 return make_sec_desc(ctx, SEC_DESC_REVISION,
717 owner_sid, grp_sid, NULL, dacl, sd_size);
720 /*******************************************************************
721 Reads or writes a SEC_DESC structure.
722 If reading and the *ppsd = NULL, allocates the structure.
723 ********************************************************************/
725 BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
728 uint32 max_offset = 0; /* after we're done, move offset to end */
729 uint32 tmp_offset = 0;
739 if(UNMARSHALLING(ps)) {
740 if((psd = (SEC_DESC *)prs_alloc_mem(ps,sizeof(SEC_DESC))) == NULL)
744 /* Marshalling - just ignore. */
749 prs_debug(ps, depth, desc, "sec_io_desc");
754 * if alignment is needed, should be done by the the
755 * caller. Not here. This caused me problems when marshalling
756 * printer info into a buffer. --jerry
762 /* start of security descriptor stored for back-calc offset purposes */
763 old_offset = prs_offset(ps);
765 if(!prs_uint16("revision ", ps, depth, &psd->revision))
768 if(!prs_uint16("type ", ps, depth, &psd->type))
771 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
774 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
777 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
780 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
783 max_offset = MAX(max_offset, prs_offset(ps));
785 if (psd->off_owner_sid != 0) {
787 if (UNMARSHALLING(ps)) {
788 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
791 if((psd->owner_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->owner_sid))) == NULL)
795 tmp_offset = ps->data_offset;
796 ps->data_offset = psd->off_owner_sid;
798 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
803 ps->data_offset = tmp_offset;
806 max_offset = MAX(max_offset, prs_offset(ps));
808 if (psd->off_grp_sid != 0) {
810 if (UNMARSHALLING(ps)) {
812 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
814 if((psd->grp_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->grp_sid))) == NULL)
818 tmp_offset = ps->data_offset;
819 ps->data_offset = psd->off_grp_sid;
821 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
826 ps->data_offset = tmp_offset;
829 max_offset = MAX(max_offset, prs_offset(ps));
831 if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
832 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
834 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
840 max_offset = MAX(max_offset, prs_offset(ps));
842 if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
843 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
845 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
851 max_offset = MAX(max_offset, prs_offset(ps));
853 if(!prs_set_offset(ps, max_offset))
858 /*******************************************************************
859 Creates a SEC_DESC_BUF structure.
860 ********************************************************************/
862 SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
866 if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
869 /* max buffer size (allocated size) */
870 dst->max_len = (uint32)len;
871 dst->len = (uint32)len;
873 if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
882 /*******************************************************************
883 Duplicates a SEC_DESC_BUF structure.
884 ********************************************************************/
886 SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
891 return make_sec_desc_buf( ctx, src->len, src->sec);
894 /*******************************************************************
895 Reads or writes a SEC_DESC_BUF structure.
896 ********************************************************************/
898 BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
911 if (UNMARSHALLING(ps) && psdb == NULL) {
912 if((psdb = (SEC_DESC_BUF *)prs_alloc_mem(ps,sizeof(SEC_DESC_BUF))) == NULL)
917 prs_debug(ps, depth, desc, "sec_io_desc_buf");
923 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
926 if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr))
929 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
932 old_offset = prs_offset(ps);
934 /* reading, length is non-zero; writing, descriptor is non-NULL */
935 if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
936 if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
943 size = prs_offset(ps) - old_offset;
944 if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
947 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
953 /*******************************************************************
954 adds new SID with its permissions to SEC_DESC
955 ********************************************************************/
957 NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
966 if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
968 status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
970 if (!NT_STATUS_IS_OK(status))
973 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
974 return NT_STATUS_UNSUCCESSFUL;
976 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
977 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
978 return NT_STATUS_UNSUCCESSFUL;
985 /*******************************************************************
986 modify SID's permissions at SEC_DESC
987 ********************************************************************/
989 NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
993 if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER;
995 status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
997 if (!NT_STATUS_IS_OK(status))
1000 return NT_STATUS_OK;
1003 /*******************************************************************
1004 delete SID from SEC_DESC
1005 ********************************************************************/
1007 NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
1016 if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
1018 status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
1020 if (!NT_STATUS_IS_OK(status))
1023 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
1024 return NT_STATUS_UNSUCCESSFUL;
1026 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
1027 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
1028 return NT_STATUS_UNSUCCESSFUL;
1032 return NT_STATUS_OK;