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