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