This removes the 3rd argument from init_unistr2(). There were 240
[samba.git] / source / rpc_parse / parse_misc.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  
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);
770
771         } else {
772
773                 *ptr = 0;
774                 init_unistr2(str, "");
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.  This function used to deliberately
885  over-allocate to a minimum of 256 bytes. That is rather silly, and
886  just hides potential bugs. If you need to overallocate then don't use
887  this function!
888 ********************************************************************/
889 void init_unistr2(UNISTR2 *str, const char *buf)
890 {
891         size_t len;
892
893         if (!buf) {
894                 /* this is incorrect, but is needed to cope with some 
895                    broken code that assumes this function will always 
896                    return a valid initialised UNISTR2 */
897                 buf = "";
898         }
899
900         len = push_ucs2_talloc(get_talloc_ctx() , &str->buffer, buf);
901
902         if (len == -1) {
903                 /* oops - we can't convert the string? */
904                 smb_panic("failed to convert string in init_unistr2");
905         }
906
907         /* set up string lengths. Note that len is guaranteed to be a
908          * multiple of 2 from push_ucs2 */
909         str->uni_max_len = len/2;
910         str->undoc       = 0;
911         str->uni_str_len = len/2;
912 }
913
914 /** 
915  *  Inits a UNISTR2 structure.
916  *  @param  ctx talloc context to allocate string on
917  *  @param  str pointer to string to create
918  *  @param  buf UCS2 null-terminated buffer to init from
919 */
920
921 void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
922 {
923         uint32 len = strlen_w(buf);
924         uint32 max_len = len;
925         uint32 alloc_len;
926
927         ZERO_STRUCTP(str);
928
929         /* set up string lengths. */
930         str->uni_max_len = len;
931         str->undoc       = 0;
932         str->uni_str_len = len;
933
934         if (max_len < MAX_UNISTRLEN)
935                 max_len = MAX_UNISTRLEN;
936
937         alloc_len = (max_len + 1) * sizeof(uint16);
938
939         str->buffer = (uint16 *)talloc_zero(ctx, alloc_len);
940         if ((str->buffer == NULL) && (alloc_len > 0))
941         {
942                 smb_panic("init_unistr2_w: malloc fail\n");
943                 return;
944         }
945         
946         /*
947          * don't move this test above ! The UNISTR2 must be initialized !!!
948          * jfm, 7/7/2001.
949          */
950         if (buf==NULL)
951                 return;
952         
953         /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
954            long as the buffer above is talloc()ed correctly then this
955            is the correct thing to do */
956         strncpy_w(str->buffer, buf, len + 1);
957 }
958
959 /*******************************************************************
960  Inits a UNISTR2 structure from a UNISTR
961 ********************************************************************/
962 void init_unistr2_from_unistr (UNISTR2 *to, const UNISTR *from)
963 {
964
965         uint32 i;
966
967         /* the destination UNISTR2 should never be NULL.
968            if it is it is a programming error */
969
970         /* if the source UNISTR is NULL, then zero out
971            the destination string and return */
972         ZERO_STRUCTP (to);
973         if ((from == NULL) || (from->buffer == NULL))
974                 return;
975
976         /* get the length; UNISTR must be NULL terminated */
977         i = 0;
978         while ((from->buffer)[i]!='\0')
979                 i++;
980         i++;    /* one more to catch the terminating NULL */
981                 /* is this necessary -- jerry?  I need to think */
982
983         /* set up string lengths; uni_max_len is set to i+1
984            because we need to account for the final NULL termination */
985         to->uni_max_len = i;
986         to->undoc       = 0;
987         to->uni_str_len = i;
988
989         /* allocate the space and copy the string buffer */
990         to->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), sizeof(uint16)*(to->uni_str_len));
991         if (to->buffer == NULL)
992                 smb_panic("init_unistr2_from_unistr: malloc fail\n");
993         memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
994                 
995         return;
996 }
997
998
999 /*******************************************************************
1000  Reads or writes a UNISTR2 structure.
1001  XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
1002    the uni_str_len member tells you how long the string is;
1003    the uni_max_len member tells you how large the buffer is.
1004 ********************************************************************/
1005
1006 BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
1007 {
1008         if (uni2 == NULL)
1009                 return False;
1010
1011         if (buffer) {
1012
1013                 prs_debug(ps, depth, desc, "smb_io_unistr2");
1014                 depth++;
1015
1016                 if(!prs_align(ps))
1017                         return False;
1018                 
1019                 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
1020                         return False;
1021                 if(!prs_uint32("undoc      ", ps, depth, &uni2->undoc))
1022                         return False;
1023                 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
1024                         return False;
1025
1026                 /* buffer advanced by indicated length of string
1027                    NOT by searching for null-termination */
1028                 if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
1029                         return False;
1030
1031         } else {
1032
1033                 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
1034                 depth++;
1035                 memset((char *)uni2, '\0', sizeof(*uni2));
1036
1037         }
1038
1039         return True;
1040 }
1041
1042
1043 /*******************************************************************
1044  Reads or writes a UNISTR_ARRAY structure.
1045 ********************************************************************/
1046 BOOL smb_io_unistr_array(const char *desc, UNISTR_ARRAY *array, prs_struct *ps, int depth)
1047 {
1048         int i;
1049
1050         depth++;
1051
1052         array->count = 0;
1053
1054         if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
1055                 return False;
1056
1057         if (! array->ref_id) {
1058                 return True;
1059         }
1060
1061         if(!prs_uint32("count", ps, depth, &array->count))
1062                 return False;
1063
1064         if (array->count == 0) {
1065                 return True;
1066         }
1067
1068         array->strings = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->strings[0]));
1069         if (! array->strings) {
1070                 return False;
1071         }
1072
1073         for (i=0;i<array->count;i++) {
1074                 if(!prs_uint16("length", ps, depth, &array->strings[i].length))
1075                         return False;
1076                 if(!prs_uint16("size", ps, depth, &array->strings[i].size))
1077                         return False;
1078                 if(!prs_uint32("ref_id", ps, depth, &array->strings[i].ref_id))
1079                         return False;
1080         }
1081
1082         for (i=0;i<array->count;i++) {
1083                 if (! smb_io_unistr2("string", &array->strings[i].string, array->strings[i].ref_id, ps, depth)) 
1084                         return False;
1085         }
1086         
1087         return True;
1088 }
1089
1090
1091 /*******************************************************************
1092  Inits a DOM_RID2 structure.
1093 ********************************************************************/
1094
1095 void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
1096 {
1097         rid2->type    = type;
1098         rid2->rid     = rid;
1099         rid2->rid_idx = idx;
1100 }
1101
1102 /*******************************************************************
1103  Reads or writes a DOM_RID2 structure.
1104 ********************************************************************/
1105
1106 BOOL smb_io_dom_rid2(const char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
1107 {
1108         if (rid2 == NULL)
1109                 return False;
1110
1111         prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1112         depth++;
1113
1114         if(!prs_align(ps))
1115                 return False;
1116    
1117         if(!prs_uint8("type   ", ps, depth, &rid2->type))
1118                 return False;
1119         if(!prs_align(ps))
1120                 return False;
1121         if(!prs_uint32("rid    ", ps, depth, &rid2->rid))
1122                 return False;
1123         if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
1124                 return False;
1125
1126         return True;
1127 }
1128
1129 /*******************************************************************
1130 creates a DOM_RID3 structure.
1131 ********************************************************************/
1132
1133 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1134 {
1135     rid3->rid      = rid;
1136     rid3->type1    = type;
1137     rid3->ptr_type = 0x1; /* non-zero, basically. */
1138     rid3->type2    = 0x1;
1139     rid3->unk      = type;
1140 }
1141
1142 /*******************************************************************
1143 reads or writes a DOM_RID3 structure.
1144 ********************************************************************/
1145
1146 BOOL smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1147 {
1148         if (rid3 == NULL)
1149                 return False;
1150
1151         prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1152         depth++;
1153
1154         if(!prs_align(ps))
1155                 return False;
1156
1157         if(!prs_uint32("rid     ", ps, depth, &rid3->rid))
1158                 return False;
1159         if(!prs_uint32("type1   ", ps, depth, &rid3->type1))
1160                 return False;
1161         if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1162                 return False;
1163         if(!prs_uint32("type2   ", ps, depth, &rid3->type2))
1164                 return False;
1165         if(!prs_uint32("unk     ", ps, depth, &rid3->unk))
1166                 return False;
1167
1168         return True;
1169 }
1170
1171 /*******************************************************************
1172  Inits a DOM_RID4 structure.
1173 ********************************************************************/
1174
1175 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1176 {
1177     rid4->unknown = unknown;
1178     rid4->attr    = attr;
1179     rid4->rid     = rid;
1180 }
1181
1182 /*******************************************************************
1183  Inits a DOM_CLNT_SRV structure.
1184 ********************************************************************/
1185
1186 static void init_clnt_srv(DOM_CLNT_SRV *log, const char *logon_srv, const char *comp_name)
1187 {
1188         DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1189
1190         if (logon_srv != NULL) {
1191                 log->undoc_buffer = 1;
1192                 init_unistr2(&log->uni_logon_srv, logon_srv);
1193         } else {
1194                 log->undoc_buffer = 0;
1195         }
1196
1197         if (comp_name != NULL) {
1198                 log->undoc_buffer2 = 1;
1199                 init_unistr2(&log->uni_comp_name, comp_name);
1200         } else {
1201                 log->undoc_buffer2 = 0;
1202         }
1203 }
1204
1205 /*******************************************************************
1206  Inits or writes a DOM_CLNT_SRV structure.
1207 ********************************************************************/
1208
1209 static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
1210 {
1211         if (log == NULL)
1212                 return False;
1213
1214         prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1215         depth++;
1216
1217         if(!prs_align(ps))
1218                 return False;
1219         
1220         if(!prs_uint32("undoc_buffer ", ps, depth, &log->undoc_buffer))
1221                 return False;
1222
1223         if (log->undoc_buffer != 0) {
1224                 if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, log->undoc_buffer, ps, depth))
1225                         return False;
1226         }
1227
1228         if(!prs_align(ps))
1229                 return False;
1230
1231         if(!prs_uint32("undoc_buffer2", ps, depth, &log->undoc_buffer2))
1232                 return False;
1233
1234         if (log->undoc_buffer2 != 0) {
1235                 if(!smb_io_unistr2("unistr2", &log->uni_comp_name, log->undoc_buffer2, ps, depth))
1236                         return False;
1237         }
1238
1239         return True;
1240 }
1241
1242 /*******************************************************************
1243  Inits a DOM_LOG_INFO structure.
1244 ********************************************************************/
1245
1246 void init_log_info(DOM_LOG_INFO *log, const char *logon_srv, const char *acct_name,
1247                 uint16 sec_chan, const char *comp_name)
1248 {
1249         DEBUG(5,("make_log_info %d\n", __LINE__));
1250
1251         log->undoc_buffer = 1;
1252
1253         init_unistr2(&log->uni_logon_srv, logon_srv);
1254         init_unistr2(&log->uni_acct_name, acct_name);
1255
1256         log->sec_chan = sec_chan;
1257
1258         init_unistr2(&log->uni_comp_name, comp_name);
1259 }
1260
1261 /*******************************************************************
1262  Reads or writes a DOM_LOG_INFO structure.
1263 ********************************************************************/
1264
1265 BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
1266 {
1267         if (log == NULL)
1268                 return False;
1269
1270         prs_debug(ps, depth, desc, "smb_io_log_info");
1271         depth++;
1272
1273         if(!prs_align(ps))
1274                 return False;
1275         
1276         if(!prs_uint32("undoc_buffer", ps, depth, &log->undoc_buffer))
1277                 return False;
1278
1279         if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, True, ps, depth))
1280                 return False;
1281         if(!smb_io_unistr2("unistr2", &log->uni_acct_name, True, ps, depth))
1282                 return False;
1283
1284         if(!prs_uint16("sec_chan", ps, depth, &log->sec_chan))
1285                 return False;
1286
1287         if(!smb_io_unistr2("unistr2", &log->uni_comp_name, True, ps, depth))
1288                 return False;
1289
1290         return True;
1291 }
1292
1293 /*******************************************************************
1294  Reads or writes a DOM_CHAL structure.
1295 ********************************************************************/
1296
1297 BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1298 {
1299         if (chal == NULL)
1300                 return False;
1301
1302         prs_debug(ps, depth, desc, "smb_io_chal");
1303         depth++;
1304         
1305         if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1306                 return False;
1307
1308         return True;
1309 }
1310
1311 /*******************************************************************
1312  Reads or writes a DOM_CRED structure.
1313 ********************************************************************/
1314
1315 BOOL smb_io_cred(const char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
1316 {
1317         if (cred == NULL)
1318                 return False;
1319
1320         prs_debug(ps, depth, desc, "smb_io_cred");
1321         depth++;
1322
1323         if(!prs_align(ps))
1324                 return False;
1325
1326         if(!smb_io_chal ("", &cred->challenge, ps, depth))
1327                 return False;
1328
1329         if(!smb_io_utime("", &cred->timestamp, ps, depth))
1330                 return False;
1331
1332         return True;
1333 }
1334
1335 /*******************************************************************
1336  Inits a DOM_CLNT_INFO2 structure.
1337 ********************************************************************/
1338
1339 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1340                                 const char *logon_srv, const char *comp_name,
1341                                 const DOM_CRED *clnt_cred)
1342 {
1343         DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1344
1345         init_clnt_srv(&clnt->login, logon_srv, comp_name);
1346
1347         if (clnt_cred != NULL) {
1348                 clnt->ptr_cred = 1;
1349                 memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
1350         } else {
1351                 clnt->ptr_cred = 0;
1352         }
1353 }
1354
1355 /*******************************************************************
1356  Reads or writes a DOM_CLNT_INFO2 structure.
1357 ********************************************************************/
1358
1359 BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1360 {
1361         if (clnt == NULL)
1362                 return False;
1363
1364         prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1365         depth++;
1366
1367         if(!prs_align(ps))
1368                 return False;
1369         
1370         if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1371                 return False;
1372
1373         if(!prs_align(ps))
1374                 return False;
1375         
1376         if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1377                 return False;
1378         if(!smb_io_cred("", &clnt->cred, ps, depth))
1379                 return False;
1380
1381         return True;
1382 }
1383
1384 /*******************************************************************
1385  Inits a DOM_CLNT_INFO structure.
1386 ********************************************************************/
1387
1388 void init_clnt_info(DOM_CLNT_INFO *clnt,
1389                 const char *logon_srv, const char *acct_name,
1390                 uint16 sec_chan, const char *comp_name,
1391                 const DOM_CRED *cred)
1392 {
1393         DEBUG(5,("make_clnt_info\n"));
1394
1395         init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1396         memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1397 }
1398
1399 /*******************************************************************
1400  Reads or writes a DOM_CLNT_INFO structure.
1401 ********************************************************************/
1402
1403 BOOL smb_io_clnt_info(const char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1404 {
1405         if (clnt == NULL)
1406                 return False;
1407
1408         prs_debug(ps, depth, desc, "smb_io_clnt_info");
1409         depth++;
1410
1411         if(!prs_align(ps))
1412                 return False;
1413         
1414         if(!smb_io_log_info("", &clnt->login, ps, depth))
1415                 return False;
1416         if(!smb_io_cred("", &clnt->cred, ps, depth))
1417                 return False;
1418
1419         return True;
1420 }
1421
1422 /*******************************************************************
1423  Inits a DOM_LOGON_ID structure.
1424 ********************************************************************/
1425
1426 void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
1427 {
1428         DEBUG(5,("make_logon_id: %d\n", __LINE__));
1429
1430         log->low  = log_id_low;
1431         log->high = log_id_high;
1432 }
1433
1434 /*******************************************************************
1435  Reads or writes a DOM_LOGON_ID structure.
1436 ********************************************************************/
1437
1438 BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
1439 {
1440         if (log == NULL)
1441                 return False;
1442
1443         prs_debug(ps, depth, desc, "smb_io_logon_id");
1444         depth++;
1445
1446         if(!prs_align(ps))
1447                 return False;
1448         
1449         if(!prs_uint32("low ", ps, depth, &log->low ))
1450                 return False;
1451         if(!prs_uint32("high", ps, depth, &log->high))
1452                 return False;
1453
1454         return True;
1455 }
1456
1457 /*******************************************************************
1458  Inits an OWF_INFO structure.
1459 ********************************************************************/
1460
1461 void init_owf_info(OWF_INFO *hash, const uint8 data[16])
1462 {
1463         DEBUG(5,("init_owf_info: %d\n", __LINE__));
1464         
1465         if (data != NULL)
1466                 memcpy(hash->data, data, sizeof(hash->data));
1467         else
1468                 memset((char *)hash->data, '\0', sizeof(hash->data));
1469 }
1470
1471 /*******************************************************************
1472  Reads or writes an OWF_INFO structure.
1473 ********************************************************************/
1474
1475 BOOL smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1476 {
1477         if (hash == NULL)
1478                 return False;
1479
1480         prs_debug(ps, depth, desc, "smb_io_owf_info");
1481         depth++;
1482
1483         if(!prs_align(ps))
1484                 return False;
1485         
1486         if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1487                 return False;
1488
1489         return True;
1490 }
1491
1492 /*******************************************************************
1493  Reads or writes a DOM_GID structure.
1494 ********************************************************************/
1495
1496 BOOL smb_io_gid(const char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
1497 {
1498         if (gid == NULL)
1499                 return False;
1500
1501         prs_debug(ps, depth, desc, "smb_io_gid");
1502         depth++;
1503
1504         if(!prs_align(ps))
1505                 return False;
1506         
1507         if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1508                 return False;
1509         if(!prs_uint32("attr ", ps, depth, &gid->attr))
1510                 return False;
1511
1512         return True;
1513 }
1514
1515 /*******************************************************************
1516  Reads or writes an POLICY_HND structure.
1517 ********************************************************************/
1518
1519 BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1520 {
1521         if (pol == NULL)
1522                 return False;
1523
1524         prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1525         depth++;
1526
1527         if(!prs_align(ps))
1528                 return False;
1529
1530         if(UNMARSHALLING(ps))
1531                 ZERO_STRUCTP(pol);
1532         
1533         if (!prs_uint32("data1", ps, depth, &pol->data1))
1534                 return False;
1535         if (!prs_uint32("data2", ps, depth, &pol->data2))
1536                 return False;
1537         if (!prs_uint16("data3", ps, depth, &pol->data3))
1538                 return False;
1539         if (!prs_uint16("data4", ps, depth, &pol->data4))
1540                 return False;
1541         if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1542                 return False;
1543
1544         return True;
1545 }
1546
1547 /*******************************************************************
1548  Create a UNISTR3.
1549 ********************************************************************/
1550
1551 void init_unistr3(UNISTR3 *str, const char *buf)
1552 {
1553         size_t len;
1554
1555         if (buf == NULL) {
1556                 str->uni_str_len=0;
1557                 str->str.buffer = NULL;
1558                 return;
1559         }
1560
1561         len = strlen(buf) + 1;
1562
1563         str->uni_str_len=len;
1564
1565         if (len < MAX_UNISTRLEN)
1566                 len = MAX_UNISTRLEN;
1567
1568         len *= sizeof(uint16);
1569
1570         str->str.buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
1571         if (str->str.buffer == NULL)
1572                 smb_panic("init_unistr3: malloc fail\n");
1573
1574         rpcstr_push((char *)str->str.buffer, buf, len, STR_TERMINATE);
1575 }
1576
1577 /*******************************************************************
1578  Reads or writes a UNISTR3 structure.
1579 ********************************************************************/
1580
1581 BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1582 {
1583         if (name == NULL)
1584                 return False;
1585
1586         prs_debug(ps, depth, desc, "smb_io_unistr3");
1587         depth++;
1588
1589         if(!prs_align(ps))
1590                 return False;
1591         
1592         if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1593                 return False;
1594
1595         /* don't know if len is specified by uni_str_len member... */
1596         /* assume unicode string is unicode-null-terminated, instead */
1597
1598         if(!prs_unistr3(True, "unistr", name, ps, depth))
1599                 return False;
1600
1601         return True;
1602 }
1603
1604
1605 /*******************************************************************
1606  Stream a uint64_struct
1607  ********************************************************************/
1608 BOOL prs_uint64(const char *name, prs_struct *ps, int depth, UINT64_S *data64)
1609 {
1610         return prs_uint32(name, ps, depth+1, &data64->low) &&
1611                 prs_uint32(name, ps, depth+1, &data64->high);
1612 }
1613
1614 /*******************************************************************
1615 reads or writes a BUFHDR2 structure.
1616 ********************************************************************/
1617 BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
1618 {
1619         prs_debug(ps, depth, desc, "smb_io_bufhdr2");
1620         depth++;
1621
1622         prs_align(ps);
1623         prs_uint32("info_level", ps, depth, &(hdr->info_level));
1624         prs_uint32("length    ", ps, depth, &(hdr->length    ));
1625         prs_uint32("buffer    ", ps, depth, &(hdr->buffer    ));
1626
1627         return True;
1628 }
1629
1630 /*******************************************************************
1631 reads or writes a BUFFER4 structure.
1632 ********************************************************************/
1633 BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
1634 {
1635         prs_debug(ps, depth, desc, "smb_io_buffer4");
1636         depth++;
1637
1638         prs_align(ps);
1639         prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
1640
1641         if (buf4->buf_len > MAX_BUFFERLEN)
1642         {
1643                 buf4->buf_len = MAX_BUFFERLEN;
1644         }
1645
1646         prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
1647
1648         return True;
1649 }
1650
1651 /*******************************************************************
1652 creates a UNIHDR structure.
1653 ********************************************************************/
1654
1655 BOOL make_uni_hdr(UNIHDR *hdr, int len)
1656 {
1657         if (hdr == NULL)
1658         {
1659                 return False;
1660         }
1661         hdr->uni_str_len = 2 * len;
1662         hdr->uni_max_len = 2 * len;
1663         hdr->buffer      = len != 0 ? 1 : 0;
1664
1665         return True;
1666 }
1667
1668 /*******************************************************************
1669 creates a BUFHDR2 structure.
1670 ********************************************************************/
1671 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
1672 {
1673         hdr->info_level = info_level;
1674         hdr->length     = length;
1675         hdr->buffer     = buffer;
1676
1677         return True;
1678 }