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