- typecast malloc / Realloc issues.
[bbaumbach/samba-autobuild/.git] / source / 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-1999,
6  *  Copyright (C) Jeremy R. Allison            1995-1999
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
8  *  Copyright (C) Paul Ashton                  1997-1999.
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
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30
31 /*******************************************************************
32 makes a structure.
33 ********************************************************************/
34 BOOL make_sec_access(SEC_ACCESS *t, uint32 mask)
35 {
36         t->mask = mask;
37
38         return True;
39 }
40
41 /*******************************************************************
42 reads or writes a structure.
43 ********************************************************************/
44 BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
45 {
46         if (t == NULL) return False;
47
48         prs_debug(ps, depth, desc, "sec_io_access");
49         depth++;
50
51         prs_align(ps);
52         
53         prs_uint32("mask", ps, depth, &(t->mask));
54
55         return True;
56 }
57
58
59 /*******************************************************************
60 makes a structure.
61 ********************************************************************/
62 BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
63 {
64         t->type = type;
65         t->flags = flag;
66         t->size = sid_size(sid) + 8;
67         t->info = mask;
68
69         sid_copy(&t->sid, sid);
70
71         return True;
72 }
73
74 /*******************************************************************
75 reads or writes a structure.
76 ********************************************************************/
77 BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth)
78 {
79         uint32 old_offset;
80         uint32 offset_ace_size;
81         if (t == NULL) return False;
82
83         prs_debug(ps, depth, desc, "sec_io_ace");
84         depth++;
85
86         prs_align(ps);
87         
88         old_offset = ps->offset;
89
90         prs_uint8     ("type ", ps, depth, &(t->type));
91         prs_uint8     ("flags", ps, depth, &(t->flags));
92         prs_uint16_pre("size ", ps, depth, &(t->size ), &offset_ace_size);
93
94         sec_io_access   ("info ", &t->info, ps, depth);
95         prs_align(ps);
96         smb_io_dom_sid("sid  ", &t->sid , ps, depth);
97
98         prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size, old_offset);
99
100         return True;
101 }
102
103 /*******************************************************************
104 makes a structure.  
105 ********************************************************************/
106 BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace)
107 {
108         int i;
109         t->revision = revision;
110         t->num_aces = num_aces;
111         t->size = 4;
112         t->ace = ace;
113
114         for (i = 0; i < num_aces; i++)
115         {
116                 t->size += ace[i].size;
117         }
118
119         return True;
120 }
121
122 /*******************************************************************
123 frees a structure.  
124 ********************************************************************/
125 void free_sec_acl(SEC_ACL *t)
126 {
127         if (t->ace != NULL)
128         {
129                 free(t->ace);
130         }
131 }
132
133 /*******************************************************************
134 reads or writes a structure.  
135
136 first of the xx_io_xx functions that allocates its data structures
137  for you as it reads them.
138 ********************************************************************/
139 BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth)
140 {
141         uint32 i;
142         uint32 old_offset;
143         uint32 offset_acl_size;
144
145         if (t == NULL) return False;
146
147         prs_debug(ps, depth, desc, "sec_io_acl");
148         depth++;
149
150         prs_align(ps);
151         
152         old_offset = ps->offset;
153
154         prs_uint16("revision", ps, depth, &(t->revision));
155         prs_uint16_pre("size     ", ps, depth, &(t->size     ), &offset_acl_size);
156         prs_uint32("num_aces ", ps, depth, &(t->num_aces ));
157
158         if (ps->io && t->num_aces != 0)
159         {
160                 /* reading */
161                 t->ace = (SEC_ACE*)malloc(sizeof(t->ace[0]) * t->num_aces);
162                 ZERO_STRUCTP(t->ace);
163                 }
164
165         if (t->ace == NULL && t->num_aces != 0)
166         {
167                 DEBUG(0,("INVALID ACL\n"));
168                 ps->offset = 0xfffffffe;
169                 return False;
170         }
171
172         for (i = 0; i < MIN(t->num_aces, MAX_SEC_ACES); i++)
173         {
174                 fstring tmp;
175                 slprintf(tmp, sizeof(tmp)-1, "ace[%02d]: ", i);
176                 sec_io_ace(tmp, &t->ace[i], ps, depth);
177         }
178
179         prs_align(ps);
180
181         prs_uint16_post("size     ", ps, depth, &t->size    , offset_acl_size, old_offset);
182
183         return True;
184 }
185
186
187 /*******************************************************************
188 makes a structure
189 ********************************************************************/
190 int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
191                         DOM_SID *owner_sid, DOM_SID *grp_sid,
192                                 SEC_ACL *sacl, SEC_ACL *dacl)
193 {
194         uint32 offset;
195
196         t->revision = revision;
197         t->type     = type;
198
199         t->off_owner_sid = 0;
200         t->off_grp_sid   = 0;
201         t->off_sacl      = 0;
202         t->off_dacl      = 0;
203
204         t->dacl      = dacl;
205         t->sacl      = sacl;
206         t->owner_sid = owner_sid;
207         t->grp_sid   = grp_sid;
208
209         offset = 0x0;
210
211         if (dacl != NULL)
212         {
213                 if (offset == 0)
214                 {
215                         offset = 0x14;
216                 }
217                 t->off_dacl = offset;
218                 offset += dacl->size;
219         }
220
221         if (sacl != NULL)
222         {
223                 if (offset == 0)
224                 {
225                         offset = 0x14;
226                 }
227                 t->off_dacl = offset;
228                 offset += dacl->size;
229         }
230
231         if (owner_sid != NULL)
232         {
233                 if (offset == 0)
234                 {
235                         offset = 0x14;
236                 }
237                 t->off_owner_sid = offset;
238                 offset += sid_size(owner_sid);
239         }
240
241         if (grp_sid != NULL)
242         {
243                 if (offset == 0)
244                 {
245                         offset = 0x14;
246                 }
247                 t->off_grp_sid = offset;
248                 offset += sid_size(grp_sid);
249         }
250
251         return (offset == 0) ? 0x14 : offset;
252 }
253
254
255 /*******************************************************************
256 frees a structure
257 ********************************************************************/
258 void free_sec_desc(SEC_DESC *t)
259 {
260         if (t->dacl != NULL)
261         {
262                 free_sec_acl(t->dacl);
263         }
264
265         if (t->sacl != NULL)
266         {
267                 free_sec_acl(t->dacl);
268
269         }
270
271         if (t->owner_sid != NULL)
272         {
273                 free(t->owner_sid);
274         }
275
276         if (t->grp_sid != NULL)
277         {
278                 free(t->grp_sid);
279         }
280 }
281
282
283 /*******************************************************************
284 reads or writes a structure.
285 ********************************************************************/
286 static BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
287 {
288 #if 0
289         uint32 off_owner_sid;
290         uint32 off_grp_sid  ;
291         uint32 off_sacl     ;
292         uint32 off_dacl     ;
293 #endif
294         uint32 old_offset;
295         uint32 max_offset = 0; /* after we're done, move offset to end */
296
297         if (t == NULL) return False;
298
299         prs_debug(ps, depth, desc, "sec_io_desc");
300         depth++;
301
302         prs_align(ps);
303         
304         /* start of security descriptor stored for back-calc offset purposes */
305         old_offset = ps->offset;
306
307         prs_uint16("revision ", ps, depth, &(t->revision ));
308         prs_uint16("type     ", ps, depth, &(t->type     ));
309
310         prs_uint32("off_owner_sid", ps, depth, &(t->off_owner_sid));
311         prs_uint32("off_grp_sid  ", ps, depth, &(t->off_grp_sid  ));
312         prs_uint32("off_sacl     ", ps, depth, &(t->off_sacl     ));
313         prs_uint32("off_dacl     ", ps, depth, &(t->off_dacl     ));
314 #if 0
315         prs_uint32_pre("off_owner_sid", ps, depth, &(t->off_owner_sid), &off_owner_sid);
316         prs_uint32_pre("off_grp_sid  ", ps, depth, &(t->off_grp_sid  ), &off_grp_sid  );
317         prs_uint32_pre("off_sacl     ", ps, depth, &(t->off_sacl     ), &off_sacl     );
318         prs_uint32_pre("off_dacl     ", ps, depth, &(t->off_dacl     ), &off_dacl     );
319 #endif
320         max_offset = MAX(max_offset, ps->offset);
321
322         if (IS_BITS_SET_ALL(t->type, SEC_DESC_DACL_PRESENT))
323         {
324 #if 0
325                 prs_uint32_post("off_dacl    ", ps, depth, &(t->off_dacl     ), off_dacl     , ps->offset - old_offset);
326 #endif
327                 ps->offset = old_offset + t->off_dacl;
328                 if (ps->io)
329                 {
330                         /* reading */
331                         t->dacl = (SEC_ACL*)malloc(sizeof(*t->dacl));
332                         ZERO_STRUCTP(t->dacl);
333                 }
334
335                 if (t->dacl == NULL)
336                 {
337                         DEBUG(0,("INVALID DACL\n"));
338                         ps->offset = 0xfffffffe;
339                         return False;
340                 }
341
342                 sec_io_acl     ("dacl"        , t->dacl       , ps, depth);
343                 prs_align(ps);
344         }
345 #if 0
346         else
347         {
348                 prs_uint32_post("off_dacl    ", ps, depth, &(t->off_dacl     ), off_dacl     , 0);
349         }
350 #endif
351
352         max_offset = MAX(max_offset, ps->offset);
353
354         if (IS_BITS_SET_ALL(t->type, SEC_DESC_SACL_PRESENT))
355         {
356 #if 0
357                 prs_uint32_post("off_sacl  ", ps, depth, &(t->off_sacl  ), off_sacl  , ps->offset - old_offset);
358 #endif
359                 ps->offset = old_offset + t->off_sacl;
360                 if (ps->io)
361                 {
362                         /* reading */
363                         t->sacl = (SEC_ACL*)malloc(sizeof(*t->sacl));
364                         ZERO_STRUCTP(t->sacl);
365                 }
366
367                 if (t->sacl == NULL)
368                 {
369                         DEBUG(0,("INVALID SACL\n"));
370                         ps->offset = 0xfffffffe;
371                         return False;
372                 }
373
374                 sec_io_acl     ("sacl"      , t->sacl       , ps, depth);
375                 prs_align(ps);
376         }
377 #if 0
378         else
379         {
380                 prs_uint32_post("off_sacl  ", ps, depth, &(t->off_sacl  ), off_sacl  , 0);
381         }
382 #endif
383
384         max_offset = MAX(max_offset, ps->offset);
385
386 #if 0
387         prs_uint32_post("off_owner_sid", ps, depth, &(t->off_owner_sid), off_owner_sid, ps->offset - old_offset);
388 #endif
389         if (t->off_owner_sid != 0)
390         {
391                 if (ps->io)
392                 {
393                         ps->offset = old_offset + t->off_owner_sid;
394                         }
395                 if (ps->io)
396                 {
397                         /* reading */
398                         t->owner_sid = (DOM_SID*)malloc(sizeof(*t->owner_sid));
399                         ZERO_STRUCTP(t->owner_sid);
400                 }
401
402                 if (t->owner_sid == NULL)
403                 {
404                         DEBUG(0,("INVALID OWNER SID\n"));
405                         ps->offset = 0xfffffffe;
406                         return False;
407                 }
408
409                 smb_io_dom_sid("owner_sid ", t->owner_sid , ps, depth);
410                 prs_align(ps);
411         }
412
413         max_offset = MAX(max_offset, ps->offset);
414
415 #if 0
416         prs_uint32_post("off_grp_sid  ", ps, depth, &(t->off_grp_sid  ), off_grp_sid  , ps->offset - old_offset);
417 #endif
418         if (t->off_grp_sid != 0)
419         {
420                 if (ps->io)
421                 {
422                         ps->offset = old_offset + t->off_grp_sid;
423
424                 }
425                 if (ps->io)
426                 {
427                         /* reading */
428                         t->grp_sid = (DOM_SID*)malloc(sizeof(*t->grp_sid));
429                         ZERO_STRUCTP(t->grp_sid);
430                 }
431
432                 if (t->grp_sid == NULL)
433                 {
434                         DEBUG(0,("INVALID GROUP SID\n"));
435                         ps->offset = 0xfffffffe;
436                         return False;
437                 }
438
439                 smb_io_dom_sid("grp_sid", t->grp_sid, ps, depth);
440                 prs_align(ps);
441         }
442
443         max_offset = MAX(max_offset, ps->offset);
444
445         ps->offset = max_offset;
446
447         return True;
448 }
449
450 /*******************************************************************
451 creates a SEC_DESC_BUF structure.
452 ********************************************************************/
453 BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data)
454 {
455         ZERO_STRUCTP(buf);
456
457         /* max buffer size (allocated size) */
458         buf->max_len = len;
459         buf->undoc       = 0;
460         buf->len = data != NULL ? len : 0;
461         buf->sec = data;
462
463         return True;
464 }
465
466 /*******************************************************************
467 frees a SEC_DESC_BUF structure.
468 ********************************************************************/
469 void free_sec_desc_buf(SEC_DESC_BUF *buf)
470 {
471         if (buf->sec != NULL)
472         {
473                 free_sec_desc(buf->sec);
474                 free(buf->sec);
475         }
476 }
477
478
479 /*******************************************************************
480 reads or writes a SEC_DESC_BUF structure.
481 ********************************************************************/
482 BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth)
483 {
484         uint32 off_len;
485         uint32 off_max_len;
486         uint32 old_offset;
487         uint32 size;
488
489         if (sec == NULL) return False;
490
491         prs_debug(ps, depth, desc, "sec_io_desc_buf");
492         depth++;
493
494         prs_align(ps);
495         
496         prs_uint32_pre("max_len", ps, depth, &(sec->max_len), &off_max_len);
497         prs_uint32    ("undoc  ", ps, depth, &(sec->undoc  ));
498         prs_uint32_pre("len    ", ps, depth, &(sec->len    ), &off_len);
499
500         old_offset = ps->offset;
501
502         if (sec->len != 0 && ps->io)
503         {
504                 /* reading */
505                 sec->sec = (SEC_DESC*)malloc(sizeof(*sec->sec));
506                 ZERO_STRUCTP(sec->sec);
507
508                 if (sec->sec == NULL)
509                 {
510                         DEBUG(0,("INVALID SEC_DESC\n"));
511                         ps->offset = 0xfffffffe;
512                         return False;
513                 }
514         }
515
516         /* reading, length is non-zero; writing, descriptor is non-NULL */
517         if ((sec->len != 0 || (!ps->io)) && sec->sec != NULL)
518         {
519                 sec_io_desc("sec   ", sec->sec, ps, depth);
520         }
521
522         size = ps->offset - old_offset;
523         prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len, size == 0 ? sec->max_len : size);
524         prs_uint32_post("len    ", ps, depth, &(sec->len    ), off_len    , size);
525
526         return True;
527 }
528