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