r10656: BIG merge from trunk. Features not copied over
[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         } else {
834                 /* no buffer -- nothing to do */
835                 str->uni_max_len = 0;
836                 str->offset = 0;
837                 str->uni_str_len = 0;
838
839                 return;
840         }
841         
842
843         str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
844         if (str->buffer == NULL) {
845                 smb_panic("init_unistr2: malloc fail\n");
846                 return;
847         }
848
849         /* Ensure len is the length in *bytes* */
850         len *= sizeof(uint16);
851
852         /*
853          * The UNISTR2 must be initialized !!!
854          * jfm, 7/7/2001.
855          */
856         if (buf) {
857                 rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
858                 num_chars = strlen_w(str->buffer);
859                 if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
860                         num_chars++;
861                 }
862         }
863
864         str->uni_max_len = num_chars;
865         str->offset = 0;
866         str->uni_str_len = num_chars;
867         if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) )
868                 str->uni_max_len++;
869 }
870
871 /*******************************************************************
872  Inits a UNISTR4 structure.
873 ********************************************************************/
874
875 void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags)
876 {
877         uni4->string = TALLOC_P( get_talloc_ctx(), UNISTR2 );
878         init_unistr2( uni4->string, buf, flags );
879
880         uni4->length = 2 * (uni4->string->uni_str_len);
881         uni4->size   = 2 * (uni4->string->uni_max_len);
882 }
883
884 void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf )
885 {
886         uni4->string = TALLOC_P( ctx, UNISTR2 );
887         init_unistr2_w( ctx, uni4->string, buf );
888
889         uni4->length = 2 * (uni4->string->uni_str_len);
890         uni4->size   = 2 * (uni4->string->uni_max_len);
891 }
892
893 /** 
894  *  Inits a UNISTR2 structure.
895  *  @param  ctx talloc context to allocate string on
896  *  @param  str pointer to string to create
897  *  @param  buf UCS2 null-terminated buffer to init from
898 */
899
900 void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
901 {
902         uint32 len = strlen_w(buf);
903
904         ZERO_STRUCTP(str);
905
906         /* set up string lengths. */
907         str->uni_max_len = len;
908         str->offset = 0;
909         str->uni_str_len = len;
910
911         str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, len + 1);
912         if (str->buffer == NULL) {
913                 smb_panic("init_unistr2_w: malloc fail\n");
914                 return;
915         }
916         
917         /*
918          * don't move this test above ! The UNISTR2 must be initialized !!!
919          * jfm, 7/7/2001.
920          */
921         if (buf==NULL)
922                 return;
923         
924         /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
925            long as the buffer above is talloc()ed correctly then this
926            is the correct thing to do */
927         strncpy_w(str->buffer, buf, len + 1);
928 }
929
930 /*******************************************************************
931  Inits a UNISTR2 structure from a UNISTR
932 ********************************************************************/
933
934 void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
935 {
936         uint32 i;
937
938         /* the destination UNISTR2 should never be NULL.
939            if it is it is a programming error */
940
941         /* if the source UNISTR is NULL, then zero out
942            the destination string and return */
943         ZERO_STRUCTP (to);
944         if ((from == NULL) || (from->buffer == NULL))
945                 return;
946
947         /* get the length; UNISTR must be NULL terminated */
948         i = 0;
949         while ((from->buffer)[i]!='\0')
950                 i++;
951         i++;    /* one more to catch the terminating NULL */
952                 /* is this necessary -- jerry?  I need to think */
953
954         /* set up string lengths; uni_max_len is set to i+1
955            because we need to account for the final NULL termination */
956         to->uni_max_len = i;
957         to->offset = 0;
958         to->uni_str_len = i;
959
960         /* allocate the space and copy the string buffer */
961         to->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, i);
962         if (to->buffer == NULL)
963                 smb_panic("init_unistr2_from_unistr: malloc fail\n");
964         memcpy(to->buffer, from->buffer, i*sizeof(uint16));
965         return;
966 }
967
968 /*******************************************************************
969   Inits a UNISTR2 structure from a DATA_BLOB.
970   The length of the data_blob must count the bytes of the buffer.
971   Copies the blob data.
972 ********************************************************************/
973
974 void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) 
975 {
976         /* Allocs the unistring */
977         init_unistr2(str, NULL, UNI_FLAGS_NONE);
978         
979         /* Sets the values */
980         str->uni_str_len = blob->length / sizeof(uint16);
981         str->uni_max_len = str->uni_str_len;
982         str->offset = 0;
983         if (blob->length) {
984                 str->buffer = (uint16 *) memdup(blob->data, blob->length);
985         } else {
986                 str->buffer = NULL;
987         }
988         if ((str->buffer == NULL) && (blob->length > 0)) {
989                 smb_panic("init_unistr2_from_datablob: malloc fail\n");
990         }
991 }
992
993 /*******************************************************************
994  UNISTR2* are a little different in that the pointer and the UNISTR2
995  are not necessarily read/written back to back.  So we break it up 
996  into 2 separate functions.
997  See SPOOL_USER_1 in include/rpc_spoolss.h for an example.
998 ********************************************************************/
999
1000 BOOL prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2)
1001 {
1002         uint32 data_p;
1003
1004         /* caputure the pointer value to stream */
1005
1006         data_p = *uni2 ? 0xf000baaa : 0;
1007
1008         if ( !prs_uint32("ptr", ps, depth, &data_p ))
1009                 return False;
1010
1011         /* we're done if there is no data */
1012
1013         if ( !data_p )
1014                 return True;
1015
1016         if (UNMARSHALLING(ps)) {
1017                 if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) )
1018                         return False;
1019         }
1020
1021         return True;
1022 }
1023
1024 /*******************************************************************
1025  now read/write the actual UNISTR2.  Memory for the UNISTR2 (but
1026  not UNISTR2.buffer) has been allocated previously by prs_unistr2_p()
1027 ********************************************************************/
1028
1029 BOOL prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
1030 {
1031         /* just return true if there is no pointer to deal with.
1032            the memory must have been previously allocated on unmarshalling
1033            by prs_unistr2_p() */
1034
1035         if ( !uni2 )
1036                 return True;
1037
1038         /* just pass off to smb_io_unstr2() passing the uni2 address as 
1039            the pointer (like you would expect) */
1040
1041         return smb_io_unistr2( desc, uni2, uni2 ? 1 : 0, ps, depth );
1042 }
1043
1044 /*******************************************************************
1045  Reads or writes a UNISTR2 structure.
1046  XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
1047    the uni_str_len member tells you how long the string is;
1048    the uni_max_len member tells you how large the buffer is.
1049 ********************************************************************/
1050
1051 BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
1052 {
1053         if (uni2 == NULL)
1054                 return False;
1055
1056         if (buffer) {
1057
1058                 prs_debug(ps, depth, desc, "smb_io_unistr2");
1059                 depth++;
1060
1061                 if(!prs_align(ps))
1062                         return False;
1063                 
1064                 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
1065                         return False;
1066                 if(!prs_uint32("offset     ", ps, depth, &uni2->offset))
1067                         return False;
1068                 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
1069                         return False;
1070
1071                 /* buffer advanced by indicated length of string
1072                    NOT by searching for null-termination */
1073                 if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
1074                         return False;
1075
1076         } else {
1077
1078                 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
1079                 depth++;
1080                 memset((char *)uni2, '\0', sizeof(*uni2));
1081
1082         }
1083
1084         return True;
1085 }
1086
1087 /*******************************************************************
1088  now read/write UNISTR4
1089 ********************************************************************/
1090
1091 BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1092 {
1093         prs_debug(ps, depth, desc, "prs_unistr4");
1094         depth++;
1095
1096         if ( !prs_uint16("length", ps, depth, &uni4->length ))
1097                 return False;
1098         if ( !prs_uint16("size", ps, depth, &uni4->size ))
1099                 return False;
1100                 
1101         if ( !prs_pointer( desc, ps, depth, (void**)&uni4->string, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
1102                 return False;
1103                 
1104         return True;
1105 }
1106
1107 /*******************************************************************
1108  now read/write UNISTR4 header
1109 ********************************************************************/
1110
1111 BOOL prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1112 {
1113         prs_debug(ps, depth, desc, "prs_unistr4_hdr");
1114         depth++;
1115
1116         if ( !prs_uint16("length", ps, depth, &uni4->length) )
1117                 return False;
1118         if ( !prs_uint16("size", ps, depth, &uni4->size) )
1119                 return False;
1120         if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) )
1121                 return False;
1122                 
1123         return True;
1124 }
1125
1126 /*******************************************************************
1127  now read/write UNISTR4 string
1128 ********************************************************************/
1129
1130 BOOL prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1131 {
1132         prs_debug(ps, depth, desc, "prs_unistr4_str");
1133         depth++;
1134
1135         if ( !prs_io_unistr2(desc, ps, depth, uni4->string) )
1136                 return False;
1137                 
1138         return True;
1139 }
1140
1141 /*******************************************************************
1142  Reads or writes a UNISTR4_ARRAY structure.
1143 ********************************************************************/
1144
1145 BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
1146 {
1147         unsigned int i;
1148
1149         prs_debug(ps, depth, desc, "prs_unistr4_array");
1150         depth++;
1151
1152         if(!prs_uint32("count", ps, depth, &array->count))
1153                 return False;
1154
1155         if ( array->count == 0 ) 
1156                 return True;
1157         
1158         if (UNMARSHALLING(ps)) {
1159                 if ( !(array->strings = TALLOC_ZERO_ARRAY( get_talloc_ctx(), UNISTR4, array->count)) )
1160                         return False;
1161         }
1162         
1163         /* write the headers and then the actual string buffer */
1164         
1165         for ( i=0; i<array->count; i++ ) {
1166                 if ( !prs_unistr4_hdr( "string", ps, depth, &array->strings[i]) )
1167                         return False;
1168         }
1169
1170         for (i=0;i<array->count;i++) {
1171                 if ( !prs_unistr4_str("string", ps, depth, &array->strings[i]) ) 
1172                         return False;
1173         }
1174         
1175         return True;
1176 }
1177
1178 /********************************************************************
1179   initialise a UNISTR_ARRAY from a char**
1180 ********************************************************************/
1181
1182 BOOL init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings )
1183 {
1184         unsigned int i;
1185
1186         array->count = count;
1187
1188         if ( array->count == 0 )
1189                 return True;
1190
1191         /* allocate memory for the array of UNISTR4 objects */
1192
1193         if ( !(array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR4, count )) )
1194                 return False;
1195
1196         for ( i=0; i<count; i++ ) 
1197                 init_unistr4( &array->strings[i], strings[i], UNI_STR_TERMINATE );
1198
1199         return True;
1200 }
1201
1202 BOOL smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth)
1203 {
1204         prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr");
1205         depth++;
1206
1207         if(!prs_align(ps))
1208                 return False;
1209
1210         if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size))
1211                 return False;
1212         if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length))
1213                 return False;
1214         if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer))
1215                 return False;
1216
1217         return True;
1218 }
1219
1220 BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockout, uint32 buffer, prs_struct *ps, int depth)
1221 {
1222         prs_debug(ps, depth, desc, "smb_io_account_lockout_string");
1223         depth++;
1224
1225         if(!prs_uint32("array_size", ps, depth, &account_lockout->array_size))
1226                 return False;
1227
1228         if(!prs_uint32("offset", ps, depth, &account_lockout->offset))
1229                 return False;
1230         if(!prs_uint32("length", ps, depth, &account_lockout->length))
1231                 return False;
1232
1233         if (!prs_uint64("lockout_duration", ps, depth, &account_lockout->lockout_duration))
1234                 return False;
1235         if (!prs_uint64("reset_count", ps, depth, &account_lockout->reset_count))
1236                 return False;
1237         if (!prs_uint32("bad_attempt_lockout", ps, depth, &account_lockout->bad_attempt_lockout))
1238                 return False;
1239         if (!prs_uint32("dummy", ps, depth, &account_lockout->dummy))
1240                 return False;
1241 #if 0
1242         if(!prs_uint16s (False, "bindata", ps, depth, &account_lockout->bindata, length))
1243                 return False;
1244 #endif
1245
1246         return True;
1247 }
1248
1249 /*******************************************************************
1250  Inits a DOM_RID2 structure.
1251 ********************************************************************/
1252
1253 void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
1254 {
1255         rid2->type    = type;
1256         rid2->rid     = rid;
1257         rid2->rid_idx = idx;
1258 }
1259
1260 /*******************************************************************
1261  Reads or writes a DOM_RID2 structure.
1262 ********************************************************************/
1263
1264 BOOL smb_io_dom_rid2(const char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
1265 {
1266         if (rid2 == NULL)
1267                 return False;
1268
1269         prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1270         depth++;
1271
1272         if(!prs_align(ps))
1273                 return False;
1274    
1275         if(!prs_uint8("type   ", ps, depth, &rid2->type))
1276                 return False;
1277         if(!prs_align(ps))
1278                 return False;
1279         if(!prs_uint32("rid    ", ps, depth, &rid2->rid))
1280                 return False;
1281         if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
1282                 return False;
1283
1284         return True;
1285 }
1286
1287 /*******************************************************************
1288 creates a DOM_RID3 structure.
1289 ********************************************************************/
1290
1291 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1292 {
1293     rid3->rid      = rid;
1294     rid3->type1    = type;
1295     rid3->ptr_type = 0x1; /* non-zero, basically. */
1296     rid3->type2    = 0x1;
1297     rid3->unk      = type;
1298 }
1299
1300 /*******************************************************************
1301 reads or writes a DOM_RID3 structure.
1302 ********************************************************************/
1303
1304 BOOL smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1305 {
1306         if (rid3 == NULL)
1307                 return False;
1308
1309         prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1310         depth++;
1311
1312         if(!prs_align(ps))
1313                 return False;
1314
1315         if(!prs_uint32("rid     ", ps, depth, &rid3->rid))
1316                 return False;
1317         if(!prs_uint32("type1   ", ps, depth, &rid3->type1))
1318                 return False;
1319         if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1320                 return False;
1321         if(!prs_uint32("type2   ", ps, depth, &rid3->type2))
1322                 return False;
1323         if(!prs_uint32("unk     ", ps, depth, &rid3->unk))
1324                 return False;
1325
1326         return True;
1327 }
1328
1329 /*******************************************************************
1330  Inits a DOM_RID4 structure.
1331 ********************************************************************/
1332
1333 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1334 {
1335     rid4->unknown = unknown;
1336     rid4->attr    = attr;
1337     rid4->rid     = rid;
1338 }
1339
1340 /*******************************************************************
1341  Inits a DOM_CLNT_SRV structure.
1342 ********************************************************************/
1343
1344 static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name)
1345 {
1346         DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1347
1348         if (logon_srv != NULL) {
1349                 logcln->undoc_buffer = 1;
1350                 init_unistr2(&logcln->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1351         } else {
1352                 logcln->undoc_buffer = 0;
1353         }
1354
1355         if (comp_name != NULL) {
1356                 logcln->undoc_buffer2 = 1;
1357                 init_unistr2(&logcln->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1358         } else {
1359                 logcln->undoc_buffer2 = 0;
1360         }
1361 }
1362
1363 /*******************************************************************
1364  Inits or writes a DOM_CLNT_SRV structure.
1365 ********************************************************************/
1366
1367 static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
1368 {
1369         if (logcln == NULL)
1370                 return False;
1371
1372         prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1373         depth++;
1374
1375         if(!prs_align(ps))
1376                 return False;
1377         
1378         if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
1379                 return False;
1380
1381         if (logcln->undoc_buffer != 0) {
1382                 if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
1383                         return False;
1384         }
1385
1386         if(!prs_align(ps))
1387                 return False;
1388
1389         if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
1390                 return False;
1391
1392         if (logcln->undoc_buffer2 != 0) {
1393                 if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
1394                         return False;
1395         }
1396
1397         return True;
1398 }
1399
1400 /*******************************************************************
1401  Inits a DOM_LOG_INFO structure.
1402 ********************************************************************/
1403
1404 void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
1405                 uint16 sec_chan, const char *comp_name)
1406 {
1407         DEBUG(5,("make_log_info %d\n", __LINE__));
1408
1409         loginfo->undoc_buffer = 1;
1410
1411         init_unistr2(&loginfo->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1412         init_unistr2(&loginfo->uni_acct_name, acct_name, UNI_STR_TERMINATE);
1413
1414         loginfo->sec_chan = sec_chan;
1415
1416         init_unistr2(&loginfo->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1417 }
1418
1419 /*******************************************************************
1420  Reads or writes a DOM_LOG_INFO structure.
1421 ********************************************************************/
1422
1423 BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
1424 {
1425         if (loginfo == NULL)
1426                 return False;
1427
1428         prs_debug(ps, depth, desc, "smb_io_log_info");
1429         depth++;
1430
1431         if(!prs_align(ps))
1432                 return False;
1433         
1434         if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
1435                 return False;
1436
1437         if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
1438                 return False;
1439         if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
1440                 return False;
1441
1442         if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
1443                 return False;
1444
1445         if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
1446                 return False;
1447
1448         return True;
1449 }
1450
1451 /*******************************************************************
1452  Reads or writes a DOM_CHAL structure.
1453 ********************************************************************/
1454
1455 BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1456 {
1457         if (chal == NULL)
1458                 return False;
1459
1460         prs_debug(ps, depth, desc, "smb_io_chal");
1461         depth++;
1462         
1463         if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1464                 return False;
1465
1466         return True;
1467 }
1468
1469 /*******************************************************************
1470  Reads or writes a DOM_CRED structure.
1471 ********************************************************************/
1472
1473 BOOL smb_io_cred(const char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
1474 {
1475         if (cred == NULL)
1476                 return False;
1477
1478         prs_debug(ps, depth, desc, "smb_io_cred");
1479         depth++;
1480
1481         if(!prs_align(ps))
1482                 return False;
1483
1484         if(!smb_io_chal ("", &cred->challenge, ps, depth))
1485                 return False;
1486
1487         if(!smb_io_utime("", &cred->timestamp, ps, depth))
1488                 return False;
1489
1490         return True;
1491 }
1492
1493 /*******************************************************************
1494  Inits a DOM_CLNT_INFO2 structure.
1495 ********************************************************************/
1496
1497 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1498                                 const char *logon_srv, const char *comp_name,
1499                                 const DOM_CRED *clnt_cred)
1500 {
1501         DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1502
1503         init_clnt_srv(&clnt->login, logon_srv, comp_name);
1504
1505         if (clnt_cred != NULL) {
1506                 clnt->ptr_cred = 1;
1507                 memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
1508         } else {
1509                 clnt->ptr_cred = 0;
1510         }
1511 }
1512
1513 /*******************************************************************
1514  Reads or writes a DOM_CLNT_INFO2 structure.
1515 ********************************************************************/
1516
1517 BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1518 {
1519         if (clnt == NULL)
1520                 return False;
1521
1522         prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1523         depth++;
1524
1525         if(!prs_align(ps))
1526                 return False;
1527         
1528         if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1529                 return False;
1530
1531         if(!prs_align(ps))
1532                 return False;
1533         
1534         if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1535                 return False;
1536         if(!smb_io_cred("", &clnt->cred, ps, depth))
1537                 return False;
1538
1539         return True;
1540 }
1541
1542 /*******************************************************************
1543  Inits a DOM_CLNT_INFO structure.
1544 ********************************************************************/
1545
1546 void init_clnt_info(DOM_CLNT_INFO *clnt,
1547                 const char *logon_srv, const char *acct_name,
1548                 uint16 sec_chan, const char *comp_name,
1549                 const DOM_CRED *cred)
1550 {
1551         DEBUG(5,("make_clnt_info\n"));
1552
1553         init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1554         memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1555 }
1556
1557 /*******************************************************************
1558  Reads or writes a DOM_CLNT_INFO structure.
1559 ********************************************************************/
1560
1561 BOOL smb_io_clnt_info(const char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1562 {
1563         if (clnt == NULL)
1564                 return False;
1565
1566         prs_debug(ps, depth, desc, "smb_io_clnt_info");
1567         depth++;
1568
1569         if(!prs_align(ps))
1570                 return False;
1571         
1572         if(!smb_io_log_info("", &clnt->login, ps, depth))
1573                 return False;
1574         if(!smb_io_cred("", &clnt->cred, ps, depth))
1575                 return False;
1576
1577         return True;
1578 }
1579
1580 /*******************************************************************
1581  Inits a DOM_LOGON_ID structure.
1582 ********************************************************************/
1583
1584 void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
1585 {
1586         DEBUG(5,("make_logon_id: %d\n", __LINE__));
1587
1588         logonid->low  = log_id_low;
1589         logonid->high = log_id_high;
1590 }
1591
1592 /*******************************************************************
1593  Reads or writes a DOM_LOGON_ID structure.
1594 ********************************************************************/
1595
1596 BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
1597 {
1598         if (logonid == NULL)
1599                 return False;
1600
1601         prs_debug(ps, depth, desc, "smb_io_logon_id");
1602         depth++;
1603
1604         if(!prs_align(ps))
1605                 return False;
1606         
1607         if(!prs_uint32("low ", ps, depth, &logonid->low ))
1608                 return False;
1609         if(!prs_uint32("high", ps, depth, &logonid->high))
1610                 return False;
1611
1612         return True;
1613 }
1614
1615 /*******************************************************************
1616  Inits an OWF_INFO structure.
1617 ********************************************************************/
1618
1619 void init_owf_info(OWF_INFO *hash, const uint8 data[16])
1620 {
1621         DEBUG(5,("init_owf_info: %d\n", __LINE__));
1622         
1623         if (data != NULL)
1624                 memcpy(hash->data, data, sizeof(hash->data));
1625         else
1626                 memset((char *)hash->data, '\0', sizeof(hash->data));
1627 }
1628
1629 /*******************************************************************
1630  Reads or writes an OWF_INFO structure.
1631 ********************************************************************/
1632
1633 BOOL smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1634 {
1635         if (hash == NULL)
1636                 return False;
1637
1638         prs_debug(ps, depth, desc, "smb_io_owf_info");
1639         depth++;
1640
1641         if(!prs_align(ps))
1642                 return False;
1643         
1644         if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1645                 return False;
1646
1647         return True;
1648 }
1649
1650 /*******************************************************************
1651  Reads or writes a DOM_GID structure.
1652 ********************************************************************/
1653
1654 BOOL smb_io_gid(const char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
1655 {
1656         if (gid == NULL)
1657                 return False;
1658
1659         prs_debug(ps, depth, desc, "smb_io_gid");
1660         depth++;
1661
1662         if(!prs_align(ps))
1663                 return False;
1664         
1665         if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1666                 return False;
1667         if(!prs_uint32("attr ", ps, depth, &gid->attr))
1668                 return False;
1669
1670         return True;
1671 }
1672
1673 /*******************************************************************
1674  Reads or writes an POLICY_HND structure.
1675 ********************************************************************/
1676
1677 BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1678 {
1679         if (pol == NULL)
1680                 return False;
1681
1682         prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1683         depth++;
1684
1685         if(!prs_align(ps))
1686                 return False;
1687
1688         if(UNMARSHALLING(ps))
1689                 ZERO_STRUCTP(pol);
1690         
1691         if (!prs_uint32("data1", ps, depth, &pol->data1))
1692                 return False;
1693         if (!prs_uint32("data2", ps, depth, &pol->data2))
1694                 return False;
1695         if (!prs_uint16("data3", ps, depth, &pol->data3))
1696                 return False;
1697         if (!prs_uint16("data4", ps, depth, &pol->data4))
1698                 return False;
1699         if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1700                 return False;
1701
1702         return True;
1703 }
1704
1705 /*******************************************************************
1706  Create a UNISTR3.
1707 ********************************************************************/
1708
1709 void init_unistr3(UNISTR3 *str, const char *buf)
1710 {
1711         if (buf == NULL) {
1712                 str->uni_str_len=0;
1713                 str->str.buffer = NULL;
1714                 return;
1715         }
1716
1717         str->uni_str_len = strlen(buf) + 1;
1718
1719         str->str.buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_str_len);
1720         if (str->str.buffer == NULL)
1721                 smb_panic("init_unistr3: malloc fail\n");
1722
1723         rpcstr_push((char *)str->str.buffer, buf, str->uni_str_len * sizeof(uint16), STR_TERMINATE);
1724 }
1725
1726 /*******************************************************************
1727  Reads or writes a UNISTR3 structure.
1728 ********************************************************************/
1729
1730 BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1731 {
1732         if (name == NULL)
1733                 return False;
1734
1735         prs_debug(ps, depth, desc, "smb_io_unistr3");
1736         depth++;
1737
1738         if(!prs_align(ps))
1739                 return False;
1740         
1741         if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1742                 return False;
1743                 
1744         /* we're done if there is no string */
1745         
1746         if ( name->uni_str_len == 0 )
1747                 return True;
1748
1749         /* don't know if len is specified by uni_str_len member... */
1750         /* assume unicode string is unicode-null-terminated, instead */
1751
1752         if(!prs_unistr3(True, "unistr", name, ps, depth))
1753                 return False;
1754
1755         return True;
1756 }
1757
1758 /*******************************************************************
1759  Stream a uint64_struct
1760  ********************************************************************/
1761 BOOL prs_uint64(const char *name, prs_struct *ps, int depth, UINT64_S *data64)
1762 {
1763         return prs_uint32(name, ps, depth+1, &data64->low) &&
1764                 prs_uint32(name, ps, depth+1, &data64->high);
1765 }
1766
1767 /*******************************************************************
1768 reads or writes a BUFHDR2 structure.
1769 ********************************************************************/
1770 BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
1771 {
1772         prs_debug(ps, depth, desc, "smb_io_bufhdr2");
1773         depth++;
1774
1775         prs_align(ps);
1776         prs_uint32("info_level", ps, depth, &(hdr->info_level));
1777         prs_uint32("length    ", ps, depth, &(hdr->length    ));
1778         prs_uint32("buffer    ", ps, depth, &(hdr->buffer    ));
1779
1780         return True;
1781 }
1782
1783 /*******************************************************************
1784 reads or writes a BUFHDR4 structure.
1785 ********************************************************************/
1786 BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
1787 {
1788         prs_debug(ps, depth, desc, "smb_io_bufhdr4");
1789         depth++;
1790
1791         prs_align(ps);
1792         prs_uint32("size", ps, depth, &hdr->size);
1793         prs_uint32("buffer", ps, depth, &hdr->buffer);
1794
1795         return True;
1796 }
1797
1798 /*******************************************************************
1799 reads or writes a RPC_DATA_BLOB structure.
1800 ********************************************************************/
1801
1802 BOOL smb_io_rpc_blob(const char *desc, RPC_DATA_BLOB *blob, prs_struct *ps, int depth)
1803 {
1804         prs_debug(ps, depth, desc, "smb_io_rpc_blob");
1805         depth++;
1806
1807         prs_align(ps);
1808         if ( !prs_uint32("buf_len", ps, depth, &blob->buf_len) )
1809                 return False;
1810
1811         if ( blob->buf_len == 0 )
1812                 return True;
1813
1814         if (UNMARSHALLING(ps)) {
1815                 blob->buffer = PRS_ALLOC_MEM(ps, uint8, blob->buf_len);
1816                 if (!blob->buffer) {
1817                         return False;
1818                 }
1819         }
1820
1821         if ( !prs_uint8s(True, "buffer", ps, depth, blob->buffer, blob->buf_len) )
1822                 return False;
1823
1824         return True;
1825 }
1826
1827 /*******************************************************************
1828 creates a UNIHDR structure.
1829 ********************************************************************/
1830
1831 BOOL make_uni_hdr(UNIHDR *hdr, int len)
1832 {
1833         if (hdr == NULL)
1834         {
1835                 return False;
1836         }
1837         hdr->uni_str_len = 2 * len;
1838         hdr->uni_max_len = 2 * len;
1839         hdr->buffer      = len != 0 ? 1 : 0;
1840
1841         return True;
1842 }
1843
1844 /*******************************************************************
1845 creates a BUFHDR2 structure.
1846 ********************************************************************/
1847 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
1848 {
1849         hdr->info_level = info_level;
1850         hdr->length     = length;
1851         hdr->buffer     = buffer;
1852
1853         return True;
1854 }
1855
1856 /*******************************************************************
1857 return the length of a UNISTR string.
1858 ********************************************************************/  
1859
1860 uint32 str_len_uni(UNISTR *source)
1861 {
1862         uint32 i=0;
1863
1864         if (!source->buffer)
1865                 return 0;
1866
1867         while (source->buffer[i])
1868                 i++;
1869
1870         return i;
1871 }
1872
1873