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