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.
27 #define DBGC_CLASS DBGC_RPC_PARSE
29 /*******************************************************************
30 Sets up a SEC_ACCESS structure.
31 ********************************************************************/
33 void init_sec_access(SEC_ACCESS *t, uint32 mask)
38 /*******************************************************************
39 Reads or writes a SEC_ACCESS structure.
40 ********************************************************************/
42 BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
47 prs_debug(ps, depth, desc, "sec_io_access");
53 if(!prs_uint32("mask", ps, depth, &(t->mask)))
59 /*******************************************************************
60 Check if ACE has OBJECT type.
61 ********************************************************************/
63 BOOL sec_ace_object(uint8 type)
65 if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
66 type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
67 type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
68 type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
74 /*******************************************************************
75 copy a SEC_ACE structure.
76 ********************************************************************/
77 void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
79 ace_dest->type = ace_src->type;
80 ace_dest->flags = ace_src->flags;
81 ace_dest->size = ace_src->size;
82 ace_dest->info.mask = ace_src->info.mask;
83 ace_dest->obj_flags = ace_src->obj_flags;
84 memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, GUID_SIZE);
85 memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE);
86 sid_copy(&ace_dest->trustee, &ace_src->trustee);
89 /*******************************************************************
90 Sets up a SEC_ACE structure.
91 ********************************************************************/
93 void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
97 t->size = sid_size(sid) + 8;
100 ZERO_STRUCTP(&t->trustee);
101 sid_copy(&t->trustee, sid);
104 /*******************************************************************
105 Reads or writes a SEC_ACE structure.
106 ********************************************************************/
108 BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
111 uint32 offset_ace_size;
116 prs_debug(ps, depth, desc, "sec_io_ace");
122 old_offset = prs_offset(ps);
124 if(!prs_uint8("type ", ps, depth, &psa->type))
127 if(!prs_uint8("flags", ps, depth, &psa->flags))
130 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
133 if(!sec_io_access("info ", &psa->info, ps, depth))
139 /* check whether object access is present */
140 if (!sec_ace_object(psa->type)) {
141 if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
144 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
147 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
148 if (!prs_uint8s(False, "obj_guid", ps, depth, psa->obj_guid.info, GUID_SIZE))
151 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
152 if (!prs_uint8s(False, "inh_guid", ps, depth, psa->inh_guid.info, GUID_SIZE))
155 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
159 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
164 /*******************************************************************
165 adds new SID with its permissions to ACE list
166 ********************************************************************/
168 NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid, uint32 mask)
172 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
176 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
177 return NT_STATUS_NO_MEMORY;
179 for (i = 0; i < *num - 1; i ++)
180 sec_ace_copy(&(*new)[i], &old[i]);
184 (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
185 (*new)[i].info.mask = mask;
186 sid_copy(&(*new)[i].trustee, sid);
190 /*******************************************************************
191 modify SID's permissions at ACL
192 ********************************************************************/
194 NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
198 if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
200 for (i = 0; i < num; i ++) {
201 if (sid_compare(&ace[i].trustee, sid) == 0) {
202 ace[i].info.mask = mask;
206 return NT_STATUS_NOT_FOUND;
209 /*******************************************************************
211 ********************************************************************/
213 NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid)
218 if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
220 if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0)
221 return NT_STATUS_NO_MEMORY;
223 for (i = 0; i < *num; i ++) {
224 if (sid_compare(&old[i].trustee, sid) != 0)
225 sec_ace_copy(&(*new)[i], &old[i]);
230 return NT_STATUS_NOT_FOUND;
237 /*******************************************************************
238 Create a SEC_ACL structure.
239 ********************************************************************/
241 SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
246 if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
249 dst->revision = revision;
250 dst->num_aces = num_aces;
251 dst->size = SEC_ACL_HEADER_SIZE;
253 /* Now we need to return a non-NULL address for the ace list even
254 if the number of aces required is zero. This is because there
255 is a distinct difference between a NULL ace and an ace with zero
256 entries in it. This is achieved by checking that num_aces is a
260 ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
265 for (i = 0; i < num_aces; i++) {
266 dst->ace[i] = ace_list[i]; /* Structure copy. */
267 dst->size += ace_list[i].size;
273 /*******************************************************************
274 Duplicate a SEC_ACL structure.
275 ********************************************************************/
277 SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
282 return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
285 /*******************************************************************
286 Reads or writes a SEC_ACL structure.
288 First of the xx_io_xx functions that allocates its data structures
289 for you as it reads them.
290 ********************************************************************/
292 BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
296 uint32 offset_acl_size;
304 if(UNMARSHALLING(ps) && psa == NULL) {
306 * This is a read and we must allocate the stuct to read into.
308 if((psa = (SEC_ACL *)prs_alloc_mem(ps, sizeof(SEC_ACL))) == NULL)
313 prs_debug(ps, depth, desc, "sec_io_acl");
319 old_offset = prs_offset(ps);
321 if(!prs_uint16("revision", ps, depth, &psa->revision))
324 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
327 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
330 if (UNMARSHALLING(ps)) {
332 * Even if the num_aces is zero, allocate memory as there's a difference
333 * between a non-present DACL (allow all access) and a DACL with no ACE's
336 if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * (psa->num_aces+1))) == NULL)
340 for (i = 0; i < psa->num_aces; i++) {
342 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
343 if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
350 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
356 /*******************************************************************
357 Works out the linearization size of a SEC_DESC.
358 ********************************************************************/
360 size_t sec_desc_size(SEC_DESC *psd)
366 offset = SEC_DESC_HEADER_SIZE;
368 if (psd->owner_sid != NULL)
369 offset += ((sid_size(psd->owner_sid) + 3) & ~3);
371 if (psd->grp_sid != NULL)
372 offset += ((sid_size(psd->grp_sid) + 3) & ~3);
374 if (psd->sacl != NULL)
375 offset += ((psd->sacl->size + 3) & ~3);
377 if (psd->dacl != NULL)
378 offset += ((psd->dacl->size + 3) & ~3);
383 /*******************************************************************
384 Compares two SEC_ACE structures
385 ********************************************************************/
387 BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
391 if (!s1 && !s2) return True;
393 /* Check top level stuff */
395 if (s1->type != s2->type || s1->flags != s2->flags ||
396 s1->info.mask != s2->info.mask) {
402 if (!sid_equal(&s1->trustee, &s2->trustee)) {
409 /*******************************************************************
410 Compares two SEC_ACL structures
411 ********************************************************************/
413 BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
419 if (!s1 && !s2) return True;
420 if (!s1 || !s2) return False;
422 /* Check top level stuff */
424 if (s1->revision != s2->revision) {
425 DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
426 s1->revision, s2->revision));
430 if (s1->num_aces != s2->num_aces) {
431 DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
432 s1->revision, s2->revision));
436 /* The ACEs could be in any order so check each ACE in s1 against
439 for (i = 0; i < s1->num_aces; i++) {
442 for (j = 0; j < s2->num_aces; j++) {
443 if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
449 if (!found) return False;
455 /*******************************************************************
456 Compares two SEC_DESC structures
457 ********************************************************************/
459 BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
467 /* Check top level stuff */
469 if (s1->revision != s2->revision) {
470 DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
471 s1->revision, s2->revision));
475 if (s1->type!= s2->type) {
476 DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
477 s1->type, s2->type));
481 /* Check owner and group */
483 if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
486 sid_to_string(str1, s1->owner_sid);
487 sid_to_string(str2, s2->owner_sid);
489 DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
494 if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
497 sid_to_string(str1, s1->grp_sid);
498 sid_to_string(str2, s2->grp_sid);
500 DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
505 /* Check ACLs present in one but not the other */
507 if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
508 (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
509 DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
513 /* Sigh - we have to do it the hard way by iterating over all
514 the ACEs in the ACLs */
516 if (!sec_acl_equal(s1->dacl, s2->dacl) ||
517 !sec_acl_equal(s1->sacl, s2->sacl)) {
518 DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
523 DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
527 /*******************************************************************
528 Merge part of security descriptor old_sec in to the empty sections of
529 security descriptor new_sec.
530 ********************************************************************/
532 SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
534 DOM_SID *owner_sid, *group_sid;
535 SEC_DESC_BUF *return_sdb;
536 SEC_ACL *dacl, *sacl;
537 SEC_DESC *psd = NULL;
541 /* Copy over owner and group sids. There seems to be no flag for
542 this so just check the pointer values. */
544 owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
545 old_sdb->sec->owner_sid;
547 group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
548 old_sdb->sec->grp_sid;
550 secdesc_type = new_sdb->sec->type;
552 /* Ignore changes to the system ACL. This has the effect of making
553 changes through the security tab audit button not sticking.
554 Perhaps in future Samba could implement these settings somehow. */
557 secdesc_type &= ~SEC_DESC_SACL_PRESENT;
559 /* Copy across discretionary ACL */
561 if (secdesc_type & SEC_DESC_DACL_PRESENT) {
562 dacl = new_sdb->sec->dacl;
564 dacl = old_sdb->sec->dacl;
567 /* Create new security descriptor from bits */
569 psd = make_sec_desc(ctx, new_sdb->sec->revision,
570 owner_sid, group_sid, sacl, dacl, &secdesc_size);
572 return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
577 /*******************************************************************
578 Tallocs a duplicate SID.
579 ********************************************************************/
581 static DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
588 if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
595 /*******************************************************************
596 Creates a SEC_DESC structure
597 ********************************************************************/
599 SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
600 DOM_SID *owner_sid, DOM_SID *grp_sid,
601 SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
605 uint32 offset_sid = SEC_DESC_HEADER_SIZE;
606 uint32 offset_acl = 0;
610 if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
613 dst->revision = revision;
614 dst->type = SEC_DESC_SELF_RELATIVE;
616 if (sacl) dst->type |= SEC_DESC_SACL_PRESENT;
617 if (dacl) dst->type |= SEC_DESC_DACL_PRESENT;
619 dst->off_owner_sid = 0;
620 dst->off_grp_sid = 0;
624 if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
627 if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
630 if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
633 if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
639 * Work out the linearization sizes.
641 if (dst->owner_sid != NULL) {
644 offset = SEC_DESC_HEADER_SIZE;
646 offset += ((sid_size(dst->owner_sid) + 3) & ~3);
649 if (dst->grp_sid != NULL) {
652 offset = SEC_DESC_HEADER_SIZE;
654 offset += ((sid_size(dst->grp_sid) + 3) & ~3);
657 if (dst->sacl != NULL) {
659 offset_acl = SEC_DESC_HEADER_SIZE;
661 dst->off_sacl = offset_acl;
662 offset_acl += ((dst->sacl->size + 3) & ~3);
663 offset += dst->sacl->size;
664 offset_sid += dst->sacl->size;
667 if (dst->dacl != NULL) {
670 offset_acl = SEC_DESC_HEADER_SIZE;
672 dst->off_dacl = offset_acl;
673 offset_acl += ((dst->dacl->size + 3) & ~3);
674 offset += dst->dacl->size;
675 offset_sid += dst->dacl->size;
678 *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset);
680 if (dst->owner_sid != NULL) {
681 dst->off_owner_sid = offset_sid;
682 dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid);
685 if (dst->grp_sid != NULL)
686 dst->off_grp_sid = offset_sid;
696 /*******************************************************************
697 Duplicate a SEC_DESC structure.
698 ********************************************************************/
700 SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src)
707 return make_sec_desc( ctx, src->revision,
708 src->owner_sid, src->grp_sid, src->sacl,
712 /*******************************************************************
713 Creates a SEC_DESC structure with typical defaults.
714 ********************************************************************/
716 SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
717 SEC_ACL *dacl, size_t *sd_size)
719 return make_sec_desc(ctx, SEC_DESC_REVISION,
720 owner_sid, grp_sid, NULL, dacl, sd_size);
723 /*******************************************************************
724 Reads or writes a SEC_DESC structure.
725 If reading and the *ppsd = NULL, allocates the structure.
726 ********************************************************************/
728 BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
731 uint32 max_offset = 0; /* after we're done, move offset to end */
732 uint32 tmp_offset = 0;
742 if(UNMARSHALLING(ps)) {
743 if((psd = (SEC_DESC *)prs_alloc_mem(ps,sizeof(SEC_DESC))) == NULL)
747 /* Marshalling - just ignore. */
752 prs_debug(ps, depth, desc, "sec_io_desc");
757 * if alignment is needed, should be done by the the
758 * caller. Not here. This caused me problems when marshalling
759 * printer info into a buffer. --jerry
765 /* start of security descriptor stored for back-calc offset purposes */
766 old_offset = prs_offset(ps);
768 if(!prs_uint16("revision ", ps, depth, &psd->revision))
771 if(!prs_uint16("type ", ps, depth, &psd->type))
774 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
777 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
780 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
783 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
786 max_offset = MAX(max_offset, prs_offset(ps));
788 if (psd->off_owner_sid != 0) {
790 if (UNMARSHALLING(ps)) {
791 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
794 if((psd->owner_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->owner_sid))) == NULL)
798 tmp_offset = ps->data_offset;
799 ps->data_offset = psd->off_owner_sid;
801 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
806 ps->data_offset = tmp_offset;
809 max_offset = MAX(max_offset, prs_offset(ps));
811 if (psd->off_grp_sid != 0) {
813 if (UNMARSHALLING(ps)) {
815 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
817 if((psd->grp_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->grp_sid))) == NULL)
821 tmp_offset = ps->data_offset;
822 ps->data_offset = psd->off_grp_sid;
824 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
829 ps->data_offset = tmp_offset;
832 max_offset = MAX(max_offset, prs_offset(ps));
834 if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
835 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
837 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
843 max_offset = MAX(max_offset, prs_offset(ps));
845 if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
846 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
848 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
854 max_offset = MAX(max_offset, prs_offset(ps));
856 if(!prs_set_offset(ps, max_offset))
861 /*******************************************************************
862 Creates a SEC_DESC_BUF structure.
863 ********************************************************************/
865 SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
869 if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
872 /* max buffer size (allocated size) */
873 dst->max_len = (uint32)len;
874 dst->len = (uint32)len;
876 if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
885 /*******************************************************************
886 Duplicates a SEC_DESC_BUF structure.
887 ********************************************************************/
889 SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
894 return make_sec_desc_buf( ctx, src->len, src->sec);
897 /*******************************************************************
898 Reads or writes a SEC_DESC_BUF structure.
899 ********************************************************************/
901 BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
914 if (UNMARSHALLING(ps) && psdb == NULL) {
915 if((psdb = (SEC_DESC_BUF *)prs_alloc_mem(ps,sizeof(SEC_DESC_BUF))) == NULL)
920 prs_debug(ps, depth, desc, "sec_io_desc_buf");
926 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
929 if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr))
932 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
935 old_offset = prs_offset(ps);
937 /* reading, length is non-zero; writing, descriptor is non-NULL */
938 if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
939 if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
946 size = prs_offset(ps) - old_offset;
947 if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
950 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
956 /*******************************************************************
957 adds new SID with its permissions to SEC_DESC
958 ********************************************************************/
960 NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
969 if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
971 status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
973 if (!NT_STATUS_IS_OK(status))
976 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
977 return NT_STATUS_UNSUCCESSFUL;
979 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
980 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
981 return NT_STATUS_UNSUCCESSFUL;
988 /*******************************************************************
989 modify SID's permissions at SEC_DESC
990 ********************************************************************/
992 NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
996 if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER;
998 status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
1000 if (!NT_STATUS_IS_OK(status))
1003 return NT_STATUS_OK;
1006 /*******************************************************************
1007 delete SID from SEC_DESC
1008 ********************************************************************/
1010 NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
1019 if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
1021 status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
1023 if (!NT_STATUS_IS_OK(status))
1026 if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
1027 return NT_STATUS_UNSUCCESSFUL;
1029 if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid,
1030 psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
1031 return NT_STATUS_UNSUCCESSFUL;
1035 return NT_STATUS_OK;