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