4b118dd2b45de243a053931ca94f8beceec64ca9
[samba.git] / source / rpc_parse / parse_misc.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1997,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7  *  Copyright (C) Paul Ashton                       1997.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
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
24
25 #include "includes.h"
26
27 extern int DEBUGLEVEL;
28
29 /****************************************************************************
30  A temporary TALLOC context for things like unistrs, that is valid for
31  the life of a complete RPC call.
32 ****************************************************************************/
33
34 static TALLOC_CTX *current_rpc_talloc = NULL;
35
36 TALLOC_CTX *get_current_rpc_talloc(void)
37 {
38     return current_rpc_talloc;
39 }
40
41 void set_current_rpc_talloc( TALLOC_CTX *ctx)
42 {
43         current_rpc_talloc = ctx;
44 }
45
46 static TALLOC_CTX *main_loop_talloc = NULL;
47
48 /*******************************************************************
49 free up temporary memory - called from the main loop
50 ********************************************************************/
51
52 void main_loop_talloc_free(void)
53 {
54     if (!main_loop_talloc)
55         return;
56     talloc_destroy(main_loop_talloc);
57     main_loop_talloc = NULL;
58 }
59
60 /*******************************************************************
61  Get a talloc context that is freed in the main loop...
62 ********************************************************************/
63
64 TALLOC_CTX *main_loop_talloc_get(void)
65 {
66     if (!main_loop_talloc) {
67         main_loop_talloc = talloc_init();
68         if (!main_loop_talloc)
69             smb_panic("main_loop_talloc: malloc fail\n");
70     }
71
72     return main_loop_talloc;
73 }
74
75 /*******************************************************************
76  Try and get a talloc context. Get the rpc one if possible, else
77  get the main loop one. The main loop one is more dangerous as it
78  goes away between packets, the rpc one will stay around for as long
79  as a current RPC lasts.
80 ********************************************************************/ 
81
82 TALLOC_CTX *get_talloc_ctx(void)
83 {
84         TALLOC_CTX *tc = get_current_rpc_talloc();
85
86         if (tc)
87                 return tc;
88         return main_loop_talloc_get();
89 }
90
91 /*******************************************************************
92  Reads or writes a UTIME type.
93 ********************************************************************/
94
95 static BOOL smb_io_utime(char *desc, UTIME *t, prs_struct *ps, int depth)
96 {
97         if (t == NULL)
98                 return False;
99
100         prs_debug(ps, depth, desc, "smb_io_utime");
101         depth++;
102
103         if(!prs_align(ps))
104                 return False;
105         
106         if(!prs_uint32 ("time", ps, depth, &t->time))
107                 return False;
108
109         return True;
110 }
111
112 /*******************************************************************
113  Reads or writes an NTTIME structure.
114 ********************************************************************/
115
116 BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth)
117 {
118         if (nttime == NULL)
119                 return False;
120
121         prs_debug(ps, depth, desc, "smb_io_time");
122         depth++;
123
124         if(!prs_align(ps))
125                 return False;
126         
127         if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
128                 return False;
129         if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
130                 return False;
131
132         return True;
133 }
134
135 /*******************************************************************
136  Reads or writes a LOOKUP_LEVEL structure.
137 ********************************************************************/
138
139 BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
140 {
141         if (level == NULL)
142                 return False;
143
144         prs_debug(ps, depth, desc, "smb_io_lookup_level");
145         depth++;
146
147         if(!prs_align(ps))
148                 return False;
149         if(!prs_uint16("value", ps, depth, &level->value))
150                 return False;
151         if(!prs_align(ps))
152                 return False;
153
154         return True;
155 }
156
157 /*******************************************************************
158  Gets an enumeration handle from an ENUM_HND structure.
159 ********************************************************************/
160
161 uint32 get_enum_hnd(ENUM_HND *enh)
162 {
163         return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
164 }
165
166 /*******************************************************************
167  Inits an ENUM_HND structure.
168 ********************************************************************/
169
170 void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
171 {
172         DEBUG(5,("smb_io_enum_hnd\n"));
173
174         enh->ptr_hnd = (hnd != 0) ? 1 : 0;
175         enh->handle = hnd;
176 }
177
178 /*******************************************************************
179  Reads or writes an ENUM_HND structure.
180 ********************************************************************/
181
182 BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
183 {
184         if (hnd == NULL)
185                 return False;
186
187         prs_debug(ps, depth, desc, "smb_io_enum_hnd");
188         depth++;
189
190         if(!prs_align(ps))
191                 return False;
192         
193         if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
194                 return False;
195
196         if (hnd->ptr_hnd != 0) {
197                 if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
198                         return False;
199         }
200
201         return True;
202 }
203
204 /*******************************************************************
205  Reads or writes a DOM_SID structure.
206 ********************************************************************/
207
208 BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth)
209 {
210         int i;
211
212         if (sid == NULL)
213                 return False;
214
215         prs_debug(ps, depth, desc, "smb_io_dom_sid");
216         depth++;
217
218         if(!prs_align(ps))
219                 return False;
220         
221         if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
222                 return False;
223         if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
224                 return False;
225
226         for (i = 0; i < 6; i++)
227         {
228                 fstring tmp;
229                 slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
230                 if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
231                         return False;
232         }
233
234         /* oops! XXXX should really issue a warning here... */
235         if (sid->num_auths > MAXSUBAUTHS)
236                 sid->num_auths = MAXSUBAUTHS;
237
238         if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
239                 return False;
240
241         return True;
242 }
243
244 /*******************************************************************
245  Inits a DOM_SID structure.
246
247  BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 
248  identauth >= 2^32 can be detected because it will be specified in hex
249 ********************************************************************/
250
251 void init_dom_sid(DOM_SID *sid, char *str_sid)
252 {
253         pstring domsid;
254         int identauth;
255         char *p;
256
257         if (str_sid == NULL)
258         {
259                 DEBUG(4,("netlogon domain SID: none\n"));
260                 sid->sid_rev_num = 0;
261                 sid->num_auths = 0;
262                 return;
263         }
264                 
265         pstrcpy(domsid, str_sid);
266
267         DEBUG(4,("init_dom_sid %d SID:  %s\n", __LINE__, domsid));
268
269         /* assume, but should check, that domsid starts "S-" */
270         p = strtok(domsid+2,"-");
271         sid->sid_rev_num = atoi(p);
272
273         /* identauth in decimal should be <  2^32 */
274         /* identauth in hex     should be >= 2^32 */
275         identauth = atoi(strtok(0,"-"));
276
277         DEBUG(4,("netlogon rev %d\n", sid->sid_rev_num));
278         DEBUG(4,("netlogon %s ia %d\n", p, identauth));
279
280         sid->id_auth[0] = 0;
281         sid->id_auth[1] = 0;
282         sid->id_auth[2] = (identauth & 0xff000000) >> 24;
283         sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
284         sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
285         sid->id_auth[5] = (identauth & 0x000000ff);
286
287         sid->num_auths = 0;
288
289         while ((p = strtok(0, "-")) != NULL && sid->num_auths < MAXSUBAUTHS)
290                 sid->sub_auths[sid->num_auths++] = atoi(p);
291
292         DEBUG(4,("init_dom_sid: %d SID:  %s\n", __LINE__, domsid));
293 }
294
295 /*******************************************************************
296  Inits a DOM_SID2 structure.
297 ********************************************************************/
298
299 void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid)
300 {
301         sid2->sid = *sid;
302         sid2->num_auths = sid2->sid.num_auths;
303 }
304
305 /*******************************************************************
306  Reads or writes a DOM_SID2 structure.
307 ********************************************************************/
308
309 BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
310 {
311         if (sid == NULL)
312                 return False;
313
314         prs_debug(ps, depth, desc, "smb_io_dom_sid2");
315         depth++;
316
317         if(!prs_align(ps))
318                 return False;
319         
320         if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
321                 return False;
322
323         if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
324                 return False;
325
326         return True;
327 }
328
329 /*******************************************************************
330 creates a STRHDR structure.
331 ********************************************************************/
332
333 void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
334 {
335         hdr->str_max_len = max_len;
336         hdr->str_str_len = len;
337         hdr->buffer      = buffer;
338 }
339
340 /*******************************************************************
341  Reads or writes a STRHDR structure.
342 ********************************************************************/
343
344 BOOL smb_io_strhdr(char *desc,  STRHDR *hdr, prs_struct *ps, int depth)
345 {
346         if (hdr == NULL)
347                 return False;
348
349         prs_debug(ps, depth, desc, "smb_io_strhdr");
350         depth++;
351
352         prs_align(ps);
353         
354         if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
355                 return False;
356         if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
357                 return False;
358         if(!prs_uint32("buffer     ", ps, depth, &hdr->buffer))
359                 return False;
360
361         return True;
362 }
363
364 /*******************************************************************
365  Inits a UNIHDR structure.
366 ********************************************************************/
367
368 void init_uni_hdr(UNIHDR *hdr, int len)
369 {
370         hdr->uni_str_len = 2 * len;
371         hdr->uni_max_len = 2 * len;
372         hdr->buffer      = len != 0 ? 1 : 0;
373 }
374
375 /*******************************************************************
376  Reads or writes a UNIHDR structure.
377 ********************************************************************/
378
379 BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
380 {
381         if (hdr == NULL)
382                 return False;
383
384         prs_debug(ps, depth, desc, "smb_io_unihdr");
385         depth++;
386
387         if(!prs_align(ps))
388                 return False;
389         
390         if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
391                 return False;
392         if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
393                 return False;
394         if(!prs_uint32("buffer     ", ps, depth, &hdr->buffer))
395                 return False;
396
397         return True;
398 }
399
400 /*******************************************************************
401  Inits a BUFHDR structure.
402 ********************************************************************/
403
404 void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
405 {
406         hdr->buf_max_len = max_len;
407         hdr->buf_len     = len;
408 }
409
410 /*******************************************************************
411  prs_uint16 wrapper. Call this and it sets up a pointer to where the
412  uint16 should be stored, or gets the size if reading.
413  ********************************************************************/
414
415 BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
416 {
417         (*offset) = prs_offset(ps);
418         if (ps->io) {
419
420                 /* reading. */
421
422                 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
423                         return False;
424
425         } else {
426
427                 /* writing. */
428
429                 if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
430                         return False;
431         }
432
433         return True;
434 }
435
436 /*******************************************************************
437  smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
438  Does nothing on reading, as that is already handled by ...._pre()
439  ********************************************************************/
440
441 BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, 
442                                 uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
443 {
444         if (!ps->io) {
445                 /* writing: go back and do a retrospective job.  i hate this */
446
447                 uint32 old_offset = prs_offset(ps);
448
449                 init_buf_hdr(hdr, max_len, len);
450                 if(!prs_set_offset(ps, ptr_hdrbuf))
451                         return False;
452                 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
453                         return False;
454
455                 if(!prs_set_offset(ps, old_offset))
456                         return False;
457         }
458
459         return True;
460 }
461
462 /*******************************************************************
463  Reads or writes a BUFHDR structure.
464 ********************************************************************/
465
466 BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
467 {
468         if (hdr == NULL)
469                 return False;
470
471         prs_debug(ps, depth, desc, "smb_io_hdrbuf");
472         depth++;
473
474         if(!prs_align(ps))
475                 return False;
476         
477         if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
478                 return False;
479         if(!prs_uint32("buf_len    ", ps, depth, &hdr->buf_len))
480                 return False;
481
482         return True;
483 }
484
485 /*******************************************************************
486 creates a UNIHDR2 structure.
487 ********************************************************************/
488
489 void init_uni_hdr2(UNIHDR2 *hdr, int len)
490 {
491         init_uni_hdr(&hdr->unihdr, len);
492         hdr->buffer = (len > 0) ? 1 : 0;
493 }
494
495 /*******************************************************************
496  Reads or writes a UNIHDR2 structure.
497 ********************************************************************/
498
499 BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
500 {
501         if (hdr2 == NULL)
502                 return False;
503
504         prs_debug(ps, depth, desc, "smb_io_unihdr2");
505         depth++;
506
507         if(!prs_align(ps))
508                 return False;
509
510         if(!smb_io_unihdr("hdr", &hdr2->unihdr, ps, depth))
511                 return False;
512         if(!prs_uint32("buffer", ps, depth, &hdr2->buffer))
513                 return False;
514
515         return True;
516 }
517
518 /*******************************************************************
519  Inits a UNISTR structure.
520 ********************************************************************/
521
522 void init_unistr(UNISTR *str, const char *buf)
523 {
524         size_t len;
525
526         if (buf == NULL) {
527                 str->buffer = NULL;
528                 return;
529         }
530                 
531
532         len = strlen(buf) + 1;
533
534         if (len < MAX_UNISTRLEN)
535                 len = MAX_UNISTRLEN;
536         len *= sizeof(uint16);
537
538         str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
539         if (str->buffer == NULL)
540                 smb_panic("init_unistr: malloc fail\n");
541
542         /* store the string (null-terminated copy) */
543         dos_struni2((char *)str->buffer, buf, len);
544 }
545
546 /*******************************************************************
547 reads or writes a UNISTR structure.
548 XXXX NOTE: UNISTR structures NEED to be null-terminated.
549 ********************************************************************/
550
551 BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
552 {
553         if (uni == NULL)
554                 return False;
555
556         prs_debug(ps, depth, desc, "smb_io_unistr");
557         depth++;
558
559         if(!prs_align(ps))
560                 return False;
561         if(!prs_unistr("unistr", ps, depth, uni))
562                 return False;
563
564         return True;
565 }
566
567 /*******************************************************************
568  Allocate the BUFFER3 memory.
569 ********************************************************************/
570
571 static void create_buffer3(BUFFER3 *str, size_t len)
572 {
573         if (len < MAX_BUFFERLEN)
574                 len = MAX_BUFFERLEN;
575
576     str->buffer = talloc_zero(get_talloc_ctx(), len);
577         if (str->buffer == NULL)
578                 smb_panic("create_buffer3: talloc fail\n");
579
580 }
581
582 /*******************************************************************
583  Inits a BUFFER3 structure from a uint32
584 ********************************************************************/
585
586 void init_buffer3_uint32(BUFFER3 *str, uint32 val)
587 {
588         ZERO_STRUCTP(str);
589
590         /* set up string lengths. */
591         str->buf_max_len = sizeof(uint32);
592         str->buf_len     = sizeof(uint32);
593
594         create_buffer3(str, sizeof(uint32));
595         SIVAL(str->buffer, 0, val);
596 }
597
598 /*******************************************************************
599  Inits a BUFFER3 structure.
600 ********************************************************************/
601
602 void init_buffer3_str(BUFFER3 *str, char *buf, int len)
603 {
604         ZERO_STRUCTP(str);
605
606         /* set up string lengths. */
607         str->buf_max_len = len * 2;
608         str->buf_len     = len * 2;
609
610         create_buffer3(str, str->buf_max_len);
611
612         /* store the string (null-terminated 8 bit chars into 16 bit chars) */
613         dos_struni2((char *)str->buffer, buf, str->buf_max_len);
614 }
615
616 /*******************************************************************
617  Inits a BUFFER3 structure from a hex string.
618 ********************************************************************/
619
620 void init_buffer3_hex(BUFFER3 *str, char *buf)
621 {
622         ZERO_STRUCTP(str);
623         create_buffer3(str, strlen(buf));
624         str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
625 }
626
627 /*******************************************************************
628  Inits a BUFFER3 structure.
629 ********************************************************************/
630
631 void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
632 {
633         ZERO_STRUCTP(str);
634
635         /* max buffer size (allocated size) */
636         str->buf_max_len = len;
637         if (buf != NULL) {
638                 create_buffer3(str, len);
639                 memcpy(str->buffer, buf, len);
640         }
641         str->buf_len = buf != NULL ? len : 0;
642 }
643
644 /*******************************************************************
645  Reads or writes a BUFFER3 structure.
646    the uni_max_len member tells you how large the buffer is.
647    the uni_str_len member tells you how much of the buffer is really used.
648 ********************************************************************/
649
650 BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
651 {
652         if (buf3 == NULL)
653                 return False;
654
655         prs_debug(ps, depth, desc, "smb_io_buffer3");
656         depth++;
657
658         if(!prs_align(ps))
659                 return False;
660         
661         if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
662                 return False;
663
664         if (UNMARSHALLING(ps)) {
665                 buf3->buffer = (unsigned char *)prs_alloc_mem(ps, buf3->buf_max_len);
666                 if (buf3->buffer == NULL)
667                         return False;
668         }
669
670         if(!prs_uint8s(True, "buffer     ", ps, depth, buf3->buffer, buf3->buf_max_len))
671                 return False;
672
673         if(!prs_uint32("buf_len    ", ps, depth, &buf3->buf_len))
674                 return False;
675
676         return True;
677 }
678
679 /*******************************************************************
680 reads or writes a BUFFER5 structure.
681 the buf_len member tells you how large the buffer is.
682 ********************************************************************/
683 BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
684 {
685         prs_debug(ps, depth, desc, "smb_io_buffer5");
686         depth++;
687
688         if (buf5 == NULL) return False;
689
690         if(!prs_align(ps))
691                 return False;
692         if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len))
693                 return False;
694
695
696         if(!prs_buffer5(True, "buffer" , ps, depth, buf5))
697                 return False;
698
699         return True;
700 }
701
702 /*******************************************************************
703  Inits a BUFFER2 structure.
704 ********************************************************************/
705
706 void init_buffer2(BUFFER2 *str, uint8 *buf, int len)
707 {
708         ZERO_STRUCTP(str);
709
710         /* max buffer size (allocated size) */
711         str->buf_max_len = len;
712         str->undoc       = 0;
713         str->buf_len = buf != NULL ? len : 0;
714
715         if (buf != NULL) {
716                 if (len < MAX_BUFFERLEN)
717                         len = MAX_BUFFERLEN;
718                 str->buffer = talloc_zero(get_talloc_ctx(), len);
719                 if (str->buffer == NULL)
720                         smb_panic("init_buffer2: talloc fail\n");
721                 memcpy(str->buffer, buf, MIN(str->buf_len, len));
722         }
723 }
724
725 /*******************************************************************
726  Reads or writes a BUFFER2 structure.
727    the uni_max_len member tells you how large the buffer is.
728    the uni_str_len member tells you how much of the buffer is really used.
729 ********************************************************************/
730
731 BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
732 {
733         if (buf2 == NULL)
734                 return False;
735
736         if (buffer) {
737
738                 prs_debug(ps, depth, desc, "smb_io_buffer2");
739                 depth++;
740
741                 if(!prs_align(ps))
742                         return False;
743                 
744                 if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
745                         return False;
746                 if(!prs_uint32("undoc      ", ps, depth, &buf2->undoc))
747                         return False;
748                 if(!prs_uint32("buf_len    ", ps, depth, &buf2->buf_len))
749                         return False;
750
751                 /* buffer advanced by indicated length of string
752                    NOT by searching for null-termination */
753
754                 if(!prs_buffer2(True, "buffer     ", ps, depth, buf2))
755                         return False;
756
757         } else {
758
759                 prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
760                 depth++;
761                 memset((char *)buf2, '\0', sizeof(*buf2));
762
763         }
764         return True;
765 }
766
767 /*******************************************************************
768 creates a UNISTR2 structure: sets up the buffer, too
769 ********************************************************************/
770
771 void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
772 {
773         if (buf != NULL) {
774
775                 *ptr = 1;
776                 init_unistr2(str, buf, strlen(buf)+1);
777
778         } else {
779
780                 *ptr = 0;
781                 init_unistr2(str, "", 0);
782
783         }
784 }
785
786 /*******************************************************************
787  Copies a UNISTR2 structure.
788 ********************************************************************/
789
790 void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
791 {
792
793         /* set up string lengths. add one if string is not null-terminated */
794         str->uni_max_len = from->uni_max_len;
795         str->undoc       = from->undoc;
796         str->uni_str_len = from->uni_str_len;
797
798         if (from->buffer == NULL)
799                 return;
800                 
801         /* the string buffer is allocated to the maximum size
802            (the the length of the source string) to prevent
803            reallocation of memory. */
804         if (str->buffer == NULL) {
805                 size_t len = from->uni_max_len * sizeof(uint16);
806
807                 if (len < MAX_UNISTRLEN)
808                         len = MAX_UNISTRLEN;
809                 len *= sizeof(uint16);
810
811                 str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
812                 if ((str->buffer == NULL) && (len > 0 ))
813                 {
814                         smb_panic("copy_unistr2: talloc fail\n");
815                         return;
816                 }
817         }
818
819         /* copy the string */
820         memcpy(str->buffer, from->buffer, from->uni_max_len*sizeof(uint16));
821 }
822
823 /*******************************************************************
824  Creates a STRING2 structure.
825 ********************************************************************/
826
827 void init_string2(STRING2 *str, char *buf, int len)
828 {
829         int alloc_len = 0;
830
831         /* set up string lengths. */
832         str->str_max_len = len;
833         str->undoc       = 0;
834         str->str_str_len = len;
835
836         /* store the string */
837         if(len != 0) {
838                 if (len < MAX_STRINGLEN)
839                         alloc_len = MAX_STRINGLEN;
840                 str->buffer = talloc_zero(get_talloc_ctx(), alloc_len);
841                 if (str->buffer == NULL)
842                         smb_panic("init_string2: malloc fail\n");
843                 memcpy(str->buffer, buf, len);
844   }
845 }
846
847 /*******************************************************************
848  Reads or writes a STRING2 structure.
849  XXXX NOTE: STRING2 structures need NOT be null-terminated.
850    the str_str_len member tells you how long the string is;
851    the str_max_len member tells you how large the buffer is.
852 ********************************************************************/
853
854 BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
855 {
856         if (str2 == NULL)
857                 return False;
858
859         if (buffer) {
860
861                 prs_debug(ps, depth, desc, "smb_io_string2");
862                 depth++;
863
864                 if(!prs_align(ps))
865                         return False;
866                 
867                 if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
868                         return False;
869                 if(!prs_uint32("undoc      ", ps, depth, &str2->undoc))
870                         return False;
871                 if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
872                         return False;
873
874                 /* buffer advanced by indicated length of string
875                    NOT by searching for null-termination */
876                 if(!prs_string2(True, "buffer     ", ps, depth, str2))
877                         return False;
878
879         } else {
880
881                 prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
882                 depth++;
883                 memset((char *)str2, '\0', sizeof(*str2));
884
885         }
886
887         return True;
888 }
889
890 /*******************************************************************
891  Inits a UNISTR2 structure.
892 ********************************************************************/
893
894 void init_unistr2(UNISTR2 *str, const char *buf, size_t len)
895 {
896         ZERO_STRUCTP(str);
897
898         /* set up string lengths. */
899         str->uni_max_len = (uint32)len;
900         str->undoc       = 0;
901         str->uni_str_len = (uint32)len;
902
903         if (len < MAX_UNISTRLEN)
904                 len = MAX_UNISTRLEN;
905         len *= sizeof(uint16);
906
907         str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
908         if ((str->buffer == NULL) && (len > 0))
909         {
910                 smb_panic("init_unistr2: malloc fail\n");
911                 return;
912         }
913
914         /* store the string (null-terminated 8 bit chars into 16 bit chars) */
915         dos_struni2((char *)str->buffer, buf, len);
916 }
917
918 /*******************************************************************
919  Inits a UNISTR2 structure from a UNISTR
920 ********************************************************************/
921 void init_unistr2_from_unistr (UNISTR2 *to, UNISTR *from)
922 {
923
924         uint32 i;
925
926         /* the destination UNISTR2 should never be NULL.
927            if it is it is a programming error */
928
929         /* if the source UNISTR is NULL, then zero out
930            the destination string and return */
931         ZERO_STRUCTP (to);
932         if ((from == NULL) || (from->buffer == NULL))
933                 return;
934
935         /* get the length; UNISTR must be NULL terminated */
936         i = 0;
937         while ((from->buffer)[i]!='\0')
938                 i++;
939         i++;    /* one more to catch the terminating NULL */
940                 /* is this necessary -- jerry?  I need to think */
941
942         /* set up string lengths; uni_max_len is set to i+1
943            because we need to account for the final NULL termination */
944         to->uni_max_len = i;
945         to->undoc       = 0;
946         to->uni_str_len = i;
947
948         /* allocate the space and copy the string buffer */
949         to->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), sizeof(uint16)*(to->uni_str_len));
950         if (to->buffer == NULL)
951                 smb_panic("init_unistr2_from_unistr: malloc fail\n");
952         memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
953                 
954         return;
955 }
956
957
958 /*******************************************************************
959  Reads or writes a UNISTR2 structure.
960  XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
961    the uni_str_len member tells you how long the string is;
962    the uni_max_len member tells you how large the buffer is.
963 ********************************************************************/
964
965 BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
966 {
967         if (uni2 == NULL)
968                 return False;
969
970         if (buffer) {
971
972                 prs_debug(ps, depth, desc, "smb_io_unistr2");
973                 depth++;
974
975                 if(!prs_align(ps))
976                         return False;
977                 
978                 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
979                         return False;
980                 if(!prs_uint32("undoc      ", ps, depth, &uni2->undoc))
981                         return False;
982                 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
983                         return False;
984
985                 /* buffer advanced by indicated length of string
986                    NOT by searching for null-termination */
987                 if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
988                         return False;
989
990         } else {
991
992                 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
993                 depth++;
994                 memset((char *)uni2, '\0', sizeof(*uni2));
995
996         }
997
998         return True;
999 }
1000
1001 /*******************************************************************
1002  Inits a DOM_RID2 structure.
1003 ********************************************************************/
1004
1005 void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
1006 {
1007         rid2->type    = type;
1008         rid2->rid     = rid;
1009         rid2->rid_idx = idx;
1010 }
1011
1012 /*******************************************************************
1013  Reads or writes a DOM_RID2 structure.
1014 ********************************************************************/
1015
1016 BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
1017 {
1018         if (rid2 == NULL)
1019                 return False;
1020
1021         prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1022         depth++;
1023
1024         if(!prs_align(ps))
1025                 return False;
1026    
1027         if(!prs_uint8("type   ", ps, depth, &rid2->type))
1028                 return False;
1029         if(!prs_align(ps))
1030                 return False;
1031         if(!prs_uint32("rid    ", ps, depth, &rid2->rid))
1032                 return False;
1033         if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
1034                 return False;
1035
1036         return True;
1037 }
1038
1039 /*******************************************************************
1040 creates a DOM_RID3 structure.
1041 ********************************************************************/
1042
1043 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1044 {
1045     rid3->rid      = rid;
1046     rid3->type1    = type;
1047     rid3->ptr_type = 0x1; /* non-zero, basically. */
1048     rid3->type2    = 0x1;
1049     rid3->unk      = type;
1050 }
1051
1052 /*******************************************************************
1053 reads or writes a DOM_RID3 structure.
1054 ********************************************************************/
1055
1056 BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1057 {
1058         if (rid3 == NULL)
1059                 return False;
1060
1061         prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1062         depth++;
1063
1064         if(!prs_align(ps))
1065                 return False;
1066
1067         if(!prs_uint32("rid     ", ps, depth, &rid3->rid))
1068                 return False;
1069         if(!prs_uint32("type1   ", ps, depth, &rid3->type1))
1070                 return False;
1071         if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1072                 return False;
1073         if(!prs_uint32("type2   ", ps, depth, &rid3->type2))
1074                 return False;
1075         if(!prs_uint32("unk     ", ps, depth, &rid3->unk))
1076                 return False;
1077
1078         return True;
1079 }
1080
1081 /*******************************************************************
1082  Inits a DOM_RID4 structure.
1083 ********************************************************************/
1084
1085 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1086 {
1087     rid4->unknown = unknown;
1088     rid4->attr    = attr;
1089     rid4->rid     = rid;
1090 }
1091
1092 /*******************************************************************
1093  Inits a DOM_CLNT_SRV structure.
1094 ********************************************************************/
1095
1096 static void init_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name)
1097 {
1098         DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1099
1100         if (logon_srv != NULL) {
1101                 log->undoc_buffer = 1;
1102                 init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
1103         } else {
1104                 log->undoc_buffer = 0;
1105         }
1106
1107         if (comp_name != NULL) {
1108                 log->undoc_buffer2 = 1;
1109                 init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
1110         } else {
1111                 log->undoc_buffer2 = 0;
1112         }
1113 }
1114
1115 /*******************************************************************
1116  Inits or writes a DOM_CLNT_SRV structure.
1117 ********************************************************************/
1118
1119 static BOOL smb_io_clnt_srv(char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
1120 {
1121         if (log == NULL)
1122                 return False;
1123
1124         prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1125         depth++;
1126
1127         if(!prs_align(ps))
1128                 return False;
1129         
1130         if(!prs_uint32("undoc_buffer ", ps, depth, &log->undoc_buffer))
1131                 return False;
1132
1133         if (log->undoc_buffer != 0) {
1134                 if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, log->undoc_buffer, ps, depth))
1135                         return False;
1136         }
1137
1138         if(!prs_align(ps))
1139                 return False;
1140
1141         if(!prs_uint32("undoc_buffer2", ps, depth, &log->undoc_buffer2))
1142                 return False;
1143
1144         if (log->undoc_buffer2 != 0) {
1145                 if(!smb_io_unistr2("unistr2", &log->uni_comp_name, log->undoc_buffer2, ps, depth))
1146                         return False;
1147         }
1148
1149         return True;
1150 }
1151
1152 /*******************************************************************
1153  Inits a DOM_LOG_INFO structure.
1154 ********************************************************************/
1155
1156 void init_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
1157                 uint16 sec_chan, char *comp_name)
1158 {
1159         DEBUG(5,("make_log_info %d\n", __LINE__));
1160
1161         log->undoc_buffer = 1;
1162
1163         init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
1164         init_unistr2(&log->uni_acct_name, acct_name, strlen(acct_name)+1);
1165
1166         log->sec_chan = sec_chan;
1167
1168         init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
1169 }
1170
1171 /*******************************************************************
1172  Reads or writes a DOM_LOG_INFO structure.
1173 ********************************************************************/
1174
1175 BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
1176 {
1177         if (log == NULL)
1178                 return False;
1179
1180         prs_debug(ps, depth, desc, "smb_io_log_info");
1181         depth++;
1182
1183         if(!prs_align(ps))
1184                 return False;
1185         
1186         if(!prs_uint32("undoc_buffer", ps, depth, &log->undoc_buffer))
1187                 return False;
1188
1189         if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, True, ps, depth))
1190                 return False;
1191         if(!smb_io_unistr2("unistr2", &log->uni_acct_name, True, ps, depth))
1192                 return False;
1193
1194         if(!prs_uint16("sec_chan", ps, depth, &log->sec_chan))
1195                 return False;
1196
1197         if(!smb_io_unistr2("unistr2", &log->uni_comp_name, True, ps, depth))
1198                 return False;
1199
1200         return True;
1201 }
1202
1203 /*******************************************************************
1204  Reads or writes a DOM_CHAL structure.
1205 ********************************************************************/
1206
1207 BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1208 {
1209         if (chal == NULL)
1210                 return False;
1211
1212         prs_debug(ps, depth, desc, "smb_io_chal");
1213         depth++;
1214
1215         if(!prs_align(ps))
1216                 return False;
1217         
1218         if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1219                 return False;
1220
1221         return True;
1222 }
1223
1224 /*******************************************************************
1225  Reads or writes a DOM_CRED structure.
1226 ********************************************************************/
1227
1228 BOOL smb_io_cred(char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
1229 {
1230         if (cred == NULL)
1231                 return False;
1232
1233         prs_debug(ps, depth, desc, "smb_io_cred");
1234         depth++;
1235
1236         if(!prs_align(ps))
1237                 return False;
1238
1239         if(!smb_io_chal ("", &cred->challenge, ps, depth))
1240                 return False;
1241         if(!smb_io_utime("", &cred->timestamp, ps, depth))
1242                 return False;
1243
1244         return True;
1245 }
1246
1247 /*******************************************************************
1248  Inits a DOM_CLNT_INFO2 structure.
1249 ********************************************************************/
1250
1251 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1252                                 char *logon_srv, char *comp_name,
1253                                 DOM_CRED *clnt_cred)
1254 {
1255         DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1256
1257         init_clnt_srv(&(clnt->login), logon_srv, comp_name);
1258
1259         if (clnt_cred != NULL) {
1260                 clnt->ptr_cred = 1;
1261                 memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
1262         } else {
1263                 clnt->ptr_cred = 0;
1264         }
1265 }
1266
1267 /*******************************************************************
1268  Reads or writes a DOM_CLNT_INFO2 structure.
1269 ********************************************************************/
1270
1271 BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1272 {
1273         if (clnt == NULL)
1274                 return False;
1275
1276         prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1277         depth++;
1278
1279         if(!prs_align(ps))
1280                 return False;
1281         
1282         if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1283                 return False;
1284
1285         if(!prs_align(ps))
1286                 return False;
1287         
1288         if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1289                 return False;
1290         if(!smb_io_cred("", &clnt->cred, ps, depth))
1291                 return False;
1292
1293         return True;
1294 }
1295
1296 /*******************************************************************
1297  Inits a DOM_CLNT_INFO structure.
1298 ********************************************************************/
1299
1300 void init_clnt_info(DOM_CLNT_INFO *clnt,
1301                 char *logon_srv, char *acct_name,
1302                 uint16 sec_chan, char *comp_name,
1303                                 DOM_CRED *cred)
1304 {
1305         DEBUG(5,("make_clnt_info\n"));
1306
1307         init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1308         memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1309 }
1310
1311 /*******************************************************************
1312  Reads or writes a DOM_CLNT_INFO structure.
1313 ********************************************************************/
1314
1315 BOOL smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1316 {
1317         if (clnt == NULL)
1318                 return False;
1319
1320         prs_debug(ps, depth, desc, "smb_io_clnt_info");
1321         depth++;
1322
1323         if(!prs_align(ps))
1324                 return False;
1325         
1326         if(!smb_io_log_info("", &clnt->login, ps, depth))
1327                 return False;
1328         if(!smb_io_cred("", &clnt->cred, ps, depth))
1329                 return False;
1330
1331         return True;
1332 }
1333
1334 /*******************************************************************
1335  Inits a DOM_LOGON_ID structure.
1336 ********************************************************************/
1337
1338 void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
1339 {
1340         DEBUG(5,("make_logon_id: %d\n", __LINE__));
1341
1342         log->low  = log_id_low;
1343         log->high = log_id_high;
1344 }
1345
1346 /*******************************************************************
1347  Reads or writes a DOM_LOGON_ID structure.
1348 ********************************************************************/
1349
1350 BOOL smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
1351 {
1352         if (log == NULL)
1353                 return False;
1354
1355         prs_debug(ps, depth, desc, "smb_io_logon_id");
1356         depth++;
1357
1358         if(!prs_align(ps))
1359                 return False;
1360         
1361         if(!prs_uint32("low ", ps, depth, &log->low ))
1362                 return False;
1363         if(!prs_uint32("high", ps, depth, &log->high))
1364                 return False;
1365
1366         return True;
1367 }
1368
1369 /*******************************************************************
1370  Inits an OWF_INFO structure.
1371 ********************************************************************/
1372
1373 void init_owf_info(OWF_INFO *hash, uint8 data[16])
1374 {
1375         DEBUG(5,("init_owf_info: %d\n", __LINE__));
1376         
1377         if (data != NULL)
1378                 memcpy(hash->data, data, sizeof(hash->data));
1379         else
1380                 memset((char *)hash->data, '\0', sizeof(hash->data));
1381 }
1382
1383 /*******************************************************************
1384  Reads or writes an OWF_INFO structure.
1385 ********************************************************************/
1386
1387 BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1388 {
1389         if (hash == NULL)
1390                 return False;
1391
1392         prs_debug(ps, depth, desc, "smb_io_owf_info");
1393         depth++;
1394
1395         if(!prs_align(ps))
1396                 return False;
1397         
1398         if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1399                 return False;
1400
1401         return True;
1402 }
1403
1404 /*******************************************************************
1405  Reads or writes a DOM_GID structure.
1406 ********************************************************************/
1407
1408 BOOL smb_io_gid(char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
1409 {
1410         if (gid == NULL)
1411                 return False;
1412
1413         prs_debug(ps, depth, desc, "smb_io_gid");
1414         depth++;
1415
1416         if(!prs_align(ps))
1417                 return False;
1418         
1419         if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1420                 return False;
1421         if(!prs_uint32("attr ", ps, depth, &gid->attr))
1422                 return False;
1423
1424         return True;
1425 }
1426
1427 /*******************************************************************
1428  Reads or writes an POLICY_HND structure.
1429 ********************************************************************/
1430
1431 BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1432 {
1433         if (pol == NULL)
1434                 return False;
1435
1436         prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1437         depth++;
1438
1439         if(!prs_align(ps))
1440                 return False;
1441
1442         if(UNMARSHALLING(ps))
1443                 ZERO_STRUCTP(pol);
1444         
1445         if (!prs_uint32("data1", ps, depth, &pol->data1))
1446                 return False;
1447         if (!prs_uint32("data2", ps, depth, &pol->data2))
1448                 return False;
1449         if (!prs_uint16("data3", ps, depth, &pol->data3))
1450                 return False;
1451         if (!prs_uint16("data4", ps, depth, &pol->data4))
1452                 return False;
1453         if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1454                 return False;
1455
1456         return True;
1457 }
1458
1459 /*******************************************************************
1460  Create a UNISTR3.
1461 ********************************************************************/
1462
1463 void init_unistr3(UNISTR3 *str, const char *buf)
1464 {
1465         size_t len;
1466
1467         if (buf == NULL) {
1468                 str->uni_str_len=0;
1469                 str->str.buffer = NULL;
1470                 return;
1471         }
1472
1473         len = strlen(buf) + 1;
1474
1475         str->uni_str_len=len;
1476
1477         if (len < MAX_UNISTRLEN)
1478                 len = MAX_UNISTRLEN;
1479
1480         len *= sizeof(uint16);
1481
1482         str->str.buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
1483         if (str->str.buffer == NULL)
1484                 smb_panic("init_unistr3: malloc fail\n");
1485
1486         /* store the string (null-terminated copy) */
1487         dos_struni2((char *)str->str.buffer, buf, len);
1488 }
1489
1490 /*******************************************************************
1491  Reads or writes a UNISTR3 structure.
1492 ********************************************************************/
1493
1494 BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1495 {
1496         if (name == NULL)
1497                 return False;
1498
1499         prs_debug(ps, depth, desc, "smb_io_unistr3");
1500         depth++;
1501
1502         if(!prs_align(ps))
1503                 return False;
1504         
1505         if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1506                 return False;
1507
1508         /* don't know if len is specified by uni_str_len member... */
1509         /* assume unicode string is unicode-null-terminated, instead */
1510
1511         if(!prs_unistr3(True, "unistr", name, ps, depth))
1512                 return False;
1513
1514         return True;
1515 }
1516
1517
1518 /*******************************************************************
1519  Stream a uint64_struct
1520  ********************************************************************/
1521 BOOL prs_uint64(char *name, prs_struct *ps, int depth, UINT64_S *data64)
1522 {
1523         return prs_uint32(name, ps, depth+1, &data64->low) &&
1524                 prs_uint32(name, ps, depth+1, &data64->high);
1525 }
1526
1527