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