813316177ac74e2f2a7dede2b87439ea0b7ffd7c
[abartlet/samba.git/.git] / source3 / rpc_parse / parse_net.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Jean François Micouleau           2002.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29 /*******************************************************************
30  Reads or writes a structure.
31 ********************************************************************/
32
33 static BOOL net_io_neg_flags(const char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
34 {
35         if (neg == NULL)
36                 return False;
37
38         prs_debug(ps, depth, desc, "net_io_neg_flags");
39         depth++;
40
41         if(!prs_align(ps))
42                 return False;
43         
44         if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
45                 return False;
46
47         return True;
48 }
49
50 /*******************************************************************
51  Inits a NETLOGON_INFO_3 structure.
52 ********************************************************************/
53
54 static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
55 {
56         info->flags          = flags;
57         info->logon_attempts = logon_attempts;
58         info->reserved_1     = 0x0;
59         info->reserved_2     = 0x0;
60         info->reserved_3     = 0x0;
61         info->reserved_4     = 0x0;
62         info->reserved_5     = 0x0;
63 }
64
65 /*******************************************************************
66  Reads or writes a NETLOGON_INFO_3 structure.
67 ********************************************************************/
68
69 static BOOL net_io_netinfo_3(const char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
70 {
71         if (info == NULL)
72                 return False;
73
74         prs_debug(ps, depth, desc, "net_io_netinfo_3");
75         depth++;
76
77         if(!prs_align(ps))
78                 return False;
79
80         if(!prs_uint32("flags         ", ps, depth, &info->flags))
81                 return False;
82         if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
83                 return False;
84         if(!prs_uint32("reserved_1    ", ps, depth, &info->reserved_1))
85                 return False;
86         if(!prs_uint32("reserved_2    ", ps, depth, &info->reserved_2))
87                 return False;
88         if(!prs_uint32("reserved_3    ", ps, depth, &info->reserved_3))
89                 return False;
90         if(!prs_uint32("reserved_4    ", ps, depth, &info->reserved_4))
91                 return False;
92         if(!prs_uint32("reserved_5    ", ps, depth, &info->reserved_5))
93                 return False;
94
95         return True;
96 }
97
98
99 /*******************************************************************
100  Inits a NETLOGON_INFO_1 structure.
101 ********************************************************************/
102
103 static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
104 {
105         info->flags      = flags;
106         info->pdc_status = pdc_status;
107 }
108
109 /*******************************************************************
110  Reads or writes a NETLOGON_INFO_1 structure.
111 ********************************************************************/
112
113 static BOOL net_io_netinfo_1(const char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
114 {
115         if (info == NULL)
116                 return False;
117
118         prs_debug(ps, depth, desc, "net_io_netinfo_1");
119         depth++;
120
121         if(!prs_align(ps))
122                 return False;
123         
124         if(!prs_uint32("flags     ", ps, depth, &info->flags))
125                 return False;
126         if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
127                 return False;
128
129         return True;
130 }
131
132 /*******************************************************************
133  Inits a NETLOGON_INFO_2 structure.
134 ********************************************************************/
135
136 static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
137                                 uint32 tc_status, const char *trusted_dc_name)
138 {
139         info->flags      = flags;
140         info->pdc_status = pdc_status;
141         info->ptr_trusted_dc_name = 1;
142         info->tc_status  = tc_status;
143
144         if (trusted_dc_name != NULL)
145                 init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, UNI_STR_TERMINATE);
146         else
147                 init_unistr2(&info->uni_trusted_dc_name, "", UNI_STR_TERMINATE);
148 }
149
150 /*******************************************************************
151  Reads or writes a NETLOGON_INFO_2 structure.
152 ********************************************************************/
153
154 static BOOL net_io_netinfo_2(const char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
155 {
156         if (info == NULL)
157                 return False;
158
159         prs_debug(ps, depth, desc, "net_io_netinfo_2");
160         depth++;
161
162         if(!prs_align(ps))
163                 return False;
164         
165         if(!prs_uint32("flags              ", ps, depth, &info->flags))
166                 return False;
167         if(!prs_uint32("pdc_status         ", ps, depth, &info->pdc_status))
168                 return False;
169         if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
170                 return False;
171         if(!prs_uint32("tc_status          ", ps, depth, &info->tc_status))
172                 return False;
173
174         if (info->ptr_trusted_dc_name != 0) {
175                 if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
176                         return False;
177         }
178
179         if(!prs_align(ps))
180                 return False;
181
182         return True;
183 }
184
185 static BOOL net_io_ctrl_data_info_5(const char *desc, CTRL_DATA_INFO_5 *info, prs_struct *ps, int depth)
186 {
187         if (info == NULL)
188                 return False;
189                 
190         prs_debug(ps, depth, desc, "net_io_ctrl_data_info_5");
191         depth++;
192         
193         if ( !prs_uint32( "function_code", ps, depth, &info->function_code ) )
194                 return False;
195         
196         if(!prs_uint32("ptr_domain", ps, depth, &info->ptr_domain))
197                 return False;
198                 
199         if ( info->ptr_domain ) {
200                 if(!smb_io_unistr2("domain", &info->domain, info->ptr_domain, ps, depth))
201                         return False;
202         }
203                 
204         return True;
205 }
206
207 static BOOL net_io_ctrl_data_info_6(const char *desc, CTRL_DATA_INFO_6 *info, prs_struct *ps, int depth)
208 {
209         if (info == NULL)
210                 return False;
211                 
212         prs_debug(ps, depth, desc, "net_io_ctrl_data_info_6");
213         depth++;
214         
215         if ( !prs_uint32( "function_code", ps, depth, &info->function_code ) )
216                 return False;
217         
218         if(!prs_uint32("ptr_domain", ps, depth, &info->ptr_domain))
219                 return False;
220                 
221         if ( info->ptr_domain ) {
222                 if(!smb_io_unistr2("domain", &info->domain, info->ptr_domain, ps, depth))
223                         return False;
224         }
225                 
226         return True;
227 }
228
229 /*******************************************************************
230  Reads or writes an NET_Q_LOGON_CTRL2 structure.
231 ********************************************************************/
232
233 BOOL net_io_q_logon_ctrl2(const char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
234 {
235         if (q_l == NULL)
236                 return False;
237
238         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
239         depth++;
240
241         if(!prs_align(ps))
242                 return False;
243
244         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
245                 return False;
246
247         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
248                 return False;
249
250         if(!prs_align(ps))
251                 return False;
252
253         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
254                 return False;
255         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
256                 return False;
257         switch ( q_l->function_code ) {
258                 case NETLOGON_CONTROL_REDISCOVER:
259                         if ( !net_io_ctrl_data_info_5( "ctrl_data_info5", &q_l->info.info5, ps, depth) ) 
260                                 return False;
261                         break;
262                         
263                 case NETLOGON_CONTROL_TC_QUERY:
264                         if ( !net_io_ctrl_data_info_6( "ctrl_data_info6", &q_l->info.info6, ps, depth) ) 
265                                 return False;
266                         break;
267
268                 default:
269                         DEBUG(0,("net_io_q_logon_ctrl2: unknown function_code [%d]\n",
270                                 q_l->function_code));
271                         return False;
272         }
273         
274         return True;
275 }
276
277 /*******************************************************************
278  Inits an NET_Q_LOGON_CTRL2 structure.
279 ********************************************************************/
280
281 void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, const char *srv_name,
282                             uint32 query_level)
283 {
284         DEBUG(5,("init_q_logon_ctrl2\n"));
285
286         q_l->function_code = 0x01;
287         q_l->query_level = query_level;
288
289         init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
290 }
291
292 /*******************************************************************
293  Inits an NET_R_LOGON_CTRL2 structure.
294 ********************************************************************/
295
296 void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
297                             uint32 flags, uint32 pdc_status, 
298                             uint32 logon_attempts, uint32 tc_status, 
299                             const char *trusted_domain_name)
300 {
301         r_l->switch_value  = query_level; 
302
303         switch (query_level) {
304         case 1:
305                 r_l->ptr = 1; /* undocumented pointer */
306                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
307                 r_l->status = NT_STATUS_OK;
308                 break;
309         case 2:
310                 r_l->ptr = 1; /* undocumented pointer */
311                 init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
312                                tc_status, trusted_domain_name); 
313                 r_l->status = NT_STATUS_OK;
314                 break;
315         case 3:
316                 r_l->ptr = 1; /* undocumented pointer */
317                 init_netinfo_3(&r_l->logon.info3, flags, logon_attempts);       
318                 r_l->status = NT_STATUS_OK;
319                 break;
320         default:
321                 DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
322                         r_l->switch_value));
323                 r_l->ptr = 0; /* undocumented pointer */
324
325                 /* take a guess at an error code... */
326                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
327                 break;
328         }
329 }
330
331 /*******************************************************************
332  Reads or writes an NET_R_LOGON_CTRL2 structure.
333 ********************************************************************/
334
335 BOOL net_io_r_logon_ctrl2(const char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
336 {
337         if (r_l == NULL)
338                 return False;
339
340         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
341         depth++;
342
343         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
344                 return False;
345         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
346                 return False;
347
348         if (r_l->ptr != 0) {
349                 switch (r_l->switch_value) {
350                 case 1:
351                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
352                                 return False;
353                         break;
354                 case 2:
355                         if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
356                                 return False;
357                         break;
358                 case 3:
359                         if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
360                                 return False;
361                         break;
362                 default:
363                         DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
364                                 r_l->switch_value));
365                         break;
366                 }
367         }
368
369         if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
370                 return False;
371
372         return True;
373 }
374
375 /*******************************************************************
376  Reads or writes an NET_Q_LOGON_CTRL structure.
377 ********************************************************************/
378
379 BOOL net_io_q_logon_ctrl(const char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, 
380                          int depth)
381 {
382         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl");
383         depth++;
384
385         if(!prs_align(ps))
386                 return False;
387
388         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
389                 return False;
390
391         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
392                 return False;
393
394         if(!prs_align(ps))
395                 return False;
396
397         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
398                 return False;
399         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
400                 return False;
401
402         return True;
403 }
404
405 /*******************************************************************
406  Inits an NET_Q_LOGON_CTRL structure.
407 ********************************************************************/
408
409 void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, const char *srv_name,
410                            uint32 query_level)
411 {
412         DEBUG(5,("init_q_logon_ctrl\n"));
413
414         q_l->function_code = 0x01; /* ??? */
415         q_l->query_level = query_level;
416
417         init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
418 }
419
420 /*******************************************************************
421  Inits an NET_R_LOGON_CTRL structure.
422 ********************************************************************/
423
424 void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
425                            uint32 flags, uint32 pdc_status)
426 {
427         DEBUG(5,("init_r_logon_ctrl\n"));
428
429         r_l->switch_value  = query_level; /* should only be 0x1 */
430
431         switch (query_level) {
432         case 1:
433                 r_l->ptr = 1; /* undocumented pointer */
434                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
435                 r_l->status = NT_STATUS_OK;
436                 break;
437         default:
438                 DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n",
439                         r_l->switch_value));
440                 r_l->ptr = 0; /* undocumented pointer */
441
442                 /* take a guess at an error code... */
443                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
444                 break;
445         }
446 }
447
448 /*******************************************************************
449  Reads or writes an NET_R_LOGON_CTRL structure.
450 ********************************************************************/
451
452 BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, 
453                          int depth)
454 {
455         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl");
456         depth++;
457
458         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
459                 return False;
460         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
461                 return False;
462
463         if (r_l->ptr != 0) {
464                 switch (r_l->switch_value) {
465                 case 1:
466                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
467                                 return False;
468                         break;
469                 default:
470                         DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n",
471                                 r_l->switch_value));
472                         break;
473                 }
474         }
475
476         if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
477                 return False;
478
479         return True;
480 }
481
482 /*******************************************************************
483  Inits an NET_R_GETDCNAME structure.
484 ********************************************************************/
485 void init_net_q_getdcname(NET_Q_GETDCNAME *r_t, const char *logon_server,
486                           const char *domainname)
487 {
488         DEBUG(5,("init_r_getdcname\n"));
489
490         r_t->ptr_logon_server = (logon_server != NULL);
491         init_unistr2(&r_t->uni_logon_server, logon_server, UNI_STR_TERMINATE);
492         r_t->ptr_domainname = (domainname != NULL);
493         init_unistr2(&r_t->uni_domainname, domainname, UNI_STR_TERMINATE);
494 }
495
496 /*******************************************************************
497  Reads or writes an NET_Q_GETDCNAME structure.
498 ********************************************************************/
499
500 BOOL net_io_q_getdcname(const char *desc, NET_Q_GETDCNAME *r_t, prs_struct *ps,
501                         int depth)
502 {
503         if (r_t == NULL)
504                 return False;
505
506         prs_debug(ps, depth, desc, "net_io_q_getdcname");
507         depth++;
508
509         if (!prs_uint32("ptr_logon_server", ps, depth, &r_t->ptr_logon_server))
510                 return False;
511
512         if (!smb_io_unistr2("logon_server", &r_t->uni_logon_server,
513                             r_t->ptr_logon_server, ps, depth))
514                 return False;
515
516         if (!prs_align(ps))
517                 return False;
518
519         if (!prs_uint32("ptr_domainname", ps, depth, &r_t->ptr_domainname))
520                 return False;
521
522         if (!smb_io_unistr2("domainname", &r_t->uni_domainname,
523                             r_t->ptr_domainname, ps, depth))
524                 return False;
525
526         return True;
527 }
528
529
530 /*******************************************************************
531  Inits an NET_R_GETDCNAME structure.
532 ********************************************************************/
533 void init_net_r_getdcname(NET_R_GETDCNAME *r_t, const char *dcname)
534 {
535         DEBUG(5,("init_r_getdcname\n"));
536
537         init_unistr2(&r_t->uni_dcname, dcname, UNI_STR_TERMINATE);
538 }
539
540 /*******************************************************************
541  Reads or writes an NET_R_GETDCNAME structure.
542 ********************************************************************/
543
544 BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps,
545                         int depth)
546 {
547         if (r_t == NULL)
548                 return False;
549
550         prs_debug(ps, depth, desc, "net_io_r_getdcname");
551         depth++;
552
553         if (!prs_uint32("ptr_dcname", ps, depth, &r_t->ptr_dcname))
554                 return False;
555
556         if (!smb_io_unistr2("dcname", &r_t->uni_dcname,
557                             r_t->ptr_dcname, ps, depth))
558                 return False;
559
560         if (!prs_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 = (DOM_SID2 *)talloc_zero(ctx, count * sizeof(DOM_SID2));
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 = (NET_ID_INFO_CTR *)prs_alloc_mem(ps, sizeof(NET_ID_INFO_CTR));
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 = (DOM_GID *)talloc_zero(ctx,sizeof(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 = (DOM_GID *)prs_alloc_mem(ps, sizeof(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 = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(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 = (DOM_GID *)prs_alloc_mem(ps, sizeof(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(ps->mem_ctx, sizeof(uint32) *
2326                                     info->num_members2);
2327
2328                 if (info->rids == NULL) {
2329                         DEBUG(0, ("out of memory allocating %d rids\n",
2330                                   info->num_members2));
2331                         return False;
2332                 }
2333
2334                 for (i = 0; i < info->num_members2; i++)
2335                 {
2336                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2337                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2338                                 return False;
2339                 }
2340         }
2341
2342         if (info->ptr_attribs != 0)
2343         {
2344                 if (!prs_uint32("num_members3", ps, depth, 
2345                                 &info->num_members3))
2346                         return False;
2347                 if (info->num_members3 != info->num_members)
2348                 {
2349                         /* RPC fault */
2350                         return False;
2351                 }
2352
2353                 info->attribs = talloc(ps->mem_ctx, sizeof(uint32) *
2354                                        info->num_members3);
2355
2356                 if (info->attribs == NULL) {
2357                         DEBUG(0, ("out of memory allocating %d attribs\n",
2358                                   info->num_members3));
2359                         return False;
2360                 }
2361
2362                 for (i = 0; i < info->num_members3; i++)
2363                 {
2364                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2365                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2366                                 return False;
2367                 }
2368         }
2369
2370         return True;
2371 }
2372
2373 /*******************************************************************
2374 reads or writes a structure.
2375 ********************************************************************/
2376 static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
2377                                   prs_struct *ps, int depth)
2378 {
2379         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2380         depth++;
2381
2382         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2383                 return False;
2384         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2385                 return False;
2386         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2387                 return False;
2388         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2389                 return False;
2390
2391         if (ps->data_offset + 40 > ps->buffer_size)
2392                 return False;
2393         ps->data_offset += 40;
2394
2395         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2396                             info->hdr_als_name.buffer, ps, depth))
2397                 return False;
2398         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2399                             info->hdr_sec_desc.buffer, ps, depth))
2400                 return False;
2401
2402         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2403                             info->hdr_als_desc.buffer, ps, depth))
2404                 return False;
2405
2406         return True;
2407 }
2408
2409 /*******************************************************************
2410 reads or writes a structure.
2411 ********************************************************************/
2412 static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info,
2413                                       prs_struct *ps, int depth)
2414 {
2415         uint32 i;
2416         fstring tmp;
2417
2418         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2419         depth++;
2420
2421         prs_align(ps);
2422         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2423                 return False;
2424         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2425                 return False;
2426
2427         if (ps->data_offset + 16 > ps->buffer_size)
2428                 return False;
2429         ps->data_offset += 16;
2430
2431         if (info->ptr_members != 0)
2432         {
2433                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2434                         return False;
2435                 if (info->num_sids != info->num_members)
2436                 {
2437                         /* RPC fault */
2438                         return False;
2439                 }
2440
2441                 info->ptr_sids = talloc(ps->mem_ctx, sizeof(uint32) *
2442                                         info->num_sids);
2443                 
2444                 if (info->ptr_sids == NULL) {
2445                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2446                                   info->num_sids));
2447                         return False;
2448                 }
2449
2450                 for (i = 0; i < info->num_sids; i++)
2451                 {
2452                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2453                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2454                                 return False;
2455                 }
2456
2457                 info->sids = talloc(ps->mem_ctx, sizeof(DOM_SID2) *
2458                                     info->num_sids);
2459
2460                 if (info->sids == NULL) {
2461                         DEBUG(0, ("error allocating %d sids\n",
2462                                   info->num_sids));
2463                         return False;
2464                 }
2465
2466                 for (i = 0; i < info->num_sids; i++)
2467                 {
2468                         if (info->ptr_sids[i] != 0)
2469                         {
2470                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2471                                          i);
2472                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2473                                                      ps, depth))
2474                                         return False;
2475                         }
2476                 }
2477         }
2478
2479         return True;
2480 }
2481
2482 /*******************************************************************
2483 reads or writes a structure.
2484 ********************************************************************/
2485 static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
2486                                       prs_struct *ps, int depth)
2487 {
2488         unsigned int i;
2489         prs_debug(ps, depth, desc, "net_io_sam_policy_info");
2490         depth++;
2491
2492         if(!prs_align(ps))
2493                 return False;
2494
2495         if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
2496                 return False;
2497         if (!prs_uint64("audit_retention_period", ps, depth,
2498                         &info->audit_retention_period))
2499                 return False;
2500         if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
2501                 return False;
2502         if (!prs_uint32("num_events", ps, depth, &info->num_events))
2503                 return False;
2504         if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
2505                 return False;
2506
2507         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2508                 return False;
2509
2510         if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
2511                 return False;
2512
2513         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2514                 return False;
2515         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2516                         &info->non_paged_pool_limit))
2517                 return False;
2518         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2519                 return False;
2520         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2521                 return False;
2522         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2523                 return False;
2524         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2525                 return False;
2526         if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
2527                 return False;
2528         if (!smb_io_time("create_time", &info->create_time, ps, depth))
2529                 return False;
2530         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2531                 return False;
2532
2533         for (i=0; i<4; i++) {
2534                 UNIHDR dummy;
2535                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2536                         return False;
2537         }
2538
2539         for (i=0; i<4; i++) {
2540                 uint32 reserved;
2541                 if (!prs_uint32("reserved", ps, depth, &reserved))
2542                         return False;
2543         }
2544
2545         if (!prs_uint32("num_event_audit_options", ps, depth,
2546                         &info->num_event_audit_options))
2547                 return False;
2548
2549         for (i=0; i<info->num_event_audit_options; i++)
2550                 if (!prs_uint32("event_audit_option", ps, depth,
2551                                 &info->event_audit_option))
2552                         return False;
2553
2554         if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2555                 return False;
2556
2557         if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2558                 return False;
2559
2560         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2561                             info->hdr_sec_desc.buffer, ps, depth))
2562
2563                 return False;
2564
2565         return True;
2566 }
2567
2568 #if 0
2569
2570 /* This function is pretty broken - see bug #334 */
2571
2572 /*******************************************************************
2573 reads or writes a structure.
2574 ********************************************************************/
2575 static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
2576                                       prs_struct *ps, int depth)
2577 {
2578         int i;
2579
2580         prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
2581         depth++;
2582
2583         if(!prs_align(ps))
2584                 return False;
2585
2586         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2587                 return False;
2588
2589         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2590                 return False;
2591
2592         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2593                 return False;
2594
2595         if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2596                 return False;
2597
2598         if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2599                 return False;
2600         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2601                 return False;
2602         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2603                 return False;
2604
2605         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2606                 return False;
2607         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2608                 return False;
2609
2610         for (i=0; i<12; i++)
2611                 if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2612                         return False;
2613
2614         if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2615                 return False;
2616
2617         return True;
2618 }
2619
2620 #endif
2621
2622 #if 0
2623
2624 /* This function doesn't work - see bug #334 */
2625
2626 /*******************************************************************
2627 reads or writes a structure.
2628 ********************************************************************/
2629 static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
2630                                    prs_struct *ps, int depth)
2631 {
2632         int i;
2633
2634         prs_debug(ps, depth, desc, "net_io_sam_secret_info");
2635         depth++;
2636
2637         if(!prs_align(ps))
2638                 return False;
2639
2640         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2641                 return False;
2642
2643         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2644                 return False;
2645
2646         if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2647                 return False;
2648
2649         if(!prs_align(ps))
2650                 return False;
2651
2652         if(!prs_uint32("count1", ps, depth, &info->count1))
2653                 return False;
2654         if(!prs_uint32("count2", ps, depth, &info->count2))
2655                 return False;
2656         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2657                 return False;
2658
2659
2660         if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2661                 return False;
2662         if(!prs_uint32("count3", ps, depth, &info->count3))
2663                 return False;
2664         if(!prs_uint32("count4", ps, depth, &info->count4))
2665                 return False;
2666         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2667                 return False;
2668         if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2669                 return False;
2670         if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2671                 return False;
2672
2673
2674         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2675                 return False;
2676         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2677                 return False;
2678         for(i=0; i<12; i++)
2679                 if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2680                         return False;
2681
2682         if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2683                 return False;
2684         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2685                 return False;
2686         if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2687                 return False;
2688
2689         if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2690                 return False;
2691
2692         if(!prs_uint32("key_len", ps, depth, &info->key_len))
2693                 return False;
2694         if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2695                 return False;
2696         if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2697                 return False;
2698
2699         if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2700                 return False;
2701
2702
2703         if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2704                 return False;
2705
2706         if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2707                 return False;
2708
2709
2710         return True;
2711 }
2712
2713 #endif
2714
2715 /*******************************************************************
2716 reads or writes a structure.
2717 ********************************************************************/
2718 static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
2719                                       prs_struct *ps, int depth)
2720 {
2721         unsigned int i;
2722
2723         prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2724         depth++;
2725
2726         if(!prs_align(ps))
2727                 return False;
2728
2729         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2730                 return False;
2731
2732         if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2733                 return False;
2734         if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
2735                 return False;
2736
2737         if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
2738                 return False;
2739         if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
2740                 return False;
2741
2742         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2743                 return False;
2744         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2745                         &info->non_paged_pool_limit))
2746                 return False;
2747         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2748                 return False;
2749         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2750                 return False;
2751         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2752                 return False;
2753         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2754                 return False;
2755         if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
2756                 return False;
2757         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2758                 return False;
2759
2760         for (i=0; i<4; i++) {
2761                 UNIHDR dummy;
2762                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2763                         return False;
2764         }
2765
2766         for (i=0; i<4; i++) {
2767                 uint32 reserved;
2768                 if (!prs_uint32("reserved", ps, depth, &reserved))
2769                         return False;
2770         }
2771
2772         if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2773                 return False;
2774
2775         info->attributes = talloc(ps->mem_ctx, sizeof(uint32) * info->attribute_count);
2776
2777         for (i=0; i<info->attribute_count; i++)
2778                 if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2779                         return False;
2780
2781         if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2782                 return False;
2783
2784         info->hdr_privslist = talloc(ps->mem_ctx, sizeof(UNIHDR) * info->privlist_count);
2785         info->uni_privslist = talloc(ps->mem_ctx, sizeof(UNISTR2) * info->privlist_count);
2786
2787         for (i=0; i<info->privlist_count; i++)
2788                 if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2789                         return False;
2790
2791         for (i=0; i<info->privlist_count; i++)
2792                 if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2793                         return False;
2794
2795         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2796                             info->hdr_sec_desc.buffer, ps, depth))
2797                 return False;
2798
2799         return True;
2800 }
2801
2802 /*******************************************************************
2803 reads or writes a structure.
2804 ********************************************************************/
2805 static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
2806                                  SAM_DELTA_CTR * delta, uint16 type,
2807                                  prs_struct *ps, int depth)
2808 {
2809         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2810         depth++;
2811
2812         switch (type) {
2813                 /* Seen in sam deltas */
2814                 case SAM_DELTA_MODIFIED_COUNT:
2815                         if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
2816                                 return False;
2817                         break;
2818
2819                 case SAM_DELTA_DOMAIN_INFO:
2820                         if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2821                                 return False;
2822                         break;
2823
2824                 case SAM_DELTA_GROUP_INFO:
2825                         if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2826                                 return False;
2827                         break;
2828
2829                 case SAM_DELTA_ACCOUNT_INFO:
2830                         if (!net_io_sam_account_info("", sess_key, &delta->account_info, ps, depth))
2831                                 return False;
2832                         break;
2833
2834                 case SAM_DELTA_GROUP_MEM:
2835                         if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2836                                 return False;
2837                         break;
2838
2839                 case SAM_DELTA_ALIAS_INFO:
2840                         if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2841                                 return False;
2842                         break;
2843
2844                 case SAM_DELTA_POLICY_INFO:
2845                         if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
2846                                 return False;
2847                         break;
2848
2849                 case SAM_DELTA_ALIAS_MEM:
2850                         if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2851                                 return False;
2852                         break;
2853
2854                 case SAM_DELTA_PRIVS_INFO:
2855                         if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2856                                 return False;
2857                         break;
2858
2859                         /* These guys are implemented but broken */
2860
2861                 case SAM_DELTA_TRUST_DOMS:
2862                 case SAM_DELTA_SECRET_INFO:
2863                         break;
2864
2865                         /* These guys are not implemented yet */
2866
2867                 case SAM_DELTA_RENAME_GROUP:
2868                 case SAM_DELTA_RENAME_USER:
2869                 case SAM_DELTA_RENAME_ALIAS:
2870                 case SAM_DELTA_DELETE_GROUP:
2871                 case SAM_DELTA_DELETE_USER:
2872                 default:
2873                         DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
2874                         break;
2875         }
2876
2877         return True;
2878 }
2879
2880 /*******************************************************************
2881 reads or writes a structure.
2882 ********************************************************************/
2883 BOOL net_io_r_sam_sync(const char *desc, uint8 sess_key[16],
2884                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2885 {
2886         uint32 i;
2887
2888         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2889         depth++;
2890
2891         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2892                 return False;
2893         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2894                 return False;
2895
2896         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2897                 return False;
2898         if (r_s->ptr_deltas != 0)
2899         {
2900                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2901                         return False;
2902                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2903                         return False;
2904                 if (r_s->ptr_deltas2 != 0)
2905                 {
2906                         if (!prs_uint32("num_deltas2", ps, depth,
2907                                         &r_s->num_deltas2))
2908                                 return False;
2909
2910                         if (r_s->num_deltas2 != r_s->num_deltas)
2911                         {
2912                                 /* RPC fault */
2913                                 return False;
2914                         }
2915
2916                         if (r_s->num_deltas2 > 0) {
2917                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2918                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2919                                                sizeof(SAM_DELTA_HDR));
2920                           
2921                                 if (r_s->hdr_deltas == NULL) {
2922                                         DEBUG(0, ("error tallocating memory "
2923                                                   "for %d delta headers\n", 
2924                                                   r_s->num_deltas2));
2925                                         return False;
2926                                 }
2927                         }
2928
2929                         for (i = 0; i < r_s->num_deltas2; i++)
2930                         {
2931                                 if (!net_io_sam_delta_hdr("", 
2932                                                           &r_s->hdr_deltas[i],
2933                                                           ps, depth))
2934                                         return False;
2935                         }
2936
2937                         if (r_s->num_deltas2 > 0) {
2938                                 r_s->deltas = (SAM_DELTA_CTR *)
2939                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2940                                                sizeof(SAM_DELTA_CTR));
2941
2942                                 if (r_s->deltas == NULL) {
2943                                         DEBUG(0, ("error tallocating memory "
2944                                                   "for %d deltas\n", 
2945                                                   r_s->num_deltas2));
2946                                         return False;
2947                                 }
2948                         }
2949
2950                         for (i = 0; i < r_s->num_deltas2; i++)
2951                         {
2952                                 if (!net_io_sam_delta_ctr(
2953                                         "", sess_key, &r_s->deltas[i],
2954                                         r_s->hdr_deltas[i].type3,
2955                                         ps, depth)) {
2956                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
2957                                         return False;
2958                                 }
2959                         }
2960                 }
2961         }
2962
2963         prs_align(ps);
2964         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
2965                 return False;
2966
2967         return True;
2968 }
2969
2970 /*******************************************************************
2971 makes a NET_Q_SAM_DELTAS structure.
2972 ********************************************************************/
2973 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
2974                            const char *cli_name, DOM_CRED *cli_creds, 
2975                            uint32 database_id, UINT64_S dom_mod_count)
2976 {
2977         DEBUG(5, ("init_net_q_sam_deltas\n"));
2978
2979         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
2980         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
2981
2982         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
2983         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
2984
2985         q_s->database_id = database_id;
2986         q_s->dom_mod_count.low = dom_mod_count.low;
2987         q_s->dom_mod_count.high = dom_mod_count.high;
2988         q_s->max_size = 0xffff;
2989
2990         return True;
2991 }
2992
2993 /*******************************************************************
2994 reads or writes a structure.
2995 ********************************************************************/
2996 BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
2997                          int depth)
2998 {
2999         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
3000         depth++;
3001
3002         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
3003                 return False;
3004         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
3005                 return False;
3006
3007         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
3008                 return False;
3009         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
3010                 return False;
3011
3012         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
3013                 return False;
3014         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
3015                 return False;
3016         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
3017                 return False;
3018
3019         return True;
3020 }
3021
3022 /*******************************************************************
3023 reads or writes a structure.
3024 ********************************************************************/
3025 BOOL net_io_r_sam_deltas(const char *desc, uint8 sess_key[16],
3026                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
3027 {
3028         unsigned int i;
3029
3030         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
3031         depth++;
3032
3033         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
3034                 return False;
3035         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
3036                 return False;
3037
3038         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
3039                 return False;
3040         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
3041                 return False;
3042         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
3043                 return False;
3044
3045         if (r_s->num_deltas2 != 0)
3046         {
3047                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
3048                         return False;
3049
3050                 if (r_s->ptr_deltas != 0)
3051                 {
3052                         if (r_s->num_deltas > 0) {
3053                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
3054                                         talloc(ps->mem_ctx, r_s->num_deltas *
3055                                                sizeof(SAM_DELTA_HDR));
3056                                 if (r_s->hdr_deltas == NULL) {
3057                                         DEBUG(0, ("error tallocating memory "
3058                                                   "for %d delta headers\n", 
3059                                                   r_s->num_deltas));
3060                                         return False;
3061                                 }
3062                         }
3063
3064                         for (i = 0; i < r_s->num_deltas; i++)
3065                         {
3066                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
3067                                                       ps, depth);
3068                         }
3069                         
3070                         if (r_s->num_deltas > 0) {
3071                                 r_s->deltas = (SAM_DELTA_CTR *)
3072                                         talloc(ps->mem_ctx, r_s->num_deltas *
3073                                                sizeof(SAM_DELTA_CTR));
3074
3075                                 if (r_s->deltas == NULL) {
3076                                         DEBUG(0, ("error tallocating memory "
3077                                                   "for %d deltas\n", 
3078                                                   r_s->num_deltas));
3079                                         return False;
3080                                 }
3081                         }
3082
3083                         for (i = 0; i < r_s->num_deltas; i++)
3084                         {
3085                                 if (!net_io_sam_delta_ctr(
3086                                         "", sess_key,
3087                                         &r_s->deltas[i],
3088                                         r_s->hdr_deltas[i].type2,
3089                                         ps, depth))
3090                                         
3091                                         return False;
3092                         }
3093                 }
3094         }
3095
3096         prs_align(ps);
3097         if (!prs_ntstatus("status", ps, depth, &r_s->status))
3098                 return False;
3099
3100         return True;
3101 }