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