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