source: trunk/lib/smb_deps.c @ 31

Last change on this file since 31 was 31, checked in by tim, 19 years ago

Added new lightweight stack library

rewrote test program to use this instead of string concatenation/recursion.

  • Property svn:keywords set to Id
File size: 24.9 KB
Line 
1/*
2 * This file contains miscellaneous pieces of code which regfio.c
3 * depends upon, from the Samba Subversion tree.  See:
4 *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
5 *
6 * Copyright (C) 2005 Timothy D. Morgan
7 * Copyright (C) 1992-2005 Samba development team
8 *               (see individual files under Subversion for details.)
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; version 2 of the License.
13 *
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.
18 *
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.
22 *
23 * $Id: smb_deps.c 31 2005-07-16 19:05:19Z tim $
24 */
25
26#include "../include/smb_deps.h"
27
28
29/* These act as replacements for numerous Samba memory allocation
30 *   functions.
31 */
32void* zalloc(size_t size)
33{
34  void* ret_val = NULL;
35  if((ret_val = (void*)malloc(size)) != NULL)
36    memset(ret_val, 0, size);
37  return ret_val;
38}
39
40void* zcalloc(size_t size, unsigned int count)
41{
42  return zalloc(size*count);
43}
44
45/* From lib/time.c */
46
47/****************************************************************************
48 Put a 8 byte filetime from a time_t
49 This takes real GMT as input and converts to kludge-GMT
50****************************************************************************/
51void unix_to_nt_time(NTTIME *nt, time_t t)
52{
53        double d;
54
55        if (t==0) {
56                nt->low = 0;
57                nt->high = 0;
58                return;
59        }
60        if (t == TIME_T_MAX) {
61                nt->low = 0xffffffff;
62                nt->high = 0x7fffffff;
63                return;
64        }               
65        if (t == -1) {
66                nt->low = 0xffffffff;
67                nt->high = 0xffffffff;
68                return;
69        }               
70
71        /* this converts GMT to kludge-GMT */
72        /*XXX t -= TimeDiff(t) - get_serverzone(); */
73
74        d = (double)(t);
75        d += TIME_FIXUP_CONSTANT;
76        d *= 1.0e7;
77
78        nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
79        nt->low  = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
80}
81
82/* End of stuff from lib/time.c */
83
84/* From parse_prs.c */
85
86/*******************************************************************
87 Attempt, if needed, to grow a data buffer.
88 Also depends on the data stream mode (io).
89 ********************************************************************/
90bool prs_grow(prs_struct *ps, uint32 extra_space)
91{
92        uint32 new_size;
93        char *new_data;
94
95        ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);
96
97        if(ps->data_offset + extra_space <= ps->buffer_size)
98                return true;
99
100        /*
101         * We cannot grow the buffer if we're not reading
102         * into the prs_struct, or if we don't own the memory.
103         */
104
105        if(ps->io || !ps->is_dynamic) {
106                return false;
107        }
108       
109        /*
110         * Decide how much extra space we really need.
111         */
112
113        extra_space -= (ps->buffer_size - ps->data_offset);
114        if(ps->buffer_size == 0) {
115                /*
116                 * Ensure we have at least a PDU's length, or extra_space, whichever
117                 * is greater.
118                 */
119
120                new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);
121
122                if((new_data = zalloc(new_size)) == NULL) {
123                        return false;
124                }
125                memset(new_data, '\0', (size_t)new_size );
126        } else {
127                /*
128                 * If the current buffer size is bigger than the space needed, just
129                 * double it, else add extra_space.
130                 */
131                new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);               
132
133                if ((new_data = (char*)realloc(ps->data_p, new_size)) == NULL) {
134                        return false;
135                }
136
137                memset(&new_data[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));
138        }
139        ps->buffer_size = new_size;
140        ps->data_p = new_data;
141
142        return true;
143}
144
145
146/*******************************************************************
147 Align a the data_len to a multiple of align bytes - filling with
148 zeros.
149 ********************************************************************/
150bool prs_align(prs_struct *ps)
151{
152        uint32 mod = ps->data_offset & (ps->align-1);
153
154        if (ps->align != 0 && mod != 0) {
155                uint32 extra_space = (ps->align - mod);
156                if(!prs_grow(ps, extra_space))
157                        return false;
158                memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
159                ps->data_offset += extra_space;
160        }
161
162        return true;
163}
164
165
166/**
167 * Initialise an expandable parse structure.
168 *
169 * @param size Initial buffer size.  If >0, a new buffer will be
170 * created with malloc().
171 *
172 * @return false if allocation fails, otherwise true.
173 **/
174
175bool prs_init(prs_struct *ps, uint32 size, void *ctx, bool io)
176{
177  memset(ps, 0, sizeof(prs_struct));
178  ps->io = io;
179  ps->bigendian_data = RPC_LITTLE_ENDIAN;
180  ps->align = RPC_PARSE_ALIGN;
181  ps->is_dynamic = false;
182  ps->data_offset = 0;
183  ps->buffer_size = 0;
184  ps->data_p = NULL;
185  ps->mem_ctx = ctx;
186 
187  if (size != 0) {
188    ps->buffer_size = size;
189    if((ps->data_p = (char *)zalloc((size_t)size)) == NULL) {
190      return false;
191    }
192    memset(ps->data_p, '\0', (size_t)size);
193    ps->is_dynamic = true; /* We own this memory. */
194  }
195 
196  return true;
197}
198
199
200char *prs_mem_get(prs_struct *ps, uint32 extra_size)
201{
202        if(ps->io) {
203                /*
204                 * If reading, ensure that we can read the requested size item.
205                 */
206                if (ps->data_offset + extra_size > ps->buffer_size) {
207                        return NULL;
208                }
209        } else {
210                /*
211                 * Writing - grow the buffer if needed.
212                 */
213                if(!prs_grow(ps, extra_size))
214                        return NULL;
215        }
216        return &ps->data_p[ps->data_offset];
217}
218
219
220/*******************************************************************
221 Stream a uint32.
222 ********************************************************************/
223bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32)
224{
225        char *q = prs_mem_get(ps, sizeof(uint32));
226        if (q == NULL)
227                return false;
228
229        if (ps->io) {
230                if (ps->bigendian_data)
231                        *data32 = RIVAL(q,0);
232                else
233                        *data32 = IVAL(q,0);
234        } else {
235                if (ps->bigendian_data)
236                        RSIVAL(q,0,*data32);
237                else
238                        SIVAL(q,0,*data32);
239        }
240
241        ps->data_offset += sizeof(uint32);
242
243        return true;
244}
245
246
247/******************************************************************
248 Stream an array of uint32s. Length is number of uint32s.
249 ********************************************************************/
250bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, 
251                 int depth, uint32 *data32s, int len)
252{
253        int i;
254        char *q = prs_mem_get(ps, len * sizeof(uint32));
255        if (q == NULL)
256                return false;
257
258        if (ps->io) {
259                if (ps->bigendian_data) {
260                        for (i = 0; i < len; i++)
261                                data32s[i] = RIVAL(q, 4*i);
262                } else {
263                        for (i = 0; i < len; i++)
264                                data32s[i] = IVAL(q, 4*i);
265                }
266        } else {
267                if (ps->bigendian_data) {
268                        for (i = 0; i < len; i++)
269                                RSIVAL(q, 4*i, data32s[i]);
270                } else {
271                        for (i = 0; i < len; i++)
272                                SIVAL(q, 4*i, data32s[i]);
273                }
274        }
275
276        ps->data_offset += (len * sizeof(uint32));
277
278        return true;
279}
280
281
282/*******************************************************************
283 Stream a uint16.
284 ********************************************************************/
285bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)
286{
287        char *q = prs_mem_get(ps, sizeof(uint16));
288        if (q == NULL)
289                return false;
290
291        if (ps->io) {
292                if (ps->bigendian_data)
293                        *data16 = RSVAL(q,0);
294                else
295                        *data16 = SVAL(q,0);
296        } else {
297                if (ps->bigendian_data)
298                        RSSVAL(q,0,*data16);
299                else
300                        SSVAL(q,0,*data16);
301        }
302
303
304        ps->data_offset += sizeof(uint16);
305
306        return true;
307}
308
309
310/*******************************************************************
311 prs_uint16 wrapper. Call this and it sets up a pointer to where the
312 uint16 should be stored, or gets the size if reading.
313 ********************************************************************/
314bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, 
315                    uint16 *data16, uint32 *offset)
316{
317        *offset = ps->data_offset;
318        if (ps->io) {
319                /* reading. */
320                return prs_uint16(name, ps, depth, data16);
321        } else {
322                char *q = prs_mem_get(ps, sizeof(uint16));
323                if(q ==NULL)
324                        return false;
325                ps->data_offset += sizeof(uint16);
326        }
327        return true;
328}
329
330
331/*******************************************************************
332 prs_uint16 wrapper.  call this and it retrospectively stores the size.
333 does nothing on reading, as that is already handled by ...._pre()
334 ********************************************************************/
335bool prs_uint16_post(const char *name, prs_struct *ps, int depth, 
336                     uint16 *data16, uint32 ptr_uint16, uint32 start_offset)
337{
338        if (!ps->io) {
339                /*
340                 * Writing - temporarily move the offset pointer.
341                 */
342                uint16 data_size = ps->data_offset - start_offset;
343                uint32 old_offset = ps->data_offset;
344
345                ps->data_offset = ptr_uint16;
346                if(!prs_uint16(name, ps, depth, &data_size)) {
347                        ps->data_offset = old_offset;
348                        return false;
349                }
350                ps->data_offset = old_offset;
351        } else {
352                ps->data_offset = start_offset + (uint32)(*data16);
353        }
354        return true;
355}
356
357
358/*******************************************************************
359 Stream a uint8.
360 ********************************************************************/
361bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
362{
363        char *q = prs_mem_get(ps, 1);
364        if (q == NULL)
365                return false;
366
367    if (ps->io)
368                *data8 = CVAL(q,0);
369        else
370                SCVAL(q,0,*data8);
371
372        ps->data_offset += 1;
373
374        return true;
375}
376
377
378/******************************************************************
379 Stream an array of uint8s. Length is number of uint8s.
380 ********************************************************************/
381bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
382{
383        int i;
384        char *q = prs_mem_get(ps, len);
385        if (q == NULL)
386                return false;
387
388        if (ps->io) {
389                for (i = 0; i < len; i++)
390                        data8s[i] = CVAL(q,i);
391        } else {
392                for (i = 0; i < len; i++)
393                        SCVAL(q, i, data8s[i]);
394        }
395
396        ps->data_offset += len;
397
398        return true;
399}
400
401
402/*******************************************************************
403 Set the current offset (external interface).
404 ********************************************************************/
405bool prs_set_offset(prs_struct *ps, uint32 offset)
406{
407        if(offset <= ps->data_offset) {
408                ps->data_offset = offset;
409                return true;
410        }
411
412        if(!prs_grow(ps, offset - ps->data_offset))
413                return false;
414
415        ps->data_offset = offset;
416        return true;
417}
418
419/* End of stuff from parse_prs.c */
420
421/* From rpc_parse/parse_misc.c */
422
423/*******************************************************************
424 Reads or writes a struct uuid
425********************************************************************/
426bool smb_io_uuid(const char *desc, struct uuid *uuid, 
427                 prs_struct *ps, int depth)
428{
429        if (uuid == NULL)
430                return false;
431        depth++;
432
433        if(!prs_uint32 ("data   ", ps, depth, &uuid->time_low))
434                return false;
435        if(!prs_uint16 ("data   ", ps, depth, &uuid->time_mid))
436                return false;
437        if(!prs_uint16 ("data   ", ps, depth, &uuid->time_hi_and_version))
438                return false;
439
440        if(!prs_uint8s (false, "data   ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq)))
441                return false;
442        if(!prs_uint8s (false, "data   ", ps, depth, uuid->node, sizeof(uuid->node)))
443                return false;
444
445        return true;
446}
447
448
449/*******************************************************************
450 Reads or writes an NTTIME structure.
451********************************************************************/
452bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
453{
454        if (nttime == NULL)
455                return false;
456        depth++;
457
458        if(!prs_align(ps))
459                return false;
460       
461        if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
462                return false;
463        if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
464                return false;
465
466        return true;
467}
468
469
470/*******************************************************************
471 Reads or writes a DOM_SID structure.
472********************************************************************/
473bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
474{
475        int i;
476
477        if (sid == NULL)
478                return false;
479        depth++;
480
481        if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
482                return false;
483
484        if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
485                return false;
486
487        for (i = 0; i < 6; i++)
488        {
489                fstring tmp;
490                snprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
491                if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
492                        return false;
493        }
494
495        /* oops! XXXX should really issue a warning here... */
496        if (sid->num_auths > MAXSUBAUTHS)
497                sid->num_auths = MAXSUBAUTHS;
498
499        if(!prs_uint32s(false, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
500                return false;
501
502        return true;
503}
504
505/* End of stuff from rpc_parse/parse_misc.c */
506
507/* From lib/util_sid.c */
508
509/*****************************************************************
510 Calculates size of a sid.
511*****************************************************************/ 
512size_t sid_size(const DOM_SID *sid)
513{
514        if (sid == NULL)
515                return 0;
516
517        return sid->num_auths * sizeof(uint32) + 8;
518}
519
520
521/*****************************************************************
522 Compare the auth portion of two sids.
523*****************************************************************/ 
524int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
525{
526        int i;
527
528        if (sid1 == sid2)
529                return 0;
530        if (!sid1)
531                return -1;
532        if (!sid2)
533                return 1;
534
535        if (sid1->sid_rev_num != sid2->sid_rev_num)
536                return sid1->sid_rev_num - sid2->sid_rev_num;
537
538        for (i = 0; i < 6; i++)
539                if (sid1->id_auth[i] != sid2->id_auth[i])
540                        return sid1->id_auth[i] - sid2->id_auth[i];
541
542        return 0;
543}
544
545
546/*****************************************************************
547 Compare two sids.
548*****************************************************************/ 
549int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
550{
551        int i;
552
553        if (sid1 == sid2)
554                return 0;
555        if (!sid1)
556                return -1;
557        if (!sid2)
558                return 1;
559
560        /* Compare most likely different rids, first: i.e start at end */
561        if (sid1->num_auths != sid2->num_auths)
562                return sid1->num_auths - sid2->num_auths;
563
564        for (i = sid1->num_auths-1; i >= 0; --i)
565                if (sid1->sub_auths[i] != sid2->sub_auths[i])
566                        return sid1->sub_auths[i] - sid2->sub_auths[i];
567
568        return sid_compare_auth(sid1, sid2);
569}
570
571
572/*****************************************************************
573 Compare two sids.
574*****************************************************************/ 
575bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
576{
577        return sid_compare(sid1, sid2) == 0;
578}
579
580/* End of stuff from lib/util_sid.c */
581
582/* From lib/secace.c */
583
584/*******************************************************************
585 Check if ACE has OBJECT type.
586********************************************************************/
587
588bool sec_ace_object(uint8 type)
589{
590        if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
591            type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
592            type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
593            type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
594                return true;
595        }
596        return false;
597}
598
599/* End of stuff from lib/secace.c */
600
601/* From rpc_parse/parse_sec.c */
602
603/*******************************************************************
604 Reads or writes a SEC_ACCESS structure.
605********************************************************************/
606bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
607{
608        if (t == NULL)
609                return false;
610
611        depth++;
612       
613        if(!prs_uint32("mask", ps, depth, &t->mask))
614                return false;
615
616        return true;
617}
618
619
620/*******************************************************************
621 Reads or writes a SEC_ACE structure.
622********************************************************************/
623bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
624{
625        uint32 old_offset;
626        uint32 offset_ace_size;
627
628        if (psa == NULL)
629                return false;
630
631        depth++;
632       
633        old_offset = ps->data_offset;
634
635        if(!prs_uint8("type ", ps, depth, &psa->type))
636                return false;
637
638        if(!prs_uint8("flags", ps, depth, &psa->flags))
639                return false;
640
641        if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
642                return false;
643
644        if(!sec_io_access("info ", &psa->info, ps, depth))
645                return false;
646
647        /* check whether object access is present */
648        if (!sec_ace_object(psa->type)) {
649                if (!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
650                        return false;
651        } else {
652                if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
653                        return false;
654
655                if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
656                        if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
657                                return false;
658
659                if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
660                        if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
661                                return false;
662
663                if(!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
664                        return false;
665        }
666
667        /* Theorectically an ACE can have a size greater than the
668           sum of its components. When marshalling, pad with extra null bytes up to the
669           correct size. */
670
671        if (!ps->io && (psa->size > ps->data_offset - old_offset)) {
672                uint32 extra_len = psa->size - (ps->data_offset - old_offset);
673                uint32 i;
674                uint8 c = 0;
675
676                for (i = 0; i < extra_len; i++) {
677                        if (!prs_uint8("ace extra space", ps, depth, &c))
678                                return false;
679                }
680        }
681
682        if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
683                return false;
684
685        return true;
686}
687
688
689/*******************************************************************
690 Reads or writes a SEC_ACL structure. 
691
692 First of the xx_io_xx functions that allocates its data structures
693 for you as it reads them.
694********************************************************************/
695bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
696{
697        unsigned int i;
698        uint32 old_offset;
699        uint32 offset_acl_size;
700        SEC_ACL *psa;
701
702        /*
703         * Note that the size is always a multiple of 4 bytes due to the
704         * nature of the data structure.  Therefore the prs_align() calls
705         * have been removed as they through us off when doing two-layer
706         * marshalling such as in the printing code (RPC_BUFFER).  --jerry
707         */
708
709        if (ppsa == NULL)
710                return false;
711
712        psa = *ppsa;
713
714        if(ps->io && psa == NULL) {
715                /*
716                 * This is a read and we must allocate the stuct to read into.
717                 */
718          if((psa = (SEC_ACL*)zalloc(sizeof(SEC_ACL))) == NULL)
719                        return false;
720                *ppsa = psa;
721        }
722
723        depth++;
724       
725        old_offset = ps->data_offset;
726
727        if(!prs_uint16("revision", ps, depth, &psa->revision))
728                return false;
729
730        if(!prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size))
731                return false;
732
733        if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
734                return false;
735
736        if (ps->io) {
737                /*
738                 * Even if the num_aces is zero, allocate memory as there's a difference
739                 * between a non-present DACL (allow all access) and a DACL with no ACE's
740                 * (allow no access).
741                 */
742          if((psa->ace = (SEC_ACE*)zcalloc(sizeof(SEC_ACE), psa->num_aces+1)) == NULL)
743                        return false;
744        }
745
746        for (i = 0; i < psa->num_aces; i++) {
747                fstring tmp;
748                snprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
749                if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
750                        return false;
751        }
752
753        /* Theorectically an ACL can have a size greater than the
754           sum of its components. When marshalling, pad with extra null bytes up to the
755           correct size. */
756
757        if (!ps->io && (psa->size > ps->data_offset - old_offset)) {
758                uint32 extra_len = psa->size - (ps->data_offset - old_offset);
759                uint8 c = 0;
760
761                for (i = 0; i < extra_len; i++) {
762                        if (!prs_uint8("acl extra space", ps, depth, &c))
763                                return false;
764                }
765        }
766
767        if(!prs_uint16_post("size     ", ps, depth, &psa->size, offset_acl_size, old_offset))
768                return false;
769
770        return true;
771}
772
773
774/*******************************************************************
775 Reads or writes a SEC_DESC structure.
776 If reading and the *ppsd = NULL, allocates the structure.
777********************************************************************/
778bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
779{
780        uint32 old_offset;
781        uint32 max_offset = 0; /* after we're done, move offset to end */
782        uint32 tmp_offset = 0;
783
784        SEC_DESC *psd;
785
786        if (ppsd == NULL)
787                return false;
788
789        psd = *ppsd;
790
791        if (psd == NULL) {
792                if(ps->io) {
793                  if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
794                                return false;
795                        *ppsd = psd;
796                } else {
797                        /* Marshalling - just ignore. */
798                        return true;
799                }
800        }
801
802        depth++;
803
804        /* start of security descriptor stored for back-calc offset purposes */
805        old_offset = ps->data_offset;
806
807        if(!prs_uint16("revision ", ps, depth, &psd->revision))
808                return false;
809
810        if(!prs_uint16("type     ", ps, depth, &psd->type))
811                return false;
812
813        if (!ps->io) {
814                uint32 offset = SEC_DESC_HEADER_SIZE;
815
816                /*
817                 * Work out the offsets here, as we write it out.
818                 */
819
820                if (psd->sacl != NULL) {
821                        psd->off_sacl = offset;
822                        offset += psd->sacl->size;
823                } else {
824                        psd->off_sacl = 0;
825                }
826
827                if (psd->dacl != NULL) {
828                        psd->off_dacl = offset;
829                        offset += psd->dacl->size;
830                } else {
831                        psd->off_dacl = 0;
832                }
833
834                if (psd->owner_sid != NULL) {
835                        psd->off_owner_sid = offset;
836                        offset += sid_size(psd->owner_sid);
837                } else {
838                        psd->off_owner_sid = 0;
839                }
840
841                if (psd->grp_sid != NULL) {
842                        psd->off_grp_sid = offset;
843                        offset += sid_size(psd->grp_sid);
844                } else {
845                        psd->off_grp_sid = 0;
846                }
847        }
848
849        if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
850                return false;
851
852        if(!prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid))
853                return false;
854
855        if(!prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl))
856                return false;
857
858        if(!prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
859                return false;
860
861        max_offset = MAX(max_offset, ps->data_offset);
862
863        if (psd->off_owner_sid != 0) {
864
865                tmp_offset = ps->data_offset;
866                if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
867                        return false;
868
869                if (ps->io) {
870                        /* reading */
871                  if((psd->owner_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
872                                return false;
873                }
874
875                if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
876                        return false;
877
878                max_offset = MAX(max_offset, ps->data_offset);
879
880                if (!prs_set_offset(ps,tmp_offset))
881                        return false;
882        }
883
884        if (psd->off_grp_sid != 0) {
885
886                tmp_offset = ps->data_offset;
887                if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
888                        return false;
889
890                if (ps->io) {
891                        /* reading */
892                        if((psd->grp_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
893                                return false;
894                }
895
896                if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
897                        return false;
898                       
899                max_offset = MAX(max_offset, ps->data_offset);
900
901                if (!prs_set_offset(ps,tmp_offset))
902                        return false;
903        }
904
905        if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
906                tmp_offset = ps->data_offset;
907                if(!prs_set_offset(ps, old_offset + psd->off_sacl))
908                        return false;
909                if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
910                        return false;
911                max_offset = MAX(max_offset, ps->data_offset);
912                if (!prs_set_offset(ps,tmp_offset))
913                        return false;
914        }
915
916        if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
917                tmp_offset = ps->data_offset;
918                if(!prs_set_offset(ps, old_offset + psd->off_dacl))
919                        return false;
920                if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
921                        return false;
922                max_offset = MAX(max_offset, ps->data_offset);
923                if (!prs_set_offset(ps,tmp_offset))
924                        return false;
925        }
926
927        if(!prs_set_offset(ps, max_offset))
928                return false;
929
930        return true;
931}
932
933/* End of stuff from rpc_parse/parse_sec.c */
934
935/* From lib/secace.c */
936
937/*******************************************************************
938 Compares two SEC_ACE structures
939********************************************************************/
940bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
941{
942        /* Trivial case */
943
944        if (!s1 && !s2) return true;
945
946        /* Check top level stuff */
947
948        if (s1->type != s2->type || s1->flags != s2->flags ||
949            s1->info.mask != s2->info.mask) {
950                return false;
951        }
952
953        /* Check SID */
954
955        if (!sid_equal(&s1->trustee, &s2->trustee)) {
956                return false;
957        }
958
959        return true;
960}
961
962/* End of stuff from lib/secace.c */
963
964/* From lib/secacl.c */
965
966/*******************************************************************
967 Compares two SEC_ACL structures
968********************************************************************/
969
970bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
971{
972        unsigned int i, j;
973
974        /* Trivial cases */
975
976        if (!s1 && !s2) return true;
977        if (!s1 || !s2) return false;
978
979        /* Check top level stuff */
980
981        if (s1->revision != s2->revision) {
982                return false;
983        }
984
985        if (s1->num_aces != s2->num_aces) {
986                return false;
987        }
988
989        /* The ACEs could be in any order so check each ACE in s1 against
990           each ACE in s2. */
991
992        for (i = 0; i < s1->num_aces; i++) {
993                bool found = false;
994
995                for (j = 0; j < s2->num_aces; j++) {
996                        if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
997                                found = true;
998                                break;
999                        }
1000                }
1001
1002                if (!found) return false;
1003        }
1004
1005        return true;
1006}
1007
1008/* End of stuff from lib/secacl.c */
1009
1010/* From lib/secdesc.c */
1011
1012/*******************************************************************
1013 Compares two SEC_DESC structures
1014********************************************************************/
1015bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
1016{
1017        /* Trivial case */
1018
1019        if (!s1 && !s2) {
1020                goto done;
1021        }
1022
1023        /* Check top level stuff */
1024
1025        if (s1->revision != s2->revision) {
1026                return false;
1027        }
1028
1029        if (s1->type!= s2->type) {
1030                return false;
1031        }
1032
1033        /* Check owner and group */
1034
1035        if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
1036                return false;
1037        }
1038
1039        if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
1040                return false;
1041        }
1042
1043        /* Check ACLs present in one but not the other */
1044
1045        if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
1046            (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) 
1047        {
1048                return false;
1049        }
1050
1051        /* Sigh - we have to do it the hard way by iterating over all
1052           the ACEs in the ACLs */
1053
1054        if (!sec_acl_equal(s1->dacl, s2->dacl) ||
1055            !sec_acl_equal(s1->sacl, s2->sacl)) 
1056        {
1057                return false;
1058        }
1059
1060 done:
1061        return true;
1062}
1063
1064/* End of stuff from lib/secdesc.c */
Note: See TracBrowser for help on using the repository browser.