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