fe65aaf4d4e51cbea2163e77011c8239ed88dcf1
[nivanova/samba-autobuild/.git] / source3 / rpc_parse / parse_misc.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
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; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30
31 /*******************************************************************
32 reads or writes a BIGINT structure.
33 ********************************************************************/
34 BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth)
35 {
36         if (bigint == NULL) return False;
37
38         prs_debug(ps, depth, desc, "smb_io_bigint");
39         depth++;
40
41         prs_align(ps);
42         
43         prs_uint32("low ", ps, depth, &(bigint->low ));
44         prs_uint32("high", ps, depth, &(bigint->high));
45
46         return True;
47 }
48
49 /*******************************************************************
50 reads or writes a UTIME type.
51 ********************************************************************/
52 static BOOL smb_io_utime(char *desc,  UTIME *t, prs_struct *ps, int depth)
53 {
54         if (t == NULL) return False;
55
56         prs_debug(ps, depth, desc, "smb_io_utime");
57         depth++;
58
59         prs_align(ps);
60         
61         prs_uint32 ("time", ps, depth, &(t->time));
62
63         return True;
64 }
65
66 /*******************************************************************
67 reads or writes an NTTIME structure.
68 ********************************************************************/
69 BOOL smb_io_time(char *desc,  NTTIME *nttime, prs_struct *ps, int depth)
70 {
71         if (nttime == NULL) return False;
72
73         prs_debug(ps, depth, desc, "smb_io_time");
74         depth++;
75
76         prs_align(ps);
77         
78         prs_uint32("low ", ps, depth, &(nttime->low )); /* low part */
79         prs_uint32("high", ps, depth, &(nttime->high)); /* high part */
80
81         return True;
82 }
83
84 /*******************************************************************
85 reads or writes a LOOKUP_LEVEL structure.
86 ********************************************************************/
87 BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
88 {
89         if (level == NULL) return False;
90
91         prs_debug(ps, depth, desc, "smb_io_lookup_level");
92         depth++;
93
94         prs_align(ps);
95         prs_uint16("value", ps, depth, &(level->value));
96         prs_align(ps);
97
98         return True;
99 }
100
101 /*******************************************************************
102 gets an enumeration handle from an ENUM_HND structure.
103 ********************************************************************/
104 uint32 get_enum_hnd(ENUM_HND *enh)
105 {
106         return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
107
108         return True;
109 }
110
111 /*******************************************************************
112 makes an ENUM_HND structure.
113 ********************************************************************/
114 BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd)
115 {
116         if (enh == NULL) return False;
117
118         DEBUG(5,("smb_io_enum_hnd\n"));
119
120         enh->ptr_hnd = (hnd != 0) ? 1 : 0;
121         enh->handle = hnd;
122
123         return True;
124 }
125
126 /*******************************************************************
127 reads or writes an ENUM_HND structure.
128 ********************************************************************/
129 BOOL smb_io_enum_hnd(char *desc,  ENUM_HND *hnd, prs_struct *ps, int depth)
130 {
131         if (hnd == NULL) return False;
132
133         prs_debug(ps, depth, desc, "smb_io_enum_hnd");
134         depth++;
135
136         prs_align(ps);
137         
138         prs_uint32("ptr_hnd", ps, depth, &(hnd->ptr_hnd)); /* pointer */
139         if (hnd->ptr_hnd != 0)
140         {
141                 prs_uint32("handle ", ps, depth, &(hnd->handle )); /* enum handle */
142         }
143
144         return True;
145 }
146
147 /*******************************************************************
148 reads or writes a DOM_SID structure.
149 ********************************************************************/
150 BOOL smb_io_dom_sid(char *desc,  DOM_SID *sid, prs_struct *ps, int depth)
151 {
152         int i;
153
154         if (sid == NULL) return False;
155
156         prs_debug(ps, depth, desc, "smb_io_dom_sid");
157         depth++;
158
159         prs_align(ps);
160         
161         prs_uint8 ("sid_rev_num", ps, depth, &(sid->sid_rev_num)); 
162         prs_uint8 ("num_auths  ", ps, depth, &(sid->num_auths));
163
164         for (i = 0; i < 6; i++)
165         {
166                 fstring tmp;
167                 slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
168                 prs_uint8 (tmp, ps, depth, &(sid->id_auth[i]));
169         }
170
171         /* oops! XXXX should really issue a warning here... */
172         if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
173
174         prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths);
175
176         return True;
177 }
178
179 /*******************************************************************
180 creates a DOM_SID2 structure.
181 ********************************************************************/
182 BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
183 {
184         sid_copy(&sid2->sid, sid);
185         sid2->num_auths = sid2->sid.num_auths;
186
187         return True;
188 }
189
190 /*******************************************************************
191 reads or writes a DOM_SID2 structure.
192 ********************************************************************/
193 BOOL smb_io_dom_sid2(char *desc,  DOM_SID2 *sid, prs_struct *ps, int depth)
194 {
195         if (sid == NULL) return False;
196
197         prs_debug(ps, depth, desc, "smb_io_dom_sid2");
198         depth++;
199
200         prs_align(ps);
201         
202         prs_uint32("num_auths", ps, depth, &(sid->num_auths));
203
204         smb_io_dom_sid("sid", &(sid->sid), ps, depth);
205
206         return True;
207 }
208
209 /*******************************************************************
210 creates a STRHDR structure.
211 ********************************************************************/
212 BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
213 {
214         hdr->str_max_len = max_len;
215         hdr->str_str_len = len;
216         hdr->buffer      = buffer;
217
218         return True;
219 }
220
221 /*******************************************************************
222 reads or writes a STRHDR structure.
223 ********************************************************************/
224 BOOL smb_io_strhdr(char *desc,  STRHDR *hdr, prs_struct *ps, int depth)
225 {
226         if (hdr == NULL) return False;
227
228         prs_debug(ps, depth, desc, "smb_io_strhdr");
229         depth++;
230
231         prs_align(ps);
232         
233         prs_uint16("str_str_len", ps, depth, &(hdr->str_str_len));
234         prs_uint16("str_max_len", ps, depth, &(hdr->str_max_len));
235         prs_uint32("buffer     ", ps, depth, &(hdr->buffer     ));
236
237         /* oops! XXXX maybe issue a warning that this is happening... */
238         if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
239         if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
240
241         return True;
242 }
243
244 /*******************************************************************
245 creates a STRHDR2 structure.
246 ********************************************************************/
247 BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer)
248 {
249         hdr->str_max_len = max_len;
250         hdr->str_str_len = len;
251         hdr->buffer      = buffer;
252
253         return True;
254 }
255
256 /*******************************************************************
257 reads or writes a STRHDR2 structure.
258 ********************************************************************/
259 BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth)
260 {
261         if (hdr == NULL) return False;
262
263         prs_debug(ps, depth, desc, "smb_io_strhdr");
264         depth++;
265
266         prs_align(ps);
267         
268         prs_uint32("str_str_len", ps, depth, &(hdr->str_str_len));
269         prs_uint32("str_max_len", ps, depth, &(hdr->str_max_len));
270         prs_uint32("buffer     ", ps, depth, &(hdr->buffer     ));
271
272         /* oops! XXXX maybe issue a warning that this is happening... */
273         if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
274         if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
275
276         return True;
277 }
278
279 /*******************************************************************
280 creates a UNIHDR structure.
281 ********************************************************************/
282 BOOL make_uni_hdr(UNIHDR *hdr, int len)
283 {
284         hdr->uni_str_len = 2 * len;
285         hdr->uni_max_len = 2 * len;
286         hdr->buffer      = len != 0 ? 1 : 0;
287
288         return True;
289 }
290
291 /*******************************************************************
292 reads or writes a UNIHDR structure.
293 ********************************************************************/
294 BOOL smb_io_unihdr(char *desc,  UNIHDR *hdr, prs_struct *ps, int depth)
295 {
296         if (hdr == NULL) return False;
297
298         prs_debug(ps, depth, desc, "smb_io_unihdr");
299         depth++;
300
301         prs_align(ps);
302         
303         prs_uint16("uni_str_len", ps, depth, &(hdr->uni_str_len));
304         prs_uint16("uni_max_len", ps, depth, &(hdr->uni_max_len));
305         prs_uint32("buffer     ", ps, depth, &(hdr->buffer     ));
306
307         /* oops! XXXX maybe issue a warning that this is happening... */
308         if (hdr->uni_max_len > MAX_UNISTRLEN) hdr->uni_max_len = MAX_UNISTRLEN;
309         if (hdr->uni_str_len > MAX_UNISTRLEN) hdr->uni_str_len = MAX_UNISTRLEN;
310
311         return True;
312 }
313
314 /*******************************************************************
315 creates a BUFHDR structure.
316 ********************************************************************/
317 BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len)
318 {
319         hdr->buf_max_len = max_len;
320         hdr->buf_len     = len;
321
322         return True;
323 }
324
325 /*******************************************************************
326  prs_uint16 wrapper.  call this and it sets up a pointer to where the
327  uint16 should be stored, or gets the size if reading
328  ********************************************************************/
329 BOOL smb_io_hdrbuf_pre(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
330 {
331         (*offset) = ps->offset;
332         if (ps->io)
333         {
334                 /* reading. */
335                 smb_io_hdrbuf(desc, hdr, ps, depth);
336         }
337         else
338         {
339                 ps->offset += sizeof(uint32) * 2;
340         }
341
342         return True;
343 }
344
345 /*******************************************************************
346  smb_io_hdrbuf wrapper.  call this and it retrospectively stores the size.
347  does nothing on reading, as that is already handled by ...._pre()
348  ********************************************************************/
349 BOOL smb_io_hdrbuf_post(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth, 
350                                 uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
351 {
352         if (!ps->io)
353         {
354                 /* storing: go back and do a retrospective job.  i hate this */
355                 uint32 old_offset = ps->offset;
356
357                 make_buf_hdr(hdr, max_len, len);
358                 ps->offset = ptr_hdrbuf;
359                 smb_io_hdrbuf(desc, hdr, ps, depth);
360                 ps->offset = old_offset;
361         }
362
363         return True;
364 }
365
366 /*******************************************************************
367 reads or writes a BUFHDR structure.
368 ********************************************************************/
369 BOOL smb_io_hdrbuf(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth)
370 {
371         if (hdr == NULL) return False;
372
373         prs_debug(ps, depth, desc, "smb_io_hdrbuf");
374         depth++;
375
376         prs_align(ps);
377         
378         prs_uint32("buf_max_len", ps, depth, &(hdr->buf_max_len));
379         prs_uint32("buf_len    ", ps, depth, &(hdr->buf_len    ));
380
381         /* oops! XXXX maybe issue a warning that this is happening... */
382         if (hdr->buf_max_len > MAX_BUFFERLEN) hdr->buf_max_len = MAX_BUFFERLEN;
383         if (hdr->buf_len     > MAX_BUFFERLEN) hdr->buf_len     = MAX_BUFFERLEN;
384
385         return True;
386 }
387
388 /*******************************************************************
389 creates a BUFHDR2 structure.
390 ********************************************************************/
391 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
392 {
393         hdr->info_level = info_level;
394         hdr->length     = length;
395         hdr->buffer     = buffer;
396
397         return True;
398 }
399
400 /*******************************************************************
401 reads or writes a BUFHDR2 structure.
402 ********************************************************************/
403 BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
404 {
405         if (hdr == NULL) return False;
406
407         prs_debug(ps, depth, desc, "smb_io_bufhdr2");
408         depth++;
409
410         prs_align(ps);
411         prs_uint32("info_level", ps, depth, &(hdr->info_level));
412         prs_uint32("length    ", ps, depth, &(hdr->length    ));
413         prs_uint32("buffer    ", ps, depth, &(hdr->buffer    ));
414
415         return True;
416 }
417
418 /*******************************************************************
419 creates a UNIHDR2 structure.
420 ********************************************************************/
421 BOOL make_uni_hdr2(UNIHDR2 *hdr, int len)
422 {
423         make_uni_hdr(&(hdr->unihdr), len);
424         hdr->buffer = len > 0 ? 1 : 0;
425
426         return True;
427 }
428
429 /*******************************************************************
430 reads or writes a UNIHDR2 structure.
431 ********************************************************************/
432 BOOL smb_io_unihdr2(char *desc,  UNIHDR2 *hdr2, prs_struct *ps, int depth)
433 {
434         if (hdr2 == NULL) return False;
435
436         prs_debug(ps, depth, desc, "smb_io_unihdr2");
437         depth++;
438
439         prs_align(ps);
440
441         smb_io_unihdr("hdr", &(hdr2->unihdr), ps, depth);
442         prs_uint32("buffer", ps, depth, &(hdr2->buffer));
443
444         return True;
445 }
446
447 /*******************************************************************
448 creates a UNISTR structure.
449 ********************************************************************/
450 BOOL make_unistr(UNISTR *str, char *buf)
451 {
452         ascii_to_unistr(str->buffer, buf, sizeof(str->buffer)-1);
453
454         return True;
455 }
456
457 /*******************************************************************
458 reads or writes a UNISTR structure.
459 XXXX NOTE: UNISTR structures NEED to be null-terminated.
460 ********************************************************************/
461 BOOL smb_io_unistr(char *desc,  UNISTR *uni, prs_struct *ps, int depth)
462 {
463         if (uni == NULL) return False;
464
465         prs_debug(ps, depth, desc, "smb_io_unistr");
466         depth++;
467
468         prs_unistr("unistr", ps, depth, uni);
469
470         return True;
471 }
472
473 /*******************************************************************
474 creates a BUFFER3 structure from a uint32
475 ********************************************************************/
476 BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val)
477 {
478         ZERO_STRUCTP(str);
479
480         /* set up string lengths. */
481         str->buf_max_len = sizeof(uint32);
482         str->buf_len     = sizeof(uint32);
483
484         SIVAL(str->buffer, 0, val);
485
486         return True;
487 }
488
489 /*******************************************************************
490 creates a BUFFER3 structure.
491 ********************************************************************/
492 BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len)
493 {
494         ZERO_STRUCTP(str);
495
496         /* set up string lengths. */
497         str->buf_max_len = len * 2;
498         str->buf_len     = len * 2;
499
500         /* store the string (little endian buffer) */
501         ascii_to_unibuf((char*)str->buffer, buf, str->buf_len);
502
503         return True;
504 }
505
506 /*******************************************************************
507 creates a BUFFER3 structure from a hex string.
508 ********************************************************************/
509 BOOL make_buffer3_hex(BUFFER3 *str, char *buf)
510 {
511         ZERO_STRUCTP(str);
512         str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
513
514         return True;
515 }
516
517 /*******************************************************************
518 creates a BUFFER3 structure.
519 ********************************************************************/
520 BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
521 {
522         ZERO_STRUCTP(str);
523
524         /* max buffer size (allocated size) */
525         str->buf_max_len = len;
526         if (buf != NULL)
527         {
528                 memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer)));
529         }
530         str->buf_len = buf != NULL ? len : 0;
531
532         return True;
533 }
534
535 /*******************************************************************
536 reads or writes a BUFFER3 structure.
537      the uni_max_len member tells you how large the buffer is.
538      the uni_str_len member tells you how much of the buffer is really used.
539 ********************************************************************/
540 BOOL smb_io_buffer3(char *desc,  BUFFER3 *buf3, prs_struct *ps, int depth)
541 {
542         if (buf3 == NULL) return False;
543
544         prs_debug(ps, depth, desc, "smb_io_buffer3");
545         depth++;
546
547         prs_align(ps);
548         
549         prs_uint32("uni_max_len", ps, depth, &(buf3->buf_max_len));
550         if (buf3->buf_max_len > MAX_UNISTRLEN) buf3->buf_max_len = MAX_UNISTRLEN;
551
552         prs_uint8s(True, "buffer     ", ps, depth, buf3->buffer, buf3->buf_max_len);
553
554         prs_uint32("buf_len    ", ps, depth, &(buf3->buf_len));
555         if (buf3->buf_len     > MAX_UNISTRLEN) buf3->buf_len     = MAX_UNISTRLEN;
556
557         return True;
558 }
559
560 /*******************************************************************
561 creates a BUFFER4 structure.
562 ********************************************************************/
563 BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len)
564 {
565         ZERO_STRUCTP(str);
566
567         /* set up string lengths. */
568         str->buf_len     = len * 2;
569
570         /* store the string (little endian buffer) */
571         ascii_to_unibuf((char*)str->buffer, buf, str->buf_len);
572
573         return True;
574 }
575
576 /*******************************************************************
577 reads or writes a BUFFER4 structure.
578 ********************************************************************/
579 BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
580 {
581         if ((buf4 == NULL) || (buffer == 0)) return False;
582
583         prs_debug(ps, depth, desc, "smb_io_buffer4");
584         depth++;
585
586         prs_align(ps);
587         prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
588
589         if (buf4->buf_len > MAX_BUFFERLEN)
590         {
591                 buf4->buf_len = MAX_BUFFERLEN;
592         }
593
594         prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
595
596         return True;
597 }
598
599 /*******************************************************************
600 initialise a BUFFER5 structure.
601 ********************************************************************/
602 BOOL init_buffer5(BUFFER5 **str)
603 {
604         BUFFER5 *buf5;
605                 
606         buf5=(BUFFER5 *)malloc( sizeof(BUFFER5) );
607         
608         buf5->buf_len=0;
609         buf5->buffer=NULL;      
610         *str=buf5;
611
612         return True;
613 }
614
615 /*******************************************************************
616 clear a BUFFER5 structure.
617 ********************************************************************/
618 BOOL clear_buffer5(BUFFER5 **str)
619 {
620         BUFFER5 *buf5;
621         
622         buf5=*str;      
623         if (buf5->buffer != NULL )
624         {
625                 free(buf5->buffer);
626         }
627         free(buf5);
628         *str=NULL;
629
630         return True;
631 }
632
633 /*******************************************************************
634 creates a BUFFER5 structure.
635 ********************************************************************/
636 BOOL make_buffer5(BUFFER5 *str, char *buf, int len)
637 {
638
639         /* max buffer size (allocated size) */
640         str->buf_len = len;     
641         str->buffer = (uint16 *)malloc( sizeof(uint16) * len ); 
642         ascii_to_unistr(str->buffer, buf, len);
643
644         return True;
645 }
646
647 /*******************************************************************
648 reads or writes a BUFFER5 structure.
649 the buf_len member tells you how large the buffer is.
650 ********************************************************************/
651 BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
652 {
653         prs_debug(ps, depth, desc, "smb_io_buffer4");
654         depth++;
655
656         if (buf5 == NULL) return False;
657
658         prs_align(ps);
659         prs_uint32("buf_len", ps, depth, &(buf5->buf_len));
660
661         /* reading: alloc the buffer first */
662         if ( ps->io )
663         {
664                 buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len );
665         }
666         
667         prs_uint16s(True, "buffer     ", ps, depth, buf5->buffer, buf5->buf_len);
668
669         return True;
670 }
671
672 /*******************************************************************
673 creates a BUFFER2 structure.
674 ********************************************************************/
675 BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num)
676 {
677         int i;
678         char *dest = (char*)str->buffer;
679         size_t max_len = sizeof(str->buffer)-1;
680
681         ZERO_STRUCTP(str);
682
683         str->buf_max_len = 0;
684         str->undoc       = 0;
685
686         for (i = 0; i < num && max_len > 0; i++)
687         {
688                 size_t len = buf[i] != NULL ? strlen(buf[i]) : 0;
689
690                 str->buf_max_len += len * 2;
691                 str->buf_len     += len * 2;
692
693                 ascii_to_unibuf(dest, buf[i], max_len);
694         
695                 dest += len * 2 + 2;
696                 max_len -= len * 2 + 2;
697         }
698
699         return True;
700 }
701
702 /*******************************************************************
703 creates a BUFFER2 structure.
704 ********************************************************************/
705 BOOL make_buffer2(BUFFER2 *str, const char *buf, int len)
706 {
707         ZERO_STRUCTP(str);
708
709         /* set up string lengths. */
710         str->buf_max_len = str->buf_len = len * 2;
711         str->undoc       = 0;
712
713         /* store the string */
714         ascii_to_unibuf((char*)str->buffer, buf,
715                          MIN(str->buf_len, sizeof(str->buffer)-1));
716
717         return True;
718 }
719
720 /*******************************************************************
721 reads or writes a BUFFER2 structure.
722      the uni_max_len member tells you how large the buffer is.
723      the uni_str_len member tells you how much of the buffer is really used.
724 ********************************************************************/
725 BOOL smb_io_buffer2(char *desc,  BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
726 {
727         if (buf2 == NULL) return False;
728
729         if (buffer)
730         {
731                 prs_debug(ps, depth, desc, "smb_io_buffer2");
732                 depth++;
733
734                 prs_align(ps);
735                 
736                 prs_uint32("buf_max_len", ps, depth, &(buf2->buf_max_len));
737                 prs_uint32("undoc      ", ps, depth, &(buf2->undoc      ));
738                 prs_uint32("buf_len    ", ps, depth, &(buf2->buf_len));
739
740                 /* oops! XXXX maybe issue a warning that this is happening... */
741                 if (buf2->buf_max_len > MAX_UNISTRLEN) buf2->buf_max_len = MAX_UNISTRLEN;
742                 if (buf2->buf_len     > MAX_UNISTRLEN) buf2->buf_len     = MAX_UNISTRLEN;
743
744                 /* buffer advanced by indicated length of string
745                    NOT by searching for null-termination */
746                 prs_buffer2(True, "buffer     ", ps, depth, buf2);
747         }
748         else
749         {
750                 prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
751                 depth++;
752                 bzero(buf2, sizeof(*buf2));
753         }
754
755         return True;
756 }
757
758 /*******************************************************************
759 creates a UNISTR2 structure: sets up the buffer, too
760 ********************************************************************/
761 BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
762 {
763         if (buf != NULL)
764         {
765                 *ptr = 1;
766                 make_unistr2(str, buf, strlen(buf)+1);
767         }
768         else
769         {
770                 *ptr = 0;
771                 make_unistr2(str, "", 0);
772         }
773
774         return True;
775 }
776
777 /*******************************************************************
778 creates a STRING2 structure.
779 ********************************************************************/
780 BOOL make_string2(STRING2 *str, const char *buf, int len)
781 {
782         /* set up string lengths. */
783         str->str_max_len = len;
784         str->undoc       = 0;
785         str->str_str_len = len;
786
787         /* store the string */
788         if(len != 0)
789         {
790                 memcpy(str->buffer, buf, len);
791         }
792
793         return True;
794 }
795
796 /*******************************************************************
797 creates a STRING2 structure: sets up the buffer, too
798 ********************************************************************/
799 BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf)
800 {
801         if (buf != NULL)
802         {
803                 *ptr = 1;
804                 make_string2(str, buf, strlen(buf)+1);
805         }
806         else
807         {
808                 *ptr = 0;
809                 make_string2(str, "", 0);
810         }
811
812         return True;
813 }
814
815 /*******************************************************************
816 reads or writes a STRING2 structure.
817 XXXX NOTE: STRING2 structures need NOT be null-terminated.
818      the str_str_len member tells you how long the string is;
819      the str_max_len member tells you how large the buffer is.
820 ********************************************************************/
821 BOOL smb_io_string2(char *desc,  STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
822 {
823         if (str2 == NULL) return False;
824
825         if (buffer)
826         {
827                 prs_debug(ps, depth, desc, "smb_io_string2");
828                 depth++;
829
830                 prs_align(ps);
831                 
832                 prs_uint32("str_max_len", ps, depth, &(str2->str_max_len));
833                 prs_uint32("undoc      ", ps, depth, &(str2->undoc      ));
834                 prs_uint32("str_str_len", ps, depth, &(str2->str_str_len));
835
836                 /* oops! XXXX maybe issue a warning that this is happening... */
837                 if (str2->str_max_len > MAX_STRINGLEN) str2->str_max_len = MAX_STRINGLEN;
838                 if (str2->str_str_len > MAX_STRINGLEN) str2->str_str_len = MAX_STRINGLEN;
839
840                 /* buffer advanced by indicated length of string
841                    NOT by searching for null-termination */
842                 prs_string2(True, "buffer     ", ps, depth, str2);
843         }
844         else
845         {
846                 prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
847                 depth++;
848                 bzero(str2, sizeof(*str2));
849         }
850
851         return True;
852 }
853
854 /*******************************************************************
855 creates a UNISTR2 structure.
856 ********************************************************************/
857 BOOL make_unistr2(UNISTR2 *str, const char *buf, int len)
858 {
859         ZERO_STRUCTP(str);
860
861         /* set up string lengths. */
862         str->uni_max_len = len;
863         str->undoc       = 0;
864         str->uni_str_len = len;
865
866         /* store the string (wide chars) */
867         ascii_to_unistr(str->buffer, buf, len);
868
869         return True;
870 }
871
872 /*******************************************************************
873 reads or writes a UNISTR2 structure.
874 XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
875      the uni_str_len member tells you how long the string is;
876      the uni_max_len member tells you how large the buffer is.
877 ********************************************************************/
878 BOOL smb_io_unistr2(char *desc,  UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
879 {
880         if (uni2 == NULL) return False;
881
882         if (buffer)
883         {
884                 prs_debug(ps, depth, desc, "smb_io_unistr2");
885                 depth++;
886
887                 prs_align(ps);
888                 
889                 prs_uint32("uni_max_len", ps, depth, &(uni2->uni_max_len));
890                 prs_uint32("undoc      ", ps, depth, &(uni2->undoc      ));
891                 prs_uint32("uni_str_len", ps, depth, &(uni2->uni_str_len));
892
893                 /* oops! XXXX maybe issue a warning that this is happening... */
894                 if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
895                 if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
896
897                 /* buffer advanced by indicated length of string
898                    NOT by searching for null-termination */
899                 prs_unistr2(True, "buffer     ", ps, depth, uni2);
900         }
901         else
902         {
903                 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
904                 depth++;
905                 bzero(uni2, sizeof(*uni2));
906         }
907
908         return True;
909 }
910
911 /*******************************************************************
912 creates a DOM_RID2 structure.
913 ********************************************************************/
914 BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
915 {
916         rid2->type    = type;
917         rid2->rid     = rid;
918         rid2->rid_idx = idx;
919
920         return True;
921 }
922
923 /*******************************************************************
924 reads or writes a DOM_RID2 structure.
925 ********************************************************************/
926 BOOL smb_io_dom_rid2(char *desc,  DOM_RID2 *rid2, prs_struct *ps, int depth)
927 {
928         if (rid2 == NULL) return False;
929
930         prs_debug(ps, depth, desc, "smb_io_dom_rid2");
931         depth++;
932
933         prs_align(ps);
934         
935         prs_uint8("type   ", ps, depth, &(rid2->type));
936         prs_align(ps);
937         prs_uint32("rid    ", ps, depth, &(rid2->rid     ));
938         prs_uint32("rid_idx", ps, depth, &(rid2->rid_idx ));
939
940         return True;
941 }
942
943 /*******************************************************************
944 creates a DOM_RID3 structure.
945 ********************************************************************/
946 BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
947 {
948         rid3->rid      = rid;
949         rid3->type1    = type;
950         rid3->ptr_type = 0x1; /* non-zero, basically. */
951         rid3->type2    = 0x1;
952         rid3->unk      = type;
953
954         return True;
955 }
956
957 /*******************************************************************
958 reads or writes a DOM_RID3 structure.
959 ********************************************************************/
960 BOOL smb_io_dom_rid3(char *desc,  DOM_RID3 *rid3, prs_struct *ps, int depth)
961 {
962         if (rid3 == NULL) return False;
963
964         prs_debug(ps, depth, desc, "smb_io_dom_rid3");
965         depth++;
966
967         prs_align(ps);
968         
969         prs_uint32("rid     ", ps, depth, &(rid3->rid     ));
970         prs_uint32("type1   ", ps, depth, &(rid3->type1   ));
971         prs_uint32("ptr_type", ps, depth, &(rid3->ptr_type));
972         prs_uint32("type2   ", ps, depth, &(rid3->type2   ));
973         prs_uint32("unk     ", ps, depth, &(rid3->unk     ));
974
975         return True;
976 }
977
978 /*******************************************************************
979 makes a DOM_CLNT_SRV structure.
980 ********************************************************************/
981 static BOOL make_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name)
982 {
983         if (log == NULL) return False;
984
985         DEBUG(5,("make_clnt_srv: %d\n", __LINE__));
986
987         if (logon_srv != NULL)
988         {
989                 log->undoc_buffer = 1;
990                 make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
991         }
992         else
993         {
994                 log->undoc_buffer = 0;
995         }
996
997         if (comp_name != NULL)
998         {
999                 log->undoc_buffer2 = 1;
1000                 make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
1001         }
1002         else
1003         {
1004                 log->undoc_buffer2 = 0;
1005         }
1006
1007         return True;
1008 }
1009
1010 /*******************************************************************
1011 reads or writes a DOM_CLNT_SRV structure.
1012 ********************************************************************/
1013 static BOOL smb_io_clnt_srv(char *desc,  DOM_CLNT_SRV *log, prs_struct *ps, int depth)
1014 {
1015         if (log == NULL) return False;
1016
1017         prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1018         depth++;
1019
1020         prs_align(ps);
1021         
1022         prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer ));
1023         if (log->undoc_buffer != 0)
1024         {
1025                 smb_io_unistr2("unistr2", &(log->uni_logon_srv), log->undoc_buffer, ps, depth);
1026         }
1027
1028         prs_align(ps);
1029
1030         prs_uint32("undoc_buffer2", ps, depth, &(log->undoc_buffer2));
1031         if (log->undoc_buffer2 != 0)
1032         {
1033                 smb_io_unistr2("unistr2", &(log->uni_comp_name), log->undoc_buffer2, ps, depth);
1034         }
1035
1036         return True;
1037 }
1038
1039 /*******************************************************************
1040 makes a DOM_LOG_INFO structure.
1041 ********************************************************************/
1042 BOOL make_log_info(DOM_LOG_INFO *log,
1043                 const char *logon_srv, const char *acct_name,
1044                 uint16 sec_chan, const char *comp_name)
1045 {
1046         if (log == NULL) return False;
1047
1048         DEBUG(5,("make_log_info %d\n", __LINE__));
1049
1050         log->undoc_buffer = 1;
1051
1052         make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
1053         make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name)+1);
1054
1055         log->sec_chan = sec_chan;
1056
1057         make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
1058
1059         return True;
1060 }
1061
1062 /*******************************************************************
1063 reads or writes a DOM_LOG_INFO structure.
1064 ********************************************************************/
1065 BOOL smb_io_log_info(char *desc,  DOM_LOG_INFO *log, prs_struct *ps, int depth)
1066 {
1067         if (log == NULL) return False;
1068
1069         prs_debug(ps, depth, desc, "smb_io_log_info");
1070         depth++;
1071
1072         prs_align(ps);
1073         
1074         prs_uint32("undoc_buffer", ps, depth, &(log->undoc_buffer));
1075
1076         smb_io_unistr2("unistr2", &(log->uni_logon_srv), True, ps, depth);
1077         smb_io_unistr2("unistr2", &(log->uni_acct_name), True, ps, depth);
1078
1079         prs_uint16("sec_chan", ps, depth, &(log->sec_chan));
1080
1081         smb_io_unistr2("unistr2", &(log->uni_comp_name), True, ps, depth);
1082
1083         return True;
1084 }
1085
1086 /*******************************************************************
1087 reads or writes a DOM_CHAL structure.
1088 ********************************************************************/
1089 BOOL smb_io_chal(char *desc,  DOM_CHAL *chal, prs_struct *ps, int depth)
1090 {
1091         if (chal == NULL) return False;
1092
1093         prs_debug(ps, depth, desc, "smb_io_chal");
1094         depth++;
1095
1096         prs_align(ps);
1097         
1098         prs_uint8s (False, "data", ps, depth, chal->data, 8);
1099
1100         return True;
1101 }
1102
1103 /*******************************************************************
1104 reads or writes a DOM_CRED structure.
1105 ********************************************************************/
1106 BOOL smb_io_cred(char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
1107 {
1108         if (cred == NULL) return False;
1109
1110         prs_debug(ps, depth, desc, "smb_io_cred");
1111         depth++;
1112
1113         prs_align(ps);
1114         
1115         smb_io_chal ("", &(cred->challenge), ps, depth);
1116         smb_io_utime("", &(cred->timestamp), ps, depth);
1117
1118         return True;
1119 }
1120
1121 /*******************************************************************
1122 makes a DOM_CLNT_INFO2 structure.
1123 ********************************************************************/
1124 BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
1125                                 char *logon_srv, char *comp_name,
1126                                 DOM_CRED *clnt_cred)
1127 {
1128         if (clnt == NULL) return False;
1129
1130         DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1131
1132         make_clnt_srv(&(clnt->login), logon_srv, comp_name);
1133
1134         if (clnt_cred != NULL)
1135         {
1136                 clnt->ptr_cred = 1;
1137                 memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
1138         }
1139         else
1140         {
1141                 clnt->ptr_cred = 0;
1142         }
1143
1144         return True;
1145 }
1146
1147 /*******************************************************************
1148 reads or writes a DOM_CLNT_INFO2 structure.
1149 ********************************************************************/
1150 BOOL smb_io_clnt_info2(char *desc,  DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1151 {
1152         if (clnt == NULL) return False;
1153
1154         prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1155         depth++;
1156
1157         prs_align(ps);
1158         
1159         smb_io_clnt_srv("", &(clnt->login), ps, depth);
1160
1161         prs_align(ps);
1162         
1163         prs_uint32("ptr_cred", ps, depth, &(clnt->ptr_cred));
1164         smb_io_cred    ("", &(clnt->cred ), ps, depth);
1165
1166         return True;
1167 }
1168
1169 /*******************************************************************
1170 makes a DOM_CLNT_INFO structure.
1171 ********************************************************************/
1172 BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
1173                 char *logon_srv, char *acct_name,
1174                 uint16 sec_chan, char *comp_name,
1175                                 DOM_CRED *cred)
1176 {
1177         if (clnt == NULL || cred == NULL) return False;
1178
1179         DEBUG(5,("make_clnt_info\n"));
1180
1181         make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan, comp_name);
1182         memcpy(&(clnt->cred), cred, sizeof(clnt->cred));
1183
1184         return True;
1185 }
1186
1187 /*******************************************************************
1188 reads or writes a DOM_CLNT_INFO structure.
1189 ********************************************************************/
1190 BOOL smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1191 {
1192         if (clnt == NULL) return False;
1193
1194         prs_debug(ps, depth, desc, "smb_io_clnt_info");
1195         depth++;
1196
1197         prs_align(ps);
1198         
1199         smb_io_log_info("", &(clnt->login), ps, depth);
1200         smb_io_cred    ("", &(clnt->cred ), ps, depth);
1201
1202         return True;
1203 }
1204
1205 /*******************************************************************
1206 makes an OWF_INFO structure.
1207 ********************************************************************/
1208 BOOL make_owf_info(OWF_INFO *hash, uint8 data[16])
1209 {
1210         if (hash == NULL) return False;
1211
1212         DEBUG(5,("make_owf_info: %d\n", __LINE__));
1213         
1214         if (data != NULL)
1215         {
1216                 memcpy(hash->data, data, sizeof(hash->data));
1217         }
1218         else
1219         {
1220                 bzero(hash->data, sizeof(hash->data));
1221         }
1222
1223         return True;
1224 }
1225
1226 /*******************************************************************
1227 reads or writes an OWF_INFO structure.
1228 ********************************************************************/
1229 BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1230 {
1231         if (hash == NULL) return False;
1232
1233         prs_debug(ps, depth, desc, "smb_io_owf_info");
1234         depth++;
1235
1236         prs_align(ps);
1237         
1238         prs_uint8s (False, "data", ps, depth, hash->data, 16);
1239
1240         return True;
1241 }
1242
1243 /*******************************************************************
1244 reads or writes a DOM_GID structure.
1245 ********************************************************************/
1246 BOOL smb_io_gid(char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
1247 {
1248         if (gid == NULL) return False;
1249
1250         prs_debug(ps, depth, desc, "smb_io_gid");
1251         depth++;
1252
1253         prs_align(ps);
1254         
1255         prs_uint32("g_rid", ps, depth, &(gid->g_rid));
1256         prs_uint32("attr ", ps, depth, &(gid->attr ));
1257
1258         return True;
1259 }
1260
1261 /*******************************************************************
1262 reads or writes an POLICY_HND structure.
1263 ********************************************************************/
1264 BOOL smb_io_pol_hnd(char *desc,  POLICY_HND *pol, prs_struct *ps, int depth)
1265 {
1266         if (pol == NULL) return False;
1267
1268         prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1269         depth++;
1270
1271         prs_align(ps);
1272         
1273         prs_uint8s (False, "data", ps, depth, pol->data, POL_HND_SIZE);
1274
1275         return True;
1276 }
1277
1278 /*******************************************************************
1279 reads or writes a dom query structure.
1280 ********************************************************************/
1281 static BOOL smb_io_dom_query(char *desc,  DOM_QUERY *d_q, prs_struct *ps, int depth)
1282 {
1283         if (d_q == NULL) return False;
1284
1285         prs_debug(ps, depth, desc, "smb_io_dom_query");
1286         depth++;
1287
1288         prs_align(ps);
1289         
1290         prs_uint16("uni_dom_max_len", ps, depth, &(d_q->uni_dom_max_len)); /* domain name string length * 2 */
1291         prs_uint16("uni_dom_str_len", ps, depth, &(d_q->uni_dom_str_len)); /* domain name string length * 2 */
1292
1293         prs_uint32("buffer_dom_name", ps, depth, &(d_q->buffer_dom_name)); /* undocumented domain name string buffer pointer */
1294         prs_uint32("buffer_dom_sid ", ps, depth, &(d_q->buffer_dom_sid )); /* undocumented domain SID string buffer pointer */
1295
1296         smb_io_unistr2("unistr2", &(d_q->uni_domain_name), d_q->buffer_dom_name, ps, depth); /* domain name (unicode string) */
1297
1298         prs_align(ps);
1299
1300         if (d_q->buffer_dom_sid != 0)
1301         {
1302                 smb_io_dom_sid2("", &(d_q->dom_sid), ps, depth); /* domain SID */
1303         }
1304         else
1305         {
1306                 bzero(&(d_q->dom_sid), sizeof(d_q->dom_sid));
1307         }
1308
1309         return True;
1310 }
1311
1312 /*******************************************************************
1313 reads or writes a dom query structure.
1314 ********************************************************************/
1315 BOOL smb_io_dom_query_3(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
1316 {
1317         smb_io_dom_query("", d_q, ps, depth);
1318
1319         return True;
1320 }
1321
1322 /*******************************************************************
1323 reads or writes a dom query structure.
1324 ********************************************************************/
1325 BOOL smb_io_dom_query_5(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
1326 {
1327         smb_io_dom_query("", d_q, ps, depth);
1328
1329         return True;
1330 }
1331
1332
1333 /*******************************************************************
1334 reads or writes a UNISTR3 structure.
1335 ********************************************************************/
1336 BOOL smb_io_unistr3(char *desc,  UNISTR3 *name, prs_struct *ps, int depth)
1337 {
1338         if (name == NULL) return False;
1339
1340         prs_debug(ps, depth, desc, "smb_io_unistr3");
1341         depth++;
1342
1343         prs_align(ps);
1344         
1345         prs_uint32("uni_str_len", ps, depth, &(name->uni_str_len));
1346
1347         /* don't know if len is specified by uni_str_len member... */
1348         /* assume unicode string is unicode-null-terminated, instead */
1349
1350         prs_unistr3(True, "unistr", name, ps, depth);
1351
1352         return True;
1353 }
1354