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(const 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(const 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))
131 /* check whether object access is present */
132 if (!sec_ace_object(psa->type)) {
133 if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
136 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
139 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
140 if (!prs_uint8s(False, "obj_guid", ps, depth, psa->obj_guid.info, GUID_SIZE))
143 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
144 if (!prs_uint8s(False, "inh_guid", ps, depth, psa->inh_guid.info, GUID_SIZE))
147 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
151 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
156 /*******************************************************************
157 adds new SID with its permissions to ACE list
158 ********************************************************************/
160 NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask)
164 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
168 if((new[0] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 0)
169 return NT_STATUS_NO_MEMORY;
171 for (i = 0; i < *num - 1; i ++)
172 sec_ace_copy(&(*new)[i], &old[i]);
176 (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
177 (*new)[i].info.mask = mask;
178 sid_copy(&(*new)[i].trustee, sid);
182 /*******************************************************************
183 modify SID's permissions at ACL
184 ********************************************************************/
186 NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
190 if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
192 for (i = 0; i < num; i ++) {
193 if (sid_compare(&ace[i].trustee, sid) == 0) {
194 ace[i].info.mask = mask;
198 return NT_STATUS_NOT_FOUND;
201 /*******************************************************************
203 ********************************************************************/
205 NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid)
210 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
212 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
213 return NT_STATUS_NO_MEMORY;
215 for (i = 0; i < *num; i ++) {
216 if (sid_compare(&old[i].trustee, sid) != 0)
217 sec_ace_copy(&(*new)[i], &old[i]);
222 return NT_STATUS_NOT_FOUND;
229 /*******************************************************************
230 Create a SEC_ACL structure.
231 ********************************************************************/
233 SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
238 if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
241 dst->revision = revision;
242 dst->num_aces = num_aces;
243 dst->size = SEC_ACL_HEADER_SIZE;
245 /* Now we need to return a non-NULL address for the ace list even
246 if the number of aces required is zero. This is because there
247 is a distinct difference between a NULL ace and an ace with zero
248 entries in it. This is achieved by checking that num_aces is a
252 ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
257 for (i = 0; i < num_aces; i++) {
258 dst->ace[i] = ace_list[i]; /* Structure copy. */
259 dst->size += ace_list[i].size;
265 /*******************************************************************
266 Duplicate a SEC_ACL structure.
267 ********************************************************************/
269 SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
274 return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
277 /*******************************************************************
278 Reads or writes a SEC_ACL structure.
280 First of the xx_io_xx functions that allocates its data structures
281 for you as it reads them.
282 ********************************************************************/
284 BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
288 uint32 offset_acl_size;
292 * Note that the size is always a multiple of 4 bytes due to the
293 * nature of the data structure. Therefore the prs_align() calls
294 * have been removed as they through us off when doing two-layer
295 * marshalling such as in the printing code (NEW_BUFFER). --jerry
303 if(UNMARSHALLING(ps) && psa == NULL) {
305 * This is a read and we must allocate the stuct to read into.
307 if((psa = (SEC_ACL *)prs_alloc_mem(ps, sizeof(SEC_ACL))) == NULL)
312 prs_debug(ps, depth, desc, "sec_io_acl");
315 old_offset = prs_offset(ps);
317 if(!prs_uint16("revision", ps, depth, &psa->revision))
320 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
323 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
326 if (UNMARSHALLING(ps)) {
328 * Even if the num_aces is zero, allocate memory as there's a difference
329 * between a non-present DACL (allow all access) and a DACL with no ACE's
332 if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * (psa->num_aces+1))) == NULL)
336 for (i = 0; i < psa->num_aces; i++) {
338 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
339 if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
343 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
349 /*******************************************************************
350 Works out the linearization size of a SEC_DESC.
351 ********************************************************************/
353 size_t sec_desc_size(SEC_DESC *psd)
359 offset = SEC_DESC_HEADER_SIZE;
363 if (psd->owner_sid != NULL)
364 offset += sid_size(psd->owner_sid);
366 if (psd->grp_sid != NULL)
367 offset += sid_size(psd->grp_sid);
369 if (psd->sacl != NULL)
370 offset += psd->sacl->size;
372 if (psd->dacl != NULL)
373 offset += psd->dacl->size;
378 /*******************************************************************
379 Compares two SEC_ACE structures
380 ********************************************************************/
382 BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
386 if (!s1 && !s2) return True;
388 /* Check top level stuff */
390 if (s1->type != s2->type || s1->flags != s2->flags ||
391 s1->info.mask != s2->info.mask) {
397 if (!sid_equal(&s1->trustee, &s2->trustee)) {
404 /*******************************************************************
405 Compares two SEC_ACL structures
406 ********************************************************************/
408 BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
414 if (!s1 && !s2) return True;
415 if (!s1 || !s2) return False;
417 /* Check top level stuff */
419 if (s1->revision != s2->revision) {
420 DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
421 s1->revision, s2->revision));
425 if (s1->num_aces != s2->num_aces) {
426 DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
427 s1->revision, s2->revision));
431 /* The ACEs could be in any order so check each ACE in s1 against
434 for (i = 0; i < s1->num_aces; i++) {
437 for (j = 0; j < s2->num_aces; j++) {
438 if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
444 if (!found) return False;
450 /*******************************************************************
451 Compares two SEC_DESC structures
452 ********************************************************************/
454 BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
462 /* Check top level stuff */
464 if (s1->revision != s2->revision) {
465 DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
466 s1->revision, s2->revision));
470 if (s1->type!= s2->type) {
471 DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
472 s1->type, s2->type));
476 /* Check owner and group */
478 if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
481 sid_to_string(str1, s1->owner_sid);
482 sid_to_string(str2, s2->owner_sid);
484 DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
489 if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
492 sid_to_string(str1, s1->grp_sid);
493 sid_to_string(str2, s2->grp_sid);
495 DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
500 /* Check ACLs present in one but not the other */
502 if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
503 (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
504 DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
508 /* Sigh - we have to do it the hard way by iterating over all
509 the ACEs in the ACLs */
511 if (!sec_acl_equal(s1->dacl, s2->dacl) ||
512 !sec_acl_equal(s1->sacl, s2->sacl)) {
513 DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
518 DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
522 /*******************************************************************
523 Merge part of security descriptor old_sec in to the empty sections of
524 security descriptor new_sec.
525 ********************************************************************/
527 SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
529 DOM_SID *owner_sid, *group_sid;
530 SEC_DESC_BUF *return_sdb;
531 SEC_ACL *dacl, *sacl;
532 SEC_DESC *psd = NULL;
536 /* Copy over owner and group sids. There seems to be no flag for
537 this so just check the pointer values. */
539 owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
540 old_sdb->sec->owner_sid;
542 group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
543 old_sdb->sec->grp_sid;
545 secdesc_type = new_sdb->sec->type;
547 /* Ignore changes to the system ACL. This has the effect of making
548 changes through the security tab audit button not sticking.
549 Perhaps in future Samba could implement these settings somehow. */
552 secdesc_type &= ~SEC_DESC_SACL_PRESENT;
554 /* Copy across discretionary ACL */
556 if (secdesc_type & SEC_DESC_DACL_PRESENT) {
557 dacl = new_sdb->sec->dacl;
559 dacl = old_sdb->sec->dacl;
562 /* Create new security descriptor from bits */
564 psd = make_sec_desc(ctx, new_sdb->sec->revision,
565 owner_sid, group_sid, sacl, dacl, &secdesc_size);
567 return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
572 /*******************************************************************
573 Creates a SEC_DESC structure
574 ********************************************************************/
576 SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
577 DOM_SID *owner_sid, DOM_SID *grp_sid,
578 SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
582 uint32 offset_sid = SEC_DESC_HEADER_SIZE;
583 uint32 offset_acl = 0;
587 if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
590 dst->revision = revision;
591 dst->type = SEC_DESC_SELF_RELATIVE;
593 if (sacl) dst->type |= SEC_DESC_SACL_PRESENT;
594 if (dacl) dst->type |= SEC_DESC_DACL_PRESENT;
596 dst->off_owner_sid = 0;
597 dst->off_grp_sid = 0;
601 if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
604 if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
607 if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
610 if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
616 * Work out the linearization sizes.
618 if (dst->owner_sid != NULL) {
621 offset = SEC_DESC_HEADER_SIZE;
623 offset += sid_size(dst->owner_sid);
626 if (dst->grp_sid != NULL) {
629 offset = SEC_DESC_HEADER_SIZE;
631 offset += sid_size(dst->grp_sid);
634 if (dst->sacl != NULL) {
636 offset_acl = SEC_DESC_HEADER_SIZE;
638 dst->off_sacl = offset_acl;
639 offset_acl += dst->sacl->size;
640 offset += dst->sacl->size;
641 offset_sid += dst->sacl->size;
644 if (dst->dacl != NULL) {
647 offset_acl = SEC_DESC_HEADER_SIZE;
649 dst->off_dacl = offset_acl;
650 offset_acl += dst->dacl->size;
651 offset += dst->dacl->size;
652 offset_sid += dst->dacl->size;
655 *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset);
657 if (dst->owner_sid != NULL)
658 dst->off_owner_sid = offset_sid;
660 /* sid_size() returns 0 if the sid is NULL so this is ok */
662 if (dst->grp_sid != NULL)
663 dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid);
673 /*******************************************************************
674 Duplicate a SEC_DESC structure.
675 ********************************************************************/
677 SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src)
684 return make_sec_desc( ctx, src->revision,
685 src->owner_sid, src->grp_sid, src->sacl,
689 /*******************************************************************
690 Creates a SEC_DESC structure with typical defaults.
691 ********************************************************************/
693 SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
694 SEC_ACL *dacl, size_t *sd_size)
696 return make_sec_desc(ctx, SEC_DESC_REVISION,
697 owner_sid, grp_sid, NULL, dacl, sd_size);
700 /*******************************************************************
701 Reads or writes a SEC_DESC structure.
702 If reading and the *ppsd = NULL, allocates the structure.
703 ********************************************************************/
705 BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
708 uint32 max_offset = 0; /* after we're done, move offset to end */
709 uint32 tmp_offset = 0;
719 if(UNMARSHALLING(ps)) {
720 if((psd = (SEC_DESC *)prs_alloc_mem(ps,sizeof(SEC_DESC))) == NULL)
724 /* Marshalling - just ignore. */
729 prs_debug(ps, depth, desc, "sec_io_desc");
734 * if alignment is needed, should be done by the the
735 * caller. Not here. This caused me problems when marshalling
736 * printer info into a buffer. --jerry
742 /* start of security descriptor stored for back-calc offset purposes */
743 old_offset = prs_offset(ps);
745 if(!prs_uint16("revision ", ps, depth, &psd->revision))
748 if(!prs_uint16("type ", ps, depth, &psd->type))
751 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
754 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
757 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
760 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
763 max_offset = MAX(max_offset, prs_offset(ps));
765 if (psd->off_owner_sid != 0) {
767 tmp_offset = prs_offset(ps);
768 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
771 if (UNMARSHALLING(ps)) {
773 if((psd->owner_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->owner_sid))) == NULL)
777 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
780 max_offset = MAX(max_offset, prs_offset(ps));
782 if (!prs_set_offset(ps,tmp_offset))
786 if (psd->off_grp_sid != 0) {
788 tmp_offset = prs_offset(ps);
789 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
792 if (UNMARSHALLING(ps)) {
794 if((psd->grp_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->grp_sid))) == NULL)
798 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
801 max_offset = MAX(max_offset, prs_offset(ps));
803 if (!prs_set_offset(ps,tmp_offset))
807 if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
808 tmp_offset = prs_offset(ps);
809 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
811 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
813 max_offset = MAX(max_offset, prs_offset(ps));
814 if (!prs_set_offset(ps,tmp_offset))
819 if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
820 tmp_offset = prs_offset(ps);
821 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
823 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
825 max_offset = MAX(max_offset, prs_offset(ps));
826 if (!prs_set_offset(ps,tmp_offset))
830 if(!prs_set_offset(ps, max_offset))
835 /*******************************************************************
836 Creates a SEC_DESC_BUF structure.
837 ********************************************************************/
839 SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
843 if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
846 /* max buffer size (allocated size) */
847 dst->max_len = (uint32)len;
848 dst->len = (uint32)len;
850 if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
859 /*******************************************************************
860 Duplicates a SEC_DESC_BUF structure.
861 ********************************************************************/
863 SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
868 return make_sec_desc_buf( ctx, src->len, src->sec);
871 /*******************************************************************
872 Reads or writes a SEC_DESC_BUF structure.
873 ********************************************************************/
875 BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
888 if (UNMARSHALLING(ps) && psdb == NULL) {
889 if((psdb = (SEC_DESC_BUF *)prs_alloc_mem(ps,sizeof(SEC_DESC_BUF))) == NULL)
894 prs_debug(ps, depth, desc, "sec_io_desc_buf");
900 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
903 if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr))
906 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
909 old_offset = prs_offset(ps);
911 /* reading, length is non-zero; writing, descriptor is non-NULL */
912 if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
913 if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
920 size = prs_offset(ps) - old_offset;
921 if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
924 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
930 /*******************************************************************
931 adds new SID with its permissions to SEC_DESC
932 ********************************************************************/
934 NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
943 if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
945 status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
947 if (!NT_STATUS_IS_OK(status))
950 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
951 return NT_STATUS_UNSUCCESSFUL;
953 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
954 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
955 return NT_STATUS_UNSUCCESSFUL;
962 /*******************************************************************
963 modify SID's permissions at SEC_DESC
964 ********************************************************************/
966 NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
970 if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER;
972 status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
974 if (!NT_STATUS_IS_OK(status))
980 /*******************************************************************
981 delete SID from SEC_DESC
982 ********************************************************************/
984 NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
993 if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
995 status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
997 if (!NT_STATUS_IS_OK(status))
1000 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
1001 return NT_STATUS_UNSUCCESSFUL;
1003 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
1004 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
1005 return NT_STATUS_UNSUCCESSFUL;
1009 return NT_STATUS_OK;