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