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