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