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