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