2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1998,
6 * Copyright (C) Jeremy R. Allison 1995-1998
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8 * Copyright (C) Paul Ashton 1997-1998.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define DBGC_CLASS DBGC_RPC_PARSE
30 /*******************************************************************
31 Sets up a SEC_ACCESS structure.
32 ********************************************************************/
34 void init_sec_access(SEC_ACCESS *t, uint32 mask)
39 /*******************************************************************
40 Reads or writes a SEC_ACCESS structure.
41 ********************************************************************/
43 BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
48 prs_debug(ps, depth, desc, "sec_io_access");
51 if(!prs_uint32("mask", ps, depth, &(t->mask)))
57 /*******************************************************************
58 Check if ACE has OBJECT type.
59 ********************************************************************/
61 BOOL sec_ace_object(uint8 type)
63 if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
64 type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
65 type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
66 type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
72 /*******************************************************************
73 copy a SEC_ACE structure.
74 ********************************************************************/
75 void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
77 ace_dest->type = ace_src->type;
78 ace_dest->flags = ace_src->flags;
79 ace_dest->size = ace_src->size;
80 ace_dest->info.mask = ace_src->info.mask;
81 ace_dest->obj_flags = ace_src->obj_flags;
82 memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, GUID_SIZE);
83 memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE);
84 sid_copy(&ace_dest->trustee, &ace_src->trustee);
87 /*******************************************************************
88 Sets up a SEC_ACE structure.
89 ********************************************************************/
91 void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
95 t->size = sid_size(sid) + 8;
98 ZERO_STRUCTP(&t->trustee);
99 sid_copy(&t->trustee, sid);
102 /*******************************************************************
103 Reads or writes a SEC_ACE structure.
104 ********************************************************************/
106 BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
109 uint32 offset_ace_size;
114 prs_debug(ps, depth, desc, "sec_io_ace");
117 old_offset = prs_offset(ps);
119 if(!prs_uint8("type ", ps, depth, &psa->type))
122 if(!prs_uint8("flags", ps, depth, &psa->flags))
125 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
128 if(!sec_io_access("info ", &psa->info, ps, depth))
134 /* check whether object access is present */
135 if (!sec_ace_object(psa->type)) {
136 if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
139 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
142 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
143 if (!prs_uint8s(False, "obj_guid", ps, depth, psa->obj_guid.info, GUID_SIZE))
146 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
147 if (!prs_uint8s(False, "inh_guid", ps, depth, psa->inh_guid.info, GUID_SIZE))
150 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
154 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
159 /*******************************************************************
160 adds new SID with its permissions to ACE list
161 ********************************************************************/
163 NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid, uint32 mask)
167 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
171 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
172 return NT_STATUS_NO_MEMORY;
174 for (i = 0; i < *num - 1; i ++)
175 sec_ace_copy(&(*new)[i], &old[i]);
179 (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
180 (*new)[i].info.mask = mask;
181 sid_copy(&(*new)[i].trustee, sid);
185 /*******************************************************************
186 modify SID's permissions at ACL
187 ********************************************************************/
189 NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
193 if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
195 for (i = 0; i < num; i ++) {
196 if (sid_compare(&ace[i].trustee, sid) == 0) {
197 ace[i].info.mask = mask;
201 return NT_STATUS_NOT_FOUND;
204 /*******************************************************************
206 ********************************************************************/
208 NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid)
213 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
215 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
216 return NT_STATUS_NO_MEMORY;
218 for (i = 0; i < *num; i ++) {
219 if (sid_compare(&old[i].trustee, sid) != 0)
220 sec_ace_copy(&(*new)[i], &old[i]);
225 return NT_STATUS_NOT_FOUND;
232 /*******************************************************************
233 Create a SEC_ACL structure.
234 ********************************************************************/
236 SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
241 if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
244 dst->revision = revision;
245 dst->num_aces = num_aces;
246 dst->size = SEC_ACL_HEADER_SIZE;
248 /* Now we need to return a non-NULL address for the ace list even
249 if the number of aces required is zero. This is because there
250 is a distinct difference between a NULL ace and an ace with zero
251 entries in it. This is achieved by checking that num_aces is a
255 ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
260 for (i = 0; i < num_aces; i++) {
261 dst->ace[i] = ace_list[i]; /* Structure copy. */
262 dst->size += ace_list[i].size;
268 /*******************************************************************
269 Duplicate a SEC_ACL structure.
270 ********************************************************************/
272 SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
277 return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
280 /*******************************************************************
281 Reads or writes a SEC_ACL structure.
283 First of the xx_io_xx functions that allocates its data structures
284 for you as it reads them.
285 ********************************************************************/
287 BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
291 uint32 offset_acl_size;
295 * Note that the size is always a multiple of 4 bytes due to the
296 * nature of the data structure. Therefore the prs_align() calls
297 * have been removed as they through us off when doing two-layer
298 * marshalling such as in the printing code (NEW_BUFFER). --jerry
306 if(UNMARSHALLING(ps) && psa == NULL) {
308 * This is a read and we must allocate the stuct to read into.
310 if((psa = (SEC_ACL *)prs_alloc_mem(ps, sizeof(SEC_ACL))) == NULL)
315 prs_debug(ps, depth, desc, "sec_io_acl");
318 old_offset = prs_offset(ps);
320 if(!prs_uint16("revision", ps, depth, &psa->revision))
323 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
326 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
329 if (UNMARSHALLING(ps)) {
331 * Even if the num_aces is zero, allocate memory as there's a difference
332 * between a non-present DACL (allow all access) and a DACL with no ACE's
335 if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * (psa->num_aces+1))) == NULL)
339 for (i = 0; i < psa->num_aces; i++) {
341 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
342 if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
346 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
352 /*******************************************************************
353 Works out the linearization size of a SEC_DESC.
354 ********************************************************************/
356 size_t sec_desc_size(SEC_DESC *psd)
362 offset = SEC_DESC_HEADER_SIZE;
366 if (psd->owner_sid != NULL)
367 offset += sid_size(psd->owner_sid);
369 if (psd->grp_sid != NULL)
370 offset += sid_size(psd->grp_sid);
372 if (psd->sacl != NULL)
373 offset += psd->sacl->size;
375 if (psd->dacl != NULL)
376 offset += psd->dacl->size;
381 /*******************************************************************
382 Compares two SEC_ACE structures
383 ********************************************************************/
385 BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
389 if (!s1 && !s2) return True;
391 /* Check top level stuff */
393 if (s1->type != s2->type || s1->flags != s2->flags ||
394 s1->info.mask != s2->info.mask) {
400 if (!sid_equal(&s1->trustee, &s2->trustee)) {
407 /*******************************************************************
408 Compares two SEC_ACL structures
409 ********************************************************************/
411 BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
417 if (!s1 && !s2) return True;
418 if (!s1 || !s2) return False;
420 /* Check top level stuff */
422 if (s1->revision != s2->revision) {
423 DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
424 s1->revision, s2->revision));
428 if (s1->num_aces != s2->num_aces) {
429 DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
430 s1->revision, s2->revision));
434 /* The ACEs could be in any order so check each ACE in s1 against
437 for (i = 0; i < s1->num_aces; i++) {
440 for (j = 0; j < s2->num_aces; j++) {
441 if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
447 if (!found) return False;
453 /*******************************************************************
454 Compares two SEC_DESC structures
455 ********************************************************************/
457 BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
465 /* Check top level stuff */
467 if (s1->revision != s2->revision) {
468 DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
469 s1->revision, s2->revision));
473 if (s1->type!= s2->type) {
474 DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
475 s1->type, s2->type));
479 /* Check owner and group */
481 if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
484 sid_to_string(str1, s1->owner_sid);
485 sid_to_string(str2, s2->owner_sid);
487 DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
492 if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
495 sid_to_string(str1, s1->grp_sid);
496 sid_to_string(str2, s2->grp_sid);
498 DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
503 /* Check ACLs present in one but not the other */
505 if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
506 (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
507 DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
511 /* Sigh - we have to do it the hard way by iterating over all
512 the ACEs in the ACLs */
514 if (!sec_acl_equal(s1->dacl, s2->dacl) ||
515 !sec_acl_equal(s1->sacl, s2->sacl)) {
516 DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
521 DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
525 /*******************************************************************
526 Merge part of security descriptor old_sec in to the empty sections of
527 security descriptor new_sec.
528 ********************************************************************/
530 SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
532 DOM_SID *owner_sid, *group_sid;
533 SEC_DESC_BUF *return_sdb;
534 SEC_ACL *dacl, *sacl;
535 SEC_DESC *psd = NULL;
539 /* Copy over owner and group sids. There seems to be no flag for
540 this so just check the pointer values. */
542 owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
543 old_sdb->sec->owner_sid;
545 group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
546 old_sdb->sec->grp_sid;
548 secdesc_type = new_sdb->sec->type;
550 /* Ignore changes to the system ACL. This has the effect of making
551 changes through the security tab audit button not sticking.
552 Perhaps in future Samba could implement these settings somehow. */
555 secdesc_type &= ~SEC_DESC_SACL_PRESENT;
557 /* Copy across discretionary ACL */
559 if (secdesc_type & SEC_DESC_DACL_PRESENT) {
560 dacl = new_sdb->sec->dacl;
562 dacl = old_sdb->sec->dacl;
565 /* Create new security descriptor from bits */
567 psd = make_sec_desc(ctx, new_sdb->sec->revision,
568 owner_sid, group_sid, sacl, dacl, &secdesc_size);
570 return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
575 /*******************************************************************
576 Tallocs a duplicate SID.
577 ********************************************************************/
579 static DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
586 if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
593 /*******************************************************************
594 Creates a SEC_DESC structure
595 ********************************************************************/
597 SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
598 DOM_SID *owner_sid, DOM_SID *grp_sid,
599 SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
603 uint32 offset_sid = SEC_DESC_HEADER_SIZE;
604 uint32 offset_acl = 0;
608 if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
611 dst->revision = revision;
612 dst->type = SEC_DESC_SELF_RELATIVE;
614 if (sacl) dst->type |= SEC_DESC_SACL_PRESENT;
615 if (dacl) dst->type |= SEC_DESC_DACL_PRESENT;
617 dst->off_owner_sid = 0;
618 dst->off_grp_sid = 0;
622 if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
625 if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
628 if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
631 if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
637 * Work out the linearization sizes.
639 if (dst->owner_sid != NULL) {
642 offset = SEC_DESC_HEADER_SIZE;
644 offset += sid_size(dst->owner_sid);
647 if (dst->grp_sid != NULL) {
650 offset = SEC_DESC_HEADER_SIZE;
652 offset += sid_size(dst->grp_sid);
655 if (dst->sacl != NULL) {
657 offset_acl = SEC_DESC_HEADER_SIZE;
659 dst->off_sacl = offset_acl;
660 offset_acl += dst->sacl->size;
661 offset += dst->sacl->size;
662 offset_sid += dst->sacl->size;
665 if (dst->dacl != NULL) {
668 offset_acl = SEC_DESC_HEADER_SIZE;
670 dst->off_dacl = offset_acl;
671 offset_acl += dst->dacl->size;
672 offset += dst->dacl->size;
673 offset_sid += dst->dacl->size;
676 *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset);
678 if (dst->owner_sid != NULL) {
679 dst->off_owner_sid = offset_sid;
680 dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid);
683 if (dst->grp_sid != NULL)
684 dst->off_grp_sid = offset_sid;
694 /*******************************************************************
695 Duplicate a SEC_DESC structure.
696 ********************************************************************/
698 SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src)
705 return make_sec_desc( ctx, src->revision,
706 src->owner_sid, src->grp_sid, src->sacl,
710 /*******************************************************************
711 Creates a SEC_DESC structure with typical defaults.
712 ********************************************************************/
714 SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
715 SEC_ACL *dacl, size_t *sd_size)
717 return make_sec_desc(ctx, SEC_DESC_REVISION,
718 owner_sid, grp_sid, NULL, dacl, sd_size);
721 /*******************************************************************
722 Reads or writes a SEC_DESC structure.
723 If reading and the *ppsd = NULL, allocates the structure.
724 ********************************************************************/
726 BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
729 uint32 max_offset = 0; /* after we're done, move offset to end */
730 uint32 tmp_offset = 0;
740 if(UNMARSHALLING(ps)) {
741 if((psd = (SEC_DESC *)prs_alloc_mem(ps,sizeof(SEC_DESC))) == NULL)
745 /* Marshalling - just ignore. */
750 prs_debug(ps, depth, desc, "sec_io_desc");
755 * if alignment is needed, should be done by the the
756 * caller. Not here. This caused me problems when marshalling
757 * printer info into a buffer. --jerry
763 /* start of security descriptor stored for back-calc offset purposes */
764 old_offset = prs_offset(ps);
766 if(!prs_uint16("revision ", ps, depth, &psd->revision))
769 if(!prs_uint16("type ", ps, depth, &psd->type))
772 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
775 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
778 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
781 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
784 max_offset = MAX(max_offset, prs_offset(ps));
786 if (psd->off_owner_sid != 0) {
788 if (UNMARSHALLING(ps)) {
789 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
792 if((psd->owner_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->owner_sid))) == NULL)
796 tmp_offset = ps->data_offset;
797 ps->data_offset = psd->off_owner_sid;
799 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
804 ps->data_offset = tmp_offset;
807 max_offset = MAX(max_offset, prs_offset(ps));
809 if (psd->off_grp_sid != 0) {
811 if (UNMARSHALLING(ps)) {
813 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
815 if((psd->grp_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->grp_sid))) == NULL)
819 tmp_offset = ps->data_offset;
820 ps->data_offset = psd->off_grp_sid;
822 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
824 ps->data_offset = tmp_offset;
827 max_offset = MAX(max_offset, prs_offset(ps));
829 if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
830 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
832 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
836 max_offset = MAX(max_offset, prs_offset(ps));
838 if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
839 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
841 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
845 max_offset = MAX(max_offset, prs_offset(ps));
847 if(!prs_set_offset(ps, max_offset))
852 /*******************************************************************
853 Creates a SEC_DESC_BUF structure.
854 ********************************************************************/
856 SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
860 if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
863 /* max buffer size (allocated size) */
864 dst->max_len = (uint32)len;
865 dst->len = (uint32)len;
867 if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
876 /*******************************************************************
877 Duplicates a SEC_DESC_BUF structure.
878 ********************************************************************/
880 SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
885 return make_sec_desc_buf( ctx, src->len, src->sec);
888 /*******************************************************************
889 Reads or writes a SEC_DESC_BUF structure.
890 ********************************************************************/
892 BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
905 if (UNMARSHALLING(ps) && psdb == NULL) {
906 if((psdb = (SEC_DESC_BUF *)prs_alloc_mem(ps,sizeof(SEC_DESC_BUF))) == NULL)
911 prs_debug(ps, depth, desc, "sec_io_desc_buf");
917 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
920 if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr))
923 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
926 old_offset = prs_offset(ps);
928 /* reading, length is non-zero; writing, descriptor is non-NULL */
929 if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
930 if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
937 size = prs_offset(ps) - old_offset;
938 if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
941 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
947 /*******************************************************************
948 adds new SID with its permissions to SEC_DESC
949 ********************************************************************/
951 NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
960 if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
962 status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
964 if (!NT_STATUS_IS_OK(status))
967 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
968 return NT_STATUS_UNSUCCESSFUL;
970 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
971 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
972 return NT_STATUS_UNSUCCESSFUL;
979 /*******************************************************************
980 modify SID's permissions at SEC_DESC
981 ********************************************************************/
983 NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
987 if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER;
989 status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
991 if (!NT_STATUS_IS_OK(status))
997 /*******************************************************************
998 delete SID from SEC_DESC
999 ********************************************************************/
1001 NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
1010 if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
1012 status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
1014 if (!NT_STATUS_IS_OK(status))
1017 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
1018 return NT_STATUS_UNSUCCESSFUL;
1020 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
1021 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
1022 return NT_STATUS_UNSUCCESSFUL;
1026 return NT_STATUS_OK;