e168f5abbd3a565fa7ae9052ff8929c1d58bdf51
[vlendec/samba-autobuild/.git] / source / rpc_parse / parse_net.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Jean 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_srv("", &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, uint32 acct_flags,
1428                          uchar user_session_key[16],
1429                          uchar lm_session_key[16],
1430                          const char *logon_srv, const char *logon_dom,
1431                          const DOM_SID *dom_sid)
1432 {
1433         /* only cope with one "other" sid, right now. */
1434         /* need to count the number of space-delimited sids */
1435         unsigned int i;
1436         int num_other_sids = 0;
1437         
1438         NTTIME          logon_time, logoff_time, kickoff_time,
1439                         pass_last_set_time, pass_can_change_time,
1440                         pass_must_change_time;
1441
1442         ZERO_STRUCTP(usr);
1443
1444         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1445
1446         /* Create NTTIME structs */
1447         unix_to_nt_time (&logon_time,            unix_logon_time);
1448         unix_to_nt_time (&logoff_time,           unix_logoff_time);
1449         unix_to_nt_time (&kickoff_time,          unix_kickoff_time);
1450         unix_to_nt_time (&pass_last_set_time,    unix_pass_last_set_time);
1451         unix_to_nt_time (&pass_can_change_time,  unix_pass_can_change_time);
1452         unix_to_nt_time (&pass_must_change_time, unix_pass_must_change_time);
1453
1454         usr->logon_time            = logon_time;
1455         usr->logoff_time           = logoff_time;
1456         usr->kickoff_time          = kickoff_time;
1457         usr->pass_last_set_time    = pass_last_set_time;
1458         usr->pass_can_change_time  = pass_can_change_time;
1459         usr->pass_must_change_time = pass_must_change_time;
1460
1461         usr->logon_count = logon_count;
1462         usr->bad_pw_count = bad_pw_count;
1463
1464         usr->user_rid = user_rid;
1465         usr->group_rid = group_rid;
1466         usr->num_groups = num_groups;
1467
1468         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1469         usr->user_flgs = user_flgs;
1470         usr->acct_flags = acct_flags;
1471
1472         if (user_session_key != NULL)
1473                 memcpy(usr->user_sess_key, user_session_key, sizeof(usr->user_sess_key));
1474         else
1475                 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1476
1477         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1478
1479         memset((char *)usr->lm_sess_key, '\0', sizeof(usr->lm_sess_key));
1480
1481         for (i=0; i<7; i++) {
1482                 memset(&usr->unknown[i], '\0', sizeof(usr->unknown));
1483         }
1484
1485         if (lm_session_key != NULL) {
1486                 memcpy(usr->lm_sess_key, lm_session_key, sizeof(usr->lm_sess_key));
1487         }
1488
1489         num_other_sids = init_dom_sid2s(ctx, NULL, &usr->other_sids);
1490
1491         usr->num_other_sids = num_other_sids;
1492         usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
1493         
1494         init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
1495         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
1496         init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
1497         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
1498         init_unistr2(&usr->uni_logon_script, logon_script, UNI_FLAGS_NONE);
1499         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
1500         init_unistr2(&usr->uni_profile_path, profile_path, UNI_FLAGS_NONE);
1501         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
1502         init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
1503         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
1504         init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
1505         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
1506
1507         usr->num_groups2 = num_groups;
1508
1509         usr->gids = TALLOC_ZERO_ARRAY(ctx,DOM_GID,num_groups);
1510         if (usr->gids == NULL && num_groups>0)
1511                 return;
1512
1513         for (i = 0; i < num_groups; i++) 
1514                 usr->gids[i] = gids[i]; 
1515                 
1516         init_unistr2(&usr->uni_logon_srv, logon_srv, UNI_FLAGS_NONE);
1517         init_uni_hdr(&usr->hdr_logon_srv, &usr->uni_logon_srv);
1518         init_unistr2(&usr->uni_logon_dom, logon_dom, UNI_FLAGS_NONE);
1519         init_uni_hdr(&usr->hdr_logon_dom, &usr->uni_logon_dom);
1520
1521         init_dom_sid2(&usr->dom_sid, dom_sid);
1522         /* "other" sids are set up above */
1523 }
1524
1525  void dump_acct_flags(uint32 acct_flags) {
1526
1527         int lvl = 10;
1528         DEBUG(lvl,("dump_acct_flags\n"));
1529         if (acct_flags & ACB_NORMAL) {
1530                 DEBUGADD(lvl,("\taccount has ACB_NORMAL\n"));
1531         }
1532         if (acct_flags & ACB_PWNOEXP) {
1533                 DEBUGADD(lvl,("\taccount has ACB_PWNOEXP\n"));
1534         }
1535         if (acct_flags & ACB_ENC_TXT_PWD_ALLOWED) {
1536                 DEBUGADD(lvl,("\taccount has ACB_ENC_TXT_PWD_ALLOWED\n"));
1537         }
1538         if (acct_flags & ACB_NOT_DELEGATED) {
1539                 DEBUGADD(lvl,("\taccount has ACB_NOT_DELEGATED\n"));
1540         }
1541         if (acct_flags & ACB_USE_DES_KEY_ONLY) {
1542                 DEBUGADD(lvl,("\taccount has ACB_USE_DES_KEY_ONLY set, sig verify wont work\n"));
1543         }
1544         if (acct_flags & ACB_NO_AUTH_DATA_REQD) {
1545                 DEBUGADD(lvl,("\taccount has ACB_NO_AUTH_DATA_REQD set\n"));
1546         }
1547         if (acct_flags & ACB_PWEXPIRED) {
1548                 DEBUGADD(lvl,("\taccount has ACB_PWEXPIRED set\n"));
1549         }
1550 }
1551
1552  void dump_user_flgs(uint32 user_flags) {
1553
1554         int lvl = 10;
1555         DEBUG(lvl,("dump_user_flgs\n"));
1556         if (user_flags & LOGON_EXTRA_SIDS) {
1557                 DEBUGADD(lvl,("\taccount has LOGON_EXTRA_SIDS\n"));
1558         }
1559         if (user_flags & LOGON_RESOURCE_GROUPS) {
1560                 DEBUGADD(lvl,("\taccount has LOGON_RESOURCE_GROUPS\n"));
1561         }
1562         if (user_flags & LOGON_NTLMV2_ENABLED) {
1563                 DEBUGADD(lvl,("\taccount has LOGON_NTLMV2_ENABLED\n"));
1564         }
1565         if (user_flags & LOGON_CACHED_ACCOUNT) {
1566                 DEBUGADD(lvl,("\taccount has LOGON_CACHED_ACCOUNT\n"));
1567         }
1568         if (user_flags & LOGON_PROFILE_PATH_RETURNED) {
1569                 DEBUGADD(lvl,("\taccount has LOGON_PROFILE_PATH_RETURNED\n"));
1570         }
1571         if (user_flags & LOGON_SERVER_TRUST_ACCOUNT) {
1572                 DEBUGADD(lvl,("\taccount has LOGON_SERVER_TRUST_ACCOUNT\n"));
1573         }
1574
1575
1576 }
1577
1578 /*******************************************************************
1579  This code has been modified to cope with a NET_USER_INFO_2 - which is
1580  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1581  We use validation level to determine if we're marshalling a info 2 or
1582  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1583  Jacobsen at HP. JRA.
1584 ********************************************************************/
1585
1586 BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, 
1587                        int depth, uint16 validation_level, BOOL kerb_validation_level)
1588 {
1589         unsigned int i;
1590
1591         if (usr == NULL)
1592                 return False;
1593
1594         prs_debug(ps, depth, desc, "net_io_user_info3");
1595         depth++;
1596
1597         if (UNMARSHALLING(ps))
1598                 ZERO_STRUCTP(usr);
1599
1600         if(!prs_align(ps))
1601                 return False;
1602         
1603         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1604                 return False;
1605
1606         if (usr->ptr_user_info == 0)
1607                 return True;
1608
1609         if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
1610                 return False;
1611         if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
1612                 return False;
1613         if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1614                 return False;
1615         if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1616                 return False;
1617         if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1618                 return False;
1619         if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1620                 return False;
1621
1622         if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1623                 return False;
1624         if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1625                 return False;
1626         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1627                 return False;
1628         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1629                 return False;
1630         if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1631                 return False;
1632         if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1633                 return False;
1634
1635         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1636                 return False;
1637         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1638                 return False;
1639
1640         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User RID */
1641                 return False;
1642         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group RID */
1643                 return False;
1644         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1645                 return False;
1646         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1647                 return False;
1648         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1649                 return False;
1650         dump_user_flgs(usr->user_flgs);
1651         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* user session key */
1652                 return False;
1653
1654         if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1655                 return False;
1656         if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1657                 return False;
1658
1659         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1660                 return False;
1661
1662         if(!prs_uint8s(False, "lm_sess_key", ps, depth, usr->lm_sess_key, 8)) /* lm session key */
1663                 return False;
1664
1665         if(!prs_uint32("acct_flags ", ps, depth, &usr->acct_flags)) /* Account flags  */
1666                 return False;
1667         dump_acct_flags(usr->acct_flags);
1668         for (i = 0; i < 7; i++)
1669         {
1670                 if (!prs_uint32("unkown", ps, depth, &usr->unknown[i])) /* unknown */
1671                         return False;
1672         }
1673
1674         if (validation_level == 3) {
1675                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1676                         return False;
1677                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1678                         return False;
1679         } else {
1680                 if (UNMARSHALLING(ps)) {
1681                         usr->num_other_sids = 0;
1682                         usr->buffer_other_sids = 0;
1683                 }
1684         }
1685                 
1686         /* get kerb validation info (not really part of user_info_3) - Guenther */
1687
1688         if (kerb_validation_level) {
1689
1690                 if(!prs_uint32("ptr_res_group_dom_sid", ps, depth, &usr->ptr_res_group_dom_sid))
1691                         return False;
1692                 if(!prs_uint32("res_group_count", ps, depth, &usr->res_group_count))
1693                         return False;
1694                 if(!prs_uint32("ptr_res_groups", ps, depth, &usr->ptr_res_groups))
1695                         return False;
1696         }
1697
1698         if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1699                 return False;
1700         if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1701                 return False;
1702         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1703                 return False;
1704         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1705                 return False;
1706         if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1707                 return False;
1708         if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1709                 return False;
1710
1711         if(!prs_align(ps))
1712                 return False;
1713
1714         if (usr->num_groups > 0) {
1715
1716                 if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups2 */
1717                         return False;
1718
1719                 if (usr->num_groups != usr->num_groups2) {
1720                         DEBUG(3,("net_io_user_info3: num_groups mismatch! (%d != %d)\n", 
1721                         usr->num_groups, usr->num_groups2));
1722                         return False;
1723                 }
1724
1725
1726                 if (UNMARSHALLING(ps)) {
1727                         usr->gids = PRS_ALLOC_MEM(ps, DOM_GID, usr->num_groups);
1728                         if (usr->gids == NULL)
1729                                 return False;
1730                 }
1731
1732                 for (i = 0; i < usr->num_groups; i++) {
1733                         if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1734                                 return False;
1735                 }
1736                 
1737         }
1738
1739         if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1740                 return False;
1741         if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_dom.buffer, ps, depth)) /* logon domain unicode string */
1742                 return False;
1743
1744         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1745                 return False;
1746
1747         if (validation_level == 3 && usr->buffer_other_sids) {
1748
1749                 uint32 num_other_sids = usr->num_other_sids;
1750
1751                 if (!(usr->user_flgs & LOGON_EXTRA_SIDS)) {
1752                         DEBUG(10,("net_io_user_info3: user_flgs attribute does not have LOGON_EXTRA_SIDS\n"));
1753                         /* return False; */
1754                 }
1755
1756                 if (!prs_uint32("num_other_sids", ps, depth,
1757                                 &num_other_sids))
1758                         return False;
1759
1760                 if (num_other_sids != usr->num_other_sids)
1761                         return False;
1762
1763                 if (UNMARSHALLING(ps)) {
1764                         usr->other_sids = PRS_ALLOC_MEM(ps, DOM_SID2, usr->num_other_sids);
1765                         usr->other_sids_attrib =
1766                                 PRS_ALLOC_MEM(ps, uint32, usr->num_other_sids);
1767                                                                
1768                         if ((num_other_sids != 0) &&
1769                             ((usr->other_sids == NULL) ||
1770                              (usr->other_sids_attrib == NULL)))
1771                                 return False;
1772                 }
1773
1774                 /* First the pointers to the SIDS and attributes */
1775
1776                 depth++;
1777
1778                 for (i=0; i<usr->num_other_sids; i++) {
1779                         uint32 ptr = 1;
1780
1781                         if (!prs_uint32("sid_ptr", ps, depth, &ptr))
1782                                 return False;
1783
1784                         if (UNMARSHALLING(ps) && (ptr == 0))
1785                                 return False;
1786
1787                         if (!prs_uint32("attribute", ps, depth,
1788                                         &usr->other_sids_attrib[i]))
1789                                 return False;
1790                 }
1791         
1792                 for (i = 0; i < usr->num_other_sids; i++) {
1793                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1794                                 return False;
1795                 }
1796
1797                 depth--;
1798         }
1799
1800         return True;
1801 }
1802
1803 /*******************************************************************
1804  Reads or writes a structure.
1805 ********************************************************************/
1806
1807 BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1808 {
1809         if (q_l == NULL)
1810                 return False;
1811
1812         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1813         depth++;
1814
1815         if(!prs_align(ps))
1816                 return False;
1817         
1818         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1819                 return False;
1820
1821         if(!prs_align_uint16(ps))
1822                 return False;
1823
1824         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1825                 return False;
1826
1827         return True;
1828 }
1829
1830 /*******************************************************************
1831  Reads or writes a structure.
1832 ********************************************************************/
1833
1834 BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1835 {
1836         if (r_l == NULL)
1837                 return False;
1838
1839         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1840         depth++;
1841
1842         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1843                 return False;
1844         if (&r_l->buffer_creds) {
1845                 if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1846                         return False;
1847         }
1848
1849         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1850                 return False;
1851         if(!prs_align(ps))
1852                 return False;
1853
1854 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1855         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1856                 return False;
1857 #else
1858         if (r_l->switch_value != 0) {
1859                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1860                         return False;
1861         }
1862 #endif
1863
1864         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1865                 return False;
1866
1867         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1868                 return False;
1869
1870         if(!prs_align(ps))
1871                 return False;
1872
1873         return True;
1874 }
1875
1876 /*******************************************************************
1877  Reads or writes a structure.
1878 ********************************************************************/
1879
1880 BOOL net_io_q_sam_logon_ex(const char *desc, NET_Q_SAM_LOGON_EX *q_l, prs_struct *ps, int depth)
1881 {
1882         if (q_l == NULL)
1883                 return False;
1884
1885         prs_debug(ps, depth, desc, "net_io_q_sam_logon_ex");
1886         depth++;
1887
1888         if(!prs_align(ps))
1889                 return False;
1890         
1891         if(!smb_io_sam_info_ex("", &q_l->sam_id, ps, depth))
1892                 return False;
1893
1894         if(!prs_align_uint16(ps))
1895                 return False;
1896
1897         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1898                 return False;
1899
1900         if(!prs_uint32("flags  ", ps, depth, &q_l->flags))
1901                 return False;
1902
1903         return True;
1904 }
1905
1906 /*******************************************************************
1907  Reads or writes a structure.
1908 ********************************************************************/
1909
1910 BOOL net_io_r_sam_logon_ex(const char *desc, NET_R_SAM_LOGON_EX *r_l, prs_struct *ps, int depth)
1911 {
1912         if (r_l == NULL)
1913                 return False;
1914
1915         prs_debug(ps, depth, desc, "net_io_r_sam_logon_ex");
1916         depth++;
1917
1918         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1919                 return False;
1920         if(!prs_align(ps))
1921                 return False;
1922
1923 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1924         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1925                 return False;
1926 #else
1927         if (r_l->switch_value != 0) {
1928                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1929                         return False;
1930         }
1931 #endif
1932
1933         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1934                 return False;
1935
1936         if(!prs_uint32("flags   ", ps, depth, &r_l->flags))
1937                 return False;
1938
1939         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1940                 return False;
1941
1942         if(!prs_align(ps))
1943                 return False;
1944
1945         return True;
1946 }
1947
1948
1949 /*******************************************************************
1950  Reads or writes a structure.
1951 ********************************************************************/
1952
1953 BOOL net_io_q_sam_logoff(const char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1954 {
1955         if (q_l == NULL)
1956                 return False;
1957
1958         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1959         depth++;
1960
1961         if(!prs_align(ps))
1962                 return False;
1963         
1964         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1965                 return False;
1966
1967         return True;
1968 }
1969
1970 /*******************************************************************
1971  Reads or writes a structure.
1972 ********************************************************************/
1973
1974 BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1975 {
1976         if (r_l == NULL)
1977                 return False;
1978
1979         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1980         depth++;
1981
1982         if(!prs_align(ps))
1983                 return False;
1984         
1985         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1986                 return False;
1987         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1988                 return False;
1989
1990         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1991                 return False;
1992
1993         return True;
1994 }
1995
1996 /*******************************************************************
1997 makes a NET_Q_SAM_SYNC structure.
1998 ********************************************************************/
1999 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
2000                          const char *cli_name, DOM_CRED *cli_creds, 
2001                          DOM_CRED *ret_creds, uint32 database_id, 
2002                          uint32 next_rid)
2003 {
2004         DEBUG(5, ("init_q_sam_sync\n"));
2005
2006         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
2007         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
2008
2009         if (cli_creds)
2010                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
2011
2012         if (cli_creds)
2013                 memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
2014         else
2015                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
2016
2017         q_s->database_id = database_id;
2018         q_s->restart_state = 0;
2019         q_s->sync_context = next_rid;
2020         q_s->max_size = 0xffff;
2021
2022         return True;
2023 }
2024
2025 /*******************************************************************
2026 reads or writes a structure.
2027 ********************************************************************/
2028 BOOL net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
2029                        int depth)
2030 {
2031         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
2032         depth++;
2033
2034         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
2035                 return False;
2036         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
2037                 return False;
2038
2039         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
2040                 return False;
2041         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
2042                 return False;
2043
2044         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
2045                 return False;
2046         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
2047                 return False;
2048         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
2049                 return False;
2050
2051         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
2052                 return False;
2053
2054         return True;
2055 }
2056
2057 /*******************************************************************
2058 reads or writes a structure.
2059 ********************************************************************/
2060 static BOOL net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta,
2061                                  prs_struct *ps, int depth)
2062 {
2063         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
2064         depth++;
2065
2066         if (!prs_uint16("type", ps, depth, &delta->type))
2067                 return False;
2068         if (!prs_uint16("type2", ps, depth, &delta->type2))
2069                 return False;
2070         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
2071                 return False;
2072
2073         if (!prs_uint32("type3", ps, depth, &delta->type3))
2074                 return False;
2075
2076         /* Not sure why we need this but it seems to be necessary to get
2077            sam deltas working. */
2078
2079         if (delta->type != 0x16) {
2080                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
2081                         return False;
2082         }
2083
2084         return True;
2085 }
2086
2087 /*******************************************************************
2088 reads or writes a structure.
2089 ********************************************************************/
2090 static BOOL net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info,
2091                                    prs_struct *ps, int depth)
2092 {
2093         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
2094         depth++;
2095
2096         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
2097                 return False;
2098         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
2099                         &info->dom_mod_count_ptr))
2100                 return False;
2101
2102         if (info->dom_mod_count_ptr) {
2103                 if (!prs_uint64("dom_mod_count", ps, depth,
2104                                 &info->dom_mod_count))
2105                         return False;
2106         }
2107
2108         return True;
2109 }
2110
2111 /*******************************************************************
2112 reads or writes a structure.
2113 ********************************************************************/
2114 static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
2115                                    prs_struct *ps, int depth)
2116 {
2117         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
2118         depth++;
2119
2120         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2121                 return False;
2122         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
2123                 return False;
2124
2125         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
2126                 return False;
2127         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
2128                 return False;
2129         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
2130                 return False;
2131         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
2132                 return False;
2133         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
2134                 return False;
2135         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
2136                 return False;
2137         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
2138                 return False;
2139         if (!prs_uint32("security_information", ps, depth, &info->security_information))
2140                 return False;
2141         if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2142                 return False;
2143         if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
2144                 return False;
2145         if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
2146                 return False;
2147         if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
2148                 return False;
2149         if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
2150                 return False;
2151         if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
2152                 return False;
2153         if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
2154                 return False;
2155         if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
2156                 return False;
2157         if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
2158                 return False;
2159
2160         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
2161                             info->hdr_dom_name.buffer, ps, depth))
2162                 return False;
2163         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
2164                             info->hdr_oem_info.buffer, ps, depth))
2165                 return False;
2166
2167         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2168                 return False;
2169
2170         if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout, 
2171                                         info->hdr_account_lockout.buffer, ps, depth))
2172                 return False;
2173
2174         if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2, 
2175                             info->hdr_unknown2.buffer, ps, depth))
2176                 return False;
2177         if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3, 
2178                             info->hdr_unknown3.buffer, ps, depth))
2179                 return False;
2180         if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4, 
2181                             info->hdr_unknown4.buffer, ps, depth))
2182                 return False;
2183
2184         return True;
2185 }
2186
2187 /*******************************************************************
2188 reads or writes a structure.
2189 ********************************************************************/
2190 static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
2191                                   prs_struct *ps, int depth)
2192 {
2193         prs_debug(ps, depth, desc, "net_io_sam_group_info");
2194         depth++;
2195
2196         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
2197                 return False;
2198         if (!smb_io_gid("gid", &info->gid, ps, depth))
2199                 return False;
2200         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
2201                 return False;
2202         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2203                 return False;
2204
2205         if (ps->data_offset + 48 > ps->buffer_size)
2206                 return False;
2207         ps->data_offset += 48;
2208
2209         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
2210                             info->hdr_grp_name.buffer, ps, depth))
2211                 return False;
2212         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
2213                             info->hdr_grp_desc.buffer, ps, depth))
2214                 return False;
2215         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2216                 return False;
2217
2218         return True;
2219 }
2220
2221 /*******************************************************************
2222 reads or writes a structure.
2223 ********************************************************************/
2224 static BOOL net_io_sam_passwd_info(const char *desc, SAM_PWD * pwd,
2225                                    prs_struct *ps, int depth)
2226 {
2227         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
2228         depth++;
2229
2230         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
2231                 return False;
2232
2233         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
2234                 return False;
2235         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
2236                 return False;
2237
2238         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
2239                 return False;
2240         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
2241                 return False;
2242
2243         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
2244                 return False;
2245         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
2246                 return False;
2247
2248         return True;
2249 }
2250
2251 /*******************************************************************
2252 reads or writes a structure.
2253 ********************************************************************/
2254 static BOOL net_io_sam_account_info(const char *desc, SAM_ACCOUNT_INFO *info,
2255                                 prs_struct *ps, int depth)
2256 {
2257         BUFHDR2 hdr_priv_data;
2258         uint32 i;
2259
2260         prs_debug(ps, depth, desc, "net_io_sam_account_info");
2261         depth++;
2262
2263         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
2264                 return False;
2265         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
2266                 return False;
2267
2268         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
2269                 return False;
2270         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
2271                 return False;
2272
2273         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
2274                 return False;
2275         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
2276                 return False;
2277         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
2278                            depth))
2279                 return False;
2280
2281         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
2282                 return False;
2283         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
2284                            depth))
2285                 return False;
2286
2287         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
2288                 return False;
2289         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
2290                 return False;
2291
2292         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
2293                 return False;
2294         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
2295                 return False;
2296
2297         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
2298                 return False;
2299         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
2300                 return False;
2301         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
2302                          depth))
2303                 return False;
2304         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
2305                          depth))
2306                 return False;
2307
2308         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
2309                 return False;
2310         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
2311                 return False;
2312         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
2313                 return False;
2314         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
2315                 return False;
2316         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
2317                 return False;
2318         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
2319                 return False;
2320
2321         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
2322                 return False;
2323         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
2324                            depth))
2325                 return False;
2326         if (!prs_uint16("country", ps, depth, &info->country))
2327                 return False;
2328         if (!prs_uint16("codepage", ps, depth, &info->codepage))
2329                 return False;
2330
2331         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
2332                 return False;
2333         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2334                 return False;
2335         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
2336                 return False;
2337
2338         for (i = 0; i < 3; i++)
2339         {
2340                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
2341                                    ps, depth))
2342                         return False;                                          
2343         }
2344
2345         for (i = 0; i < 4; i++)
2346         {
2347                 if (!prs_uint32("dw_reserved", ps, depth, 
2348                                 &info->dw_reserved[i]))
2349                         return False;
2350         }
2351
2352         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2353                             info->hdr_acct_name.buffer, ps, depth))
2354                 return False;
2355         prs_align(ps);
2356         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2357                             info->hdr_full_name.buffer, ps, depth))
2358                 return False;
2359         prs_align(ps);
2360         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2361                             info->hdr_home_dir.buffer, ps, depth))
2362                 return False;
2363         prs_align(ps);
2364         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2365                             info->hdr_dir_drive.buffer, ps, depth))
2366                 return False;
2367         prs_align(ps);
2368         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2369                             info->hdr_logon_script.buffer, ps, depth))
2370                 return False;
2371         prs_align(ps);
2372         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2373                             info->hdr_acct_desc.buffer, ps, depth))
2374                 return False;
2375         prs_align(ps);
2376         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2377                             info->hdr_workstations.buffer, ps, depth))
2378                 return False;
2379         prs_align(ps);
2380
2381         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2382                 return False;
2383         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2384                 return False;
2385
2386         if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth))
2387                 return False;
2388         prs_align(ps);
2389         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2390                             info->hdr_comment.buffer, ps, depth))
2391                 return False;
2392         prs_align(ps);
2393         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2394                             info->hdr_parameters.buffer, ps, depth))
2395                 return False;
2396         prs_align(ps);
2397         if (hdr_priv_data.buffer != 0)
2398         {
2399                 int old_offset = 0;
2400                 uint32 len = 0x44;
2401                 if (!prs_uint32("pwd_len", ps, depth, &len))
2402                         return False;
2403                 old_offset = ps->data_offset;
2404                 if (len > 0)
2405                 {
2406                         if (ps->io)
2407                         {
2408                                 /* reading */
2409                                 if (!prs_hash1(ps, ps->data_offset, len))
2410                                         return False;
2411                         }
2412                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2413                                                     ps, depth))
2414                                 return False;
2415
2416                         if (!ps->io)
2417                         {
2418                                 /* writing */
2419                                 if (!prs_hash1(ps, old_offset, len))
2420                                         return False;
2421                         }
2422                 }
2423                 if (old_offset + len > ps->buffer_size)
2424                         return False;
2425                 ps->data_offset = old_offset + len;
2426         }
2427         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2428                 return False;
2429         prs_align(ps);
2430         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2431                             info->hdr_profile.buffer, ps, depth))
2432                 return False;
2433
2434         prs_align(ps);
2435
2436         return True;
2437 }
2438
2439 /*******************************************************************
2440 reads or writes a structure.
2441 ********************************************************************/
2442 static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * info,
2443                                       prs_struct *ps, int depth)
2444 {
2445         uint32 i;
2446         fstring tmp;
2447
2448         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2449         depth++;
2450
2451         prs_align(ps);
2452         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2453                 return False;
2454         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2455                 return False;
2456         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2457                 return False;
2458
2459         if (ps->data_offset + 16 > ps->buffer_size)
2460                 return False;
2461         ps->data_offset += 16;
2462
2463         if (info->ptr_rids != 0)
2464         {
2465                 if (!prs_uint32("num_members2", ps, depth, 
2466                                 &info->num_members2))
2467                         return False;
2468
2469                 if (info->num_members2 != info->num_members)
2470                 {
2471                         /* RPC fault */
2472                         return False;
2473                 }
2474
2475                 info->rids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members2);
2476
2477                 if (info->rids == NULL) {
2478                         DEBUG(0, ("out of memory allocating %d rids\n",
2479                                   info->num_members2));
2480                         return False;
2481                 }
2482
2483                 for (i = 0; i < info->num_members2; i++)
2484                 {
2485                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2486                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2487                                 return False;
2488                 }
2489         }
2490
2491         if (info->ptr_attribs != 0)
2492         {
2493                 if (!prs_uint32("num_members3", ps, depth, 
2494                                 &info->num_members3))
2495                         return False;
2496                 if (info->num_members3 != info->num_members)
2497                 {
2498                         /* RPC fault */
2499                         return False;
2500                 }
2501
2502                 info->attribs = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members3);
2503
2504                 if (info->attribs == NULL) {
2505                         DEBUG(0, ("out of memory allocating %d attribs\n",
2506                                   info->num_members3));
2507                         return False;
2508                 }
2509
2510                 for (i = 0; i < info->num_members3; i++)
2511                 {
2512                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2513                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2514                                 return False;
2515                 }
2516         }
2517
2518         return True;
2519 }
2520
2521 /*******************************************************************
2522 reads or writes a structure.
2523 ********************************************************************/
2524 static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
2525                                   prs_struct *ps, int depth)
2526 {
2527         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2528         depth++;
2529
2530         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2531                 return False;
2532         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2533                 return False;
2534         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2535                 return False;
2536         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2537                 return False;
2538
2539         if (ps->data_offset + 40 > ps->buffer_size)
2540                 return False;
2541         ps->data_offset += 40;
2542
2543         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2544                             info->hdr_als_name.buffer, ps, depth))
2545                 return False;
2546         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2547                 return False;
2548
2549         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2550                             info->hdr_als_desc.buffer, ps, depth))
2551                 return False;
2552
2553         return True;
2554 }
2555
2556 /*******************************************************************
2557 reads or writes a structure.
2558 ********************************************************************/
2559 static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info,
2560                                       prs_struct *ps, int depth)
2561 {
2562         uint32 i;
2563         fstring tmp;
2564
2565         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2566         depth++;
2567
2568         prs_align(ps);
2569         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2570                 return False;
2571         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2572                 return False;
2573
2574         if (ps->data_offset + 16 > ps->buffer_size)
2575                 return False;
2576         ps->data_offset += 16;
2577
2578         if (info->ptr_members != 0)
2579         {
2580                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2581                         return False;
2582                 if (info->num_sids != info->num_members)
2583                 {
2584                         /* RPC fault */
2585                         return False;
2586                 }
2587
2588                 info->ptr_sids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_sids);
2589                 
2590                 if (info->ptr_sids == NULL) {
2591                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2592                                   info->num_sids));
2593                         return False;
2594                 }
2595
2596                 for (i = 0; i < info->num_sids; i++)
2597                 {
2598                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2599                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2600                                 return False;
2601                 }
2602
2603                 info->sids = TALLOC_ARRAY(ps->mem_ctx, DOM_SID2, info->num_sids);
2604
2605                 if (info->sids == NULL) {
2606                         DEBUG(0, ("error allocating %d sids\n",
2607                                   info->num_sids));
2608                         return False;
2609                 }
2610
2611                 for (i = 0; i < info->num_sids; i++)
2612                 {
2613                         if (info->ptr_sids[i] != 0)
2614                         {
2615                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2616                                          i);
2617                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2618                                                      ps, depth))
2619                                         return False;
2620                         }
2621                 }
2622         }
2623
2624         return True;
2625 }
2626
2627 /*******************************************************************
2628 reads or writes a structure.
2629 ********************************************************************/
2630 static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
2631                                       prs_struct *ps, int depth)
2632 {
2633         unsigned int i;
2634         prs_debug(ps, depth, desc, "net_io_sam_policy_info");
2635         depth++;
2636
2637         if(!prs_align(ps))
2638                 return False;
2639
2640         if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
2641                 return False;
2642         if (!prs_uint64("audit_retention_period", ps, depth,
2643                         &info->audit_retention_period))
2644                 return False;
2645         if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
2646                 return False;
2647         if (!prs_uint32("num_events", ps, depth, &info->num_events))
2648                 return False;
2649         if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
2650                 return False;
2651
2652         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2653                 return False;
2654
2655         if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
2656                 return False;
2657
2658         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2659                 return False;
2660         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2661                         &info->non_paged_pool_limit))
2662                 return False;
2663         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2664                 return False;
2665         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2666                 return False;
2667         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2668                 return False;
2669         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2670                 return False;
2671         if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
2672                 return False;
2673         if (!smb_io_time("create_time", &info->create_time, ps, depth))
2674                 return False;
2675         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2676                 return False;
2677
2678         for (i=0; i<4; i++) {
2679                 UNIHDR dummy;
2680                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2681                         return False;
2682         }
2683
2684         for (i=0; i<4; i++) {
2685                 uint32 reserved;
2686                 if (!prs_uint32("reserved", ps, depth, &reserved))
2687                         return False;
2688         }
2689
2690         if (!prs_uint32("num_event_audit_options", ps, depth,
2691                         &info->num_event_audit_options))
2692                 return False;
2693
2694         for (i=0; i<info->num_event_audit_options; i++)
2695                 if (!prs_uint32("event_audit_option", ps, depth,
2696                                 &info->event_audit_option))
2697                         return False;
2698
2699         if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2700                 return False;
2701
2702         if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2703                 return False;
2704
2705         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2706
2707                 return False;
2708
2709         return True;
2710 }
2711
2712 #if 0
2713
2714 /* This function is pretty broken - see bug #334 */
2715
2716 /*******************************************************************
2717 reads or writes a structure.
2718 ********************************************************************/
2719 static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
2720                                       prs_struct *ps, int depth)
2721 {
2722         int i;
2723
2724         prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
2725         depth++;
2726
2727         if(!prs_align(ps))
2728                 return False;
2729
2730         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2731                 return False;
2732
2733         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2734                 return False;
2735
2736         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2737                 return False;
2738
2739         if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2740                 return False;
2741
2742         if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2743                 return False;
2744         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2745                 return False;
2746         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2747                 return False;
2748
2749         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2750                 return False;
2751         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2752                 return False;
2753
2754         for (i=0; i<12; i++)
2755                 if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2756                         return False;
2757
2758         if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2759                 return False;
2760
2761         return True;
2762 }
2763
2764 #endif
2765
2766 #if 0
2767
2768 /* This function doesn't work - see bug #334 */
2769
2770 /*******************************************************************
2771 reads or writes a structure.
2772 ********************************************************************/
2773 static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
2774                                    prs_struct *ps, int depth)
2775 {
2776         int i;
2777
2778         prs_debug(ps, depth, desc, "net_io_sam_secret_info");
2779         depth++;
2780
2781         if(!prs_align(ps))
2782                 return False;
2783
2784         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2785                 return False;
2786
2787         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2788                 return False;
2789
2790         if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2791                 return False;
2792
2793         if(!prs_align(ps))
2794                 return False;
2795
2796         if(!prs_uint32("count1", ps, depth, &info->count1))
2797                 return False;
2798         if(!prs_uint32("count2", ps, depth, &info->count2))
2799                 return False;
2800         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2801                 return False;
2802
2803
2804         if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2805                 return False;
2806         if(!prs_uint32("count3", ps, depth, &info->count3))
2807                 return False;
2808         if(!prs_uint32("count4", ps, depth, &info->count4))
2809                 return False;
2810         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2811                 return False;
2812         if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2813                 return False;
2814         if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2815                 return False;
2816
2817
2818         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2819                 return False;
2820         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2821                 return False;
2822         for(i=0; i<12; i++)
2823                 if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2824                         return False;
2825
2826         if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2827                 return False;
2828         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2829                 return False;
2830         if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2831                 return False;
2832
2833         if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2834                 return False;
2835
2836         if(!prs_uint32("key_len", ps, depth, &info->key_len))
2837                 return False;
2838         if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2839                 return False;
2840         if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2841                 return False;
2842
2843         if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2844                 return False;
2845
2846
2847         if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2848                 return False;
2849
2850         if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2851                 return False;
2852
2853
2854         return True;
2855 }
2856
2857 #endif
2858
2859 /*******************************************************************
2860 reads or writes a structure.
2861 ********************************************************************/
2862 static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
2863                                       prs_struct *ps, int depth)
2864 {
2865         unsigned int i;
2866
2867         prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2868         depth++;
2869
2870         if(!prs_align(ps))
2871                 return False;
2872
2873         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2874                 return False;
2875
2876         if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2877                 return False;
2878         if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
2879                 return False;
2880
2881         if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
2882                 return False;
2883         if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
2884                 return False;
2885
2886         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2887                 return False;
2888         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2889                         &info->non_paged_pool_limit))
2890                 return False;
2891         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2892                 return False;
2893         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2894                 return False;
2895         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2896                 return False;
2897         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2898                 return False;
2899         if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
2900                 return False;
2901         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2902                 return False;
2903
2904         for (i=0; i<4; i++) {
2905                 UNIHDR dummy;
2906                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2907                         return False;
2908         }
2909
2910         for (i=0; i<4; i++) {
2911                 uint32 reserved;
2912                 if (!prs_uint32("reserved", ps, depth, &reserved))
2913                         return False;
2914         }
2915
2916         if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2917                 return False;
2918
2919         info->attributes = TALLOC_ARRAY(ps->mem_ctx, uint32, info->attribute_count);
2920
2921         for (i=0; i<info->attribute_count; i++)
2922                 if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2923                         return False;
2924
2925         if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2926                 return False;
2927
2928         info->hdr_privslist = TALLOC_ARRAY(ps->mem_ctx, UNIHDR, info->privlist_count);
2929         info->uni_privslist = TALLOC_ARRAY(ps->mem_ctx, UNISTR2, info->privlist_count);
2930
2931         for (i=0; i<info->privlist_count; i++)
2932                 if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2933                         return False;
2934
2935         for (i=0; i<info->privlist_count; i++)
2936                 if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2937                         return False;
2938
2939         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2940                 return False;
2941
2942         return True;
2943 }
2944
2945 /*******************************************************************
2946 reads or writes a structure.
2947 ********************************************************************/
2948 static BOOL net_io_sam_delta_ctr(const char *desc,
2949                                  SAM_DELTA_CTR * delta, uint16 type,
2950                                  prs_struct *ps, int depth)
2951 {
2952         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2953         depth++;
2954
2955         switch (type) {
2956                 /* Seen in sam deltas */
2957                 case SAM_DELTA_MODIFIED_COUNT:
2958                         if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
2959                                 return False;
2960                         break;
2961
2962                 case SAM_DELTA_DOMAIN_INFO:
2963                         if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2964                                 return False;
2965                         break;
2966
2967                 case SAM_DELTA_GROUP_INFO:
2968                         if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2969                                 return False;
2970                         break;
2971
2972                 case SAM_DELTA_ACCOUNT_INFO:
2973                         if (!net_io_sam_account_info("", &delta->account_info, ps, depth))
2974                                 return False;
2975                         break;
2976
2977                 case SAM_DELTA_GROUP_MEM:
2978                         if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2979                                 return False;
2980                         break;
2981
2982                 case SAM_DELTA_ALIAS_INFO:
2983                         if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2984                                 return False;
2985                         break;
2986
2987                 case SAM_DELTA_POLICY_INFO:
2988                         if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
2989                                 return False;
2990                         break;
2991
2992                 case SAM_DELTA_ALIAS_MEM:
2993                         if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2994                                 return False;
2995                         break;
2996
2997                 case SAM_DELTA_PRIVS_INFO:
2998                         if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2999                                 return False;
3000                         break;
3001
3002                         /* These guys are implemented but broken */
3003
3004                 case SAM_DELTA_TRUST_DOMS:
3005                 case SAM_DELTA_SECRET_INFO:
3006                         break;
3007
3008                         /* These guys are not implemented yet */
3009
3010                 case SAM_DELTA_RENAME_GROUP:
3011                 case SAM_DELTA_RENAME_USER:
3012                 case SAM_DELTA_RENAME_ALIAS:
3013                 case SAM_DELTA_DELETE_GROUP:
3014                 case SAM_DELTA_DELETE_USER:
3015                 default:
3016                         DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
3017                         break;
3018         }
3019
3020         return True;
3021 }
3022
3023 /*******************************************************************
3024 reads or writes a structure.
3025 ********************************************************************/
3026 BOOL net_io_r_sam_sync(const char *desc,
3027                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
3028 {
3029         uint32 i;
3030
3031         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
3032         depth++;
3033
3034         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
3035                 return False;
3036         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
3037                 return False;
3038
3039         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
3040                 return False;
3041         if (r_s->ptr_deltas != 0)
3042         {
3043                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
3044                         return False;
3045                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
3046                         return False;
3047                 if (r_s->ptr_deltas2 != 0)
3048                 {
3049                         if (!prs_uint32("num_deltas2", ps, depth,
3050                                         &r_s->num_deltas2))
3051                                 return False;
3052
3053                         if (r_s->num_deltas2 != r_s->num_deltas)
3054                         {
3055                                 /* RPC fault */
3056                                 return False;
3057                         }
3058
3059                         if (r_s->num_deltas2 > 0) {
3060                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas2);
3061                                 if (r_s->hdr_deltas == NULL) {
3062                                         DEBUG(0, ("error tallocating memory "
3063                                                   "for %d delta headers\n", 
3064                                                   r_s->num_deltas2));
3065                                         return False;
3066                                 }
3067                         }
3068
3069                         for (i = 0; i < r_s->num_deltas2; i++)
3070                         {
3071                                 if (!net_io_sam_delta_hdr("", 
3072                                                           &r_s->hdr_deltas[i],
3073                                                           ps, depth))
3074                                         return False;
3075                         }
3076
3077                         if (r_s->num_deltas2 > 0) {
3078                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas2);
3079                                 if (r_s->deltas == NULL) {
3080                                         DEBUG(0, ("error tallocating memory "
3081                                                   "for %d deltas\n", 
3082                                                   r_s->num_deltas2));
3083                                         return False;
3084                                 }
3085                         }
3086
3087                         for (i = 0; i < r_s->num_deltas2; i++)
3088                         {
3089                                 if (!net_io_sam_delta_ctr(
3090                                         "", &r_s->deltas[i],
3091                                         r_s->hdr_deltas[i].type3,
3092                                         ps, depth)) {
3093                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
3094                                         return False;
3095                                 }
3096                         }
3097                 }
3098         }
3099
3100         prs_align(ps);
3101         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
3102                 return False;
3103
3104         return True;
3105 }
3106
3107 /*******************************************************************
3108 makes a NET_Q_SAM_DELTAS structure.
3109 ********************************************************************/
3110 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
3111                            const char *cli_name, DOM_CRED *cli_creds, 
3112                            uint32 database_id, UINT64_S dom_mod_count)
3113 {
3114         DEBUG(5, ("init_net_q_sam_deltas\n"));
3115
3116         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
3117         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
3118
3119         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
3120         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
3121
3122         q_s->database_id = database_id;
3123         q_s->dom_mod_count.low = dom_mod_count.low;
3124         q_s->dom_mod_count.high = dom_mod_count.high;
3125         q_s->max_size = 0xffff;
3126
3127         return True;
3128 }
3129
3130 /*******************************************************************
3131 reads or writes a structure.
3132 ********************************************************************/
3133 BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
3134                          int depth)
3135 {
3136         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
3137         depth++;
3138
3139         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
3140                 return False;
3141         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
3142                 return False;
3143
3144         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
3145                 return False;
3146         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
3147                 return False;
3148
3149         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
3150                 return False;
3151         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
3152                 return False;
3153         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
3154                 return False;
3155
3156         return True;
3157 }
3158
3159 /*******************************************************************
3160 reads or writes a structure.
3161 ********************************************************************/
3162 BOOL net_io_r_sam_deltas(const char *desc,
3163                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
3164 {
3165         unsigned int i;
3166
3167         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
3168         depth++;
3169
3170         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
3171                 return False;
3172         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
3173                 return False;
3174
3175         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
3176                 return False;
3177         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
3178                 return False;
3179         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
3180                 return False;
3181
3182         if (r_s->num_deltas2 != 0)
3183         {
3184                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
3185                         return False;
3186
3187                 if (r_s->ptr_deltas != 0)
3188                 {
3189                         if (r_s->num_deltas > 0) {
3190                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas);
3191                                 if (r_s->hdr_deltas == NULL) {
3192                                         DEBUG(0, ("error tallocating memory "
3193                                                   "for %d delta headers\n", 
3194                                                   r_s->num_deltas));
3195                                         return False;
3196                                 }
3197                         }
3198
3199                         for (i = 0; i < r_s->num_deltas; i++)
3200                         {
3201                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
3202                                                       ps, depth);
3203                         }
3204                         
3205                         if (r_s->num_deltas > 0) {
3206                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas);
3207                                 if (r_s->deltas == NULL) {
3208                                         DEBUG(0, ("error tallocating memory "
3209                                                   "for %d deltas\n", 
3210                                                   r_s->num_deltas));
3211                                         return False;
3212                                 }
3213                         }
3214
3215                         for (i = 0; i < r_s->num_deltas; i++)
3216                         {
3217                                 if (!net_io_sam_delta_ctr(
3218                                         "",
3219                                         &r_s->deltas[i],
3220                                         r_s->hdr_deltas[i].type2,
3221                                         ps, depth))
3222                                         
3223                                         return False;
3224                         }
3225                 }
3226         }
3227
3228         prs_align(ps);
3229         if (!prs_ntstatus("status", ps, depth, &r_s->status))
3230                 return False;
3231
3232         return True;
3233 }
3234
3235 /*******************************************************************
3236  Inits a NET_Q_DSR_GETDCNAME structure.
3237 ********************************************************************/
3238
3239 void init_net_q_dsr_getdcname(NET_Q_DSR_GETDCNAME *r_t, const char *server_unc,
3240                               const char *domain_name,
3241                               struct uuid *domain_guid,
3242                               struct uuid *site_guid,
3243                               uint32_t flags)
3244 {
3245         DEBUG(5, ("init_net_q_dsr_getdcname\n"));
3246
3247         r_t->ptr_server_unc = (server_unc != NULL);
3248         init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE);
3249
3250         r_t->ptr_domain_name = (domain_name != NULL);
3251         init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
3252
3253         r_t->ptr_domain_guid = (domain_guid != NULL);
3254         r_t->domain_guid = domain_guid;
3255
3256         r_t->ptr_site_guid = (site_guid != NULL);
3257         r_t->site_guid = site_guid;
3258
3259         r_t->flags = flags;
3260 }
3261
3262 /*******************************************************************
3263  Reads or writes an NET_Q_DSR_GETDCNAME structure.
3264 ********************************************************************/
3265
3266 BOOL net_io_q_dsr_getdcname(const char *desc, NET_Q_DSR_GETDCNAME *r_t,
3267                             prs_struct *ps, int depth)
3268 {
3269         if (r_t == NULL)
3270                 return False;
3271
3272         prs_debug(ps, depth, desc, "net_io_q_dsr_getdcname");
3273         depth++;
3274
3275         if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc))
3276                 return False;
3277
3278         if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc,
3279                             r_t->ptr_server_unc, ps, depth))
3280                 return False;
3281
3282         if (!prs_align(ps))
3283                 return False;
3284
3285         if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
3286                 return False;
3287
3288         if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
3289                             r_t->ptr_domain_name, ps, depth))
3290                 return False;
3291
3292         if (!prs_align(ps))
3293                 return False;
3294
3295         if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid))
3296                 return False;
3297
3298         if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) {
3299                 r_t->domain_guid = PRS_ALLOC_MEM(ps, struct uuid, 1);
3300                 if (r_t->domain_guid == NULL)
3301                         return False;
3302         }
3303
3304         if ((r_t->ptr_domain_guid) &&
3305             (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth)))
3306                 return False;
3307
3308         if (!prs_align(ps))
3309                 return False;
3310
3311         if (!prs_uint32("ptr_site_guid", ps, depth, &r_t->ptr_site_guid))
3312                 return False;
3313
3314         if (UNMARSHALLING(ps) && (r_t->ptr_site_guid)) {
3315                 r_t->site_guid = PRS_ALLOC_MEM(ps, struct uuid, 1);
3316                 if (r_t->site_guid == NULL)
3317                         return False;
3318         }
3319
3320         if ((r_t->ptr_site_guid) &&
3321             (!smb_io_uuid("site_guid", r_t->site_guid, ps, depth)))
3322                 return False;
3323
3324         if (!prs_align(ps))
3325                 return False;
3326
3327         if (!prs_uint32("flags", ps, depth, &r_t->flags))
3328                 return False;
3329
3330         return True;
3331 }
3332
3333 /*******************************************************************
3334  Inits a NET_R_DSR_GETDCNAME structure.
3335 ********************************************************************/
3336 void init_net_r_dsr_getdcname(NET_R_DSR_GETDCNAME *r_t, const char *dc_unc,
3337                               const char *dc_address, int32 dc_address_type,
3338                               struct uuid domain_guid, const char *domain_name,
3339                               const char *forest_name, uint32 dc_flags,
3340                               const char *dc_site_name,
3341                               const char *client_site_name)
3342 {
3343         DEBUG(5, ("init_net_q_dsr_getdcname\n"));
3344
3345         r_t->ptr_dc_unc = (dc_unc != NULL);
3346         init_unistr2(&r_t->uni_dc_unc, dc_unc, UNI_STR_TERMINATE);
3347
3348         r_t->ptr_dc_address = (dc_address != NULL);
3349         init_unistr2(&r_t->uni_dc_address, dc_address, UNI_STR_TERMINATE);
3350
3351         r_t->dc_address_type = dc_address_type;
3352         r_t->domain_guid = domain_guid;
3353
3354         r_t->ptr_domain_name = (domain_name != NULL);
3355         init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
3356
3357         r_t->ptr_forest_name = (forest_name != NULL);
3358         init_unistr2(&r_t->uni_forest_name, forest_name, UNI_STR_TERMINATE);
3359
3360         r_t->dc_flags = dc_flags;
3361
3362         r_t->ptr_dc_site_name = (dc_site_name != NULL);
3363         init_unistr2(&r_t->uni_dc_site_name, dc_site_name, UNI_STR_TERMINATE);
3364
3365         r_t->ptr_client_site_name = (client_site_name != NULL);
3366         init_unistr2(&r_t->uni_client_site_name, client_site_name,
3367                      UNI_STR_TERMINATE);
3368 }
3369
3370 /*******************************************************************
3371  Reads or writes an NET_R_DSR_GETDCNAME structure.
3372 ********************************************************************/
3373
3374 BOOL net_io_r_dsr_getdcname(const char *desc, NET_R_DSR_GETDCNAME *r_t,
3375                             prs_struct *ps, int depth)
3376 {
3377         uint32 info_ptr = 1;
3378
3379         if (r_t == NULL)
3380                 return False;
3381
3382         prs_debug(ps, depth, desc, "net_io_r_dsr_getdcname");
3383         depth++;
3384
3385         /* The reply contains *just* an info struct, this is the ptr to it */
3386         if (!prs_uint32("info_ptr", ps, depth, &info_ptr))
3387                 return False;
3388
3389         if (info_ptr == 0)
3390                 return False;
3391
3392         if (!prs_uint32("ptr_dc_unc", ps, depth, &r_t->ptr_dc_unc))
3393                 return False;
3394
3395         if (!prs_uint32("ptr_dc_address", ps, depth, &r_t->ptr_dc_address))
3396                 return False;
3397
3398         if (!prs_int32("dc_address_type", ps, depth, &r_t->dc_address_type))
3399                 return False;
3400
3401         if (!smb_io_uuid("domain_guid", &r_t->domain_guid, ps, depth))
3402                 return False;
3403
3404         if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
3405                 return False;
3406
3407         if (!prs_uint32("ptr_forest_name", ps, depth, &r_t->ptr_forest_name))
3408                 return False;
3409
3410         if (!prs_uint32("dc_flags", ps, depth, &r_t->dc_flags))
3411                 return False;
3412
3413         if (!prs_uint32("ptr_dc_site_name", ps, depth, &r_t->ptr_dc_site_name))
3414                 return False;
3415
3416         if (!prs_uint32("ptr_client_site_name", ps, depth,
3417                         &r_t->ptr_client_site_name))
3418                 return False;
3419
3420         if (!prs_align(ps))
3421                 return False;
3422
3423         if (!smb_io_unistr2("dc_unc", &r_t->uni_dc_unc,
3424                             r_t->ptr_dc_unc, ps, depth))
3425                 return False;
3426
3427         if (!prs_align(ps))
3428                 return False;
3429
3430         if (!smb_io_unistr2("dc_address", &r_t->uni_dc_address,
3431                             r_t->ptr_dc_address, ps, depth))
3432                 return False;
3433
3434         if (!prs_align(ps))
3435                 return False;
3436
3437         if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
3438                             r_t->ptr_domain_name, ps, depth))
3439                 return False;
3440
3441         if (!prs_align(ps))
3442                 return False;
3443
3444         if (!smb_io_unistr2("forest_name", &r_t->uni_forest_name,
3445                             r_t->ptr_forest_name, ps, depth))
3446                 return False;
3447
3448         if (!prs_align(ps))
3449                 return False;
3450
3451         if (!smb_io_unistr2("dc_site_name", &r_t->uni_dc_site_name,
3452                             r_t->ptr_dc_site_name, ps, depth))
3453                 return False;
3454
3455         if (!prs_align(ps))
3456                 return False;
3457
3458         if (!smb_io_unistr2("client_site_name", &r_t->uni_client_site_name,
3459                             r_t->ptr_client_site_name, ps, depth))
3460                 return False;
3461
3462         if (!prs_align(ps))
3463                 return False;
3464
3465         if (!prs_werror("result", ps, depth, &r_t->result))
3466                 return False;
3467
3468         return True;
3469 }
3470
3471 /*******************************************************************
3472  Inits a NET_Q_DSR_GETSITENAME structure.
3473 ********************************************************************/
3474
3475 void init_net_q_dsr_getsitename(NET_Q_DSR_GETSITENAME *r_t, const char *computer_name)
3476 {
3477         DEBUG(5, ("init_net_q_dsr_getsitename\n"));
3478
3479         r_t->ptr_computer_name = (computer_name != NULL);
3480         init_unistr2(&r_t->uni_computer_name, computer_name, UNI_STR_TERMINATE);
3481 }
3482
3483 /*******************************************************************
3484  Reads or writes an NET_Q_DSR_GETSITENAME structure.
3485 ********************************************************************/
3486
3487 BOOL net_io_q_dsr_getsitename(const char *desc, NET_Q_DSR_GETSITENAME *r_t,
3488                               prs_struct *ps, int depth)
3489 {
3490         if (r_t == NULL)
3491                 return False;
3492
3493         prs_debug(ps, depth, desc, "net_io_q_dsr_getsitename");
3494         depth++;
3495
3496         if (!prs_uint32("ptr_computer_name", ps, depth, &r_t->ptr_computer_name))
3497                 return False;
3498
3499         if (!smb_io_unistr2("computer_name", &r_t->uni_computer_name,
3500                             r_t->ptr_computer_name, ps, depth))
3501                 return False;
3502
3503         if (!prs_align(ps))
3504                 return False;
3505
3506         return True;
3507 }
3508
3509 /*******************************************************************
3510  Reads or writes an NET_R_DSR_GETSITENAME structure.
3511 ********************************************************************/
3512
3513 BOOL net_io_r_dsr_getsitename(const char *desc, NET_R_DSR_GETSITENAME *r_t,
3514                               prs_struct *ps, int depth)
3515 {
3516         if (r_t == NULL)
3517                 return False;
3518
3519         prs_debug(ps, depth, desc, "net_io_r_dsr_getsitename");
3520         depth++;
3521
3522         if (!prs_uint32("ptr_site_name", ps, depth, &r_t->ptr_site_name))
3523                 return False;
3524
3525         if (!prs_align(ps))
3526                 return False;
3527
3528         if (!smb_io_unistr2("site_name", &r_t->uni_site_name,
3529                             r_t->ptr_site_name, ps, depth))
3530                 return False;
3531
3532         if (!prs_align(ps))
3533                 return False;
3534
3535         if (!prs_werror("result", ps, depth, &r_t->result))
3536                 return False;
3537
3538         return True;
3539 }
3540
3541