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