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