source: trunk/lib/smb_deps.c @ 30

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

Added initial version of regfio interface, borrowed from Samba project.

Library has all write capability stripped, and all Samba dependency has
either been removed, or included in the smb_deps code.

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