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