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