source: releases/0.2/lib/smb_deps.c@ 209

Last change on this file since 209 was 42, checked in by tim, 20 years ago

Changed to a CSV-like output format to accommodate extended fields

Added mtime output for keys

Added security descriptor columns (probably broken right now)

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