r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation
[jra/samba/.git] / source3 / rpc_parse / parse_sec.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1998,
6  *  Copyright (C) Jeremy R. Allison            1995-2003.
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8  *  Copyright (C) Paul Ashton                  1997-1998.
9  *  
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.
14  *  
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.
19  *  
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.
23  */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_PARSE
29
30 /*******************************************************************
31  Reads or writes a SEC_ACCESS structure.
32 ********************************************************************/
33
34 BOOL sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
35 {
36         if (t == NULL)
37                 return False;
38
39         prs_debug(ps, depth, desc, "sec_io_access");
40         depth++;
41         
42         if(!prs_uint32("mask", ps, depth, &t->mask))
43                 return False;
44
45         return True;
46 }
47
48 /*******************************************************************
49  Reads or writes a SEC_ACE structure.
50 ********************************************************************/
51
52 BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
53 {
54         uint32 old_offset;
55         uint32 offset_ace_size;
56
57         if (psa == NULL)
58                 return False;
59
60         prs_debug(ps, depth, desc, "sec_io_ace");
61         depth++;
62         
63         old_offset = prs_offset(ps);
64
65         if(!prs_uint8("type ", ps, depth, &psa->type))
66                 return False;
67
68         if(!prs_uint8("flags", ps, depth, &psa->flags))
69                 return False;
70
71         if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
72                 return False;
73
74         if(!sec_io_access("info ", &psa->info, ps, depth))
75                 return False;
76
77         /* check whether object access is present */
78         if (!sec_ace_object(psa->type)) {
79                 if (!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
80                         return False;
81         } else {
82                 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
83                         return False;
84
85                 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
86                         if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
87                                 return False;
88
89                 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
90                         if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
91                                 return False;
92
93                 if(!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
94                         return False;
95         }
96
97         if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
98                 return False;
99         return True;
100 }
101
102 /*******************************************************************
103  Reads or writes a SEC_ACL structure.  
104
105  First of the xx_io_xx functions that allocates its data structures
106  for you as it reads them.
107 ********************************************************************/
108
109 BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
110 {
111         unsigned int i;
112         uint32 old_offset;
113         uint32 offset_acl_size;
114         SEC_ACL *psa;
115
116         /*
117          * Note that the size is always a multiple of 4 bytes due to the
118          * nature of the data structure.  Therefore the prs_align() calls
119          * have been removed as they through us off when doing two-layer
120          * marshalling such as in the printing code (NEW_BUFFER).  --jerry
121          */
122
123         if (ppsa == NULL)
124                 return False;
125
126         psa = *ppsa;
127
128         if(UNMARSHALLING(ps) && psa == NULL) {
129                 /*
130                  * This is a read and we must allocate the stuct to read into.
131                  */
132                 if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL)
133                         return False;
134                 *ppsa = psa;
135         }
136
137         prs_debug(ps, depth, desc, "sec_io_acl");
138         depth++;
139         
140         old_offset = prs_offset(ps);
141
142         if(!prs_uint16("revision", ps, depth, &psa->revision))
143                 return False;
144
145         if(!prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size))
146                 return False;
147
148         if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
149                 return False;
150
151         if (UNMARSHALLING(ps)) {
152                 /*
153                  * Even if the num_aces is zero, allocate memory as there's a difference
154                  * between a non-present DACL (allow all access) and a DACL with no ACE's
155                  * (allow no access).
156                  */
157                 if((psa->ace = PRS_ALLOC_MEM(ps, SEC_ACE, psa->num_aces+1)) == NULL)
158                         return False;
159         }
160
161         for (i = 0; i < psa->num_aces; i++) {
162                 fstring tmp;
163                 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
164                 if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
165                         return False;
166         }
167
168         if(!prs_uint16_post("size     ", ps, depth, &psa->size, offset_acl_size, old_offset))
169                 return False;
170
171         return True;
172 }
173
174 /*******************************************************************
175  Reads or writes a SEC_DESC structure.
176  If reading and the *ppsd = NULL, allocates the structure.
177 ********************************************************************/
178
179 BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
180 {
181         uint32 old_offset;
182         uint32 max_offset = 0; /* after we're done, move offset to end */
183         uint32 tmp_offset = 0;
184         
185         SEC_DESC *psd;
186
187         if (ppsd == NULL)
188                 return False;
189
190         psd = *ppsd;
191
192         if (psd == NULL) {
193                 if(UNMARSHALLING(ps)) {
194                         if((psd = PRS_ALLOC_MEM(ps,SEC_DESC,1)) == NULL)
195                                 return False;
196                         *ppsd = psd;
197                 } else {
198                         /* Marshalling - just ignore. */
199                         return True;
200                 }
201         }
202
203         prs_debug(ps, depth, desc, "sec_io_desc");
204         depth++;
205
206 #if 0   
207         /*
208          * if alignment is needed, should be done by the the 
209          * caller.  Not here.  This caused me problems when marshalling
210          * printer info into a buffer.   --jerry
211          */
212         if(!prs_align(ps))
213                 return False;
214 #endif
215         
216         /* start of security descriptor stored for back-calc offset purposes */
217         old_offset = prs_offset(ps);
218
219         if(!prs_uint16("revision ", ps, depth, &psd->revision))
220                 return False;
221
222         if(!prs_uint16("type     ", ps, depth, &psd->type))
223                 return False;
224
225         if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
226                 return False;
227
228         if(!prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid))
229                 return False;
230
231         if(!prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl))
232                 return False;
233
234         if(!prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
235                 return False;
236
237         max_offset = MAX(max_offset, prs_offset(ps));
238
239         if (psd->off_owner_sid != 0) {
240
241                 tmp_offset = prs_offset(ps);
242                 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
243                         return False;
244
245                 if (UNMARSHALLING(ps)) {
246                         /* reading */
247                         if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
248                                 return False;
249                 }
250
251                 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
252                         return False;
253
254                 max_offset = MAX(max_offset, prs_offset(ps));
255
256                 if (!prs_set_offset(ps,tmp_offset))
257                         return False;
258         }
259
260         if (psd->off_grp_sid != 0) {
261
262                 tmp_offset = prs_offset(ps);
263                 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
264                         return False;
265
266                 if (UNMARSHALLING(ps)) {
267                         /* reading */
268                         if((psd->grp_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
269                                 return False;
270                 }
271
272                 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
273                         return False;
274                         
275                 max_offset = MAX(max_offset, prs_offset(ps));
276
277                 if (!prs_set_offset(ps,tmp_offset))
278                         return False;
279         }
280
281         if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
282                 tmp_offset = prs_offset(ps);
283                 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
284                         return False;
285                 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
286                         return False;
287                 max_offset = MAX(max_offset, prs_offset(ps));
288                 if (!prs_set_offset(ps,tmp_offset))
289                         return False;
290         }
291
292
293         if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
294                 tmp_offset = prs_offset(ps);
295                 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
296                         return False;
297                 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
298                         return False;
299                 max_offset = MAX(max_offset, prs_offset(ps));
300                 if (!prs_set_offset(ps,tmp_offset))
301                         return False;
302         }
303
304         if(!prs_set_offset(ps, max_offset))
305                 return False;
306         return True;
307 }
308
309 /*******************************************************************
310  Reads or writes a SEC_DESC_BUF structure.
311 ********************************************************************/
312
313 BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
314 {
315         uint32 off_len;
316         uint32 off_max_len;
317         uint32 old_offset;
318         uint32 size;
319         SEC_DESC_BUF *psdb;
320
321         if (ppsdb == NULL)
322                 return False;
323
324         psdb = *ppsdb;
325
326         if (UNMARSHALLING(ps) && psdb == NULL) {
327                 if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL)
328                         return False;
329                 *ppsdb = psdb;
330         }
331
332         prs_debug(ps, depth, desc, "sec_io_desc_buf");
333         depth++;
334
335         if(!prs_align(ps))
336                 return False;
337         
338         if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
339                 return False;
340
341         if(!prs_uint32    ("ptr  ", ps, depth, &psdb->ptr))
342                 return False;
343
344         if(!prs_uint32_pre("len    ", ps, depth, &psdb->len, &off_len))
345                 return False;
346
347         old_offset = prs_offset(ps);
348
349         /* reading, length is non-zero; writing, descriptor is non-NULL */
350         if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
351                 if(!sec_io_desc("sec   ", &psdb->sec, ps, depth))
352                         return False;
353         }
354
355         if(!prs_align(ps))
356                 return False;
357         
358         size = prs_offset(ps) - old_offset;
359         if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
360                 return False;
361
362         if(!prs_uint32_post("len    ", ps, depth, &psdb->len, off_len, size))
363                 return False;
364
365         return True;
366 }