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