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) Jean Fran�ois Micouleau           2002.
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 Reads or writes a structure.
31********************************************************************/
32
33static BOOL net_io_neg_flags(const char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
34{
35	if (neg == NULL)
36		return False;
37
38	prs_debug(ps, depth, desc, "net_io_neg_flags");
39	depth++;
40
41	if(!prs_align(ps))
42		return False;
43
44	if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
45		return False;
46
47	return True;
48}
49
50/*******************************************************************
51 Inits a NETLOGON_INFO_3 structure.
52********************************************************************/
53
54static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
55{
56	info->flags          = flags;
57	info->logon_attempts = logon_attempts;
58	info->reserved_1     = 0x0;
59	info->reserved_2     = 0x0;
60	info->reserved_3     = 0x0;
61	info->reserved_4     = 0x0;
62	info->reserved_5     = 0x0;
63}
64
65/*******************************************************************
66 Reads or writes a NETLOGON_INFO_3 structure.
67********************************************************************/
68
69static BOOL net_io_netinfo_3(const char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
70{
71	if (info == NULL)
72		return False;
73
74	prs_debug(ps, depth, desc, "net_io_netinfo_3");
75	depth++;
76
77	if(!prs_align(ps))
78		return False;
79
80	if(!prs_uint32("flags         ", ps, depth, &info->flags))
81		return False;
82	if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
83		return False;
84	if(!prs_uint32("reserved_1    ", ps, depth, &info->reserved_1))
85		return False;
86	if(!prs_uint32("reserved_2    ", ps, depth, &info->reserved_2))
87		return False;
88	if(!prs_uint32("reserved_3    ", ps, depth, &info->reserved_3))
89		return False;
90	if(!prs_uint32("reserved_4    ", ps, depth, &info->reserved_4))
91		return False;
92	if(!prs_uint32("reserved_5    ", ps, depth, &info->reserved_5))
93		return False;
94
95	return True;
96}
97
98
99/*******************************************************************
100 Inits a NETLOGON_INFO_1 structure.
101********************************************************************/
102
103static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
104{
105	info->flags      = flags;
106	info->pdc_status = pdc_status;
107}
108
109/*******************************************************************
110 Reads or writes a NETLOGON_INFO_1 structure.
111********************************************************************/
112
113static BOOL net_io_netinfo_1(const char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
114{
115	if (info == NULL)
116		return False;
117
118	prs_debug(ps, depth, desc, "net_io_netinfo_1");
119	depth++;
120
121	if(!prs_align(ps))
122		return False;
123
124	if(!prs_uint32("flags     ", ps, depth, &info->flags))
125		return False;
126	if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
127		return False;
128
129	return True;
130}
131
132/*******************************************************************
133 Inits a NETLOGON_INFO_2 structure.
134********************************************************************/
135
136static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
137				uint32 tc_status, const char *trusted_dc_name)
138{
139	info->flags      = flags;
140	info->pdc_status = pdc_status;
141	info->ptr_trusted_dc_name = 1;
142	info->tc_status  = tc_status;
143
144	if (trusted_dc_name != NULL)
145		init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, UNI_STR_TERMINATE);
146	else
147		init_unistr2(&info->uni_trusted_dc_name, "", UNI_STR_TERMINATE);
148}
149
150/*******************************************************************
151 Reads or writes a NETLOGON_INFO_2 structure.
152********************************************************************/
153
154static BOOL net_io_netinfo_2(const char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
155{
156	if (info == NULL)
157		return False;
158
159	prs_debug(ps, depth, desc, "net_io_netinfo_2");
160	depth++;
161
162	if(!prs_align(ps))
163		return False;
164
165	if(!prs_uint32("flags              ", ps, depth, &info->flags))
166		return False;
167	if(!prs_uint32("pdc_status         ", ps, depth, &info->pdc_status))
168		return False;
169	if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
170		return False;
171	if(!prs_uint32("tc_status          ", ps, depth, &info->tc_status))
172		return False;
173
174	if (info->ptr_trusted_dc_name != 0) {
175		if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
176			return False;
177	}
178
179	if(!prs_align(ps))
180		return False;
181
182	return True;
183}
184
185/*******************************************************************
186 Reads or writes an NET_Q_LOGON_CTRL2 structure.
187********************************************************************/
188
189BOOL net_io_q_logon_ctrl2(const char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
190{
191	if (q_l == NULL)
192		return False;
193
194	prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
195	depth++;
196
197	if(!prs_align(ps))
198		return False;
199
200	if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
201		return False;
202
203	if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
204		return False;
205
206	if(!prs_align(ps))
207		return False;
208
209	if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
210		return False;
211	if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
212		return False;
213	if(!prs_uint32("switch_value ", ps, depth, &q_l->switch_value))
214		return False;
215
216	return True;
217}
218
219/*******************************************************************
220 Inits an NET_Q_LOGON_CTRL2 structure.
221********************************************************************/
222
223void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, const char *srv_name,
224			    uint32 query_level)
225{
226	DEBUG(5,("init_q_logon_ctrl2\n"));
227
228	q_l->function_code = 0x01;
229	q_l->query_level = query_level;
230	q_l->switch_value  = 0x01;
231
232	init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
233}
234
235/*******************************************************************
236 Inits an NET_R_LOGON_CTRL2 structure.
237********************************************************************/
238
239void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
240			    uint32 flags, uint32 pdc_status,
241			    uint32 logon_attempts, uint32 tc_status,
242			    const char *trusted_domain_name)
243{
244	DEBUG(5,("init_r_logon_ctrl2\n"));
245
246	r_l->switch_value  = query_level; /* should only be 0x1 */
247
248	switch (query_level) {
249	case 1:
250		r_l->ptr = 1; /* undocumented pointer */
251		init_netinfo_1(&r_l->logon.info1, flags, pdc_status);
252		r_l->status = NT_STATUS_OK;
253		break;
254	case 2:
255		r_l->ptr = 1; /* undocumented pointer */
256		init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
257		               tc_status, trusted_domain_name);
258		r_l->status = NT_STATUS_OK;
259		break;
260	case 3:
261		r_l->ptr = 1; /* undocumented pointer */
262		init_netinfo_3(&r_l->logon.info3, flags, logon_attempts);
263		r_l->status = NT_STATUS_OK;
264		break;
265	default:
266		DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
267			r_l->switch_value));
268		r_l->ptr = 0; /* undocumented pointer */
269
270		/* take a guess at an error code... */
271		r_l->status = NT_STATUS_INVALID_INFO_CLASS;
272		break;
273	}
274}
275
276/*******************************************************************
277 Reads or writes an NET_R_LOGON_CTRL2 structure.
278********************************************************************/
279
280BOOL net_io_r_logon_ctrl2(const char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
281{
282	if (r_l == NULL)
283		return False;
284
285	prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
286	depth++;
287
288	if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
289		return False;
290	if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
291		return False;
292
293	if (r_l->ptr != 0) {
294		switch (r_l->switch_value) {
295		case 1:
296			if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
297				return False;
298			break;
299		case 2:
300			if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
301				return False;
302			break;
303		case 3:
304			if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
305				return False;
306			break;
307		default:
308			DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
309				r_l->switch_value));
310			break;
311		}
312	}
313
314	if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
315		return False;
316
317	return True;
318}
319
320/*******************************************************************
321 Reads or writes an NET_Q_LOGON_CTRL structure.
322********************************************************************/
323
324BOOL net_io_q_logon_ctrl(const char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps,
325			 int depth)
326{
327	prs_debug(ps, depth, desc, "net_io_q_logon_ctrl");
328	depth++;
329
330	if(!prs_align(ps))
331		return False;
332
333	if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
334		return False;
335
336	if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
337		return False;
338
339	if(!prs_align(ps))
340		return False;
341
342	if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
343		return False;
344	if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
345		return False;
346
347	return True;
348}
349
350/*******************************************************************
351 Inits an NET_Q_LOGON_CTRL structure.
352********************************************************************/
353
354void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, const char *srv_name,
355			   uint32 query_level)
356{
357	DEBUG(5,("init_q_logon_ctrl\n"));
358
359	q_l->function_code = 0x01; /* ??? */
360	q_l->query_level = query_level;
361
362	init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
363}
364
365/*******************************************************************
366 Inits an NET_R_LOGON_CTRL structure.
367********************************************************************/
368
369void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
370			   uint32 flags, uint32 pdc_status)
371{
372	DEBUG(5,("init_r_logon_ctrl\n"));
373
374	r_l->switch_value  = query_level; /* should only be 0x1 */
375
376	switch (query_level) {
377	case 1:
378		r_l->ptr = 1; /* undocumented pointer */
379		init_netinfo_1(&r_l->logon.info1, flags, pdc_status);
380		r_l->status = NT_STATUS_OK;
381		break;
382	default:
383		DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n",
384			r_l->switch_value));
385		r_l->ptr = 0; /* undocumented pointer */
386
387		/* take a guess at an error code... */
388		r_l->status = NT_STATUS_INVALID_INFO_CLASS;
389		break;
390	}
391}
392
393/*******************************************************************
394 Reads or writes an NET_R_LOGON_CTRL structure.
395********************************************************************/
396
397BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps,
398			 int depth)
399{
400	prs_debug(ps, depth, desc, "net_io_r_logon_ctrl");
401	depth++;
402
403	if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
404		return False;
405	if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
406		return False;
407
408	if (r_l->ptr != 0) {
409		switch (r_l->switch_value) {
410		case 1:
411			if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
412				return False;
413			break;
414		default:
415			DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n",
416				r_l->switch_value));
417			break;
418		}
419	}
420
421	if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
422		return False;
423
424	return True;
425}
426
427/*******************************************************************
428 Inits an NET_R_TRUST_DOM_LIST structure.
429********************************************************************/
430
431void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
432			uint32 num_doms, const char *dom_name)
433{
434	unsigned int i = 0;
435
436	DEBUG(5,("init_r_trust_dom\n"));
437
438	for (i = 0; i < MAX_TRUST_DOMS; i++) {
439		r_t->uni_trust_dom_name[i].uni_str_len = 0;
440		r_t->uni_trust_dom_name[i].uni_max_len = 0;
441	}
442	if (num_doms > MAX_TRUST_DOMS)
443		num_doms = MAX_TRUST_DOMS;
444
445	for (i = 0; i < num_doms; i++) {
446		fstring domain_name;
447		fstrcpy(domain_name, dom_name);
448		strupper_m(domain_name);
449		init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, UNI_STR_TERMINATE);
450		/* the use of UNISTR2 here is non-standard. */
451		r_t->uni_trust_dom_name[i].offset = 0x1;
452	}
453
454	r_t->status = NT_STATUS_OK;
455}
456
457/*******************************************************************
458 Reads or writes an NET_R_TRUST_DOM_LIST structure.
459********************************************************************/
460
461BOOL net_io_r_trust_dom(const char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
462{
463	uint32 value;
464
465	if (r_t == NULL)
466		 return False;
467
468	prs_debug(ps, depth, desc, "net_io_r_trust_dom");
469	depth++;
470
471	/* temporary code to give a valid response */
472	value=2;
473	if(!prs_uint32("status", ps, depth, &value))
474		 return False;
475
476	value=1;
477	if(!prs_uint32("status", ps, depth, &value))
478		 return False;
479	value=2;
480	if(!prs_uint32("status", ps, depth, &value))
481		 return False;
482
483	value=0;
484	if(!prs_uint32("status", ps, depth, &value))
485		 return False;
486
487	value=0;
488	if(!prs_uint32("status", ps, depth, &value))
489		 return False;
490
491/* old non working code */
492#if 0
493	int i;
494
495	for (i = 0; i < MAX_TRUST_DOMS; i++) {
496		if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
497			break;
498		if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
499			 return False;
500	}
501
502	if(!prs_ntstatus("status", ps, depth, &r_t->status))
503		 return False;
504#endif
505	return True;
506}
507
508
509/*******************************************************************
510 Reads or writes an NET_Q_TRUST_DOM_LIST structure.
511********************************************************************/
512
513BOOL net_io_q_trust_dom(const char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
514{
515	if (q_l == NULL)
516		 return False;
517
518	prs_debug(ps, depth, desc, "net_io_q_trust_dom");
519	depth++;
520
521	if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
522		 return False;
523	if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
524		 return False;
525
526	return True;
527}
528
529/*******************************************************************
530 Inits an NET_Q_REQ_CHAL structure.
531********************************************************************/
532
533void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
534		     const char *logon_srv, const char *logon_clnt,
535		     DOM_CHAL *clnt_chal)
536{
537	DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
538
539	q_c->undoc_buffer = 1; /* don't know what this buffer is */
540
541	init_unistr2(&q_c->uni_logon_srv, logon_srv , UNI_STR_TERMINATE);
542	init_unistr2(&q_c->uni_logon_clnt, logon_clnt, UNI_STR_TERMINATE);
543
544	memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
545
546	DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
547}
548
549/*******************************************************************
550 Reads or writes an NET_Q_REQ_CHAL structure.
551********************************************************************/
552
553BOOL net_io_q_req_chal(const char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
554{
555	if (q_c == NULL)
556		return False;
557
558	prs_debug(ps, depth, desc, "net_io_q_req_chal");
559	depth++;
560
561	if(!prs_align(ps))
562		return False;
563
564	if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
565		return False;
566
567	if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
568		return False;
569	if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
570		return False;
571
572	if(!smb_io_chal("", &q_c->clnt_chal, ps, depth))
573		return False;
574
575	return True;
576}
577
578/*******************************************************************
579 Reads or writes a structure.
580********************************************************************/
581
582BOOL net_io_r_req_chal(const char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
583{
584	if (r_c == NULL)
585		return False;
586
587	prs_debug(ps, depth, desc, "net_io_r_req_chal");
588	depth++;
589
590	if(!prs_align(ps))
591		return False;
592
593	if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
594		return False;
595
596	if(!prs_ntstatus("status", ps, depth, &r_c->status))
597		return False;
598
599	return True;
600}
601
602
603/*******************************************************************
604 Reads or writes a structure.
605********************************************************************/
606
607BOOL net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
608{
609	if (q_a == NULL)
610		return False;
611
612	prs_debug(ps, depth, desc, "net_io_q_auth");
613	depth++;
614
615	if(!prs_align(ps))
616		return False;
617
618	if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
619		return False;
620	if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
621		return False;
622
623	return True;
624}
625
626/*******************************************************************
627 Reads or writes a structure.
628********************************************************************/
629
630BOOL net_io_r_auth(const char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
631{
632	if (r_a == NULL)
633		return False;
634
635	prs_debug(ps, depth, desc, "net_io_r_auth");
636	depth++;
637
638	if(!prs_align(ps))
639		return False;
640
641	if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
642		return False;
643
644	if(!prs_ntstatus("status", ps, depth, &r_a->status))
645		return False;
646
647	return True;
648}
649
650/*******************************************************************
651 Inits a NET_Q_AUTH_2 struct.
652********************************************************************/
653
654void init_q_auth_2(NET_Q_AUTH_2 *q_a,
655		const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
656		DOM_CHAL *clnt_chal, uint32 clnt_flgs)
657{
658	DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
659
660	init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
661	memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
662	q_a->clnt_flgs.neg_flags = clnt_flgs;
663
664	DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
665}
666
667/*******************************************************************
668 Reads or writes a structure.
669********************************************************************/
670
671BOOL net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
672{
673	if (q_a == NULL)
674		return False;
675
676	prs_debug(ps, depth, desc, "net_io_q_auth_2");
677	depth++;
678
679	if(!prs_align(ps))
680		return False;
681
682	if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
683		return False;
684	if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
685		return False;
686	if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
687		return False;
688
689	return True;
690}
691
692/*******************************************************************
693 Reads or writes a structure.
694********************************************************************/
695
696BOOL net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
697{
698	if (r_a == NULL)
699		return False;
700
701	prs_debug(ps, depth, desc, "net_io_r_auth_2");
702	depth++;
703
704	if(!prs_align(ps))
705		return False;
706
707	if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
708		return False;
709	if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
710		return False;
711
712	if(!prs_ntstatus("status", ps, depth, &r_a->status))
713		return False;
714
715	return True;
716}
717
718/*******************************************************************
719 Inits a NET_Q_AUTH_3 struct.
720********************************************************************/
721
722void init_q_auth_3(NET_Q_AUTH_3 *q_a,
723		const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
724		DOM_CHAL *clnt_chal, uint32 clnt_flgs)
725{
726	DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
727
728	init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
729	memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
730	q_a->clnt_flgs.neg_flags = clnt_flgs;
731
732	DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
733}
734
735/*******************************************************************
736 Reads or writes a structure.
737********************************************************************/
738
739BOOL net_io_q_auth_3(const char *desc, NET_Q_AUTH_3 *q_a, prs_struct *ps, int depth)
740{
741	if (q_a == NULL)
742		return False;
743
744	prs_debug(ps, depth, desc, "net_io_q_auth_3");
745	depth++;
746
747	if(!prs_align(ps))
748		return False;
749
750	if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
751		return False;
752	if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
753		return False;
754	if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
755		return False;
756
757	return True;
758}
759
760/*******************************************************************
761 Reads or writes a structure.
762********************************************************************/
763
764BOOL net_io_r_auth_3(const char *desc, NET_R_AUTH_3 *r_a, prs_struct *ps, int depth)
765{
766	if (r_a == NULL)
767		return False;
768
769	prs_debug(ps, depth, desc, "net_io_r_auth_3");
770	depth++;
771
772	if(!prs_align(ps))
773		return False;
774
775	if(!smb_io_chal("srv_chal", &r_a->srv_chal, ps, depth)) /* server challenge */
776		return False;
777	if(!net_io_neg_flags("srv_flgs", &r_a->srv_flgs, ps, depth))
778		return False;
779	if (!prs_uint32("unknown", ps, depth, &r_a->unknown))
780		return False;
781
782	if(!prs_ntstatus("status", ps, depth, &r_a->status))
783		return False;
784
785	return True;
786}
787
788
789/*******************************************************************
790 Inits a NET_Q_SRV_PWSET.
791********************************************************************/
792
793void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
794		const char *logon_srv, const char *sess_key, const char *acct_name,
795                uint16 sec_chan, const char *comp_name,
796		DOM_CRED *cred, uchar hashed_mach_pwd[16])
797{
798	unsigned char nt_cypher[16];
799
800	DEBUG(5,("init_q_srv_pwset\n"));
801
802	/* Process the new password. */
803	cred_hash3( nt_cypher, hashed_mach_pwd, (const unsigned char *)sess_key, 1);
804
805	init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
806
807	memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd));
808}
809
810/*******************************************************************
811 Reads or writes a structure.
812********************************************************************/
813
814BOOL net_io_q_srv_pwset(const char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
815{
816	if (q_s == NULL)
817		return False;
818
819	prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
820	depth++;
821
822	if(!prs_align(ps))
823		return False;
824
825	if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
826		return False;
827	if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
828		return False;
829
830	return True;
831}
832
833/*******************************************************************
834 Reads or writes a structure.
835********************************************************************/
836
837BOOL net_io_r_srv_pwset(const char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
838{
839	if (r_s == NULL)
840		return False;
841
842	prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
843	depth++;
844
845	if(!prs_align(ps))
846		return False;
847
848	if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
849		return False;
850
851	if(!prs_ntstatus("status", ps, depth, &r_s->status))
852		return False;
853
854	return True;
855}
856
857/*************************************************************************
858 Init DOM_SID2 array from a string containing multiple sids
859 *************************************************************************/
860
861static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsids)
862{
863	const char *ptr;
864	pstring s2;
865	int count = 0;
866
867	DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
868
869	*ppsids = NULL;
870
871	if(sids_str) {
872		int number;
873		DOM_SID2 *sids;
874
875		/* Count the number of valid SIDs. */
876		for (count = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
877			DOM_SID tmpsid;
878			if (string_to_sid(&tmpsid, s2))
879				count++;
880		}
881
882		/* Now allocate space for them. */
883		*ppsids = (DOM_SID2 *)talloc_zero(ctx, count * sizeof(DOM_SID2));
884		if (*ppsids == NULL)
885			return 0;
886
887		sids = *ppsids;
888
889		for (number = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
890			DOM_SID tmpsid;
891			if (string_to_sid(&tmpsid, s2)) {
892				/* count only valid sids */
893				init_dom_sid2(&sids[number], &tmpsid);
894				number++;
895			}
896		}
897	}
898
899	return count;
900}
901
902/*******************************************************************
903 Inits a NET_ID_INFO_1 structure.
904********************************************************************/
905
906void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
907				uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
908				const char *user_name, const char *wksta_name,
909				const char *sess_key,
910				unsigned char lm_cypher[16], unsigned char nt_cypher[16])
911{
912	unsigned char lm_owf[16];
913	unsigned char nt_owf[16];
914
915	DEBUG(5,("init_id_info1: %d\n", __LINE__));
916
917	id->ptr_id_info1 = 1;
918
919	id->param_ctrl = param_ctrl;
920	init_logon_id(&id->logon_id, log_id_low, log_id_high);
921
922
923	if (lm_cypher && nt_cypher) {
924		unsigned char key[16];
925#ifdef DEBUG_PASSWORD
926		DEBUG(100,("lm cypher:"));
927		dump_data(100, (char *)lm_cypher, 16);
928
929		DEBUG(100,("nt cypher:"));
930		dump_data(100, (char *)nt_cypher, 16);
931#endif
932
933		memset(key, 0, 16);
934		memcpy(key, sess_key, 8);
935
936		memcpy(lm_owf, lm_cypher, 16);
937		SamOEMhash(lm_owf, key, 16);
938		memcpy(nt_owf, nt_cypher, 16);
939		SamOEMhash(nt_owf, key, 16);
940
941#ifdef DEBUG_PASSWORD
942		DEBUG(100,("encrypt of lm owf password:"));
943		dump_data(100, (char *)lm_owf, 16);
944
945		DEBUG(100,("encrypt of nt owf password:"));
946		dump_data(100, (char *)nt_owf, 16);
947#endif
948		/* set up pointers to cypher blocks */
949		lm_cypher = lm_owf;
950		nt_cypher = nt_owf;
951	}
952
953	init_owf_info(&id->lm_owf, lm_cypher);
954	init_owf_info(&id->nt_owf, nt_cypher);
955
956	init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
957	init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
958	init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
959	init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
960	init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
961	init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
962}
963
964/*******************************************************************
965 Reads or writes an NET_ID_INFO_1 structure.
966********************************************************************/
967
968static BOOL net_io_id_info1(const char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
969{
970	if (id == NULL)
971		return False;
972
973	prs_debug(ps, depth, desc, "net_io_id_info1");
974	depth++;
975
976	if(!prs_align(ps))
977		return False;
978
979	if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
980		return False;
981
982	if (id->ptr_id_info1 != 0) {
983		if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
984			return False;
985
986		if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
987			return False;
988		if(!smb_io_logon_id("", &id->logon_id, ps, depth))
989			return False;
990
991		if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
992			return False;
993		if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
994			return False;
995
996		if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
997			return False;
998		if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
999			return False;
1000
1001		if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
1002				id->hdr_domain_name.buffer, ps, depth))
1003			return False;
1004		if(!smb_io_unistr2("unistr2", &id->uni_user_name,
1005				id->hdr_user_name.buffer, ps, depth))
1006			return False;
1007		if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
1008				id->hdr_wksta_name.buffer, ps, depth))
1009			return False;
1010	}
1011
1012	return True;
1013}
1014
1015/*******************************************************************
1016Inits a NET_ID_INFO_2 structure.
1017
1018This is a network logon packet. The log_id parameters
1019are what an NT server would generate for LUID once the
1020user is logged on. I don't think we care about them.
1021
1022Note that this has no access to the NT and LM hashed passwords,
1023so it forwards the challenge, and the NT and LM responses (24
1024bytes each) over the secure channel to the Domain controller
1025for it to say yea or nay. This is the preferred method of
1026checking for a logon as it doesn't export the password
1027hashes to anyone who has compromised the secure channel. JRA.
1028********************************************************************/
1029
1030void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
1031		   uint32 param_ctrl,
1032		   uint32 log_id_low, uint32 log_id_high,
1033		   const char *user_name, const char *wksta_name,
1034		   const uchar lm_challenge[8],
1035		   const uchar * lm_chal_resp, size_t lm_chal_resp_len,
1036		   const uchar * nt_chal_resp, size_t nt_chal_resp_len)
1037{
1038	unsigned char lm_owf[24];
1039	unsigned char nt_owf[128];
1040
1041	DEBUG(5,("init_id_info2: %d\n", __LINE__));
1042
1043	id->ptr_id_info2 = 1;
1044
1045
1046	id->param_ctrl = param_ctrl;
1047	init_logon_id(&id->logon_id, log_id_low, log_id_high);
1048
1049	if (nt_chal_resp) {
1050		/* oops.  can only send what-ever-it-is direct */
1051		memcpy(nt_owf, nt_chal_resp, MIN(sizeof(nt_owf), nt_chal_resp_len));
1052		nt_chal_resp = nt_owf;
1053	}
1054	if (lm_chal_resp) {
1055		/* oops.  can only send what-ever-it-is direct */
1056		memcpy(lm_owf, lm_chal_resp, MIN(sizeof(lm_owf), lm_chal_resp_len));
1057		lm_chal_resp = lm_owf;
1058	}
1059
1060	memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
1061	init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
1062	init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
1063
1064	init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
1065	init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
1066	init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
1067	init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
1068	init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
1069	init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
1070
1071	init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len);
1072	init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len);
1073
1074}
1075
1076/*******************************************************************
1077 Reads or writes an NET_ID_INFO_2 structure.
1078********************************************************************/
1079
1080static BOOL net_io_id_info2(const char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
1081{
1082	if (id == NULL)
1083		return False;
1084
1085	prs_debug(ps, depth, desc, "net_io_id_info2");
1086	depth++;
1087
1088	if(!prs_align(ps))
1089		return False;
1090
1091	if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
1092		return False;
1093
1094	if (id->ptr_id_info2 != 0) {
1095		if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1096			return False;
1097
1098		if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1099			return False;
1100		if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1101			return False;
1102
1103		if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1104			return False;
1105		if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1106			return False;
1107
1108		if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
1109			return False;
1110
1111		if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
1112			return False;
1113		if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
1114			return False;
1115
1116		if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
1117				id->hdr_domain_name.buffer, ps, depth))
1118			return False;
1119		if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
1120				id->hdr_user_name.buffer, ps, depth))
1121			return False;
1122		if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
1123				id->hdr_wksta_name.buffer, ps, depth))
1124			return False;
1125		if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
1126				id->hdr_nt_chal_resp.buffer, ps, depth))
1127			return False;
1128		if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
1129				id->hdr_lm_chal_resp.buffer, ps, depth))
1130			return False;
1131	}
1132
1133	return True;
1134}
1135
1136
1137/*******************************************************************
1138 Inits a DOM_SAM_INFO structure.
1139********************************************************************/
1140
1141void init_sam_info(DOM_SAM_INFO *sam,
1142				const char *logon_srv, const char *comp_name,
1143				DOM_CRED *clnt_cred,
1144				DOM_CRED *rtn_cred, uint16 logon_level,
1145				NET_ID_INFO_CTR *ctr)
1146{
1147	DEBUG(5,("init_sam_info: %d\n", __LINE__));
1148
1149	init_clnt_info2(&sam->client, logon_srv, comp_name, clnt_cred);
1150
1151	if (rtn_cred != NULL) {
1152		sam->ptr_rtn_cred = 1;
1153		memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
1154	} else {
1155		sam->ptr_rtn_cred = 0;
1156	}
1157
1158	sam->logon_level  = logon_level;
1159	sam->ctr          = ctr;
1160}
1161
1162/*******************************************************************
1163 Reads or writes a DOM_SAM_INFO structure.
1164********************************************************************/
1165
1166static BOOL net_io_id_info_ctr(const char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
1167{
1168	NET_ID_INFO_CTR *ctr = *pp_ctr;
1169
1170	prs_debug(ps, depth, desc, "smb_io_sam_info");
1171	depth++;
1172
1173	if (UNMARSHALLING(ps)) {
1174		ctr = *pp_ctr = (NET_ID_INFO_CTR *)prs_alloc_mem(ps, sizeof(NET_ID_INFO_CTR));
1175		if (ctr == NULL)
1176			return False;
1177	}
1178
1179	if (ctr == NULL)
1180		return False;
1181
1182	/* don't 4-byte align here! */
1183
1184	if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
1185		return False;
1186
1187	switch (ctr->switch_value) {
1188	case 1:
1189		if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
1190			return False;
1191		break;
1192	case 2:
1193		if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
1194			return False;
1195		break;
1196	default:
1197		/* PANIC! */
1198		DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
1199		break;
1200	}
1201
1202	return True;
1203}
1204
1205/*******************************************************************
1206 Reads or writes a DOM_SAM_INFO structure.
1207 ********************************************************************/
1208
1209static BOOL smb_io_sam_info(const char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
1210{
1211	if (sam == NULL)
1212		return False;
1213
1214	prs_debug(ps, depth, desc, "smb_io_sam_info");
1215	depth++;
1216
1217	if(!prs_align(ps))
1218		return False;
1219
1220	if(!smb_io_clnt_info2("", &sam->client, ps, depth))
1221		return False;
1222
1223	if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
1224		return False;
1225	if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
1226		return False;
1227
1228	if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
1229		return False;
1230
1231	if (sam->logon_level != 0) {
1232		if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth))
1233			return False;
1234	}
1235
1236	return True;
1237}
1238
1239/*************************************************************************
1240 Inits a NET_USER_INFO_3 structure.
1241
1242 This is a network logon reply packet, and contains much information about
1243 the user.  This information is passed as a (very long) paramater list
1244 to avoid having to link in the PASSDB code to every program that deals
1245 with this file.
1246 *************************************************************************/
1247
1248void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
1249			 uint32                user_rid,
1250			 uint32                group_rid,
1251
1252			 const char*		user_name,
1253			 const char*		full_name,
1254			 const char*		home_dir,
1255			 const char*		dir_drive,
1256			 const char*		logon_script,
1257			 const char*		profile_path,
1258
1259			 time_t unix_logon_time,
1260			 time_t unix_logoff_time,
1261			 time_t unix_kickoff_time,
1262			 time_t unix_pass_last_set_time,
1263			 time_t unix_pass_can_change_time,
1264			 time_t unix_pass_must_change_time,
1265
1266			 uint16 logon_count, uint16 bad_pw_count,
1267 		 	 uint32 num_groups, const DOM_GID *gids,
1268			 uint32 user_flgs, uchar nt_session_key[16],
1269			 uchar lm_session_key[16],
1270 			 const char *logon_srv, const char *logon_dom,
1271			 const DOM_SID *dom_sid, const char *other_sids)
1272{
1273	/* only cope with one "other" sid, right now. */
1274	/* need to count the number of space-delimited sids */
1275	unsigned int i;
1276	int num_other_sids = 0;
1277
1278	NTTIME 		logon_time, logoff_time, kickoff_time,
1279			pass_last_set_time, pass_can_change_time,
1280			pass_must_change_time;
1281
1282	ZERO_STRUCTP(usr);
1283
1284	usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1285
1286	/* Create NTTIME structs */
1287	unix_to_nt_time (&logon_time, 		 unix_logon_time);
1288	unix_to_nt_time (&logoff_time, 		 unix_logoff_time);
1289	unix_to_nt_time (&kickoff_time, 	 unix_kickoff_time);
1290	unix_to_nt_time (&pass_last_set_time, 	 unix_pass_last_set_time);
1291	unix_to_nt_time (&pass_can_change_time,	 unix_pass_can_change_time);
1292	unix_to_nt_time (&pass_must_change_time, unix_pass_must_change_time);
1293
1294	usr->logon_time            = logon_time;
1295	usr->logoff_time           = logoff_time;
1296	usr->kickoff_time          = kickoff_time;
1297	usr->pass_last_set_time    = pass_last_set_time;
1298	usr->pass_can_change_time  = pass_can_change_time;
1299	usr->pass_must_change_time = pass_must_change_time;
1300
1301	usr->logon_count = logon_count;
1302	usr->bad_pw_count = bad_pw_count;
1303
1304	usr->user_rid = user_rid;
1305	usr->group_rid = group_rid;
1306	usr->num_groups = num_groups;
1307
1308	usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1309	usr->user_flgs = user_flgs;
1310
1311	if (nt_session_key != NULL)
1312		memcpy(usr->user_sess_key, nt_session_key, sizeof(usr->user_sess_key));
1313	else
1314		memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1315
1316	usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1317
1318	memset((char *)usr->padding, '\0', sizeof(usr->padding));
1319
1320#if 0 /* JRATEST - exchange auth test. */
1321	if (lm_session_key != NULL)
1322		memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key));
1323#endif
1324
1325	num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
1326
1327	usr->num_other_sids = num_other_sids;
1328	usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0;
1329
1330	init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
1331	init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
1332	init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
1333	init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
1334	init_unistr2(&usr->uni_logon_script, logon_script, UNI_FLAGS_NONE);
1335	init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
1336	init_unistr2(&usr->uni_profile_path, profile_path, UNI_FLAGS_NONE);
1337	init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
1338	init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
1339	init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
1340	init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
1341	init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
1342
1343	usr->num_groups2 = num_groups;
1344
1345	usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * (num_groups));
1346	if (usr->gids == NULL && num_groups>0)
1347		return;
1348
1349	for (i = 0; i < num_groups; i++)
1350		usr->gids[i] = gids[i];
1351
1352	init_unistr2(&usr->uni_logon_srv, logon_srv, UNI_FLAGS_NONE);
1353	init_uni_hdr(&usr->hdr_logon_srv, &usr->uni_logon_srv);
1354	init_unistr2(&usr->uni_logon_dom, logon_dom, UNI_FLAGS_NONE);
1355	init_uni_hdr(&usr->hdr_logon_dom, &usr->uni_logon_dom);
1356
1357	init_dom_sid2(&usr->dom_sid, dom_sid);
1358	/* "other" sids are set up above */
1359}
1360
1361/*******************************************************************
1362 This code has been modified to cope with a NET_USER_INFO_2 - which is
1363 exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1364 We use validation level to determine if we're marshalling a info 2 or
1365 INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1366 Jacobsen at HP. JRA.
1367********************************************************************/
1368
1369BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
1370		       int depth, uint16 validation_level)
1371{
1372	unsigned int i;
1373
1374	if (usr == NULL)
1375		return False;
1376
1377	prs_debug(ps, depth, desc, "net_io_user_info3");
1378	depth++;
1379
1380	if (UNMARSHALLING(ps))
1381		ZERO_STRUCTP(usr);
1382
1383	if(!prs_align(ps))
1384		return False;
1385
1386	if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1387		return False;
1388
1389	if (usr->ptr_user_info == 0)
1390		return True;
1391
1392	if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
1393		return False;
1394	if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
1395		return False;
1396	if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1397		return False;
1398	if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1399		return False;
1400	if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1401		return False;
1402	if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1403		return False;
1404
1405	if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1406		return False;
1407	if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1408		return False;
1409	if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1410		return False;
1411	if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1412		return False;
1413	if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1414		return False;
1415	if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1416		return False;
1417
1418	if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1419		return False;
1420	if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1421		return False;
1422
1423	if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User RID */
1424		return False;
1425	if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group RID */
1426		return False;
1427	if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1428		return False;
1429	if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1430		return False;
1431	if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1432		return False;
1433
1434	if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* user session key */
1435		return False;
1436
1437	if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1438		return False;
1439	if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1440		return False;
1441
1442	if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1443		return False;
1444	if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1445		return False;
1446
1447	if (validation_level == 3) {
1448		if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1449			return False;
1450		if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1451			return False;
1452	} else {
1453		if (UNMARSHALLING(ps)) {
1454			usr->num_other_sids = 0;
1455			usr->buffer_other_sids = 0;
1456		}
1457	}
1458
1459	if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1460		return False;
1461	if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1462		return False;
1463	if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1464		return False;
1465	if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1466		return False;
1467	if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1468		return False;
1469	if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1470		return False;
1471
1472	if(!prs_align(ps))
1473		return False;
1474	if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1475		return False;
1476
1477	if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1478		usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
1479		if (usr->gids == NULL)
1480			return False;
1481	}
1482
1483	for (i = 0; i < usr->num_groups2; i++) {
1484		if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1485			return False;
1486	}
1487
1488	if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1489		return False;
1490	if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1491		return False;
1492
1493	if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1494		return False;
1495
1496	if (usr->num_other_sids) {
1497
1498		if (UNMARSHALLING(ps)) {
1499			usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
1500			if (usr->other_sids == NULL)
1501				return False;
1502		}
1503
1504		if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
1505			return False;
1506
1507		if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
1508			usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
1509			if (usr->other_gids == NULL)
1510				return False;
1511		}
1512
1513		for (i = 0; i < usr->num_other_groups; i++) {
1514			if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
1515				return False;
1516		}
1517		for (i = 0; i < usr->num_other_sids; i++) {
1518			if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1519				return False;
1520		}
1521	}
1522
1523	return True;
1524}
1525
1526/*******************************************************************
1527 Reads or writes a structure.
1528********************************************************************/
1529
1530BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1531{
1532	if (q_l == NULL)
1533		return False;
1534
1535	prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1536	depth++;
1537
1538	if(!prs_align(ps))
1539		return False;
1540
1541	if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1542		return False;
1543
1544	if(!prs_align_uint16(ps))
1545		return False;
1546
1547	if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1548		return False;
1549
1550	return True;
1551}
1552
1553/*******************************************************************
1554 Reads or writes a structure.
1555********************************************************************/
1556
1557BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1558{
1559	if (r_l == NULL)
1560		return False;
1561
1562	prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1563	depth++;
1564
1565	if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1566		return False;
1567	if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1568		return False;
1569
1570	if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1571		return False;
1572	if(!prs_align(ps))
1573		return False;
1574
1575#if 1 /* W2k always needs this - even for bad passwd. JRA */
1576	if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1577		return False;
1578#else
1579	if (r_l->switch_value != 0) {
1580		if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1581			return False;
1582	}
1583#endif
1584
1585	if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1586		return False;
1587
1588	if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1589		return False;
1590
1591	if(!prs_align(ps))
1592		return False;
1593
1594	return True;
1595}
1596
1597/*******************************************************************
1598 Reads or writes a structure.
1599********************************************************************/
1600
1601BOOL net_io_q_sam_logoff(const char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1602{
1603	if (q_l == NULL)
1604		return False;
1605
1606	prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1607	depth++;
1608
1609	if(!prs_align(ps))
1610		return False;
1611
1612	if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1613		return False;
1614
1615	return True;
1616}
1617
1618/*******************************************************************
1619 Reads or writes a structure.
1620********************************************************************/
1621
1622BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1623{
1624	if (r_l == NULL)
1625		return False;
1626
1627	prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1628	depth++;
1629
1630	if(!prs_align(ps))
1631		return False;
1632
1633	if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1634		return False;
1635	if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1636		return False;
1637
1638	if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1639		return False;
1640
1641	return True;
1642}
1643
1644/*******************************************************************
1645makes a NET_Q_SAM_SYNC structure.
1646********************************************************************/
1647BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1648                         const char *cli_name, DOM_CRED *cli_creds,
1649                         DOM_CRED *ret_creds, uint32 database_id,
1650			 uint32 next_rid)
1651{
1652	DEBUG(5, ("init_q_sam_sync\n"));
1653
1654	init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
1655	init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
1656
1657        if (cli_creds)
1658                memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1659
1660	if (cli_creds)
1661                memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
1662	else
1663		memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1664
1665	q_s->database_id = database_id;
1666	q_s->restart_state = 0;
1667	q_s->sync_context = next_rid;
1668	q_s->max_size = 0xffff;
1669
1670	return True;
1671}
1672
1673/*******************************************************************
1674reads or writes a structure.
1675********************************************************************/
1676BOOL net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1677		       int depth)
1678{
1679	prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1680	depth++;
1681
1682	if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1683                return False;
1684	if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1685                return False;
1686
1687	if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1688                return False;
1689	if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1690                return False;
1691
1692	if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1693                return False;
1694	if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1695                return False;
1696	if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1697                return False;
1698
1699	if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1700                return False;
1701
1702	return True;
1703}
1704
1705/*******************************************************************
1706reads or writes a structure.
1707********************************************************************/
1708static BOOL net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta,
1709				 prs_struct *ps, int depth)
1710{
1711	prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1712	depth++;
1713
1714	if (!prs_uint16("type", ps, depth, &delta->type))
1715                return False;
1716	if (!prs_uint16("type2", ps, depth, &delta->type2))
1717                return False;
1718	if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1719                return False;
1720
1721	if (!prs_uint32("type3", ps, depth, &delta->type3))
1722                return False;
1723
1724        /* Not sure why we need this but it seems to be necessary to get
1725           sam deltas working. */
1726
1727        if (delta->type != 0x16) {
1728                if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1729                        return False;
1730        }
1731
1732	return True;
1733}
1734
1735/*******************************************************************
1736reads or writes a structure.
1737********************************************************************/
1738static BOOL net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info,
1739                                   prs_struct *ps, int depth)
1740{
1741	prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1742	depth++;
1743
1744        if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1745                return False;
1746        if (!prs_uint32("dom_mod_count_ptr", ps, depth,
1747                        &info->dom_mod_count_ptr))
1748                return False;
1749
1750        if (info->dom_mod_count_ptr) {
1751                if (!prs_uint64("dom_mod_count", ps, depth,
1752                                &info->dom_mod_count))
1753                        return False;
1754        }
1755
1756        return True;
1757}
1758
1759/*******************************************************************
1760reads or writes a structure.
1761********************************************************************/
1762static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
1763				   prs_struct *ps, int depth)
1764{
1765	prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1766	depth++;
1767
1768	if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1769                return False;
1770	if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1771                return False;
1772
1773        if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1774                return False;
1775	if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1776                return False;
1777	if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1778                return False;
1779	if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1780                return False;
1781	if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1782                return False;
1783	if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1784                return False;
1785	if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1786                return False;
1787
1788	if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1789                return False;
1790	if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
1791                return False;
1792
1793	if (ps->data_offset + 40 > ps->buffer_size)
1794                return False;
1795        ps->data_offset += 40;
1796
1797	if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
1798                            info->hdr_dom_name.buffer, ps, depth))
1799                return False;
1800	if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
1801                            info->hdr_oem_info.buffer, ps, depth))
1802                return False;
1803
1804	if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1805                            info->hdr_sec_desc.buffer, ps, depth))
1806                return False;
1807	if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
1808                            info->hdr_unknown.buffer, ps, depth))
1809                return False;
1810
1811	return True;
1812}
1813
1814/*******************************************************************
1815reads or writes a structure.
1816********************************************************************/
1817static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
1818				  prs_struct *ps, int depth)
1819{
1820	prs_debug(ps, depth, desc, "net_io_sam_group_info");
1821	depth++;
1822
1823	if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
1824                return False;
1825	if (!smb_io_gid("gid", &info->gid, ps, depth))
1826                return False;
1827	if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
1828                return False;
1829	if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1830                return False;
1831
1832        if (ps->data_offset + 48 > ps->buffer_size)
1833                return False;
1834	ps->data_offset += 48;
1835
1836	if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
1837                            info->hdr_grp_name.buffer, ps, depth))
1838                return False;
1839	if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
1840                            info->hdr_grp_desc.buffer, ps, depth))
1841                return False;
1842	if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1843                            info->hdr_sec_desc.buffer, ps, depth))
1844                return False;
1845
1846	return True;
1847}
1848
1849/*******************************************************************
1850reads or writes a structure.
1851********************************************************************/
1852static BOOL net_io_sam_passwd_info(const char *desc, SAM_PWD * pwd,
1853				   prs_struct *ps, int depth)
1854{
1855	prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
1856	depth++;
1857
1858	if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
1859                return False;
1860
1861	if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
1862                return False;
1863	if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
1864                return False;
1865
1866	if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
1867                return False;
1868	if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
1869                return False;
1870
1871	if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
1872                return False;
1873	if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
1874                return False;
1875
1876	return True;
1877}
1878
1879/*******************************************************************
1880makes a SAM_ACCOUNT_INFO structure.
1881********************************************************************/
1882BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
1883			   const UNISTR2 *user_name,
1884			   const UNISTR2 *full_name,
1885			   uint32 user_rid, uint32 group_rid,
1886			   const UNISTR2 *home_dir,
1887			   const UNISTR2 *dir_drive,
1888			   const UNISTR2 *log_scr,
1889			   const UNISTR2 *desc,
1890			   uint32 acb_info,
1891			   const UNISTR2 *prof_path,
1892			   const UNISTR2 *wkstas,
1893			   const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
1894{
1895	int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
1896	int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
1897	int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
1898	int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
1899	int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
1900	int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
1901	int len_description = desc != NULL ? desc->uni_str_len : 0;
1902	int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
1903	int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
1904	int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
1905
1906	DEBUG(5, ("make_sam_account_info\n"));
1907
1908	make_uni_hdr(&info->hdr_acct_name, len_user_name);
1909	make_uni_hdr(&info->hdr_full_name, len_full_name);
1910	make_uni_hdr(&info->hdr_home_dir, len_home_dir);
1911	make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
1912	make_uni_hdr(&info->hdr_logon_script, len_logon_script);
1913	make_uni_hdr(&info->hdr_profile, len_profile_path);
1914	make_uni_hdr(&info->hdr_acct_desc, len_description);
1915	make_uni_hdr(&info->hdr_workstations, len_workstations);
1916	make_uni_hdr(&info->hdr_comment, len_unknown_str);
1917	make_uni_hdr(&info->hdr_parameters, len_munged_dial);
1918
1919	/* not present */
1920	make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
1921
1922	info->user_rid = user_rid;
1923	info->group_rid = group_rid;
1924
1925	init_nt_time(&info->logon_time);
1926	init_nt_time(&info->logoff_time);
1927	init_nt_time(&info->pwd_last_set_time);
1928	init_nt_time(&info->acct_expiry_time);
1929
1930	info->logon_divs = 0xA8;
1931	info->ptr_logon_hrs = 0;	/* Don't care right now */
1932
1933	info->bad_pwd_count = 0;
1934	info->logon_count = 0;
1935	info->acb_info = acb_info;
1936	info->nt_pwd_present = 0;
1937	info->lm_pwd_present = 0;
1938	info->pwd_expired = 0;
1939	info->country = 0;
1940	info->codepage = 0;
1941
1942	info->unknown1 = 0x4EC;
1943	info->unknown2 = 0;
1944
1945	copy_unistr2(&info->uni_acct_name, user_name);
1946	copy_unistr2(&info->uni_full_name, full_name);
1947	copy_unistr2(&info->uni_home_dir, home_dir);
1948	copy_unistr2(&info->uni_dir_drive, dir_drive);
1949	copy_unistr2(&info->uni_logon_script, log_scr);
1950	copy_unistr2(&info->uni_profile, prof_path);
1951	copy_unistr2(&info->uni_acct_desc, desc);
1952	copy_unistr2(&info->uni_workstations, wkstas);
1953	copy_unistr2(&info->uni_comment, unk_str);
1954	copy_unistr2(&info->uni_parameters, mung_dial);
1955
1956	return True;
1957}
1958
1959/*******************************************************************
1960reads or writes a structure.
1961********************************************************************/
1962static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
1963				    SAM_ACCOUNT_INFO * info, prs_struct *ps,
1964				    int depth)
1965{
1966	BUFHDR2 hdr_priv_data;
1967	uint32 i;
1968
1969	prs_debug(ps, depth, desc, "net_io_sam_account_info");
1970	depth++;
1971
1972	if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
1973                return False;
1974	if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
1975                return False;
1976
1977	if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
1978                return False;
1979	if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
1980                return False;
1981
1982	if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
1983                return False;
1984	if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
1985                return False;
1986	if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
1987                           depth))
1988                return False;
1989
1990	if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
1991                return False;
1992	if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
1993                           depth))
1994                return False;
1995
1996	if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
1997                return False;
1998	if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
1999                return False;
2000
2001	if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
2002                return False;
2003	if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
2004                return False;
2005
2006	if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
2007                return False;
2008	if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
2009                return False;
2010	if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
2011                         depth))
2012                return False;
2013	if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps,
2014                         depth))
2015                return False;
2016
2017	if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
2018                return False;
2019	if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
2020                return False;
2021	if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
2022                return False;
2023	if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
2024                return False;
2025	if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
2026                return False;
2027	if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
2028                return False;
2029
2030	if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
2031                return False;
2032	if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps,
2033                           depth))
2034                return False;
2035	if (!prs_uint16("country", ps, depth, &info->country))
2036                return False;
2037	if (!prs_uint16("codepage", ps, depth, &info->codepage))
2038                return False;
2039
2040	if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
2041                return False;
2042	if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2043                return False;
2044	if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
2045                return False;
2046
2047	for (i = 0; i < 3; i++)
2048	{
2049		if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i],
2050                                   ps, depth))
2051                        return False;
2052	}
2053
2054	for (i = 0; i < 4; i++)
2055	{
2056		if (!prs_uint32("dw_reserved", ps, depth,
2057                                &info->dw_reserved[i]))
2058                        return False;
2059	}
2060
2061	if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2062                            info->hdr_acct_name.buffer, ps, depth))
2063                return False;
2064	prs_align(ps);
2065	if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2066                            info->hdr_full_name.buffer, ps, depth))
2067                return False;
2068	prs_align(ps);
2069	if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2070                            info->hdr_home_dir.buffer, ps, depth))
2071                return False;
2072	prs_align(ps);
2073	if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2074                            info->hdr_dir_drive.buffer, ps, depth))
2075                return False;
2076	prs_align(ps);
2077	if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2078                            info->hdr_logon_script.buffer, ps, depth))
2079                return False;
2080	prs_align(ps);
2081	if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2082                            info->hdr_acct_desc.buffer, ps, depth))
2083                return False;
2084	prs_align(ps);
2085	if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2086                            info->hdr_workstations.buffer, ps, depth))
2087                return False;
2088	prs_align(ps);
2089
2090	if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2091                return False;
2092	if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2093                return False;
2094
2095	if (!smb_io_buffer4("buf_logon_hrs", &info->buf_logon_hrs,
2096                            info->ptr_logon_hrs, ps, depth))
2097                return False;
2098	prs_align(ps);
2099	if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2100                            info->hdr_comment.buffer, ps, depth))
2101                return False;
2102	prs_align(ps);
2103	if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2104                            info->hdr_parameters.buffer, ps, depth))
2105                return False;
2106	prs_align(ps);
2107	if (hdr_priv_data.buffer != 0)
2108	{
2109		int old_offset = 0;
2110		uint32 len = 0x44;
2111		if (!prs_uint32("pwd_len", ps, depth, &len))
2112                        return False;
2113		old_offset = ps->data_offset;
2114		if (len > 0)
2115		{
2116			if (ps->io)
2117			{
2118				/* reading */
2119                                if (!prs_hash1(ps, ps->data_offset, sess_key, len))
2120                                        return False;
2121			}
2122			if (!net_io_sam_passwd_info("pass", &info->pass,
2123                                                    ps, depth))
2124                                return False;
2125
2126			if (!ps->io)
2127			{
2128				/* writing */
2129                                if (!prs_hash1(ps, old_offset, sess_key, len))
2130                                        return False;
2131			}
2132		}
2133                if (old_offset + len > ps->buffer_size)
2134                        return False;
2135		ps->data_offset = old_offset + len;
2136	}
2137	if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2138                            info->hdr_sec_desc.buffer, ps, depth))
2139                return False;
2140	prs_align(ps);
2141	if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2142                            info->hdr_profile.buffer, ps, depth))
2143                return False;
2144
2145	prs_align(ps);
2146
2147	return True;
2148}
2149
2150/*******************************************************************
2151reads or writes a structure.
2152********************************************************************/
2153static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * info,
2154				      prs_struct *ps, int depth)
2155{
2156	uint32 i;
2157	fstring tmp;
2158
2159	prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2160	depth++;
2161
2162	prs_align(ps);
2163	if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2164                return False;
2165	if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2166                return False;
2167	if (!prs_uint32("num_members", ps, depth, &info->num_members))
2168                return False;
2169
2170        if (ps->data_offset + 16 > ps->buffer_size)
2171                return False;
2172	ps->data_offset += 16;
2173
2174	if (info->ptr_rids != 0)
2175	{
2176		if (!prs_uint32("num_members2", ps, depth,
2177                                &info->num_members2))
2178                        return False;
2179
2180		if (info->num_members2 != info->num_members)
2181		{
2182			/* RPC fault */
2183			return False;
2184		}
2185
2186                info->rids = talloc(ps->mem_ctx, sizeof(uint32) *
2187                                    info->num_members2);
2188
2189                if (info->rids == NULL) {
2190                        DEBUG(0, ("out of memory allocating %d rids\n",
2191                                  info->num_members2));
2192                        return False;
2193                }
2194
2195		for (i = 0; i < info->num_members2; i++)
2196		{
2197			slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2198			if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2199                                return False;
2200		}
2201	}
2202
2203	if (info->ptr_attribs != 0)
2204	{
2205		if (!prs_uint32("num_members3", ps, depth,
2206                                &info->num_members3))
2207                        return False;
2208		if (info->num_members3 != info->num_members)
2209		{
2210			/* RPC fault */
2211			return False;
2212		}
2213
2214                info->attribs = talloc(ps->mem_ctx, sizeof(uint32) *
2215                                       info->num_members3);
2216
2217                if (info->attribs == NULL) {
2218                        DEBUG(0, ("out of memory allocating %d attribs\n",
2219                                  info->num_members3));
2220                        return False;
2221                }
2222
2223		for (i = 0; i < info->num_members3; i++)
2224		{
2225			slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2226			if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2227                                return False;
2228		}
2229	}
2230
2231	return True;
2232}
2233
2234/*******************************************************************
2235reads or writes a structure.
2236********************************************************************/
2237static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
2238				  prs_struct *ps, int depth)
2239{
2240	prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2241	depth++;
2242
2243	if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2244                return False;
2245	if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2246                return False;
2247	if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2248                return False;
2249	if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2250                return False;
2251
2252        if (ps->data_offset + 40 > ps->buffer_size)
2253                return False;
2254	ps->data_offset += 40;
2255
2256	if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2257                            info->hdr_als_name.buffer, ps, depth))
2258                return False;
2259	if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2260                            info->hdr_sec_desc.buffer, ps, depth))
2261                return False;
2262
2263	if (info->hdr_als_desc.buffer != 0) {
2264		if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2265				    info->hdr_als_name.buffer, ps, depth))
2266			return False;
2267	}
2268
2269	return True;
2270}
2271
2272/*******************************************************************
2273reads or writes a structure.
2274********************************************************************/
2275static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info,
2276				      prs_struct *ps, int depth)
2277{
2278	uint32 i;
2279	fstring tmp;
2280
2281	prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2282	depth++;
2283
2284	prs_align(ps);
2285	if (!prs_uint32("num_members", ps, depth, &info->num_members))
2286                return False;
2287	if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2288                return False;
2289
2290	if (ps->data_offset + 16 > ps->buffer_size)
2291		return False;
2292	ps->data_offset += 16;
2293
2294	if (info->ptr_members != 0)
2295	{
2296		if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2297                        return False;
2298		if (info->num_sids != info->num_members)
2299		{
2300			/* RPC fault */
2301			return False;
2302		}
2303
2304                info->ptr_sids = talloc(ps->mem_ctx, sizeof(uint32) *
2305                                        info->num_sids);
2306
2307                if (info->ptr_sids == NULL) {
2308                        DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2309                                  info->num_sids));
2310                        return False;
2311                }
2312
2313		for (i = 0; i < info->num_sids; i++)
2314		{
2315			slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2316			if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2317                                return False;
2318		}
2319
2320                info->sids = talloc(ps->mem_ctx, sizeof(DOM_SID2) *
2321                                    info->num_sids);
2322
2323                if (info->sids == NULL) {
2324                        DEBUG(0, ("error allocating %d sids\n",
2325                                  info->num_sids));
2326                        return False;
2327                }
2328
2329		for (i = 0; i < info->num_sids; i++)
2330		{
2331			if (info->ptr_sids[i] != 0)
2332			{
2333				slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2334					 i);
2335				if (!smb_io_dom_sid2(tmp, &info->sids[i],
2336                                                     ps, depth))
2337                                        return False;
2338			}
2339		}
2340	}
2341
2342	return True;
2343}
2344
2345/*******************************************************************
2346reads or writes a structure.
2347********************************************************************/
2348static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
2349				      prs_struct *ps, int depth)
2350{
2351	unsigned int i;
2352	prs_debug(ps, depth, desc, "net_io_sam_policy_info");
2353	depth++;
2354
2355	if(!prs_align(ps))
2356		return False;
2357
2358	if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
2359                return False;
2360	if (!prs_uint64("audit_retention_period", ps, depth,
2361			&info->audit_retention_period))
2362                return False;
2363	if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
2364                return False;
2365	if (!prs_uint32("num_events", ps, depth, &info->num_events))
2366                return False;
2367	if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
2368                return False;
2369
2370	if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2371		return False;
2372
2373	if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
2374                return False;
2375
2376	if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2377                return False;
2378	if (!prs_uint32("non_paged_pool_limit", ps, depth,
2379			&info->non_paged_pool_limit))
2380                return False;
2381	if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2382                return False;
2383	if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2384                return False;
2385	if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2386                return False;
2387	if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2388                return False;
2389	if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
2390                return False;
2391	if (!smb_io_time("create_time", &info->create_time, ps, depth))
2392                return False;
2393	if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2394                return False;
2395
2396	for (i=0; i<4; i++) {
2397		UNIHDR dummy;
2398		if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2399			return False;
2400	}
2401
2402	for (i=0; i<4; i++) {
2403		uint32 reserved;
2404		if (!prs_uint32("reserved", ps, depth, &reserved))
2405			return False;
2406	}
2407
2408	if (!prs_uint32("num_event_audit_options", ps, depth,
2409			&info->num_event_audit_options))
2410                return False;
2411
2412	for (i=0; i<info->num_event_audit_options; i++)
2413		if (!prs_uint32("event_audit_option", ps, depth,
2414				&info->event_audit_option))
2415			return False;
2416
2417	if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2418                return False;
2419
2420	if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2421		return False;
2422
2423	if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2424                            info->hdr_sec_desc.buffer, ps, depth))
2425
2426		return False;
2427
2428	return True;
2429}
2430
2431#if 0
2432
2433/* This function is pretty broken - see bug #334 */
2434
2435/*******************************************************************
2436reads or writes a structure.
2437********************************************************************/
2438static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
2439				      prs_struct *ps, int depth)
2440{
2441	int i;
2442
2443	prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
2444	depth++;
2445
2446	if(!prs_align(ps))
2447		return False;
2448
2449	if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2450                return False;
2451
2452	if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2453		return False;
2454
2455	if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2456		return False;
2457
2458	if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2459		return False;
2460
2461	if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2462                return False;
2463	if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2464                return False;
2465	if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2466                return False;
2467
2468	if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2469                return False;
2470	if(!prs_uint32("ptr", ps, depth, &info->ptr))
2471                return False;
2472
2473	for (i=0; i<12; i++)
2474		if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2475                	return False;
2476
2477	if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2478                return False;
2479
2480	return True;
2481}
2482
2483#endif
2484
2485#if 0
2486
2487/* This function doesn't work - see bug #334 */
2488
2489/*******************************************************************
2490reads or writes a structure.
2491********************************************************************/
2492static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
2493				   prs_struct *ps, int depth)
2494{
2495	int i;
2496
2497	prs_debug(ps, depth, desc, "net_io_sam_secret_info");
2498	depth++;
2499
2500	if(!prs_align(ps))
2501		return False;
2502
2503	if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2504                return False;
2505
2506	if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2507		return False;
2508
2509	if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2510                return False;
2511
2512	if(!prs_align(ps))
2513		return False;
2514
2515	if(!prs_uint32("count1", ps, depth, &info->count1))
2516                return False;
2517	if(!prs_uint32("count2", ps, depth, &info->count2))
2518                return False;
2519	if(!prs_uint32("ptr", ps, depth, &info->ptr))
2520                return False;
2521
2522
2523	if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2524		return False;
2525	if(!prs_uint32("count3", ps, depth, &info->count3))
2526                return False;
2527	if(!prs_uint32("count4", ps, depth, &info->count4))
2528                return False;
2529	if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2530                return False;
2531	if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2532		return False;
2533	if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2534                return False;
2535
2536
2537	if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2538                return False;
2539	if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2540                return False;
2541	for(i=0; i<12; i++)
2542		if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2543                	return False;
2544
2545	if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2546                return False;
2547	if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2548                return False;
2549	if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2550                return False;
2551
2552	if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2553		return False;
2554
2555	if(!prs_uint32("key_len", ps, depth, &info->key_len))
2556                return False;
2557	if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2558                return False;
2559	if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2560                return False;
2561
2562	if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2563		return False;
2564
2565
2566	if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2567                return False;
2568
2569	if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2570		return False;
2571
2572
2573	return True;
2574}
2575
2576#endif
2577
2578/*******************************************************************
2579reads or writes a structure.
2580********************************************************************/
2581static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
2582				      prs_struct *ps, int depth)
2583{
2584	unsigned int i;
2585
2586	prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2587	depth++;
2588
2589	if(!prs_align(ps))
2590		return False;
2591
2592	if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2593		return False;
2594
2595	if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2596                return False;
2597	if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
2598                return False;
2599
2600	if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
2601                return False;
2602	if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
2603                return False;
2604
2605	if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2606                return False;
2607	if (!prs_uint32("non_paged_pool_limit", ps, depth,
2608			&info->non_paged_pool_limit))
2609                return False;
2610	if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2611                return False;
2612	if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2613                return False;
2614	if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2615                return False;
2616	if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2617                return False;
2618	if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
2619                return False;
2620	if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2621                return False;
2622
2623	for (i=0; i<4; i++) {
2624		UNIHDR dummy;
2625		if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2626			return False;
2627	}
2628
2629	for (i=0; i<4; i++) {
2630		uint32 reserved;
2631		if (!prs_uint32("reserved", ps, depth, &reserved))
2632			return False;
2633	}
2634
2635	if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2636                return False;
2637
2638	info->attributes = talloc(ps->mem_ctx, sizeof(uint32) * info->attribute_count);
2639
2640	for (i=0; i<info->attribute_count; i++)
2641		if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2642	                return False;
2643
2644	if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2645                return False;
2646
2647	info->hdr_privslist = talloc(ps->mem_ctx, sizeof(UNIHDR) * info->privlist_count);
2648	info->uni_privslist = talloc(ps->mem_ctx, sizeof(UNISTR2) * info->privlist_count);
2649
2650	for (i=0; i<info->privlist_count; i++)
2651		if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2652			return False;
2653
2654	for (i=0; i<info->privlist_count; i++)
2655		if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2656			return False;
2657
2658	if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2659                            info->hdr_sec_desc.buffer, ps, depth))
2660                return False;
2661
2662	return True;
2663}
2664
2665/*******************************************************************
2666reads or writes a structure.
2667********************************************************************/
2668static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
2669				 SAM_DELTA_CTR * delta, uint16 type,
2670				 prs_struct *ps, int depth)
2671{
2672	prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2673	depth++;
2674
2675	switch (type) {
2676                /* Seen in sam deltas */
2677                case SAM_DELTA_MODIFIED_COUNT:
2678                        if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
2679                                return False;
2680                        break;
2681
2682		case SAM_DELTA_DOMAIN_INFO:
2683			if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2684                                return False;
2685			break;
2686
2687		case SAM_DELTA_GROUP_INFO:
2688			if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2689                                return False;
2690			break;
2691
2692		case SAM_DELTA_ACCOUNT_INFO:
2693			if (!net_io_sam_account_info("", sess_key, &delta->account_info, ps, depth))
2694                                return False;
2695			break;
2696
2697		case SAM_DELTA_GROUP_MEM:
2698			if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2699                                return False;
2700			break;
2701
2702		case SAM_DELTA_ALIAS_INFO:
2703                        if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2704                                return False;
2705			break;
2706
2707		case SAM_DELTA_POLICY_INFO:
2708                        if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
2709                                return False;
2710			break;
2711
2712		case SAM_DELTA_ALIAS_MEM:
2713			if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2714                                return False;
2715			break;
2716
2717		case SAM_DELTA_PRIVS_INFO:
2718			if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2719                                return False;
2720			break;
2721
2722			/* These guys are implemented but broken */
2723
2724 	        case SAM_DELTA_TRUST_DOMS:
2725		case SAM_DELTA_SECRET_INFO:
2726			break;
2727
2728			/* These guys are not implemented yet */
2729
2730  	        case SAM_DELTA_RENAME_GROUP:
2731	        case SAM_DELTA_RENAME_USER:
2732	        case SAM_DELTA_RENAME_ALIAS:
2733	        case SAM_DELTA_DELETE_GROUP:
2734	        case SAM_DELTA_DELETE_USER:
2735		default:
2736			DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
2737			break;
2738	}
2739
2740	return True;
2741}
2742
2743/*******************************************************************
2744reads or writes a structure.
2745********************************************************************/
2746BOOL net_io_r_sam_sync(const char *desc, uint8 sess_key[16],
2747		       NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2748{
2749	uint32 i;
2750
2751	prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2752	depth++;
2753
2754	if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2755                return False;
2756	if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2757                return False;
2758
2759	if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2760                return False;
2761	if (r_s->ptr_deltas != 0)
2762	{
2763		if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2764                        return False;
2765		if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2766                        return False;
2767		if (r_s->ptr_deltas2 != 0)
2768		{
2769			if (!prs_uint32("num_deltas2", ps, depth,
2770                                        &r_s->num_deltas2))
2771                                return False;
2772
2773			if (r_s->num_deltas2 != r_s->num_deltas)
2774			{
2775				/* RPC fault */
2776				return False;
2777			}
2778
2779                        if (r_s->num_deltas2 > 0) {
2780                                r_s->hdr_deltas = (SAM_DELTA_HDR *)
2781                                        talloc(ps->mem_ctx, r_s->num_deltas2 *
2782                                               sizeof(SAM_DELTA_HDR));
2783
2784                                if (r_s->hdr_deltas == NULL) {
2785                                        DEBUG(0, ("error tallocating memory "
2786                                                  "for %d delta headers\n",
2787                                                  r_s->num_deltas2));
2788                                        return False;
2789                                }
2790                        }
2791
2792			for (i = 0; i < r_s->num_deltas2; i++)
2793			{
2794				if (!net_io_sam_delta_hdr("",
2795                                                          &r_s->hdr_deltas[i],
2796                                                          ps, depth))
2797                                        return False;
2798			}
2799
2800                        if (r_s->num_deltas2 > 0) {
2801                                r_s->deltas = (SAM_DELTA_CTR *)
2802                                        talloc(ps->mem_ctx, r_s->num_deltas2 *
2803                                               sizeof(SAM_DELTA_CTR));
2804
2805                                if (r_s->deltas == NULL) {
2806                                        DEBUG(0, ("error tallocating memory "
2807                                                  "for %d deltas\n",
2808                                                  r_s->num_deltas2));
2809                                        return False;
2810                                }
2811                        }
2812
2813			for (i = 0; i < r_s->num_deltas2; i++)
2814			{
2815				if (!net_io_sam_delta_ctr(
2816                                        "", sess_key, &r_s->deltas[i],
2817                                        r_s->hdr_deltas[i].type3,
2818                                        ps, depth)) {
2819                                        DEBUG(0, ("hmm, failed on i=%d\n", i));
2820                                        return False;
2821                                }
2822			}
2823		}
2824	}
2825
2826	prs_align(ps);
2827	if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
2828		return False;
2829
2830	return True;
2831}
2832
2833/*******************************************************************
2834makes a NET_Q_SAM_DELTAS structure.
2835********************************************************************/
2836BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name,
2837                           const char *cli_name, DOM_CRED *cli_creds,
2838                           uint32 database_id, UINT64_S dom_mod_count)
2839{
2840	DEBUG(5, ("init_net_q_sam_deltas\n"));
2841
2842	init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
2843	init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
2844
2845	memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
2846	memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
2847
2848	q_s->database_id = database_id;
2849        q_s->dom_mod_count.low = dom_mod_count.low;
2850        q_s->dom_mod_count.high = dom_mod_count.high;
2851	q_s->max_size = 0xffff;
2852
2853	return True;
2854}
2855
2856/*******************************************************************
2857reads or writes a structure.
2858********************************************************************/
2859BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
2860                         int depth)
2861{
2862	prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
2863	depth++;
2864
2865	if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
2866                return False;
2867	if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
2868                return False;
2869
2870	if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
2871                return False;
2872	if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
2873                return False;
2874
2875	if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
2876                return False;
2877        if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
2878                return False;
2879	if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
2880                return False;
2881
2882	return True;
2883}
2884
2885/*******************************************************************
2886reads or writes a structure.
2887********************************************************************/
2888BOOL net_io_r_sam_deltas(const char *desc, uint8 sess_key[16],
2889                         NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
2890{
2891        unsigned int i;
2892
2893	prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
2894	depth++;
2895
2896	if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2897                return False;
2898        if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
2899                return False;
2900
2901	if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2902                return False;
2903	if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
2904                return False;
2905	if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
2906                return False;
2907
2908	if (r_s->num_deltas2 != 0)
2909	{
2910		if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
2911                        return False;
2912
2913		if (r_s->ptr_deltas != 0)
2914		{
2915                        if (r_s->num_deltas > 0) {
2916                                r_s->hdr_deltas = (SAM_DELTA_HDR *)
2917                                        talloc(ps->mem_ctx, r_s->num_deltas *
2918                                               sizeof(SAM_DELTA_HDR));
2919                                if (r_s->hdr_deltas == NULL) {
2920                                        DEBUG(0, ("error tallocating memory "
2921                                                  "for %d delta headers\n",
2922                                                  r_s->num_deltas));
2923                                        return False;
2924                                }
2925                        }
2926
2927			for (i = 0; i < r_s->num_deltas; i++)
2928			{
2929				net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
2930                                                      ps, depth);
2931			}
2932
2933                        if (r_s->num_deltas > 0) {
2934                                r_s->deltas = (SAM_DELTA_CTR *)
2935                                        talloc(ps->mem_ctx, r_s->num_deltas *
2936                                               sizeof(SAM_DELTA_CTR));
2937
2938                                if (r_s->deltas == NULL) {
2939                                        DEBUG(0, ("error tallocating memory "
2940                                                  "for %d deltas\n",
2941                                                  r_s->num_deltas));
2942                                        return False;
2943                                }
2944                        }
2945
2946			for (i = 0; i < r_s->num_deltas; i++)
2947			{
2948				if (!net_io_sam_delta_ctr(
2949                                        "", sess_key,
2950                                        &r_s->deltas[i],
2951                                        r_s->hdr_deltas[i].type2,
2952                                        ps, depth))
2953
2954                                        return False;
2955			}
2956		}
2957	}
2958
2959	prs_align(ps);
2960	if (!prs_ntstatus("status", ps, depth, &r_s->status))
2961                return False;
2962
2963	return True;
2964}
2965