c6f05df0c479b3b845acbaa5ca7d02d9b5581850
[abartlet/samba.git/.git] / source3 / rpc_parse / parse_misc.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  
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
556         len = strlen(buf) + 1;
557
558         if (len < MAX_UNISTRLEN)
559                 len = MAX_UNISTRLEN;
560         len *= sizeof(uint16);
561
562         str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
563         if (str->buffer == NULL)
564                 smb_panic("init_unistr: malloc fail\n");
565
566         rpcstr_push(str->buffer, buf, len, STR_TERMINATE);
567 }
568
569 /*******************************************************************
570 reads or writes a UNISTR structure.
571 XXXX NOTE: UNISTR structures NEED to be null-terminated.
572 ********************************************************************/
573
574 BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
575 {
576         if (uni == NULL)
577                 return False;
578
579         prs_debug(ps, depth, desc, "smb_io_unistr");
580         depth++;
581
582         if(!prs_unistr("unistr", ps, depth, uni))
583                 return False;
584
585         return True;
586 }
587
588 /*******************************************************************
589  Allocate the BUFFER3 memory.
590 ********************************************************************/
591
592 static void create_buffer3(BUFFER3 *str, size_t len)
593 {
594         if (len < MAX_BUFFERLEN)
595                 len = MAX_BUFFERLEN;
596
597     str->buffer = talloc_zero(get_talloc_ctx(), len);
598         if (str->buffer == NULL)
599                 smb_panic("create_buffer3: talloc fail\n");
600
601 }
602
603 /*******************************************************************
604  Inits a BUFFER3 structure from a uint32
605 ********************************************************************/
606
607 void init_buffer3_uint32(BUFFER3 *str, uint32 val)
608 {
609         ZERO_STRUCTP(str);
610
611         /* set up string lengths. */
612         str->buf_max_len = sizeof(uint32);
613         str->buf_len     = sizeof(uint32);
614
615         create_buffer3(str, sizeof(uint32));
616         SIVAL(str->buffer, 0, val);
617 }
618
619 /*******************************************************************
620  Inits a BUFFER3 structure.
621 ********************************************************************/
622
623 void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
624 {
625         ZERO_STRUCTP(str);
626
627         /* set up string lengths. */
628         str->buf_max_len = len * 2;
629         str->buf_len = len * 2;
630
631         create_buffer3(str, str->buf_max_len);
632
633         rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
634         
635 }
636
637 /*******************************************************************
638  Inits a BUFFER3 structure from a hex string.
639 ********************************************************************/
640
641 void init_buffer3_hex(BUFFER3 *str, const char *buf)
642 {
643         ZERO_STRUCTP(str);
644         create_buffer3(str, strlen(buf));
645         str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
646 }
647
648 /*******************************************************************
649  Inits a BUFFER3 structure.
650 ********************************************************************/
651
652 void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
653 {
654         ZERO_STRUCTP(str);
655
656         /* max buffer size (allocated size) */
657         str->buf_max_len = len;
658         if (buf != NULL) {
659                 create_buffer3(str, len);
660                 memcpy(str->buffer, buf, len);
661         }
662         str->buf_len = buf != NULL ? len : 0;
663 }
664
665 /*******************************************************************
666  Reads or writes a BUFFER3 structure.
667    the uni_max_len member tells you how large the buffer is.
668    the uni_str_len member tells you how much of the buffer is really used.
669 ********************************************************************/
670
671 BOOL smb_io_buffer3(const char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
672 {
673         if (buf3 == NULL)
674                 return False;
675
676         prs_debug(ps, depth, desc, "smb_io_buffer3");
677         depth++;
678
679         if(!prs_align(ps))
680                 return False;
681         
682         if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
683                 return False;
684
685         if (UNMARSHALLING(ps)) {
686                 buf3->buffer = (unsigned char *)prs_alloc_mem(ps, buf3->buf_max_len);
687                 if (buf3->buffer == NULL)
688                         return False;
689         }
690
691         if(!prs_uint8s(True, "buffer     ", ps, depth, buf3->buffer, buf3->buf_max_len))
692                 return False;
693
694         if(!prs_uint32("buf_len    ", ps, depth, &buf3->buf_len))
695                 return False;
696
697         return True;
698 }
699
700 /*******************************************************************
701 reads or writes a BUFFER5 structure.
702 the buf_len member tells you how large the buffer is.
703 ********************************************************************/
704 BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
705 {
706         prs_debug(ps, depth, desc, "smb_io_buffer5");
707         depth++;
708
709         if (buf5 == NULL) return False;
710
711         if(!prs_align(ps))
712                 return False;
713         if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len))
714                 return False;
715
716         if(buf5->buf_len) {
717                 if(!prs_buffer5(True, "buffer" , ps, depth, buf5))
718                         return False;
719         }
720
721         return True;
722 }
723
724 /*******************************************************************
725  Inits a BUFFER2 structure.
726 ********************************************************************/
727
728 void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
729 {
730         ZERO_STRUCTP(str);
731
732         /* max buffer size (allocated size) */
733         str->buf_max_len = len;
734         str->offset = 0;
735         str->buf_len = buf != NULL ? len : 0;
736
737         if (buf != NULL) {
738                 if (len < MAX_BUFFERLEN)
739                         len = MAX_BUFFERLEN;
740                 str->buffer = talloc_zero(get_talloc_ctx(), len);
741                 if (str->buffer == NULL)
742                         smb_panic("init_buffer2: talloc fail\n");
743                 memcpy(str->buffer, buf, MIN(str->buf_len, len));
744         }
745 }
746
747 /*******************************************************************
748  Reads or writes a BUFFER2 structure.
749    the uni_max_len member tells you how large the buffer is.
750    the uni_str_len member tells you how much of the buffer is really used.
751 ********************************************************************/
752
753 BOOL smb_io_buffer2(const char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
754 {
755         if (buf2 == NULL)
756                 return False;
757
758         if (buffer) {
759
760                 prs_debug(ps, depth, desc, "smb_io_buffer2");
761                 depth++;
762
763                 if(!prs_align(ps))
764                         return False;
765                 
766                 if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
767                         return False;
768                 if(!prs_uint32("offset     ", ps, depth, &buf2->offset))
769                         return False;
770                 if(!prs_uint32("buf_len    ", ps, depth, &buf2->buf_len))
771                         return False;
772
773                 /* buffer advanced by indicated length of string
774                    NOT by searching for null-termination */
775
776                 if(!prs_buffer2(True, "buffer     ", ps, depth, buf2))
777                         return False;
778
779         } else {
780
781                 prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
782                 depth++;
783                 memset((char *)buf2, '\0', sizeof(*buf2));
784
785         }
786         return True;
787 }
788
789 /*******************************************************************
790 creates a UNISTR2 structure: sets up the buffer, too
791 ********************************************************************/
792
793 void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
794 {
795         if (buf != NULL) {
796                 *ptr = 1;
797                 init_unistr2(str, buf, UNI_STR_TERMINATE);
798         } else {
799                 *ptr = 0;
800                 init_unistr2(str, NULL, UNI_FLAGS_NONE);
801
802         }
803 }
804
805 /*******************************************************************
806  Copies a UNISTR2 structure.
807 ********************************************************************/
808
809 void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
810 {
811         str->uni_max_len = from->uni_max_len;
812         str->offset      = from->offset;
813         str->uni_str_len = from->uni_str_len;
814
815         if (from->buffer == NULL)
816                 return;
817                 
818         /* the string buffer is allocated to the maximum size
819            (the the length of the source string) to prevent
820            reallocation of memory. */
821         if (str->buffer == NULL) {
822                 size_t len = from->uni_max_len * sizeof(uint16);
823
824                 if (len < MAX_UNISTRLEN)
825                         len = MAX_UNISTRLEN;
826                 len *= sizeof(uint16);
827
828                 str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
829                 if ((str->buffer == NULL) && (len > 0 )) {
830                         smb_panic("copy_unistr2: talloc fail\n");
831                         return;
832                 }
833         }
834
835         /* copy the string */
836         memcpy(str->buffer, from->buffer, from->uni_max_len*sizeof(uint16));
837 }
838
839 /*******************************************************************
840  Creates a STRING2 structure.
841 ********************************************************************/
842
843 void init_string2(STRING2 *str, const char *buf, int max_len, int str_len)
844 {
845         int alloc_len = 0;
846
847         /* set up string lengths. */
848         str->str_max_len = max_len;
849         str->offset = 0;
850         str->str_str_len = str_len;
851
852         /* store the string */
853         if(str_len != 0) {
854                 if (str_len < MAX_STRINGLEN)
855                         alloc_len = MAX_STRINGLEN;
856                 str->buffer = talloc_zero(get_talloc_ctx(), alloc_len);
857                 if (str->buffer == NULL)
858                         smb_panic("init_string2: malloc fail\n");
859                 memcpy(str->buffer, buf, str_len);
860         }
861 }
862
863 /*******************************************************************
864  Reads or writes a STRING2 structure.
865  XXXX NOTE: STRING2 structures need NOT be null-terminated.
866    the str_str_len member tells you how long the string is;
867    the str_max_len member tells you how large the buffer is.
868 ********************************************************************/
869
870 BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
871 {
872         if (str2 == NULL)
873                 return False;
874
875         if (buffer) {
876
877                 prs_debug(ps, depth, desc, "smb_io_string2");
878                 depth++;
879
880                 if(!prs_align(ps))
881                         return False;
882                 
883                 if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
884                         return False;
885                 if(!prs_uint32("offset     ", ps, depth, &str2->offset))
886                         return False;
887                 if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
888                         return False;
889
890                 /* buffer advanced by indicated length of string
891                    NOT by searching for null-termination */
892                 if(!prs_string2(True, "buffer     ", ps, depth, str2))
893                         return False;
894
895         } else {
896
897                 prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
898                 depth++;
899                 memset((char *)str2, '\0', sizeof(*str2));
900
901         }
902
903         return True;
904 }
905
906 /*******************************************************************
907  Inits a UNISTR2 structure.
908 ********************************************************************/
909
910 void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
911 {
912         size_t len = 0;
913         uint32 num_chars = 0;
914
915         if (buf) {
916                 /* We always null terminate the copy. */
917                 len = strlen(buf) + 1;
918         }
919
920         if (len < MAX_UNISTRLEN)
921                 len = MAX_UNISTRLEN;
922         len *= sizeof(uint16);
923
924         str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
925         if ((str->buffer == NULL) && (len > 0)) {
926                 smb_panic("init_unistr2: malloc fail\n");
927                 return;
928         }
929
930         /*
931          * The UNISTR2 must be initialized !!!
932          * jfm, 7/7/2001.
933          */
934         if (buf) {
935                 rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
936                 num_chars = strlen_w(str->buffer);
937                 if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
938                         num_chars++;
939                 }
940         }
941
942         str->uni_max_len = num_chars;
943         str->offset = 0;
944         str->uni_str_len = num_chars;
945         if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) )
946                 str->uni_max_len++;
947 }
948
949 /** 
950  *  Inits a UNISTR2 structure.
951  *  @param  ctx talloc context to allocate string on
952  *  @param  str pointer to string to create
953  *  @param  buf UCS2 null-terminated buffer to init from
954 */
955
956 void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
957 {
958         uint32 len = strlen_w(buf);
959         uint32 max_len = len;
960         uint32 alloc_len;
961
962         ZERO_STRUCTP(str);
963
964         /* set up string lengths. */
965         str->uni_max_len = len;
966         str->offset = 0;
967         str->uni_str_len = len;
968
969         if (max_len < MAX_UNISTRLEN)
970                 max_len = MAX_UNISTRLEN;
971
972         alloc_len = (max_len + 1) * sizeof(uint16);
973
974         str->buffer = (uint16 *)talloc_zero(ctx, alloc_len);
975         if ((str->buffer == NULL) && (alloc_len > 0)) {
976                 smb_panic("init_unistr2_w: malloc fail\n");
977                 return;
978         }
979         
980         /*
981          * don't move this test above ! The UNISTR2 must be initialized !!!
982          * jfm, 7/7/2001.
983          */
984         if (buf==NULL)
985                 return;
986         
987         /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
988            long as the buffer above is talloc()ed correctly then this
989            is the correct thing to do */
990         strncpy_w(str->buffer, buf, len + 1);
991 }
992
993 /*******************************************************************
994  Inits a UNISTR2 structure from a UNISTR
995 ********************************************************************/
996
997 void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
998 {
999         uint32 i;
1000
1001         /* the destination UNISTR2 should never be NULL.
1002            if it is it is a programming error */
1003
1004         /* if the source UNISTR is NULL, then zero out
1005            the destination string and return */
1006         ZERO_STRUCTP (to);
1007         if ((from == NULL) || (from->buffer == NULL))
1008                 return;
1009
1010         /* get the length; UNISTR must be NULL terminated */
1011         i = 0;
1012         while ((from->buffer)[i]!='\0')
1013                 i++;
1014         i++;    /* one more to catch the terminating NULL */
1015                 /* is this necessary -- jerry?  I need to think */
1016
1017         /* set up string lengths; uni_max_len is set to i+1
1018            because we need to account for the final NULL termination */
1019         to->uni_max_len = i;
1020         to->offset = 0;
1021         to->uni_str_len = i;
1022
1023         /* allocate the space and copy the string buffer */
1024         to->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), sizeof(uint16)*(to->uni_str_len));
1025         if (to->buffer == NULL)
1026                 smb_panic("init_unistr2_from_unistr: malloc fail\n");
1027         memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
1028         return;
1029 }
1030
1031 /*******************************************************************
1032   Inits a UNISTR2 structure from a DATA_BLOB.
1033   The length of the data_blob must count the bytes of the buffer.
1034   Copies the blob data.
1035 ********************************************************************/
1036
1037 void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) 
1038 {
1039         /* Allocs the unistring */
1040         init_unistr2(str, NULL, UNI_FLAGS_NONE);
1041         
1042         /* Sets the values */
1043         str->uni_str_len = blob->length / sizeof(uint16);
1044         str->uni_max_len = str->uni_str_len;
1045         str->offset = 0;
1046         if (blob->length) {
1047                 str->buffer = (uint16 *) memdup(blob->data, blob->length);
1048         } else {
1049                 str->buffer = NULL;
1050         }
1051         if ((str->buffer == NULL) && (blob->length > 0)) {
1052                 smb_panic("init_unistr2_from_datablob: malloc fail\n");
1053         }
1054 }
1055
1056 /*******************************************************************
1057  Reads or writes a UNISTR2 structure.
1058  XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
1059    the uni_str_len member tells you how long the string is;
1060    the uni_max_len member tells you how large the buffer is.
1061 ********************************************************************/
1062
1063 BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
1064 {
1065         if (uni2 == NULL)
1066                 return False;
1067
1068         if (buffer) {
1069
1070                 prs_debug(ps, depth, desc, "smb_io_unistr2");
1071                 depth++;
1072
1073                 if(!prs_align(ps))
1074                         return False;
1075                 
1076                 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
1077                         return False;
1078                 if(!prs_uint32("offset     ", ps, depth, &uni2->offset))
1079                         return False;
1080                 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
1081                         return False;
1082
1083                 /* buffer advanced by indicated length of string
1084                    NOT by searching for null-termination */
1085                 if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
1086                         return False;
1087
1088         } else {
1089
1090                 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
1091                 depth++;
1092                 memset((char *)uni2, '\0', sizeof(*uni2));
1093
1094         }
1095
1096         return True;
1097 }
1098
1099
1100 /*
1101   initialise a UNISTR_ARRAY from a char**
1102 */
1103 BOOL init_unistr2_array(UNISTR2_ARRAY *array, 
1104                        uint32 count, const char **strings)
1105 {
1106         unsigned int i;
1107
1108         array->count = count;
1109         array->ref_id = count?1:0;
1110         if (array->count == 0) {
1111                 return True;
1112         }
1113
1114         array->strings = (UNISTR2_ARRAY_EL *)talloc_zero(get_talloc_ctx(), count * sizeof(UNISTR2_ARRAY_EL));
1115         if (!array->strings) {
1116                 return False;
1117         }
1118
1119         for (i=0;i<count;i++) {
1120                 init_unistr2(&array->strings[i].string, strings[i], UNI_FLAGS_NONE);
1121                 array->strings[i].size = array->strings[i].string.uni_max_len*2;
1122                 array->strings[i].length = array->strings[i].size;
1123                 array->strings[i].ref_id = 1;
1124         }
1125
1126         return True;
1127 }
1128
1129 /*******************************************************************
1130  Reads or writes a UNISTR2_ARRAY structure.
1131 ********************************************************************/
1132 BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps, int depth)
1133 {
1134         unsigned int i;
1135
1136         prs_debug(ps, depth, desc, "smb_io_unistr2_array");
1137         depth++;
1138
1139         if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
1140                 return False;
1141
1142         if (! array->ref_id) {
1143                 return True;
1144         }
1145
1146         if(!prs_uint32("count", ps, depth, &array->count))
1147                 return False;
1148
1149         if (array->count == 0) {
1150                 return True;
1151         }
1152
1153         if (UNMARSHALLING(ps)) {
1154                 array->strings = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->strings[0]));
1155         }
1156         if (! array->strings) {
1157                 return False;
1158         }
1159
1160         for (i=0;i<array->count;i++) {
1161                 if(!prs_uint16("length", ps, depth, &array->strings[i].length))
1162                         return False;
1163                 if(!prs_uint16("size", ps, depth, &array->strings[i].size))
1164                         return False;
1165                 if(!prs_uint32("ref_id", ps, depth, &array->strings[i].ref_id))
1166                         return False;
1167         }
1168
1169         for (i=0;i<array->count;i++) {
1170                 if (! smb_io_unistr2("string", &array->strings[i].string, array->strings[i].ref_id, ps, depth)) 
1171                         return False;
1172         }
1173         
1174         return True;
1175 }
1176
1177
1178 /*******************************************************************
1179  Inits a DOM_RID2 structure.
1180 ********************************************************************/
1181
1182 void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
1183 {
1184         rid2->type    = type;
1185         rid2->rid     = rid;
1186         rid2->rid_idx = idx;
1187 }
1188
1189 /*******************************************************************
1190  Reads or writes a DOM_RID2 structure.
1191 ********************************************************************/
1192
1193 BOOL smb_io_dom_rid2(const char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
1194 {
1195         if (rid2 == NULL)
1196                 return False;
1197
1198         prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1199         depth++;
1200
1201         if(!prs_align(ps))
1202                 return False;
1203    
1204         if(!prs_uint8("type   ", ps, depth, &rid2->type))
1205                 return False;
1206         if(!prs_align(ps))
1207                 return False;
1208         if(!prs_uint32("rid    ", ps, depth, &rid2->rid))
1209                 return False;
1210         if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
1211                 return False;
1212
1213         return True;
1214 }
1215
1216 /*******************************************************************
1217 creates a DOM_RID3 structure.
1218 ********************************************************************/
1219
1220 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1221 {
1222     rid3->rid      = rid;
1223     rid3->type1    = type;
1224     rid3->ptr_type = 0x1; /* non-zero, basically. */
1225     rid3->type2    = 0x1;
1226     rid3->unk      = type;
1227 }
1228
1229 /*******************************************************************
1230 reads or writes a DOM_RID3 structure.
1231 ********************************************************************/
1232
1233 BOOL smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1234 {
1235         if (rid3 == NULL)
1236                 return False;
1237
1238         prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1239         depth++;
1240
1241         if(!prs_align(ps))
1242                 return False;
1243
1244         if(!prs_uint32("rid     ", ps, depth, &rid3->rid))
1245                 return False;
1246         if(!prs_uint32("type1   ", ps, depth, &rid3->type1))
1247                 return False;
1248         if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1249                 return False;
1250         if(!prs_uint32("type2   ", ps, depth, &rid3->type2))
1251                 return False;
1252         if(!prs_uint32("unk     ", ps, depth, &rid3->unk))
1253                 return False;
1254
1255         return True;
1256 }
1257
1258 /*******************************************************************
1259  Inits a DOM_RID4 structure.
1260 ********************************************************************/
1261
1262 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1263 {
1264     rid4->unknown = unknown;
1265     rid4->attr    = attr;
1266     rid4->rid     = rid;
1267 }
1268
1269 /*******************************************************************
1270  Inits a DOM_CLNT_SRV structure.
1271 ********************************************************************/
1272
1273 static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name)
1274 {
1275         DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1276
1277         if (logon_srv != NULL) {
1278                 logcln->undoc_buffer = 1;
1279                 init_unistr2(&logcln->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1280         } else {
1281                 logcln->undoc_buffer = 0;
1282         }
1283
1284         if (comp_name != NULL) {
1285                 logcln->undoc_buffer2 = 1;
1286                 init_unistr2(&logcln->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1287         } else {
1288                 logcln->undoc_buffer2 = 0;
1289         }
1290 }
1291
1292 /*******************************************************************
1293  Inits or writes a DOM_CLNT_SRV structure.
1294 ********************************************************************/
1295
1296 static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
1297 {
1298         if (logcln == NULL)
1299                 return False;
1300
1301         prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1302         depth++;
1303
1304         if(!prs_align(ps))
1305                 return False;
1306         
1307         if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
1308                 return False;
1309
1310         if (logcln->undoc_buffer != 0) {
1311                 if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
1312                         return False;
1313         }
1314
1315         if(!prs_align(ps))
1316                 return False;
1317
1318         if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
1319                 return False;
1320
1321         if (logcln->undoc_buffer2 != 0) {
1322                 if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
1323                         return False;
1324         }
1325
1326         return True;
1327 }
1328
1329 /*******************************************************************
1330  Inits a DOM_LOG_INFO structure.
1331 ********************************************************************/
1332
1333 void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
1334                 uint16 sec_chan, const char *comp_name)
1335 {
1336         DEBUG(5,("make_log_info %d\n", __LINE__));
1337
1338         loginfo->undoc_buffer = 1;
1339
1340         init_unistr2(&loginfo->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1341         init_unistr2(&loginfo->uni_acct_name, acct_name, UNI_STR_TERMINATE);
1342
1343         loginfo->sec_chan = sec_chan;
1344
1345         init_unistr2(&loginfo->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1346 }
1347
1348 /*******************************************************************
1349  Reads or writes a DOM_LOG_INFO structure.
1350 ********************************************************************/
1351
1352 BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
1353 {
1354         if (loginfo == NULL)
1355                 return False;
1356
1357         prs_debug(ps, depth, desc, "smb_io_log_info");
1358         depth++;
1359
1360         if(!prs_align(ps))
1361                 return False;
1362         
1363         if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
1364                 return False;
1365
1366         if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
1367                 return False;
1368         if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
1369                 return False;
1370
1371         if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
1372                 return False;
1373
1374         if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
1375                 return False;
1376
1377         return True;
1378 }
1379
1380 /*******************************************************************
1381  Reads or writes a DOM_CHAL structure.
1382 ********************************************************************/
1383
1384 BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1385 {
1386         if (chal == NULL)
1387                 return False;
1388
1389         prs_debug(ps, depth, desc, "smb_io_chal");
1390         depth++;
1391         
1392         if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1393                 return False;
1394
1395         return True;
1396 }
1397
1398 /*******************************************************************
1399  Reads or writes a DOM_CRED structure.
1400 ********************************************************************/
1401
1402 BOOL smb_io_cred(const char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
1403 {
1404         if (cred == NULL)
1405                 return False;
1406
1407         prs_debug(ps, depth, desc, "smb_io_cred");
1408         depth++;
1409
1410         if(!prs_align(ps))
1411                 return False;
1412
1413         if(!smb_io_chal ("", &cred->challenge, ps, depth))
1414                 return False;
1415
1416         if(!smb_io_utime("", &cred->timestamp, ps, depth))
1417                 return False;
1418
1419         return True;
1420 }
1421
1422 /*******************************************************************
1423  Inits a DOM_CLNT_INFO2 structure.
1424 ********************************************************************/
1425
1426 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1427                                 const char *logon_srv, const char *comp_name,
1428                                 const DOM_CRED *clnt_cred)
1429 {
1430         DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1431
1432         init_clnt_srv(&clnt->login, logon_srv, comp_name);
1433
1434         if (clnt_cred != NULL) {
1435                 clnt->ptr_cred = 1;
1436                 memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
1437         } else {
1438                 clnt->ptr_cred = 0;
1439         }
1440 }
1441
1442 /*******************************************************************
1443  Reads or writes a DOM_CLNT_INFO2 structure.
1444 ********************************************************************/
1445
1446 BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1447 {
1448         if (clnt == NULL)
1449                 return False;
1450
1451         prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1452         depth++;
1453
1454         if(!prs_align(ps))
1455                 return False;
1456         
1457         if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1458                 return False;
1459
1460         if(!prs_align(ps))
1461                 return False;
1462         
1463         if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1464                 return False;
1465         if(!smb_io_cred("", &clnt->cred, ps, depth))
1466                 return False;
1467
1468         return True;
1469 }
1470
1471 /*******************************************************************
1472  Inits a DOM_CLNT_INFO structure.
1473 ********************************************************************/
1474
1475 void init_clnt_info(DOM_CLNT_INFO *clnt,
1476                 const char *logon_srv, const char *acct_name,
1477                 uint16 sec_chan, const char *comp_name,
1478                 const DOM_CRED *cred)
1479 {
1480         DEBUG(5,("make_clnt_info\n"));
1481
1482         init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1483         memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1484 }
1485
1486 /*******************************************************************
1487  Reads or writes a DOM_CLNT_INFO structure.
1488 ********************************************************************/
1489
1490 BOOL smb_io_clnt_info(const char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1491 {
1492         if (clnt == NULL)
1493                 return False;
1494
1495         prs_debug(ps, depth, desc, "smb_io_clnt_info");
1496         depth++;
1497
1498         if(!prs_align(ps))
1499                 return False;
1500         
1501         if(!smb_io_log_info("", &clnt->login, ps, depth))
1502                 return False;
1503         if(!smb_io_cred("", &clnt->cred, ps, depth))
1504                 return False;
1505
1506         return True;
1507 }
1508
1509 /*******************************************************************
1510  Inits a DOM_LOGON_ID structure.
1511 ********************************************************************/
1512
1513 void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
1514 {
1515         DEBUG(5,("make_logon_id: %d\n", __LINE__));
1516
1517         logonid->low  = log_id_low;
1518         logonid->high = log_id_high;
1519 }
1520
1521 /*******************************************************************
1522  Reads or writes a DOM_LOGON_ID structure.
1523 ********************************************************************/
1524
1525 BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
1526 {
1527         if (logonid == NULL)
1528                 return False;
1529
1530         prs_debug(ps, depth, desc, "smb_io_logon_id");
1531         depth++;
1532
1533         if(!prs_align(ps))
1534                 return False;
1535         
1536         if(!prs_uint32("low ", ps, depth, &logonid->low ))
1537                 return False;
1538         if(!prs_uint32("high", ps, depth, &logonid->high))
1539                 return False;
1540
1541         return True;
1542 }
1543
1544 /*******************************************************************
1545  Inits an OWF_INFO structure.
1546 ********************************************************************/
1547
1548 void init_owf_info(OWF_INFO *hash, const uint8 data[16])
1549 {
1550         DEBUG(5,("init_owf_info: %d\n", __LINE__));
1551         
1552         if (data != NULL)
1553                 memcpy(hash->data, data, sizeof(hash->data));
1554         else
1555                 memset((char *)hash->data, '\0', sizeof(hash->data));
1556 }
1557
1558 /*******************************************************************
1559  Reads or writes an OWF_INFO structure.
1560 ********************************************************************/
1561
1562 BOOL smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1563 {
1564         if (hash == NULL)
1565                 return False;
1566
1567         prs_debug(ps, depth, desc, "smb_io_owf_info");
1568         depth++;
1569
1570         if(!prs_align(ps))
1571                 return False;
1572         
1573         if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1574                 return False;
1575
1576         return True;
1577 }
1578
1579 /*******************************************************************
1580  Reads or writes a DOM_GID structure.
1581 ********************************************************************/
1582
1583 BOOL smb_io_gid(const char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
1584 {
1585         if (gid == NULL)
1586                 return False;
1587
1588         prs_debug(ps, depth, desc, "smb_io_gid");
1589         depth++;
1590
1591         if(!prs_align(ps))
1592                 return False;
1593         
1594         if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1595                 return False;
1596         if(!prs_uint32("attr ", ps, depth, &gid->attr))
1597                 return False;
1598
1599         return True;
1600 }
1601
1602 /*******************************************************************
1603  Reads or writes an POLICY_HND structure.
1604 ********************************************************************/
1605
1606 BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1607 {
1608         if (pol == NULL)
1609                 return False;
1610
1611         prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1612         depth++;
1613
1614         if(!prs_align(ps))
1615                 return False;
1616
1617         if(UNMARSHALLING(ps))
1618                 ZERO_STRUCTP(pol);
1619         
1620         if (!prs_uint32("data1", ps, depth, &pol->data1))
1621                 return False;
1622         if (!prs_uint32("data2", ps, depth, &pol->data2))
1623                 return False;
1624         if (!prs_uint16("data3", ps, depth, &pol->data3))
1625                 return False;
1626         if (!prs_uint16("data4", ps, depth, &pol->data4))
1627                 return False;
1628         if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1629                 return False;
1630
1631         return True;
1632 }
1633
1634 /*******************************************************************
1635  Create a UNISTR3.
1636 ********************************************************************/
1637
1638 void init_unistr3(UNISTR3 *str, const char *buf)
1639 {
1640         size_t len;
1641
1642         if (buf == NULL) {
1643                 str->uni_str_len=0;
1644                 str->str.buffer = NULL;
1645                 return;
1646         }
1647
1648         len = strlen(buf) + 1;
1649
1650         str->uni_str_len=len;
1651
1652         if (len < MAX_UNISTRLEN)
1653                 len = MAX_UNISTRLEN;
1654
1655         len *= sizeof(uint16);
1656
1657         str->str.buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
1658         if (str->str.buffer == NULL)
1659                 smb_panic("init_unistr3: malloc fail\n");
1660
1661         rpcstr_push((char *)str->str.buffer, buf, len, STR_TERMINATE);
1662 }
1663
1664 /*******************************************************************
1665  Reads or writes a UNISTR3 structure.
1666 ********************************************************************/
1667
1668 BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1669 {
1670         if (name == NULL)
1671                 return False;
1672
1673         prs_debug(ps, depth, desc, "smb_io_unistr3");
1674         depth++;
1675
1676         if(!prs_align(ps))
1677                 return False;
1678         
1679         if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1680                 return False;
1681
1682         /* don't know if len is specified by uni_str_len member... */
1683         /* assume unicode string is unicode-null-terminated, instead */
1684
1685         if(!prs_unistr3(True, "unistr", name, ps, depth))
1686                 return False;
1687
1688         return True;
1689 }
1690
1691
1692 /*******************************************************************
1693  Stream a uint64_struct
1694  ********************************************************************/
1695 BOOL prs_uint64(const char *name, prs_struct *ps, int depth, UINT64_S *data64)
1696 {
1697         return prs_uint32(name, ps, depth+1, &data64->low) &&
1698                 prs_uint32(name, ps, depth+1, &data64->high);
1699 }
1700
1701 /*******************************************************************
1702 reads or writes a BUFHDR2 structure.
1703 ********************************************************************/
1704 BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
1705 {
1706         prs_debug(ps, depth, desc, "smb_io_bufhdr2");
1707         depth++;
1708
1709         prs_align(ps);
1710         prs_uint32("info_level", ps, depth, &(hdr->info_level));
1711         prs_uint32("length    ", ps, depth, &(hdr->length    ));
1712         prs_uint32("buffer    ", ps, depth, &(hdr->buffer    ));
1713
1714         return True;
1715 }
1716
1717 /*******************************************************************
1718 reads or writes a BUFFER4 structure.
1719 ********************************************************************/
1720 BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
1721 {
1722         prs_debug(ps, depth, desc, "smb_io_buffer4");
1723         depth++;
1724
1725         prs_align(ps);
1726         prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
1727
1728         if (buf4->buf_len > MAX_BUFFERLEN)
1729         {
1730                 buf4->buf_len = MAX_BUFFERLEN;
1731         }
1732
1733         prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
1734
1735         return True;
1736 }
1737
1738 /*******************************************************************
1739 creates a UNIHDR structure.
1740 ********************************************************************/
1741
1742 BOOL make_uni_hdr(UNIHDR *hdr, int len)
1743 {
1744         if (hdr == NULL)
1745         {
1746                 return False;
1747         }
1748         hdr->uni_str_len = 2 * len;
1749         hdr->uni_max_len = 2 * len;
1750         hdr->buffer      = len != 0 ? 1 : 0;
1751
1752         return True;
1753 }
1754
1755 /*******************************************************************
1756 creates a BUFHDR2 structure.
1757 ********************************************************************/
1758 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
1759 {
1760         hdr->info_level = info_level;
1761         hdr->length     = length;
1762         hdr->buffer     = buffer;
1763
1764         return True;
1765 }