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