source: releases/0.2.1/lib/smb_deps.c@ 192

Last change on this file since 192 was 53, checked in by tim, 20 years ago

Moved security descriptor parsing functions into regfio.c

Improved malloc() mode of failure.

Eliminated some warnings in regfio.c

  • 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 53 2005-09-04 21:04:58Z 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,
430 uint8* data8s, int len)
431{
432 int i;
433 char *q = prs_mem_get(ps, len);
434 if (q == NULL)
435 return false;
436
437 if (ps->io) {
438 for (i = 0; i < len; i++)
439 data8s[i] = CVAL(q,i);
440 } else {
441 for (i = 0; i < len; i++)
442 SCVAL(q, i, data8s[i]);
443 }
444
445 ps->data_offset += len;
446
447 return true;
448}
449
450
451/*******************************************************************
452 Set the current offset (external interface).
453 ********************************************************************/
454bool prs_set_offset(prs_struct *ps, uint32 offset)
455{
456 if(offset <= ps->data_offset) {
457 ps->data_offset = offset;
458 return true;
459 }
460
461 if(!prs_grow(ps, offset - ps->data_offset))
462 return false;
463
464 ps->data_offset = offset;
465 return true;
466}
467
468/* End of stuff from parse_prs.c */
469
470/* From rpc_parse/parse_misc.c */
471
472/*******************************************************************
473 Reads or writes a struct uuid
474********************************************************************/
475bool smb_io_uuid(const char *desc, struct uuid *uuid,
476 prs_struct *ps, int depth)
477{
478 if (uuid == NULL)
479 return false;
480 depth++;
481
482 if(!prs_uint32 ("data ", ps, depth, &uuid->time_low))
483 return false;
484 if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid))
485 return false;
486 if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version))
487 return false;
488
489 if(!prs_uint8s (false, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq)))
490 return false;
491 if(!prs_uint8s (false, "data ", ps, depth, uuid->node, sizeof(uuid->node)))
492 return false;
493
494 return true;
495}
496
497
498/*******************************************************************
499 Reads or writes an NTTIME structure.
500********************************************************************/
501bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
502{
503 if (nttime == NULL)
504 return false;
505 depth++;
506
507 if(!prs_align(ps))
508 return false;
509
510 if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
511 return false;
512 if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
513 return false;
514
515 return true;
516}
517
518
519/*******************************************************************
520 Reads or writes a DOM_SID structure.
521********************************************************************/
522bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
523{
524 int i;
525
526 if (sid == NULL)
527 return false;
528 depth++;
529
530 if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
531 return false;
532
533 if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths))
534 return false;
535
536 for (i = 0; i < 6; i++)
537 {
538 fstring tmp;
539 snprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
540 if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
541 return false;
542 }
543
544 /* oops! XXXX should really issue a warning here... */
545 if (sid->num_auths > MAXSUBAUTHS)
546 sid->num_auths = MAXSUBAUTHS;
547
548 if(!prs_uint32s(false, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
549 return false;
550
551 return true;
552}
553
554/* End of stuff from rpc_parse/parse_misc.c */
555
556/* From lib/util_sid.c */
557
558/*****************************************************************
559 Calculates size of a sid.
560*****************************************************************/
561size_t sid_size(const DOM_SID *sid)
562{
563 if (sid == NULL)
564 return 0;
565
566 return sid->num_auths * sizeof(uint32) + 8;
567}
568
569
570/*****************************************************************
571 Compare the auth portion of two sids.
572*****************************************************************/
573int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
574{
575 int i;
576
577 if (sid1 == sid2)
578 return 0;
579 if (!sid1)
580 return -1;
581 if (!sid2)
582 return 1;
583
584 if (sid1->sid_rev_num != sid2->sid_rev_num)
585 return sid1->sid_rev_num - sid2->sid_rev_num;
586
587 for (i = 0; i < 6; i++)
588 if (sid1->id_auth[i] != sid2->id_auth[i])
589 return sid1->id_auth[i] - sid2->id_auth[i];
590
591 return 0;
592}
593
594
595/*****************************************************************
596 Compare two sids.
597*****************************************************************/
598int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
599{
600 int i;
601
602 if (sid1 == sid2)
603 return 0;
604 if (!sid1)
605 return -1;
606 if (!sid2)
607 return 1;
608
609 /* Compare most likely different rids, first: i.e start at end */
610 if (sid1->num_auths != sid2->num_auths)
611 return sid1->num_auths - sid2->num_auths;
612
613 for (i = sid1->num_auths-1; i >= 0; --i)
614 if (sid1->sub_auths[i] != sid2->sub_auths[i])
615 return sid1->sub_auths[i] - sid2->sub_auths[i];
616
617 return sid_compare_auth(sid1, sid2);
618}
619
620
621/*****************************************************************
622 Compare two sids.
623*****************************************************************/
624bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
625{
626 return sid_compare(sid1, sid2) == 0;
627}
628
629/* End of stuff from lib/util_sid.c */
630
631/* From lib/secace.c */
632
633/*******************************************************************
634 Check if ACE has OBJECT type.
635********************************************************************/
636
637bool sec_ace_object(uint8 type)
638{
639 if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
640 type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
641 type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
642 type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
643 return true;
644 }
645 return false;
646}
647
648/* End of stuff from lib/secace.c */
649
650/* From rpc_parse/parse_sec.c */
651
652/*******************************************************************
653 Reads or writes a SEC_ACCESS structure.
654********************************************************************/
655bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
656{
657 if (t == NULL)
658 return false;
659
660 depth++;
661
662 if(!prs_uint32("mask", ps, depth, &t->mask))
663 return false;
664
665 return true;
666}
667
668
669/*******************************************************************
670 Reads or writes a SEC_ACE structure.
671********************************************************************/
672bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
673{
674 uint32 old_offset;
675 uint32 offset_ace_size;
676
677 if (psa == NULL)
678 return false;
679
680 depth++;
681
682 old_offset = ps->data_offset;
683
684 if(!prs_uint8("type ", ps, depth, &psa->type))
685 return false;
686
687 if(!prs_uint8("flags", ps, depth, &psa->flags))
688 return false;
689
690 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
691 return false;
692
693 if(!sec_io_access("info ", &psa->info, ps, depth))
694 return false;
695
696 /* check whether object access is present */
697 if (!sec_ace_object(psa->type)) {
698 if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
699 return false;
700 } else {
701 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
702 return false;
703
704 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
705 if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
706 return false;
707
708 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
709 if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
710 return false;
711
712 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
713 return false;
714 }
715
716 /* Theorectically an ACE can have a size greater than the
717 sum of its components. When marshalling, pad with extra null bytes up to the
718 correct size. */
719
720 if (!ps->io && (psa->size > ps->data_offset - old_offset)) {
721 uint32 extra_len = psa->size - (ps->data_offset - old_offset);
722 uint32 i;
723 uint8 c = 0;
724
725 for (i = 0; i < extra_len; i++) {
726 if (!prs_uint8("ace extra space", ps, depth, &c))
727 return false;
728 }
729 }
730
731 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
732 return false;
733
734 return true;
735}
736
737
738/*******************************************************************
739 Reads or writes a SEC_ACL structure.
740
741 First of the xx_io_xx functions that allocates its data structures
742 for you as it reads them.
743********************************************************************/
744bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
745{
746 unsigned int i;
747 uint32 old_offset;
748 uint32 offset_acl_size;
749 SEC_ACL *psa;
750
751 /*
752 * Note that the size is always a multiple of 4 bytes due to the
753 * nature of the data structure. Therefore the prs_align() calls
754 * have been removed as they through us off when doing two-layer
755 * marshalling such as in the printing code (RPC_BUFFER). --jerry
756 */
757
758 if (ppsa == NULL)
759 return false;
760
761 psa = *ppsa;
762
763 if(ps->io && psa == NULL) {
764 /*
765 * This is a read and we must allocate the stuct to read into.
766 */
767 if((psa = (SEC_ACL*)zalloc(sizeof(SEC_ACL))) == NULL)
768 return false;
769 *ppsa = psa;
770 }
771
772 depth++;
773
774 old_offset = ps->data_offset;
775
776 if(!prs_uint16("revision", ps, depth, &psa->revision))
777 return false;
778
779 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
780 return false;
781
782 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
783 return false;
784
785 if (ps->io) {
786 /*
787 * Even if the num_aces is zero, allocate memory as there's a difference
788 * between a non-present DACL (allow all access) and a DACL with no ACE's
789 * (allow no access).
790 */
791 if((psa->ace = (SEC_ACE*)zcalloc(sizeof(SEC_ACE), psa->num_aces+1)) == NULL)
792 return false;
793 }
794
795 for (i = 0; i < psa->num_aces; i++) {
796 fstring tmp;
797 snprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
798 if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
799 return false;
800 }
801
802 /* Theorectically an ACL can have a size greater than the
803 sum of its components. When marshalling, pad with extra null bytes up to the
804 correct size. */
805
806 if (!ps->io && (psa->size > ps->data_offset - old_offset)) {
807 uint32 extra_len = psa->size - (ps->data_offset - old_offset);
808 uint8 c = 0;
809
810 for (i = 0; i < extra_len; i++) {
811 if (!prs_uint8("acl extra space", ps, depth, &c))
812 return false;
813 }
814 }
815
816 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
817 return false;
818
819 return true;
820}
821
822
823/*******************************************************************
824 Reads or writes a SEC_DESC structure.
825 If reading and the *ppsd = NULL, allocates the structure.
826********************************************************************/
827bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
828{
829 uint32 old_offset;
830 uint32 max_offset = 0; /* after we're done, move offset to end */
831 uint32 tmp_offset = 0;
832
833 SEC_DESC *psd;
834
835 if (ppsd == NULL)
836 return false;
837
838 psd = *ppsd;
839
840 if (psd == NULL) {
841 if(ps->io) {
842 if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
843 return false;
844 *ppsd = psd;
845 } else {
846 /* Marshalling - just ignore. */
847 return true;
848 }
849 }
850
851 depth++;
852
853 /* start of security descriptor stored for back-calc offset purposes */
854 old_offset = ps->data_offset;
855
856 if(!prs_uint16("revision ", ps, depth, &psd->revision))
857 return false;
858
859 if(!prs_uint16("type ", ps, depth, &psd->type))
860 return false;
861
862 if (!ps->io) {
863 uint32 offset = SEC_DESC_HEADER_SIZE;
864
865 /*
866 * Work out the offsets here, as we write it out.
867 */
868
869 if (psd->sacl != NULL) {
870 psd->off_sacl = offset;
871 offset += psd->sacl->size;
872 } else {
873 psd->off_sacl = 0;
874 }
875
876 if (psd->dacl != NULL) {
877 psd->off_dacl = offset;
878 offset += psd->dacl->size;
879 } else {
880 psd->off_dacl = 0;
881 }
882
883 if (psd->owner_sid != NULL) {
884 psd->off_owner_sid = offset;
885 offset += sid_size(psd->owner_sid);
886 } else {
887 psd->off_owner_sid = 0;
888 }
889
890 if (psd->grp_sid != NULL) {
891 psd->off_grp_sid = offset;
892 offset += sid_size(psd->grp_sid);
893 } else {
894 psd->off_grp_sid = 0;
895 }
896 }
897
898 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
899 return false;
900
901 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
902 return false;
903
904 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
905 return false;
906
907 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
908 return false;
909
910 max_offset = MAX(max_offset, ps->data_offset);
911
912 if (psd->off_owner_sid != 0) {
913
914 tmp_offset = ps->data_offset;
915 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
916 return false;
917
918 if (ps->io) {
919 /* reading */
920 if((psd->owner_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
921 return false;
922 }
923
924 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
925 return false;
926
927 max_offset = MAX(max_offset, ps->data_offset);
928
929 if (!prs_set_offset(ps,tmp_offset))
930 return false;
931 }
932
933 if (psd->off_grp_sid != 0) {
934
935 tmp_offset = ps->data_offset;
936 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
937 return false;
938
939 if (ps->io) {
940 /* reading */
941 if((psd->grp_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
942 return false;
943 }
944
945 if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
946 return false;
947
948 max_offset = MAX(max_offset, ps->data_offset);
949
950 if (!prs_set_offset(ps,tmp_offset))
951 return false;
952 }
953
954 if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
955 tmp_offset = ps->data_offset;
956 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
957 return false;
958 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
959 return false;
960 max_offset = MAX(max_offset, ps->data_offset);
961 if (!prs_set_offset(ps,tmp_offset))
962 return false;
963 }
964
965 if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
966 tmp_offset = ps->data_offset;
967 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
968 return false;
969 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
970 return false;
971 max_offset = MAX(max_offset, ps->data_offset);
972 if (!prs_set_offset(ps,tmp_offset))
973 return false;
974 }
975
976 if(!prs_set_offset(ps, max_offset))
977 return false;
978
979 return true;
980}
981
982/* End of stuff from rpc_parse/parse_sec.c */
983
984/* From lib/secace.c */
985
986/*******************************************************************
987 Compares two SEC_ACE structures
988********************************************************************/
989bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
990{
991 /* Trivial case */
992
993 if (!s1 && !s2) return true;
994
995 /* Check top level stuff */
996
997 if (s1->type != s2->type || s1->flags != s2->flags ||
998 s1->info.mask != s2->info.mask) {
999 return false;
1000 }
1001
1002 /* Check SID */
1003
1004 if (!sid_equal(&s1->trustee, &s2->trustee)) {
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
1011/* End of stuff from lib/secace.c */
1012
1013/* From lib/secacl.c */
1014
1015/*******************************************************************
1016 Compares two SEC_ACL structures
1017********************************************************************/
1018
1019bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
1020{
1021 unsigned int i, j;
1022
1023 /* Trivial cases */
1024
1025 if (!s1 && !s2) return true;
1026 if (!s1 || !s2) return false;
1027
1028 /* Check top level stuff */
1029
1030 if (s1->revision != s2->revision) {
1031 return false;
1032 }
1033
1034 if (s1->num_aces != s2->num_aces) {
1035 return false;
1036 }
1037
1038 /* The ACEs could be in any order so check each ACE in s1 against
1039 each ACE in s2. */
1040
1041 for (i = 0; i < s1->num_aces; i++) {
1042 bool found = false;
1043
1044 for (j = 0; j < s2->num_aces; j++) {
1045 if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
1046 found = true;
1047 break;
1048 }
1049 }
1050
1051 if (!found) return false;
1052 }
1053
1054 return true;
1055}
1056
1057/* End of stuff from lib/secacl.c */
1058
1059/* From lib/secdesc.c */
1060
1061/*******************************************************************
1062 Compares two SEC_DESC structures
1063********************************************************************/
1064bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
1065{
1066 /* Trivial case */
1067
1068 if (!s1 && !s2) {
1069 goto done;
1070 }
1071
1072 /* Check top level stuff */
1073
1074 if (s1->revision != s2->revision) {
1075 return false;
1076 }
1077
1078 if (s1->type!= s2->type) {
1079 return false;
1080 }
1081
1082 /* Check owner and group */
1083
1084 if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
1085 return false;
1086 }
1087
1088 if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
1089 return false;
1090 }
1091
1092 /* Check ACLs present in one but not the other */
1093
1094 if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
1095 (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl))
1096 {
1097 return false;
1098 }
1099
1100 /* Sigh - we have to do it the hard way by iterating over all
1101 the ACEs in the ACLs */
1102
1103 if (!sec_acl_equal(s1->dacl, s2->dacl) ||
1104 !sec_acl_equal(s1->sacl, s2->sacl))
1105 {
1106 return false;
1107 }
1108
1109 done:
1110 return true;
1111}
1112
1113/* End of stuff from lib/secdesc.c */
Note: See TracBrowser for help on using the repository browser.