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