r18188: merge 3.0-libndr branch
[bbaumbach/samba-autobuild/.git] / source / rpc_parse / parse_misc.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Gerald (Jerry) Carter             2005
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 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
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 static 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("main loop talloc (mainly parse_misc)");
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(const 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(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
117 {
118         uint32 low, high;
119         if (nttime == NULL)
120                 return False;
121
122         prs_debug(ps, depth, desc, "smb_io_time");
123         depth++;
124
125         if(!prs_align(ps))
126                 return False;
127         
128         if(!prs_uint32("low ", ps, depth, &low)) /* low part */
129                 return False;
130         if(!prs_uint32("high", ps, depth, &high)) /* high part */
131                 return False;
132
133         *nttime = (((uint64_t)high << 32) + low);
134
135         return True;
136 }
137
138 /*******************************************************************
139  Reads or writes an NTTIME structure.
140 ********************************************************************/
141
142 BOOL smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime)
143 {
144         return smb_io_time( desc, nttime, ps, depth );
145 }
146
147 /*******************************************************************
148  Gets an enumeration handle from an ENUM_HND structure.
149 ********************************************************************/
150
151 uint32 get_enum_hnd(ENUM_HND *enh)
152 {
153         return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
154 }
155
156 /*******************************************************************
157  Inits an ENUM_HND structure.
158 ********************************************************************/
159
160 void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
161 {
162         DEBUG(5,("smb_io_enum_hnd\n"));
163
164         enh->ptr_hnd = (hnd != 0) ? 1 : 0;
165         enh->handle = hnd;
166 }
167
168 /*******************************************************************
169  Reads or writes an ENUM_HND structure.
170 ********************************************************************/
171
172 BOOL smb_io_enum_hnd(const char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
173 {
174         if (hnd == NULL)
175                 return False;
176
177         prs_debug(ps, depth, desc, "smb_io_enum_hnd");
178         depth++;
179
180         if(!prs_align(ps))
181                 return False;
182         
183         if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
184                 return False;
185
186         if (hnd->ptr_hnd != 0) {
187                 if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
188                         return False;
189         }
190
191         return True;
192 }
193
194 /*******************************************************************
195  Reads or writes a DOM_SID structure.
196 ********************************************************************/
197
198 BOOL smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
199 {
200         int i;
201
202         if (sid == NULL)
203                 return False;
204
205         prs_debug(ps, depth, desc, "smb_io_dom_sid");
206         depth++;
207
208         if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
209                 return False;
210
211         if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
212                 return False;
213
214         for (i = 0; i < 6; i++)
215         {
216                 fstring tmp;
217                 slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
218                 if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
219                         return False;
220         }
221
222         /* oops! XXXX should really issue a warning here... */
223         if (sid->num_auths > MAXSUBAUTHS)
224                 sid->num_auths = MAXSUBAUTHS;
225
226         if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
227                 return False;
228
229         return True;
230 }
231
232 /*******************************************************************
233  Inits a DOM_SID2 structure.
234 ********************************************************************/
235
236 void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
237 {
238         sid2->sid = *sid;
239         sid2->num_auths = sid2->sid.num_auths;
240 }
241
242 /*******************************************************************
243  Reads or writes a DOM_SID2 structure.
244 ********************************************************************/
245
246 BOOL smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **sid2)
247 {
248         uint32 data_p;
249
250         /* caputure the pointer value to stream */
251
252         data_p = *sid2 ? 0xf000baaa : 0;
253
254         if ( !prs_uint32("dom_sid2_p", ps, depth, &data_p ))
255                 return False;
256
257         /* we're done if there is no data */
258
259         if ( !data_p )
260                 return True;
261
262         if (UNMARSHALLING(ps)) {
263                 if ( !(*sid2 = PRS_ALLOC_MEM(ps, DOM_SID2, 1)) )
264                 return False;
265         }
266
267         return True;
268 }
269 /*******************************************************************
270  Reads or writes a DOM_SID2 structure.
271 ********************************************************************/
272
273 BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
274 {
275         if (sid == NULL)
276                 return False;
277
278         prs_debug(ps, depth, desc, "smb_io_dom_sid2");
279         depth++;
280
281         if(!prs_align(ps))
282                 return False;
283         
284         if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
285                 return False;
286
287         if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
288                 return False;
289
290         return True;
291 }
292
293 /*******************************************************************
294  Reads or writes a struct uuid
295 ********************************************************************/
296
297 BOOL smb_io_uuid(const char *desc, struct uuid *uuid, 
298                  prs_struct *ps, int depth)
299 {
300         if (uuid == NULL)
301                 return False;
302
303         prs_debug(ps, depth, desc, "smb_io_uuid");
304         depth++;
305
306         if(!prs_uint32 ("data   ", ps, depth, &uuid->time_low))
307                 return False;
308         if(!prs_uint16 ("data   ", ps, depth, &uuid->time_mid))
309                 return False;
310         if(!prs_uint16 ("data   ", ps, depth, &uuid->time_hi_and_version))
311                 return False;
312
313         if(!prs_uint8s (False, "data   ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq)))
314                 return False;
315         if(!prs_uint8s (False, "data   ", ps, depth, uuid->node, sizeof(uuid->node)))
316                 return False;
317
318         return True;
319 }
320
321 /*******************************************************************
322 creates a STRHDR structure.
323 ********************************************************************/
324
325 void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
326 {
327         hdr->str_max_len = max_len;
328         hdr->str_str_len = len;
329         hdr->buffer      = buffer;
330 }
331
332 /*******************************************************************
333  Reads or writes a STRHDR structure.
334 ********************************************************************/
335
336 BOOL smb_io_strhdr(const char *desc,  STRHDR *hdr, prs_struct *ps, int depth)
337 {
338         if (hdr == NULL)
339                 return False;
340
341         prs_debug(ps, depth, desc, "smb_io_strhdr");
342         depth++;
343
344         prs_align(ps);
345         
346         if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
347                 return False;
348         if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
349                 return False;
350         if(!prs_uint32("buffer     ", ps, depth, &hdr->buffer))
351                 return False;
352
353         return True;
354 }
355
356 /*******************************************************************
357  Inits a UNIHDR structure.
358 ********************************************************************/
359
360 void init_uni_hdr(UNIHDR *hdr, UNISTR2 *str2)
361 {
362         hdr->uni_str_len = 2 * (str2->uni_str_len);
363         hdr->uni_max_len = 2 * (str2->uni_max_len);
364         hdr->buffer = (str2->uni_str_len != 0) ? 1 : 0;
365 }
366
367 /*******************************************************************
368  Reads or writes a UNIHDR structure.
369 ********************************************************************/
370
371 BOOL smb_io_unihdr(const char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
372 {
373         if (hdr == NULL)
374                 return False;
375
376         prs_debug(ps, depth, desc, "smb_io_unihdr");
377         depth++;
378
379         if(!prs_align(ps))
380                 return False;
381         
382         if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
383                 return False;
384         if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
385                 return False;
386         if(!prs_uint32("buffer     ", ps, depth, &hdr->buffer))
387                 return False;
388
389         return True;
390 }
391
392 /*******************************************************************
393  Inits a BUFHDR structure.
394 ********************************************************************/
395
396 void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
397 {
398         hdr->buf_max_len = max_len;
399         hdr->buf_len     = len;
400 }
401
402 /*******************************************************************
403  prs_uint16 wrapper. Call this and it sets up a pointer to where the
404  uint16 should be stored, or gets the size if reading.
405  ********************************************************************/
406
407 BOOL smb_io_hdrbuf_pre(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
408 {
409         (*offset) = prs_offset(ps);
410         if (ps->io) {
411
412                 /* reading. */
413
414                 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
415                         return False;
416
417         } else {
418
419                 /* writing. */
420
421                 if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
422                         return False;
423         }
424
425         return True;
426 }
427
428 /*******************************************************************
429  smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
430  Does nothing on reading, as that is already handled by ...._pre()
431  ********************************************************************/
432
433 BOOL smb_io_hdrbuf_post(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, 
434                                 uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
435 {
436         if (!ps->io) {
437                 /* writing: go back and do a retrospective job.  i hate this */
438
439                 uint32 old_offset = prs_offset(ps);
440
441                 init_buf_hdr(hdr, max_len, len);
442                 if(!prs_set_offset(ps, ptr_hdrbuf))
443                         return False;
444                 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
445                         return False;
446
447                 if(!prs_set_offset(ps, old_offset))
448                         return False;
449         }
450
451         return True;
452 }
453
454 /*******************************************************************
455  Reads or writes a BUFHDR structure.
456 ********************************************************************/
457
458 BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
459 {
460         if (hdr == NULL)
461                 return False;
462
463         prs_debug(ps, depth, desc, "smb_io_hdrbuf");
464         depth++;
465
466         if(!prs_align(ps))
467                 return False;
468         
469         if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
470                 return False;
471         if(!prs_uint32("buf_len    ", ps, depth, &hdr->buf_len))
472                 return False;
473
474         return True;
475 }
476
477 /*******************************************************************
478  Inits a UNISTR structure.
479 ********************************************************************/
480
481 void init_unistr(UNISTR *str, const char *buf)
482 {
483         size_t len;
484
485         if (buf == NULL) {
486                 str->buffer = NULL;
487                 return;
488         }
489                 
490         len = strlen(buf) + 1;
491
492         str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
493         if (str->buffer == NULL)
494                 smb_panic("init_unistr: malloc fail\n");
495
496         rpcstr_push(str->buffer, buf, len*sizeof(uint16), STR_TERMINATE);
497 }
498
499 /*******************************************************************
500 reads or writes a UNISTR structure.
501 XXXX NOTE: UNISTR structures NEED to be null-terminated.
502 ********************************************************************/
503
504 BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
505 {
506         if (uni == NULL)
507                 return False;
508
509         prs_debug(ps, depth, desc, "smb_io_unistr");
510         depth++;
511
512         if(!prs_unistr("unistr", ps, depth, uni))
513                 return False;
514
515         return True;
516 }
517
518 /*******************************************************************
519  Allocate the RPC_DATA_BLOB memory.
520 ********************************************************************/
521
522 size_t create_rpc_blob(RPC_DATA_BLOB *str, size_t len)
523 {
524         str->buffer = (uint8 *)TALLOC_ZERO(get_talloc_ctx(), len);
525         if (str->buffer == NULL)
526                 smb_panic("create_rpc_blob: talloc fail\n");
527         return len;
528 }
529
530 /*******************************************************************
531  Inits a RPC_DATA_BLOB structure from a uint32
532 ********************************************************************/
533
534 void init_rpc_blob_uint32(RPC_DATA_BLOB *str, uint32 val)
535 {
536         ZERO_STRUCTP(str);
537
538         /* set up string lengths. */
539         str->buf_len = create_rpc_blob(str, sizeof(uint32));
540         SIVAL(str->buffer, 0, val);
541 }
542
543 /*******************************************************************
544  Inits a RPC_DATA_BLOB structure.
545 ********************************************************************/
546
547 void init_rpc_blob_str(RPC_DATA_BLOB *str, const char *buf, int len)
548 {
549         ZERO_STRUCTP(str);
550
551         /* set up string lengths. */
552         str->buf_len = create_rpc_blob(str, len*2);
553         rpcstr_push(str->buffer, buf, (size_t)str->buf_len, STR_TERMINATE);
554         
555 }
556
557 /*******************************************************************
558  Inits a RPC_DATA_BLOB structure from a hex string.
559 ********************************************************************/
560
561 void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf)
562 {
563         ZERO_STRUCTP(str);
564         str->buf_len = create_rpc_blob(str, strlen(buf));
565         str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
566 }
567
568 /*******************************************************************
569  Inits a RPC_DATA_BLOB structure.
570 ********************************************************************/
571
572 void init_rpc_blob_bytes(RPC_DATA_BLOB *str, uint8 *buf, size_t len)
573 {
574         ZERO_STRUCTP(str);
575
576         /* max buffer size (allocated size) */
577         if (buf != NULL) {
578                 len = create_rpc_blob(str, len);
579                 memcpy(str->buffer, buf, len);
580         }
581         str->buf_len = len;
582 }
583
584 /*******************************************************************
585 reads or writes a BUFFER5 structure.
586 the buf_len member tells you how large the buffer is.
587 ********************************************************************/
588 BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
589 {
590         prs_debug(ps, depth, desc, "smb_io_buffer5");
591         depth++;
592
593         if (buf5 == NULL) return False;
594
595         if(!prs_align(ps))
596                 return False;
597         if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len))
598                 return False;
599
600         if(buf5->buf_len) {
601                 if(!prs_buffer5(True, "buffer" , ps, depth, buf5))
602                         return False;
603         }
604
605         return True;
606 }
607
608 /*******************************************************************
609  Inits a REGVAL_BUFFER structure.
610 ********************************************************************/
611
612 void init_regval_buffer(REGVAL_BUFFER *str, const uint8 *buf, size_t len)
613 {
614         ZERO_STRUCTP(str);
615
616         /* max buffer size (allocated size) */
617         str->buf_max_len = len;
618         str->offset = 0;
619         str->buf_len = buf != NULL ? len : 0;
620
621         if (buf != NULL) {
622                 SMB_ASSERT(str->buf_max_len >= str->buf_len);
623                 str->buffer = (uint16 *)TALLOC_ZERO(get_talloc_ctx(),
624                                                     str->buf_max_len);
625                 if (str->buffer == NULL)
626                         smb_panic("init_regval_buffer: talloc fail\n");
627                 memcpy(str->buffer, buf, str->buf_len);
628         }
629 }
630
631 /*******************************************************************
632  Reads or writes a REGVAL_BUFFER structure.
633    the uni_max_len member tells you how large the buffer is.
634    the uni_str_len member tells you how much of the buffer is really used.
635 ********************************************************************/
636
637 BOOL smb_io_regval_buffer(const char *desc, prs_struct *ps, int depth, REGVAL_BUFFER *buf2)
638 {
639
640         prs_debug(ps, depth, desc, "smb_io_regval_buffer");
641         depth++;
642
643         if(!prs_align(ps))
644                 return False;
645                 
646         if(!prs_uint32("buf_max_len", ps, depth, &buf2->buf_max_len))
647                 return False;
648         if(!prs_uint32("offset     ", ps, depth, &buf2->offset))
649                 return False;
650         if(!prs_uint32("buf_len    ", ps, depth, &buf2->buf_len))
651                 return False;
652
653         /* buffer advanced by indicated length of string
654            NOT by searching for null-termination */
655
656         if(!prs_regval_buffer(True, "buffer     ", ps, depth, buf2))
657                 return False;
658
659         return True;
660 }
661
662 /*******************************************************************
663 creates a UNISTR2 structure: sets up the buffer, too
664 ********************************************************************/
665
666 void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
667 {
668         if (buf != NULL) {
669                 *ptr = 1;
670                 init_unistr2(str, buf, UNI_STR_TERMINATE);
671         } else {
672                 *ptr = 0;
673                 init_unistr2(str, NULL, UNI_FLAGS_NONE);
674
675         }
676 }
677
678 /*******************************************************************
679  Copies a UNISTR2 structure.
680 ********************************************************************/
681
682 void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
683 {
684         if (from->buffer == NULL) {
685                 ZERO_STRUCTP(str);
686                 return;
687         }
688
689         SMB_ASSERT(from->uni_max_len >= from->uni_str_len);
690
691         str->uni_max_len = from->uni_max_len;
692         str->offset      = from->offset;
693         str->uni_str_len = from->uni_str_len;
694
695         /* the string buffer is allocated to the maximum size
696            (the the length of the source string) to prevent
697            reallocation of memory. */
698         if (str->buffer == NULL) {
699                 str->buffer = (uint16 *)TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_max_len);
700                 if ((str->buffer == NULL)) {
701                         smb_panic("copy_unistr2: talloc fail\n");
702                         return;
703                 }
704         }
705
706         /* copy the string */
707         memcpy(str->buffer, from->buffer, str->uni_max_len*sizeof(uint16));
708 }
709
710 /*******************************************************************
711  Creates a STRING2 structure.
712 ********************************************************************/
713
714 void init_string2(STRING2 *str, const char *buf, size_t max_len, size_t str_len)
715 {
716         /* set up string lengths. */
717         SMB_ASSERT(max_len >= str_len);
718
719         /* Ensure buf is valid if str_len was set. Coverity check. */
720         if (str_len && !buf) {
721                 return;
722         }
723
724         str->str_max_len = max_len;
725         str->offset = 0;
726         str->str_str_len = str_len;
727
728         /* store the string */
729         if(str_len != 0) {
730                 str->buffer = (uint8 *)TALLOC_ZERO(get_talloc_ctx(),
731                                                    str->str_max_len);
732                 if (str->buffer == NULL)
733                         smb_panic("init_string2: malloc fail\n");
734                 memcpy(str->buffer, buf, str_len);
735         }
736 }
737
738 /*******************************************************************
739  Reads or writes a STRING2 structure.
740  XXXX NOTE: STRING2 structures need NOT be null-terminated.
741    the str_str_len member tells you how long the string is;
742    the str_max_len member tells you how large the buffer is.
743 ********************************************************************/
744
745 BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
746 {
747         if (str2 == NULL)
748                 return False;
749
750         if (buffer) {
751
752                 prs_debug(ps, depth, desc, "smb_io_string2");
753                 depth++;
754
755                 if(!prs_align(ps))
756                         return False;
757                 
758                 if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
759                         return False;
760                 if(!prs_uint32("offset     ", ps, depth, &str2->offset))
761                         return False;
762                 if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
763                         return False;
764
765                 /* buffer advanced by indicated length of string
766                    NOT by searching for null-termination */
767                 if(!prs_string2(True, "buffer     ", ps, depth, str2))
768                         return False;
769
770         } else {
771
772                 prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
773                 depth++;
774                 memset((char *)str2, '\0', sizeof(*str2));
775
776         }
777
778         return True;
779 }
780
781 /*******************************************************************
782  Inits a UNISTR2 structure.
783 ********************************************************************/
784
785 void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
786 {
787         size_t len = 0;
788         uint32 num_chars = 0;
789
790         if (buf) {
791                 /* We always null terminate the copy. */
792                 len = strlen(buf) + 1;
793                 if ( flags == UNI_STR_DBLTERMINATE )
794                         len++;
795         } else {
796                 /* no buffer -- nothing to do */
797                 str->uni_max_len = 0;
798                 str->offset = 0;
799                 str->uni_str_len = 0;
800
801                 return;
802         }
803         
804
805         str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
806         if (str->buffer == NULL) {
807                 smb_panic("init_unistr2: malloc fail\n");
808                 return;
809         }
810
811         /* Ensure len is the length in *bytes* */
812         len *= sizeof(uint16);
813
814         /*
815          * The UNISTR2 must be initialized !!!
816          * jfm, 7/7/2001.
817          */
818         if (buf) {
819                 rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
820                 num_chars = strlen_w(str->buffer);
821                 if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
822                         num_chars++;
823                 }
824                 if ( flags == UNI_STR_DBLTERMINATE )
825                         num_chars += 2;
826         }
827
828         str->uni_max_len = num_chars;
829         str->offset = 0;
830         str->uni_str_len = num_chars;
831         if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) )
832                 str->uni_max_len++;
833 }
834
835 /*******************************************************************
836  Inits a UNISTR4 structure.
837 ********************************************************************/
838
839 void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags)
840 {
841         uni4->string = TALLOC_P( get_talloc_ctx(), UNISTR2 );
842         if (!uni4->string) {
843                 smb_panic("init_unistr4: talloc fail\n");
844                 return;
845         }
846         init_unistr2( uni4->string, buf, flags );
847
848         uni4->length = 2 * (uni4->string->uni_str_len);
849         uni4->size   = 2 * (uni4->string->uni_max_len);
850 }
851
852 void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf )
853 {
854         uni4->string = TALLOC_P( ctx, UNISTR2 );
855         if (!uni4->string) {
856                 smb_panic("init_unistr4_w: talloc fail\n");
857                 return;
858         }
859         init_unistr2_w( ctx, uni4->string, buf );
860
861         uni4->length = 2 * (uni4->string->uni_str_len);
862         uni4->size   = 2 * (uni4->string->uni_max_len);
863 }
864
865 /** 
866  *  Inits a UNISTR2 structure.
867  *  @param  ctx talloc context to allocate string on
868  *  @param  str pointer to string to create
869  *  @param  buf UCS2 null-terminated buffer to init from
870 */
871
872 void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
873 {
874         uint32 len = buf ? strlen_w(buf) : 0;
875
876         ZERO_STRUCTP(str);
877
878         /* set up string lengths. */
879         str->uni_max_len = len;
880         str->offset = 0;
881         str->uni_str_len = len;
882
883         str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, len + 1);
884         if (str->buffer == NULL) {
885                 smb_panic("init_unistr2_w: talloc fail\n");
886                 return;
887         }
888         
889         /*
890          * don't move this test above ! The UNISTR2 must be initialized !!!
891          * jfm, 7/7/2001.
892          */
893         if (buf==NULL)
894                 return;
895         
896         /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
897            long as the buffer above is talloc()ed correctly then this
898            is the correct thing to do */
899         strncpy_w(str->buffer, buf, len + 1);
900 }
901
902 /*******************************************************************
903  Inits a UNISTR2 structure from a UNISTR
904 ********************************************************************/
905
906 void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
907 {
908         uint32 i;
909
910         /* the destination UNISTR2 should never be NULL.
911            if it is it is a programming error */
912
913         /* if the source UNISTR is NULL, then zero out
914            the destination string and return */
915         ZERO_STRUCTP (to);
916         if ((from == NULL) || (from->buffer == NULL))
917                 return;
918
919         /* get the length; UNISTR must be NULL terminated */
920         i = 0;
921         while ((from->buffer)[i]!='\0')
922                 i++;
923         i++;    /* one more to catch the terminating NULL */
924                 /* is this necessary -- jerry?  I need to think */
925
926         /* set up string lengths; uni_max_len is set to i+1
927            because we need to account for the final NULL termination */
928         to->uni_max_len = i;
929         to->offset = 0;
930         to->uni_str_len = i;
931
932         /* allocate the space and copy the string buffer */
933         to->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, i);
934         if (to->buffer == NULL)
935                 smb_panic("init_unistr2_from_unistr: malloc fail\n");
936         memcpy(to->buffer, from->buffer, i*sizeof(uint16));
937         return;
938 }
939
940 /*******************************************************************
941   Inits a UNISTR2 structure from a DATA_BLOB.
942   The length of the data_blob must count the bytes of the buffer.
943   Copies the blob data.
944 ********************************************************************/
945
946 void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) 
947 {
948         /* Allocs the unistring */
949         init_unistr2(str, NULL, UNI_FLAGS_NONE);
950         
951         /* Sets the values */
952         str->uni_str_len = blob->length / sizeof(uint16);
953         str->uni_max_len = str->uni_str_len;
954         str->offset = 0;
955         if (blob->length) {
956                 str->buffer = (uint16 *) memdup(blob->data, blob->length);
957         } else {
958                 str->buffer = NULL;
959         }
960         if ((str->buffer == NULL) && (blob->length > 0)) {
961                 smb_panic("init_unistr2_from_datablob: malloc fail\n");
962         }
963 }
964
965 /*******************************************************************
966  UNISTR2* are a little different in that the pointer and the UNISTR2
967  are not necessarily read/written back to back.  So we break it up 
968  into 2 separate functions.
969  See SPOOL_USER_1 in include/rpc_spoolss.h for an example.
970 ********************************************************************/
971
972 BOOL prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2)
973 {
974         uint32 data_p;
975
976         /* caputure the pointer value to stream */
977
978         data_p = *uni2 ? 0xf000baaa : 0;
979
980         if ( !prs_uint32("ptr", ps, depth, &data_p ))
981                 return False;
982
983         /* we're done if there is no data */
984
985         if ( !data_p )
986                 return True;
987
988         if (UNMARSHALLING(ps)) {
989                 if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) )
990                         return False;
991         }
992
993         return True;
994 }
995
996 /*******************************************************************
997  now read/write the actual UNISTR2.  Memory for the UNISTR2 (but
998  not UNISTR2.buffer) has been allocated previously by prs_unistr2_p()
999 ********************************************************************/
1000
1001 BOOL prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
1002 {
1003         /* just return true if there is no pointer to deal with.
1004            the memory must have been previously allocated on unmarshalling
1005            by prs_unistr2_p() */
1006
1007         if ( !uni2 )
1008                 return True;
1009
1010         /* just pass off to smb_io_unstr2() passing the uni2 address as 
1011            the pointer (like you would expect) */
1012
1013         return smb_io_unistr2( desc, uni2, uni2 ? 1 : 0, ps, depth );
1014 }
1015
1016 /*******************************************************************
1017  Reads or writes a UNISTR2 structure.
1018  XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
1019    the uni_str_len member tells you how long the string is;
1020    the uni_max_len member tells you how large the buffer is.
1021 ********************************************************************/
1022
1023 BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
1024 {
1025         if (uni2 == NULL)
1026                 return False;
1027
1028         if (buffer) {
1029
1030                 prs_debug(ps, depth, desc, "smb_io_unistr2");
1031                 depth++;
1032
1033                 if(!prs_align(ps))
1034                         return False;
1035                 
1036                 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
1037                         return False;
1038                 if(!prs_uint32("offset     ", ps, depth, &uni2->offset))
1039                         return False;
1040                 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
1041                         return False;
1042
1043                 /* buffer advanced by indicated length of string
1044                    NOT by searching for null-termination */
1045                 if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
1046                         return False;
1047
1048         } else {
1049
1050                 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
1051                 depth++;
1052                 memset((char *)uni2, '\0', sizeof(*uni2));
1053
1054         }
1055
1056         return True;
1057 }
1058
1059 /*******************************************************************
1060  now read/write UNISTR4
1061 ********************************************************************/
1062
1063 BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1064 {
1065         void *ptr;
1066         prs_debug(ps, depth, desc, "prs_unistr4");
1067         depth++;
1068
1069         if ( !prs_uint16("length", ps, depth, &uni4->length ))
1070                 return False;
1071         if ( !prs_uint16("size", ps, depth, &uni4->size ))
1072                 return False;
1073                 
1074         ptr = uni4->string;
1075
1076         if ( !prs_pointer( desc, ps, depth, &ptr, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
1077                 return False;
1078
1079         uni4->string = (UNISTR2 *)ptr;
1080         
1081         return True;
1082 }
1083
1084 /*******************************************************************
1085  now read/write UNISTR4 header
1086 ********************************************************************/
1087
1088 BOOL prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1089 {
1090         prs_debug(ps, depth, desc, "prs_unistr4_hdr");
1091         depth++;
1092
1093         if ( !prs_uint16("length", ps, depth, &uni4->length) )
1094                 return False;
1095         if ( !prs_uint16("size", ps, depth, &uni4->size) )
1096                 return False;
1097         if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) )
1098                 return False;
1099                 
1100         return True;
1101 }
1102
1103 /*******************************************************************
1104  now read/write UNISTR4 string
1105 ********************************************************************/
1106
1107 BOOL prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1108 {
1109         prs_debug(ps, depth, desc, "prs_unistr4_str");
1110         depth++;
1111
1112         if ( !prs_io_unistr2(desc, ps, depth, uni4->string) )
1113                 return False;
1114                 
1115         return True;
1116 }
1117
1118 /*******************************************************************
1119  Reads or writes a UNISTR4_ARRAY structure.
1120 ********************************************************************/
1121
1122 BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
1123 {
1124         unsigned int i;
1125
1126         prs_debug(ps, depth, desc, "prs_unistr4_array");
1127         depth++;
1128
1129         if(!prs_uint32("count", ps, depth, &array->count))
1130                 return False;
1131
1132         if ( array->count == 0 ) 
1133                 return True;
1134         
1135         if (UNMARSHALLING(ps)) {
1136                 if ( !(array->strings = TALLOC_ZERO_ARRAY( get_talloc_ctx(), UNISTR4, array->count)) )
1137                         return False;
1138         }
1139         
1140         /* write the headers and then the actual string buffer */
1141         
1142         for ( i=0; i<array->count; i++ ) {
1143                 if ( !prs_unistr4_hdr( "string", ps, depth, &array->strings[i]) )
1144                         return False;
1145         }
1146
1147         for (i=0;i<array->count;i++) {
1148                 if ( !prs_unistr4_str("string", ps, depth, &array->strings[i]) ) 
1149                         return False;
1150         }
1151         
1152         return True;
1153 }
1154
1155 /********************************************************************
1156   initialise a UNISTR_ARRAY from a char**
1157 ********************************************************************/
1158
1159 BOOL init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings )
1160 {
1161         unsigned int i;
1162
1163         array->count = count;
1164
1165         if ( array->count == 0 )
1166                 return True;
1167
1168         /* allocate memory for the array of UNISTR4 objects */
1169
1170         if ( !(array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR4, count )) )
1171                 return False;
1172
1173         for ( i=0; i<count; i++ ) 
1174                 init_unistr4( &array->strings[i], strings[i], UNI_STR_TERMINATE );
1175
1176         return True;
1177 }
1178
1179 BOOL smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth)
1180 {
1181         prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr");
1182         depth++;
1183
1184         if(!prs_align(ps))
1185                 return False;
1186
1187         if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size))
1188                 return False;
1189         if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length))
1190                 return False;
1191         if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer))
1192                 return False;
1193
1194         return True;
1195 }
1196
1197 BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockout, uint32 buffer, prs_struct *ps, int depth)
1198 {
1199         prs_debug(ps, depth, desc, "smb_io_account_lockout_string");
1200         depth++;
1201
1202         if(!prs_uint32("array_size", ps, depth, &account_lockout->array_size))
1203                 return False;
1204
1205         if(!prs_uint32("offset", ps, depth, &account_lockout->offset))
1206                 return False;
1207         if(!prs_uint32("length", ps, depth, &account_lockout->length))
1208                 return False;
1209
1210         if (!prs_uint64("lockout_duration", ps, depth, &account_lockout->lockout_duration))
1211                 return False;
1212         if (!prs_uint64("reset_count", ps, depth, &account_lockout->reset_count))
1213                 return False;
1214         if (!prs_uint32("bad_attempt_lockout", ps, depth, &account_lockout->bad_attempt_lockout))
1215                 return False;
1216         if (!prs_uint32("dummy", ps, depth, &account_lockout->dummy))
1217                 return False;
1218 #if 0
1219         if(!prs_uint16s (False, "bindata", ps, depth, &account_lockout->bindata, length))
1220                 return False;
1221 #endif
1222
1223         return True;
1224 }
1225
1226 /*******************************************************************
1227  Inits a DOM_RID structure.
1228 ********************************************************************/
1229
1230 void init_dom_rid(DOM_RID *prid, uint32 rid, uint16 type, uint32 idx)
1231 {
1232         prid->type    = type;
1233         prid->rid     = rid;
1234         prid->rid_idx = idx;
1235 }
1236
1237 /*******************************************************************
1238  Reads or writes a DOM_RID structure.
1239 ********************************************************************/
1240
1241 BOOL smb_io_dom_rid(const char *desc, DOM_RID *rid, prs_struct *ps, int depth)
1242 {
1243         if (rid == NULL)
1244                 return False;
1245
1246         prs_debug(ps, depth, desc, "smb_io_dom_rid");
1247         depth++;
1248
1249         if(!prs_align(ps))
1250                 return False;
1251    
1252         if(!prs_uint16("type   ", ps, depth, &rid->type))
1253                 return False;
1254         if(!prs_align(ps))
1255                 return False;
1256         if(!prs_uint32("rid    ", ps, depth, &rid->rid))
1257                 return False;
1258         if(!prs_uint32("rid_idx", ps, depth, &rid->rid_idx))
1259                 return False;
1260
1261         return True;
1262 }
1263
1264 /*******************************************************************
1265  Reads or writes a DOM_RID2 structure.
1266 ********************************************************************/
1267
1268 BOOL smb_io_dom_rid2(const char *desc, DOM_RID2 *rid, prs_struct *ps, int depth)
1269 {
1270         if (rid == NULL)
1271                 return False;
1272
1273         prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1274         depth++;
1275
1276         if(!prs_align(ps))
1277                 return False;
1278    
1279         if(!prs_uint16("type   ", ps, depth, &rid->type))
1280                 return False;
1281         if(!prs_align(ps))
1282                 return False;
1283         if(!prs_uint32("rid    ", ps, depth, &rid->rid))
1284                 return False;
1285         if(!prs_uint32("rid_idx", ps, depth, &rid->rid_idx))
1286                 return False;
1287         if(!prs_uint32("unknown", ps, depth, &rid->unknown))
1288                 return False;
1289
1290         return True;
1291 }
1292
1293
1294 /*******************************************************************
1295 creates a DOM_RID3 structure.
1296 ********************************************************************/
1297
1298 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1299 {
1300     rid3->rid      = rid;
1301     rid3->type1    = type;
1302     rid3->ptr_type = 0x1; /* non-zero, basically. */
1303     rid3->type2    = 0x1;
1304     rid3->unk      = type;
1305 }
1306
1307 /*******************************************************************
1308 reads or writes a DOM_RID3 structure.
1309 ********************************************************************/
1310
1311 BOOL smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1312 {
1313         if (rid3 == NULL)
1314                 return False;
1315
1316         prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1317         depth++;
1318
1319         if(!prs_align(ps))
1320                 return False;
1321
1322         if(!prs_uint32("rid     ", ps, depth, &rid3->rid))
1323                 return False;
1324         if(!prs_uint32("type1   ", ps, depth, &rid3->type1))
1325                 return False;
1326         if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1327                 return False;
1328         if(!prs_uint32("type2   ", ps, depth, &rid3->type2))
1329                 return False;
1330         if(!prs_uint32("unk     ", ps, depth, &rid3->unk))
1331                 return False;
1332
1333         return True;
1334 }
1335
1336 /*******************************************************************
1337  Inits a DOM_RID4 structure.
1338 ********************************************************************/
1339
1340 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1341 {
1342     rid4->unknown = unknown;
1343     rid4->attr    = attr;
1344     rid4->rid     = rid;
1345 }
1346
1347 /*******************************************************************
1348  Inits a DOM_CLNT_SRV structure.
1349 ********************************************************************/
1350
1351 static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name)
1352 {
1353         DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1354
1355         if (logon_srv != NULL) {
1356                 logcln->undoc_buffer = 1;
1357                 init_unistr2(&logcln->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1358         } else {
1359                 logcln->undoc_buffer = 0;
1360         }
1361
1362         if (comp_name != NULL) {
1363                 logcln->undoc_buffer2 = 1;
1364                 init_unistr2(&logcln->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1365         } else {
1366                 logcln->undoc_buffer2 = 0;
1367         }
1368 }
1369
1370 /*******************************************************************
1371  Inits or writes a DOM_CLNT_SRV structure.
1372 ********************************************************************/
1373
1374 BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
1375 {
1376         if (logcln == NULL)
1377                 return False;
1378
1379         prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1380         depth++;
1381
1382         if(!prs_align(ps))
1383                 return False;
1384         
1385         if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
1386                 return False;
1387
1388         if (logcln->undoc_buffer != 0) {
1389                 if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
1390                         return False;
1391         }
1392
1393         if(!prs_align(ps))
1394                 return False;
1395
1396         if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
1397                 return False;
1398
1399         if (logcln->undoc_buffer2 != 0) {
1400                 if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
1401                         return False;
1402         }
1403
1404         return True;
1405 }
1406
1407 /*******************************************************************
1408  Inits a DOM_LOG_INFO structure.
1409 ********************************************************************/
1410
1411 void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
1412                 uint16 sec_chan, const char *comp_name)
1413 {
1414         DEBUG(5,("make_log_info %d\n", __LINE__));
1415
1416         loginfo->undoc_buffer = 1;
1417
1418         init_unistr2(&loginfo->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1419         init_unistr2(&loginfo->uni_acct_name, acct_name, UNI_STR_TERMINATE);
1420
1421         loginfo->sec_chan = sec_chan;
1422
1423         init_unistr2(&loginfo->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1424 }
1425
1426 /*******************************************************************
1427  Reads or writes a DOM_LOG_INFO structure.
1428 ********************************************************************/
1429
1430 BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
1431 {
1432         if (loginfo == NULL)
1433                 return False;
1434
1435         prs_debug(ps, depth, desc, "smb_io_log_info");
1436         depth++;
1437
1438         if(!prs_align(ps))
1439                 return False;
1440         
1441         if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
1442                 return False;
1443
1444         if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
1445                 return False;
1446         if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
1447                 return False;
1448
1449         if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
1450                 return False;
1451
1452         if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
1453                 return False;
1454
1455         return True;
1456 }
1457
1458 /*******************************************************************
1459  Reads or writes a DOM_CHAL structure.
1460 ********************************************************************/
1461
1462 BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1463 {
1464         if (chal == NULL)
1465                 return False;
1466
1467         prs_debug(ps, depth, desc, "smb_io_chal");
1468         depth++;
1469         
1470         if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1471                 return False;
1472
1473         return True;
1474 }
1475
1476 /*******************************************************************
1477  Reads or writes a DOM_CRED structure.
1478 ********************************************************************/
1479
1480 BOOL smb_io_cred(const char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
1481 {
1482         if (cred == NULL)
1483                 return False;
1484
1485         prs_debug(ps, depth, desc, "smb_io_cred");
1486         depth++;
1487
1488         if(!prs_align(ps))
1489                 return False;
1490
1491         if(!smb_io_chal ("", &cred->challenge, ps, depth))
1492                 return False;
1493
1494         if(!smb_io_utime("", &cred->timestamp, ps, depth))
1495                 return False;
1496
1497         return True;
1498 }
1499
1500 /*******************************************************************
1501  Inits a DOM_CLNT_INFO2 structure.
1502 ********************************************************************/
1503
1504 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1505                                 const char *logon_srv, const char *comp_name,
1506                                 const DOM_CRED *clnt_cred)
1507 {
1508         DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1509
1510         init_clnt_srv(&clnt->login, logon_srv, comp_name);
1511
1512         if (clnt_cred != NULL) {
1513                 clnt->ptr_cred = 1;
1514                 memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
1515         } else {
1516                 clnt->ptr_cred = 0;
1517         }
1518 }
1519
1520 /*******************************************************************
1521  Reads or writes a DOM_CLNT_INFO2 structure.
1522 ********************************************************************/
1523
1524 BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1525 {
1526         if (clnt == NULL)
1527                 return False;
1528
1529         prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1530         depth++;
1531
1532         if(!prs_align(ps))
1533                 return False;
1534         
1535         if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1536                 return False;
1537
1538         if(!prs_align(ps))
1539                 return False;
1540         
1541         if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1542                 return False;
1543         if(!smb_io_cred("", &clnt->cred, ps, depth))
1544                 return False;
1545
1546         return True;
1547 }
1548
1549 /*******************************************************************
1550  Inits a DOM_CLNT_INFO structure.
1551 ********************************************************************/
1552
1553 void init_clnt_info(DOM_CLNT_INFO *clnt,
1554                 const char *logon_srv, const char *acct_name,
1555                 uint16 sec_chan, const char *comp_name,
1556                 const DOM_CRED *cred)
1557 {
1558         DEBUG(5,("make_clnt_info\n"));
1559
1560         init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1561         memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1562 }
1563
1564 /*******************************************************************
1565  Reads or writes a DOM_CLNT_INFO structure.
1566 ********************************************************************/
1567
1568 BOOL smb_io_clnt_info(const char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1569 {
1570         if (clnt == NULL)
1571                 return False;
1572
1573         prs_debug(ps, depth, desc, "smb_io_clnt_info");
1574         depth++;
1575
1576         if(!prs_align(ps))
1577                 return False;
1578         
1579         if(!smb_io_log_info("", &clnt->login, ps, depth))
1580                 return False;
1581         if(!smb_io_cred("", &clnt->cred, ps, depth))
1582                 return False;
1583
1584         return True;
1585 }
1586
1587 /*******************************************************************
1588  Inits a DOM_LOGON_ID structure.
1589 ********************************************************************/
1590
1591 void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
1592 {
1593         DEBUG(5,("make_logon_id: %d\n", __LINE__));
1594
1595         logonid->low  = log_id_low;
1596         logonid->high = log_id_high;
1597 }
1598
1599 /*******************************************************************
1600  Reads or writes a DOM_LOGON_ID structure.
1601 ********************************************************************/
1602
1603 BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
1604 {
1605         if (logonid == NULL)
1606                 return False;
1607
1608         prs_debug(ps, depth, desc, "smb_io_logon_id");
1609         depth++;
1610
1611         if(!prs_align(ps))
1612                 return False;
1613         
1614         if(!prs_uint32("low ", ps, depth, &logonid->low ))
1615                 return False;
1616         if(!prs_uint32("high", ps, depth, &logonid->high))
1617                 return False;
1618
1619         return True;
1620 }
1621
1622 /*******************************************************************
1623  Inits an OWF_INFO structure.
1624 ********************************************************************/
1625
1626 void init_owf_info(OWF_INFO *hash, const uint8 data[16])
1627 {
1628         DEBUG(5,("init_owf_info: %d\n", __LINE__));
1629         
1630         if (data != NULL)
1631                 memcpy(hash->data, data, sizeof(hash->data));
1632         else
1633                 memset((char *)hash->data, '\0', sizeof(hash->data));
1634 }
1635
1636 /*******************************************************************
1637  Reads or writes an OWF_INFO structure.
1638 ********************************************************************/
1639
1640 BOOL smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1641 {
1642         if (hash == NULL)
1643                 return False;
1644
1645         prs_debug(ps, depth, desc, "smb_io_owf_info");
1646         depth++;
1647
1648         if(!prs_align(ps))
1649                 return False;
1650         
1651         if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1652                 return False;
1653
1654         return True;
1655 }
1656
1657 /*******************************************************************
1658  Reads or writes a DOM_GID structure.
1659 ********************************************************************/
1660
1661 BOOL smb_io_gid(const char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
1662 {
1663         if (gid == NULL)
1664                 return False;
1665
1666         prs_debug(ps, depth, desc, "smb_io_gid");
1667         depth++;
1668
1669         if(!prs_align(ps))
1670                 return False;
1671         
1672         if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1673                 return False;
1674         if(!prs_uint32("attr ", ps, depth, &gid->attr))
1675                 return False;
1676
1677         return True;
1678 }
1679
1680 /*******************************************************************
1681  Reads or writes an POLICY_HND structure.
1682 ********************************************************************/
1683
1684 BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1685 {
1686         if (pol == NULL)
1687                 return False;
1688
1689         prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1690         depth++;
1691
1692         if(!prs_align(ps))
1693                 return False;
1694
1695         if(UNMARSHALLING(ps))
1696                 ZERO_STRUCTP(pol);
1697         
1698         if (!prs_uint32("data1", ps, depth, &pol->data1))
1699                 return False;
1700         if (!prs_uint32("data2", ps, depth, &pol->data2))
1701                 return False;
1702         if (!prs_uint16("data3", ps, depth, &pol->data3))
1703                 return False;
1704         if (!prs_uint16("data4", ps, depth, &pol->data4))
1705                 return False;
1706         if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1707                 return False;
1708
1709         return True;
1710 }
1711
1712 /*******************************************************************
1713  Create a UNISTR3.
1714 ********************************************************************/
1715
1716 void init_unistr3(UNISTR3 *str, const char *buf)
1717 {
1718         if (buf == NULL) {
1719                 str->uni_str_len=0;
1720                 str->str.buffer = NULL;
1721                 return;
1722         }
1723
1724         str->uni_str_len = strlen(buf) + 1;
1725
1726         str->str.buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_str_len);
1727         if (str->str.buffer == NULL)
1728                 smb_panic("init_unistr3: malloc fail\n");
1729
1730         rpcstr_push((char *)str->str.buffer, buf, str->uni_str_len * sizeof(uint16), STR_TERMINATE);
1731 }
1732
1733 /*******************************************************************
1734  Reads or writes a UNISTR3 structure.
1735 ********************************************************************/
1736
1737 BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1738 {
1739         if (name == NULL)
1740                 return False;
1741
1742         prs_debug(ps, depth, desc, "smb_io_unistr3");
1743         depth++;
1744
1745         if(!prs_align(ps))
1746                 return False;
1747         
1748         if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1749                 return False;
1750                 
1751         /* we're done if there is no string */
1752         
1753         if ( name->uni_str_len == 0 )
1754                 return True;
1755
1756         /* don't know if len is specified by uni_str_len member... */
1757         /* assume unicode string is unicode-null-terminated, instead */
1758
1759         if(!prs_unistr3(True, "unistr", name, ps, depth))
1760                 return False;
1761
1762         return True;
1763 }
1764
1765 /*******************************************************************
1766  Stream a uint64_struct
1767  ********************************************************************/
1768 BOOL prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64)
1769 {
1770         if (UNMARSHALLING(ps)) {
1771                 uint32 high, low;
1772
1773                 if (!prs_uint32(name, ps, depth+1, &low))
1774                         return False;
1775
1776                 if (!prs_uint32(name, ps, depth+1, &high))
1777                         return False;
1778
1779                 *data64 = ((uint64_t)high << 32) + low;
1780
1781                 return True;
1782         } else {
1783                 uint32 high = (*data64) >> 32, low = (*data64) & 0xFFFFFFFF;
1784                 return prs_uint32(name, ps, depth+1, &low) && 
1785                            prs_uint32(name, ps, depth+1, &high);
1786         }
1787 }
1788
1789 /*******************************************************************
1790 reads or writes a BUFHDR2 structure.
1791 ********************************************************************/
1792 BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
1793 {
1794         prs_debug(ps, depth, desc, "smb_io_bufhdr2");
1795         depth++;
1796
1797         prs_align(ps);
1798         prs_uint32("info_level", ps, depth, &(hdr->info_level));
1799         prs_uint32("length    ", ps, depth, &(hdr->length    ));
1800         prs_uint32("buffer    ", ps, depth, &(hdr->buffer    ));
1801
1802         return True;
1803 }
1804
1805 /*******************************************************************
1806 reads or writes a BUFHDR4 structure.
1807 ********************************************************************/
1808 BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
1809 {
1810         prs_debug(ps, depth, desc, "smb_io_bufhdr4");
1811         depth++;
1812
1813         prs_align(ps);
1814         prs_uint32("size", ps, depth, &hdr->size);
1815         prs_uint32("buffer", ps, depth, &hdr->buffer);
1816
1817         return True;
1818 }
1819
1820 /*******************************************************************
1821 reads or writes a RPC_DATA_BLOB structure.
1822 ********************************************************************/
1823
1824 BOOL smb_io_rpc_blob(const char *desc, RPC_DATA_BLOB *blob, prs_struct *ps, int depth)
1825 {
1826         prs_debug(ps, depth, desc, "smb_io_rpc_blob");
1827         depth++;
1828
1829         prs_align(ps);
1830         if ( !prs_uint32("buf_len", ps, depth, &blob->buf_len) )
1831                 return False;
1832
1833         if ( blob->buf_len == 0 )
1834                 return True;
1835
1836         if (UNMARSHALLING(ps)) {
1837                 blob->buffer = PRS_ALLOC_MEM(ps, uint8, blob->buf_len);
1838                 if (!blob->buffer) {
1839                         return False;
1840                 }
1841         }
1842
1843         if ( !prs_uint8s(True, "buffer", ps, depth, blob->buffer, blob->buf_len) )
1844                 return False;
1845
1846         return True;
1847 }
1848
1849 /*******************************************************************
1850 creates a UNIHDR structure.
1851 ********************************************************************/
1852
1853 BOOL make_uni_hdr(UNIHDR *hdr, int len)
1854 {
1855         if (hdr == NULL)
1856         {
1857                 return False;
1858         }
1859         hdr->uni_str_len = 2 * len;
1860         hdr->uni_max_len = 2 * len;
1861         hdr->buffer      = len != 0 ? 1 : 0;
1862
1863         return True;
1864 }
1865
1866 /*******************************************************************
1867 creates a BUFHDR2 structure.
1868 ********************************************************************/
1869 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
1870 {
1871         hdr->info_level = info_level;
1872         hdr->length     = length;
1873         hdr->buffer     = buffer;
1874
1875         return True;
1876 }
1877
1878 /*******************************************************************
1879 return the length of a UNISTR string.
1880 ********************************************************************/  
1881
1882 uint32 str_len_uni(UNISTR *source)
1883 {
1884         uint32 i=0;
1885
1886         if (!source->buffer)
1887                 return 0;
1888
1889         while (source->buffer[i])
1890                 i++;
1891
1892         return i;
1893 }
1894
1895