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