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