3 * THIS CODE IS OUT-OF-DATE BY TWO YEARS, IS LEGACY DESIGN AND VERY, VERY,
4 * INCOMPLETE. PLEASE DO NOT MAKE ANY FURTHER ENHANCEMENTS TO THIS CODE
5 * UNLESS THEY ARE ALSO CARRIED OUT IN THE SAMBA_TNG BRANCH.
7 * PLEASE DO NOT TREAT THIS CODE AS AUTHORITATIVE IN *ANY* WAY.
9 * REPEAT, PLEASE DO NOT MAKE ANY MODIFICATIONS TO THIS CODE WITHOUT
10 * FIRST CHECKING THE EQUIVALENT MODULE IN SAMBA_TNG, UPDATING THAT
11 * FIRST, *THEN* CONSIDER MAKING THE SAME MODIFICATION IN THIS BRANCH
13 * YOU WILL, ALMOST GUARANTEED, FIND THAT THE BUG-FIX OR ENHANCEMENT THAT
14 * YOU THINK IS NECESSARY, HAS ALREADY BEEN IMPLEMENTED IN SAMBA_TNG.
15 * IF IT HAS NOT, YOUR BUG-FIX OR ENHANCEMENT *MUST* GO INTO SAMBA_TNG
16 * AS THE SAMBA_TNG CODE WILL REPLACE THIS MODULE WITHOUT REFERENCE TO
17 * ANYTHING IN IT, WITH THE POSSIBLE RISK THAT THE BUG-FIX OR ENHANCEMENT
20 * PLEASE OBSERVE AND RESPECT THIS SIMPLE REQUEST.
28 * Unix SMB/Netbios implementation.
30 * RPC Pipe client / server routines
31 * Copyright (C) Andrew Tridgell 1992-1998,
32 * Copyright (C) Jeremy R. Allison 1995-1998
33 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
34 * Copyright (C) Paul Ashton 1997-1998.
36 * This program is free software; you can redistribute it and/or modify
37 * it under the terms of the GNU General Public License as published by
38 * the Free Software Foundation; either version 2 of the License, or
39 * (at your option) any later version.
41 * This program is distributed in the hope that it will be useful,
42 * but WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 * GNU General Public License for more details.
46 * You should have received a copy of the GNU General Public License
47 * along with this program; if not, write to the Free Software
48 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
54 extern int DEBUGLEVEL;
56 #define SD_HEADER_SIZE 0x14
58 /*******************************************************************
59 Sets up a SEC_ACCESS structure.
60 ********************************************************************/
62 void init_sec_access(SEC_ACCESS *t, uint32 mask)
67 /*******************************************************************
68 Reads or writes a SEC_ACCESS structure.
69 ********************************************************************/
71 BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
76 prs_debug(ps, depth, desc, "sec_io_access");
82 if(!prs_uint32("mask", ps, depth, &(t->mask)))
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->sid);
101 sid_copy(&t->sid, 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 if(!smb_io_dom_sid("sid ", &psa->sid , ps, depth))
142 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
148 /*******************************************************************
149 Create a SEC_ACL structure.
150 ********************************************************************/
152 SEC_ACL *make_sec_acl(uint16 revision, int num_aces, SEC_ACE *ace_list)
157 if((dst = (SEC_ACL *)malloc(sizeof(SEC_ACL))) == NULL)
162 dst->revision = revision;
163 dst->num_aces = num_aces;
166 if((dst->ace_list = (SEC_ACE *)malloc( sizeof(SEC_ACE) * num_aces )) == NULL) {
171 for (i = 0; i < num_aces; i++) {
172 dst->ace_list[i] = ace_list[i]; /* Structure copy. */
173 dst->size += ace_list[i].size;
179 /*******************************************************************
180 Duplicate a SEC_ACL structure.
181 ********************************************************************/
183 SEC_ACL *dup_sec_acl( SEC_ACL *src)
188 return make_sec_acl( src->revision, src->num_aces, src->ace_list);
191 /*******************************************************************
192 Delete a SEC_ACL structure.
193 ********************************************************************/
195 void free_sec_acl(SEC_ACL **ppsa)
199 if(ppsa == NULL || *ppsa == NULL)
203 if (psa->ace_list != NULL)
210 /*******************************************************************
211 Reads or writes a SEC_ACL structure.
213 First of the xx_io_xx functions that allocates its data structures
214 for you as it reads them.
215 ********************************************************************/
217 BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
221 uint32 offset_acl_size;
229 if(UNMARSHALLING(ps) && psa == NULL) {
231 * This is a read and we must allocate the stuct to read into.
233 if((psa = (SEC_ACL *)malloc(sizeof(SEC_ACL))) == NULL)
239 prs_debug(ps, depth, desc, "sec_io_acl");
245 old_offset = prs_offset(ps);
247 if(!prs_uint16("revision", ps, depth, &psa->revision))
250 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
253 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
256 if (UNMARSHALLING(ps) && psa->num_aces != 0) {
258 if((psa->ace_list = malloc(sizeof(psa->ace_list[0]) * psa->num_aces)) == NULL)
260 ZERO_STRUCTP(psa->ace_list);
263 for (i = 0; i < psa->num_aces; i++) {
265 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
266 if(!sec_io_ace(tmp, &psa->ace_list[i], ps, depth))
273 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
279 /*******************************************************************
280 Creates a SEC_DESC structure
281 ********************************************************************/
283 SEC_DESC *make_sec_desc(uint16 revision, uint16 type,
284 DOM_SID *owner_sid, DOM_SID *grp_sid,
285 SEC_ACL *sacl, SEC_ACL *dacl, size_t *sec_desc_size)
292 if(( dst = (SEC_DESC *)malloc(sizeof(SEC_DESC))) == NULL)
297 dst->revision = revision;
300 dst->off_owner_sid = 0;
301 dst->off_grp_sid = 0;
305 if(owner_sid && ((dst->owner_sid = sid_dup(owner_sid)) == NULL))
308 if(grp_sid && ((dst->grp_sid = sid_dup(grp_sid)) == NULL))
311 if(sacl && ((dst->sacl = dup_sec_acl(sacl)) == NULL))
314 if(dacl && ((dst->dacl = dup_sec_acl(dacl)) == NULL))
320 * Work out the linearization sizes.
323 if (dst->owner_sid != NULL) {
326 offset = SD_HEADER_SIZE;
328 dst->off_owner_sid = offset;
329 offset += ((sid_size(dst->owner_sid) + 3) & ~3);
332 if (dst->grp_sid != NULL) {
335 offset = SD_HEADER_SIZE;
337 dst->off_grp_sid = offset;
338 offset += ((sid_size(dst->grp_sid) + 3) & ~3);
341 if (dst->sacl != NULL) {
344 offset = SD_HEADER_SIZE;
346 dst->off_sacl = offset;
347 offset += ((sacl->size + 3) & ~3);
350 if (dst->dacl != NULL) {
353 offset = SD_HEADER_SIZE;
355 dst->off_dacl = offset;
356 offset += ((dacl->size + 3) & ~3);
359 *sec_desc_size = (size_t)((offset == 0) ? SD_HEADER_SIZE : offset);
369 /*******************************************************************
370 Duplicate a SEC_DESC structure.
371 ********************************************************************/
373 SEC_DESC *dup_sec_desc( SEC_DESC *src)
380 return make_sec_desc( src->revision, src->type,
381 src->owner_sid, src->grp_sid, src->sacl,
385 /*******************************************************************
386 Deletes a SEC_DESC structure
387 ********************************************************************/
389 void free_sec_desc(SEC_DESC **ppsd)
393 if(ppsd == NULL || *ppsd == NULL)
398 free_sec_acl(&psd->dacl);
399 free_sec_acl(&psd->dacl);
400 free(psd->owner_sid);
406 /*******************************************************************
407 Creates a SEC_DESC structure with typical defaults.
408 ********************************************************************/
410 SEC_DESC *make_standard_sec_desc(DOM_SID *owner_sid, DOM_SID *grp_sid,
411 SEC_ACL *dacl, size_t *sec_desc_size)
413 return make_sec_desc(1, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
414 owner_sid, grp_sid, NULL, dacl, sec_desc_size);
418 /*******************************************************************
419 Reads or writes a SEC_DESC structure.
420 If reading and the *ppsd = NULL, allocates the structure.
421 ********************************************************************/
423 BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
426 uint32 max_offset = 0; /* after we're done, move offset to end */
434 if(UNMARSHALLING(ps) && psd == NULL) {
435 if((psd = (SEC_DESC *)malloc(sizeof(SEC_DESC))) == NULL)
441 prs_debug(ps, depth, desc, "sec_io_desc");
447 /* start of security descriptor stored for back-calc offset purposes */
448 old_offset = prs_offset(ps);
450 if(!prs_uint16("revision ", ps, depth, &psd->revision))
453 if(!prs_uint16("type ", ps, depth, &psd->type))
456 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
459 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
462 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
465 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
468 max_offset = MAX(max_offset, prs_offset(ps));
470 if (psd->off_owner_sid != 0) {
472 if (UNMARSHALLING(ps)) {
473 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
476 if((psd->owner_sid = malloc(sizeof(*psd->owner_sid))) == NULL)
478 ZERO_STRUCTP(psd->owner_sid);
481 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
487 max_offset = MAX(max_offset, prs_offset(ps));
489 if (psd->off_grp_sid != 0) {
491 if (UNMARSHALLING(ps)) {
493 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
495 if((psd->grp_sid = malloc(sizeof(*psd->grp_sid))) == NULL)
497 ZERO_STRUCTP(psd->grp_sid);
500 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
506 max_offset = MAX(max_offset, prs_offset(ps));
508 if (IS_BITS_SET_ALL(psd->type, SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
509 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
511 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
517 max_offset = MAX(max_offset, prs_offset(ps));
519 if (IS_BITS_SET_ALL(psd->type, SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
520 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
522 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
528 max_offset = MAX(max_offset, prs_offset(ps));
530 if(!prs_set_offset(ps, max_offset))
535 /*******************************************************************
536 Creates a SEC_DESC_BUF structure.
537 ********************************************************************/
539 SEC_DESC_BUF *make_sec_desc_buf(int len, SEC_DESC *sec_desc)
543 if((dst = (SEC_DESC_BUF *)malloc(sizeof(SEC_DESC_BUF))) == NULL)
548 /* max buffer size (allocated size) */
552 if(sec_desc && ((dst->sec = dup_sec_desc(sec_desc)) == NULL)) {
553 free_sec_desc_buf(&dst);
560 /*******************************************************************
561 Duplicates a SEC_DESC_BUF structure.
562 ********************************************************************/
564 SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src)
569 return make_sec_desc_buf( src->len, src->sec);
572 /*******************************************************************
573 Deletes a SEC_DESC_BUF structure.
574 ********************************************************************/
576 void free_sec_desc_buf(SEC_DESC_BUF **ppsdb)
580 if(ppsdb == NULL || *ppsdb == NULL)
584 free_sec_desc(&psdb->sec);
590 /*******************************************************************
591 Reads or writes a SEC_DESC_BUF structure.
592 ********************************************************************/
594 BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
607 if (UNMARSHALLING(ps) && psdb == NULL) {
608 if((psdb = (SEC_DESC_BUF *)malloc(sizeof(SEC_DESC_BUF))) == NULL)
614 prs_debug(ps, depth, desc, "sec_io_desc_buf");
620 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
623 if(!prs_uint32 ("undoc ", ps, depth, &psdb->undoc))
626 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
629 old_offset = prs_offset(ps);
631 /* reading, length is non-zero; writing, descriptor is non-NULL */
632 if ((psdb->len != 0 || MARSHALLING(ps)) && psdb->sec != NULL) {
633 if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
637 size = prs_offset(ps) - old_offset;
638 if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
641 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))