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