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