This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
[sfrench/samba-autobuild/.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, DOM_GID *gids,
1222                          uint32 user_flgs, uchar *sess_key,
1223                          char *logon_srv, char *logon_dom,
1224                          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 static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level)
1335 {
1336         int i;
1337
1338         if (usr == NULL)
1339                 return False;
1340
1341         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1342         depth++;
1343
1344         if (UNMARSHALLING(ps))
1345                 ZERO_STRUCTP(usr);
1346
1347         if(!prs_align(ps))
1348                 return False;
1349         
1350         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1351                 return False;
1352
1353         if (usr->ptr_user_info == 0)
1354                 return True;
1355
1356         if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
1357                 return False;
1358         if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
1359                 return False;
1360         if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1361                 return False;
1362         if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1363                 return False;
1364         if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1365                 return False;
1366         if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1367                 return False;
1368
1369         if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1370                 return False;
1371         if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1372                 return False;
1373         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1374                 return False;
1375         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1376                 return False;
1377         if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1378                 return False;
1379         if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1380                 return False;
1381
1382         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1383                 return False;
1384         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1385                 return False;
1386
1387         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User RID */
1388                 return False;
1389         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group RID */
1390                 return False;
1391         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1392                 return False;
1393         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1394                 return False;
1395         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1396                 return False;
1397
1398         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
1399                 return False;
1400
1401         if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1402                 return False;
1403         if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1404                 return False;
1405
1406         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1407                 return False;
1408         if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1409                 return False;
1410
1411         if (validation_level == 3) {
1412                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1413                         return False;
1414                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1415                         return False;
1416         } else {
1417                 if (UNMARSHALLING(ps)) {
1418                         usr->num_other_sids = 0;
1419                         usr->buffer_other_sids = 0;
1420                 }
1421         }
1422                 
1423         if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1424                 return False;
1425         if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1426                 return False;
1427         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1428                 return False;
1429         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1430                 return False;
1431         if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1432                 return False;
1433         if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1434                 return False;
1435
1436         if(!prs_align(ps))
1437                 return False;
1438         if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1439                 return False;
1440
1441         if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1442                 usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
1443                 if (usr->gids == NULL)
1444                         return False;
1445         }
1446
1447         for (i = 0; i < usr->num_groups2; i++) {
1448                 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1449                         return False;
1450         }
1451
1452         if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1453                 return False;
1454         if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1455                 return False;
1456
1457         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1458                 return False;
1459
1460         if (usr->num_other_sids) {
1461
1462                 if (UNMARSHALLING(ps)) {
1463                         usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
1464                         if (usr->other_sids == NULL)
1465                                 return False;
1466                 }
1467         
1468                 if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
1469                         return False;
1470
1471                 if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
1472                         usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
1473                         if (usr->other_gids == NULL)
1474                                 return False;
1475                 }
1476         
1477                 for (i = 0; i < usr->num_other_groups; i++) {
1478                         if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
1479                                 return False;
1480                 }
1481                 for (i = 0; i < usr->num_other_sids; i++) {
1482                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1483                                 return False;
1484                 }
1485         }
1486
1487         return True;
1488 }
1489
1490 /*******************************************************************
1491  Reads or writes a structure.
1492 ********************************************************************/
1493
1494 BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1495 {
1496         if (q_l == NULL)
1497                 return False;
1498
1499         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1500         depth++;
1501
1502         if(!prs_align(ps))
1503                 return False;
1504         
1505         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1506                 return False;
1507
1508         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1509                 return False;
1510
1511         return True;
1512 }
1513
1514 /*******************************************************************
1515  Reads or writes a structure.
1516 ********************************************************************/
1517
1518 BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1519 {
1520         if (r_l == NULL)
1521                 return False;
1522
1523         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1524         depth++;
1525
1526         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1527                 return False;
1528         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1529                 return False;
1530
1531         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1532                 return False;
1533         if(!prs_align(ps))
1534                 return False;
1535
1536 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1537         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1538                 return False;
1539 #else
1540         if (r_l->switch_value != 0) {
1541                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1542                         return False;
1543         }
1544 #endif
1545
1546         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1547                 return False;
1548
1549         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1550                 return False;
1551
1552         if(!prs_align(ps))
1553                 return False;
1554
1555         return True;
1556 }
1557
1558 /*******************************************************************
1559  Reads or writes a structure.
1560 ********************************************************************/
1561
1562 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1563 {
1564         if (q_l == NULL)
1565                 return False;
1566
1567         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1568         depth++;
1569
1570         if(!prs_align(ps))
1571                 return False;
1572         
1573         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1574                 return False;
1575
1576         return True;
1577 }
1578
1579 /*******************************************************************
1580  Reads or writes a structure.
1581 ********************************************************************/
1582
1583 BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1584 {
1585         if (r_l == NULL)
1586                 return False;
1587
1588         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1589         depth++;
1590
1591         if(!prs_align(ps))
1592                 return False;
1593         
1594         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1595                 return False;
1596         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1597                 return False;
1598
1599         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1600                 return False;
1601
1602         return True;
1603 }
1604
1605 /*******************************************************************
1606 makes a NET_Q_SAM_SYNC structure.
1607 ********************************************************************/
1608 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1609                          const char *cli_name, DOM_CRED *cli_creds, 
1610                          DOM_CRED *ret_creds, uint32 database_id)
1611 {
1612         DEBUG(5, ("init_q_sam_sync\n"));
1613
1614         init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
1615         init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
1616
1617         if (cli_creds)
1618                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1619
1620         if (cli_creds)
1621                 memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
1622         else
1623                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1624
1625         q_s->database_id = database_id;
1626         q_s->restart_state = 0;
1627         q_s->sync_context = 0;
1628         q_s->max_size = 0xffff;
1629
1630         return True;
1631 }
1632
1633 /*******************************************************************
1634 reads or writes a structure.
1635 ********************************************************************/
1636 BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1637                        int depth)
1638 {
1639         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1640         depth++;
1641
1642         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1643                 return False;
1644         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1645                 return False;
1646
1647         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1648                 return False;
1649         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1650                 return False;
1651
1652         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1653                 return False;
1654         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1655                 return False;
1656         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1657                 return False;
1658
1659         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1660                 return False;
1661
1662         return True;
1663 }
1664
1665 /*******************************************************************
1666 reads or writes a structure.
1667 ********************************************************************/
1668 static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
1669                                  prs_struct *ps, int depth)
1670 {
1671         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1672         depth++;
1673
1674         if (!prs_uint16("type", ps, depth, &delta->type))
1675                 return False;
1676         if (!prs_uint16("type2", ps, depth, &delta->type2))
1677                 return False;
1678         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1679                 return False;
1680
1681         if (!prs_uint32("type3", ps, depth, &delta->type3))
1682                 return False;
1683
1684         /* Not sure why we need this but it seems to be necessary to get
1685            sam deltas working. */
1686
1687         if (delta->type != 0x16) {
1688                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1689                         return False;
1690         }
1691
1692         return True;
1693 }
1694
1695 /*******************************************************************
1696 reads or writes a structure.
1697 ********************************************************************/
1698 static BOOL net_io_sam_delta_stamp(char *desc, SAM_DELTA_STAMP *info,
1699                                    prs_struct *ps, int depth)
1700 {
1701         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1702         depth++;
1703
1704         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1705                 return False;
1706         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
1707                         &info->dom_mod_count_ptr))
1708                 return False;
1709
1710         if (info->dom_mod_count_ptr) {
1711                 if (!prs_uint64("dom_mod_count", ps, depth,
1712                                 &info->dom_mod_count))
1713                         return False;
1714         }
1715
1716         return True;
1717 }
1718
1719 /*******************************************************************
1720 reads or writes a structure.
1721 ********************************************************************/
1722 static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
1723                                    prs_struct *ps, int depth)
1724 {
1725         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1726         depth++;
1727
1728         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1729                 return False;
1730         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1731                 return False;
1732
1733         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1734                 return False;
1735         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1736                 return False;
1737         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1738                 return False;
1739         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1740                 return False;
1741         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1742                 return False;
1743         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1744                 return False;
1745         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1746                 return False;
1747
1748         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1749                 return False;
1750         if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
1751                 return False;
1752
1753         if (ps->data_offset + 40 > ps->buffer_size)
1754                 return False;
1755         ps->data_offset += 40;
1756
1757         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
1758                             info->hdr_dom_name.buffer, ps, depth))
1759                 return False;
1760         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
1761                             info->hdr_oem_info.buffer, ps, depth))
1762                 return False;
1763
1764         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1765                             info->hdr_sec_desc.buffer, ps, depth))
1766                 return False;
1767         if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
1768                             info->hdr_unknown.buffer, ps, depth))
1769                 return False;
1770
1771         return True;
1772 }
1773
1774 /*******************************************************************
1775 reads or writes a structure.
1776 ********************************************************************/
1777 static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
1778                                   prs_struct *ps, int depth)
1779 {
1780         prs_debug(ps, depth, desc, "net_io_sam_group_info");
1781         depth++;
1782
1783         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
1784                 return False;
1785         if (!smb_io_gid("gid", &info->gid, ps, depth))
1786                 return False;
1787         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
1788                 return False;
1789         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1790                 return False;
1791
1792         if (ps->data_offset + 48 > ps->buffer_size)
1793                 return False;
1794         ps->data_offset += 48;
1795
1796         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
1797                             info->hdr_grp_name.buffer, ps, depth))
1798                 return False;
1799         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
1800                             info->hdr_grp_desc.buffer, ps, depth))
1801                 return False;
1802         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1803                             info->hdr_sec_desc.buffer, ps, depth))
1804                 return False;
1805
1806         return True;
1807 }
1808
1809 /*******************************************************************
1810 reads or writes a structure.
1811 ********************************************************************/
1812 static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD * pwd,
1813                                    prs_struct *ps, int depth)
1814 {
1815         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
1816         depth++;
1817
1818         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
1819                 return False;
1820
1821         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
1822                 return False;
1823         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
1824                 return False;
1825
1826         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
1827                 return False;
1828         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
1829                 return False;
1830
1831         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
1832                 return False;
1833         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
1834                 return False;
1835
1836         return True;
1837 }
1838
1839 /*******************************************************************
1840 makes a SAM_ACCOUNT_INFO structure.
1841 ********************************************************************/
1842 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
1843                            const UNISTR2 *user_name,
1844                            const UNISTR2 *full_name,
1845                            uint32 user_rid, uint32 group_rid,
1846                            const UNISTR2 *home_dir,
1847                            const UNISTR2 *dir_drive,
1848                            const UNISTR2 *log_scr,
1849                            const UNISTR2 *desc,
1850                            uint32 acb_info,
1851                            const UNISTR2 *prof_path,
1852                            const UNISTR2 *wkstas,
1853                            const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
1854 {
1855         int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
1856         int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
1857         int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
1858         int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
1859         int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
1860         int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
1861         int len_description = desc != NULL ? desc->uni_str_len : 0;
1862         int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
1863         int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
1864         int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
1865
1866         DEBUG(5, ("make_sam_account_info\n"));
1867
1868         make_uni_hdr(&info->hdr_acct_name, len_user_name);
1869         make_uni_hdr(&info->hdr_full_name, len_full_name);
1870         make_uni_hdr(&info->hdr_home_dir, len_home_dir);
1871         make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
1872         make_uni_hdr(&info->hdr_logon_script, len_logon_script);
1873         make_uni_hdr(&info->hdr_profile, len_profile_path);
1874         make_uni_hdr(&info->hdr_acct_desc, len_description);
1875         make_uni_hdr(&info->hdr_workstations, len_workstations);
1876         make_uni_hdr(&info->hdr_comment, len_unknown_str);
1877         make_uni_hdr(&info->hdr_parameters, len_munged_dial);
1878
1879         /* not present */
1880         make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
1881
1882         info->user_rid = user_rid;
1883         info->group_rid = group_rid;
1884
1885         init_nt_time(&info->logon_time);
1886         init_nt_time(&info->logoff_time);
1887         init_nt_time(&info->pwd_last_set_time);
1888         init_nt_time(&info->acct_expiry_time);
1889
1890         info->logon_divs = 0xA8;
1891         info->ptr_logon_hrs = 0;        /* Don't care right now */
1892
1893         info->bad_pwd_count = 0;
1894         info->logon_count = 0;
1895         info->acb_info = acb_info;
1896         info->nt_pwd_present = 0;
1897         info->lm_pwd_present = 0;
1898         info->pwd_expired = 0;
1899         info->country = 0;
1900         info->codepage = 0;
1901
1902         info->unknown1 = 0x4EC;
1903         info->unknown2 = 0;
1904
1905         copy_unistr2(&info->uni_acct_name, user_name);
1906         copy_unistr2(&info->uni_full_name, full_name);
1907         copy_unistr2(&info->uni_home_dir, home_dir);
1908         copy_unistr2(&info->uni_dir_drive, dir_drive);
1909         copy_unistr2(&info->uni_logon_script, log_scr);
1910         copy_unistr2(&info->uni_profile, prof_path);
1911         copy_unistr2(&info->uni_acct_desc, desc);
1912         copy_unistr2(&info->uni_workstations, wkstas);
1913         copy_unistr2(&info->uni_comment, unk_str);
1914         copy_unistr2(&info->uni_parameters, mung_dial);
1915
1916         return True;
1917 }
1918
1919 /*******************************************************************
1920 reads or writes a structure.
1921 ********************************************************************/
1922 static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
1923                                     SAM_ACCOUNT_INFO * info, prs_struct *ps,
1924                                     int depth)
1925 {
1926         BUFHDR2 hdr_priv_data;
1927         uint32 i;
1928
1929         prs_debug(ps, depth, desc, "net_io_sam_account_info");
1930         depth++;
1931
1932         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
1933                 return False;
1934         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
1935                 return False;
1936
1937         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
1938                 return False;
1939         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
1940                 return False;
1941
1942         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
1943                 return False;
1944         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
1945                 return False;
1946         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
1947                            depth))
1948                 return False;
1949
1950         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
1951                 return False;
1952         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
1953                            depth))
1954                 return False;
1955
1956         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
1957                 return False;
1958         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
1959                 return False;
1960
1961         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
1962                 return False;
1963         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
1964                 return False;
1965
1966         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
1967                 return False;
1968         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
1969                 return False;
1970         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
1971                          depth))
1972                 return False;
1973         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
1974                          depth))
1975                 return False;
1976
1977         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
1978                 return False;
1979         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
1980                 return False;
1981         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
1982                 return False;
1983         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
1984                 return False;
1985         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
1986                 return False;
1987         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
1988                 return False;
1989
1990         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
1991                 return False;
1992         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
1993                            depth))
1994                 return False;
1995         if (!prs_uint16("country", ps, depth, &info->country))
1996                 return False;
1997         if (!prs_uint16("codepage", ps, depth, &info->codepage))
1998                 return False;
1999
2000         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
2001                 return False;
2002         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2003                 return False;
2004         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
2005                 return False;
2006
2007         for (i = 0; i < 3; i++)
2008         {
2009                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
2010                                    ps, depth))
2011                         return False;                                          
2012         }
2013
2014         for (i = 0; i < 4; i++)
2015         {
2016                 if (!prs_uint32("dw_reserved", ps, depth, 
2017                                 &info->dw_reserved[i]))
2018                         return False;
2019         }
2020
2021         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2022                             info->hdr_acct_name.buffer, ps, depth))
2023                 return False;
2024         prs_align(ps);
2025         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2026                             info->hdr_full_name.buffer, ps, depth))
2027                 return False;
2028         prs_align(ps);
2029         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2030                             info->hdr_home_dir.buffer, ps, depth))
2031                 return False;
2032         prs_align(ps);
2033         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2034                             info->hdr_dir_drive.buffer, ps, depth))
2035                 return False;
2036         prs_align(ps);
2037         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2038                             info->hdr_logon_script.buffer, ps, depth))
2039                 return False;
2040         prs_align(ps);
2041         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2042                             info->hdr_acct_desc.buffer, ps, depth))
2043                 return False;
2044         prs_align(ps);
2045         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2046                             info->hdr_workstations.buffer, ps, depth))
2047                 return False;
2048         prs_align(ps);
2049
2050         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2051                 return False;
2052         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2053                 return False;
2054
2055         if (!smb_io_buffer4("buf_logon_hrs", &info->buf_logon_hrs,
2056                             info->ptr_logon_hrs, ps, depth))
2057                 return False;
2058         prs_align(ps);
2059         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2060                             info->hdr_comment.buffer, ps, depth))
2061                 return False;
2062         prs_align(ps);
2063         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2064                             info->hdr_parameters.buffer, ps, depth))
2065                 return False;
2066         prs_align(ps);
2067         if (hdr_priv_data.buffer != 0)
2068         {
2069                 int old_offset = 0;
2070                 uint32 len = 0x44;
2071                 if (!prs_uint32("pwd_len", ps, depth, &len))
2072                         return False;
2073                 old_offset = ps->data_offset;
2074                 if (len == 0x44)
2075                 {
2076                         if (ps->io)
2077                         {
2078                                 /* reading */
2079                                 if (!prs_hash1(ps, ps->data_offset, sess_key))
2080                                         return False;
2081                         }
2082                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2083                                                     ps, depth))
2084                                 return False;
2085
2086                         if (!ps->io)
2087                         {
2088                                 /* writing */
2089                                 if (!prs_hash1(ps, old_offset, sess_key))
2090                                         return False;
2091                         }
2092                 }
2093                 if (old_offset + len > ps->buffer_size)
2094                         return False;
2095                 ps->data_offset = old_offset + len;
2096         }
2097         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2098                             info->hdr_sec_desc.buffer, ps, depth))
2099                 return False;
2100         prs_align(ps);
2101         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2102                             info->hdr_profile.buffer, ps, depth))
2103                 return False;
2104
2105         prs_align(ps);
2106
2107         return True;
2108 }
2109
2110 /*******************************************************************
2111 reads or writes a structure.
2112 ********************************************************************/
2113 static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
2114                                       prs_struct *ps, int depth)
2115 {
2116         uint32 i;
2117         fstring tmp;
2118
2119         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2120         depth++;
2121
2122         prs_align(ps);
2123         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2124                 return False;
2125         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2126                 return False;
2127         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2128                 return False;
2129
2130         if (ps->data_offset + 16 > ps->buffer_size)
2131                 return False;
2132         ps->data_offset += 16;
2133
2134         if (info->ptr_rids != 0)
2135         {
2136                 if (!prs_uint32("num_members2", ps, depth, 
2137                                 &info->num_members2))
2138                         return False;
2139
2140                 if (info->num_members2 != info->num_members)
2141                 {
2142                         /* RPC fault */
2143                         return False;
2144                 }
2145
2146                 info->rids = talloc(ps->mem_ctx, sizeof(uint32) *
2147                                     info->num_members2);
2148
2149                 if (info->rids == NULL) {
2150                         DEBUG(0, ("out of memory allocating %d rids\n",
2151                                   info->num_members2));
2152                         return False;
2153                 }
2154
2155                 for (i = 0; i < info->num_members2; i++)
2156                 {
2157                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2158                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2159                                 return False;
2160                 }
2161         }
2162
2163         if (info->ptr_attribs != 0)
2164         {
2165                 if (!prs_uint32("num_members3", ps, depth, 
2166                                 &info->num_members3))
2167                         return False;
2168                 if (info->num_members3 != info->num_members)
2169                 {
2170                         /* RPC fault */
2171                         return False;
2172                 }
2173
2174                 info->attribs = talloc(ps->mem_ctx, sizeof(uint32) *
2175                                        info->num_members3);
2176
2177                 if (info->attribs == NULL) {
2178                         DEBUG(0, ("out of memory allocating %d attribs\n",
2179                                   info->num_members3));
2180                         return False;
2181                 }
2182
2183                 for (i = 0; i < info->num_members3; i++)
2184                 {
2185                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2186                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2187                                 return False;
2188                 }
2189         }
2190
2191         return True;
2192 }
2193
2194 /*******************************************************************
2195 reads or writes a structure.
2196 ********************************************************************/
2197 static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
2198                                   prs_struct *ps, int depth)
2199 {
2200         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2201         depth++;
2202
2203         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2204                 return False;
2205         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2206                 return False;
2207         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2208                 return False;
2209         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2210                 return False;
2211
2212         if (ps->data_offset + 40 > ps->buffer_size)
2213                 return False;
2214         ps->data_offset += 40;
2215
2216         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2217                             info->hdr_als_name.buffer, ps, depth))
2218                 return False;
2219         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2220                             info->hdr_sec_desc.buffer, ps, depth))
2221                 return False;
2222         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2223                             info->hdr_als_name.buffer, ps, depth))
2224                 return False;
2225
2226         return True;
2227 }
2228
2229 /*******************************************************************
2230 reads or writes a structure.
2231 ********************************************************************/
2232 static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info,
2233                                       prs_struct *ps, int depth)
2234 {
2235         uint32 i;
2236         fstring tmp;
2237
2238         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2239         depth++;
2240
2241         prs_align(ps);
2242         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2243                 return False;
2244         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2245                 return False;
2246
2247         if (info->ptr_members != 0)
2248         {
2249                 if (ps->data_offset + 16 > ps->buffer_size)
2250                         return False;
2251                 ps->data_offset += 16;
2252
2253                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2254                         return False;
2255                 if (info->num_sids != info->num_members)
2256                 {
2257                         /* RPC fault */
2258                         return False;
2259                 }
2260
2261                 info->ptr_sids = talloc(ps->mem_ctx, sizeof(uint32) *
2262                                         info->num_sids);
2263                 
2264                 if (info->ptr_sids == NULL) {
2265                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2266                                   info->num_sids));
2267                         return False;
2268                 }
2269
2270                 for (i = 0; i < info->num_sids; i++)
2271                 {
2272                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2273                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2274                                 return False;
2275                 }
2276
2277                 info->sids = talloc(ps->mem_ctx, sizeof(DOM_SID2) *
2278                                     info->num_sids);
2279
2280                 if (info->sids == NULL) {
2281                         DEBUG(0, ("error allocating %d sids\n",
2282                                   info->num_sids));
2283                         return False;
2284                 }
2285
2286                 for (i = 0; i < info->num_sids; i++)
2287                 {
2288                         if (info->ptr_sids[i] != 0)
2289                         {
2290                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2291                                          i);
2292                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2293                                                      ps, depth))
2294                                         return False;
2295                         }
2296                 }
2297         }
2298
2299         return True;
2300 }
2301
2302 /*******************************************************************
2303 reads or writes a structure.
2304 ********************************************************************/
2305 static BOOL net_io_sam_dom_info(char *desc, SAM_DELTA_DOM *info,
2306                                       prs_struct *ps, int depth)
2307 {
2308         int i;
2309
2310         prs_debug(ps, depth, desc, "net_io_sam_dom_info");
2311         depth++;
2312
2313         if(!prs_align(ps))
2314                 return False;
2315
2316         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2317                 return False;
2318         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2319                 return False;
2320         if (!prs_uint32("unknown3", ps, depth, &info->unknown3))
2321                 return False;
2322         if (!prs_uint32("unknown4", ps, depth, &info->unknown4))
2323                 return False;
2324         if (!prs_uint32("count1", ps, depth, &info->count1))
2325                 return False;
2326         if (!prs_uint32("ptr1", ps, depth, &info->ptr1))
2327                 return False;
2328
2329         if (!prs_uint16("count2", ps, depth, &info->count2))
2330                 return False;
2331         if (!prs_uint16("count3", ps, depth, &info->count3))
2332                 return False;
2333
2334         if (!prs_uint32("ptr2", ps, depth, &info->ptr2))
2335                 return False;
2336         if (!prs_uint32("ptr3", ps, depth, &info->ptr3))
2337                 return False;
2338
2339         if (!prs_uint32("unknown4b", ps, depth, &info->unknown4b))
2340                 return False;
2341         if (!prs_uint32("unknown5", ps, depth, &info->unknown5))
2342                 return False;
2343         if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
2344                 return False;
2345         if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
2346                 return False;
2347         if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
2348                 return False;
2349         if (!prs_uint32("unknown9", ps, depth, &info->unknown9))
2350                 return False;
2351         if (!prs_uint32("unknown10", ps, depth, &info->unknown10))
2352                 return False;
2353         if (!prs_uint32("unknown11", ps, depth, &info->unknown11))
2354                 return False;
2355         if (!prs_uint32("unknown12", ps, depth, &info->unknown12))
2356                 return False;
2357
2358         if (!prs_uint32("unknown13", ps, depth, &info->unknown13))
2359                 return False;
2360         if (!prs_uint32("unknown14", ps, depth, &info->unknown14))
2361                 return False;
2362         if (!prs_uint32("unknown15", ps, depth, &info->unknown15))
2363                 return False;
2364         if (!prs_uint32("unknown16", ps, depth, &info->unknown16))
2365                 return False;
2366         if (!prs_uint32("unknown17", ps, depth, &info->unknown17))
2367                 return False;
2368
2369         for (i=0; i<info->count2; i++)
2370                 if (!prs_uint32("unknown18", ps, depth, &info->unknown18))
2371                         return False;
2372
2373         if (!prs_uint32("unknown19", ps, depth, &info->unknown19))
2374                 return False;
2375
2376         for (i=0; i<info->count1; i++)
2377                 if (!prs_uint32("unknown20", ps, depth, &info->unknown20))
2378                         return False;
2379
2380         if (!prs_uint32("ptr4", ps, depth, &info->ptr4))
2381                 return False;
2382
2383         if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2384                 return False;
2385
2386         if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2387                 return False;
2388
2389         return True;
2390 }
2391
2392 /*******************************************************************
2393 reads or writes a structure.
2394 ********************************************************************/
2395 static BOOL net_io_sam_unk0e_info(char *desc, SAM_DELTA_UNK0E *info,
2396                                       prs_struct *ps, int depth)
2397 {
2398         int i;
2399
2400         prs_debug(ps, depth, desc, "net_io_sam_unk0e_info");
2401         depth++;
2402
2403         if(!prs_align(ps))
2404                 return False;
2405
2406         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2407                 return False;
2408
2409         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2410                 return False;
2411
2412         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2413                 return False;
2414
2415         if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2416                 return False;
2417
2418         if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2419                 return False;
2420         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2421                 return False;
2422         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2423                 return False;
2424
2425         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2426                 return False;
2427         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2428                 return False;
2429
2430         for (i=0; i<12; i++)
2431                 if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2432                         return False;
2433
2434         if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2435                 return False;
2436
2437         return True;
2438 }
2439
2440 /*******************************************************************
2441 reads or writes a structure.
2442 ********************************************************************/
2443 static BOOL net_io_sam_unk12_info(char *desc, SAM_DELTA_UNK12 *info,
2444                                       prs_struct *ps, int depth)
2445 {
2446         int i;
2447
2448         prs_debug(ps, depth, desc, "net_io_sam_unk12_info");
2449         depth++;
2450
2451         if(!prs_align(ps))
2452                 return False;
2453
2454         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2455                 return False;
2456
2457         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2458                 return False;
2459
2460         if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2461                 return False;
2462
2463         if(!prs_align(ps))
2464                 return False;
2465
2466         if(!prs_uint32("count1", ps, depth, &info->count1))
2467                 return False;
2468         if(!prs_uint32("count2", ps, depth, &info->count2))
2469                 return False;
2470         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2471                 return False;
2472
2473
2474         if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2475                 return False;
2476         if(!prs_uint32("count3", ps, depth, &info->count3))
2477                 return False;
2478         if(!prs_uint32("count4", ps, depth, &info->count4))
2479                 return False;
2480         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2481                 return False;
2482         if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2483                 return False;
2484         if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2485                 return False;
2486
2487
2488         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2489                 return False;
2490         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2491                 return False;
2492         for(i=0; i<12; i++)
2493                 if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2494                         return False;
2495
2496         if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2497                 return False;
2498         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2499                 return False;
2500         if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2501                 return False;
2502
2503         if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2504                 return False;
2505
2506         if(!prs_uint32("key_len", ps, depth, &info->key_len))
2507                 return False;
2508         if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2509                 return False;
2510         if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2511                 return False;
2512
2513         if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2514                 return False;
2515
2516
2517         if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2518                 return False;
2519
2520         if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2521                 return False;
2522
2523
2524         return True;
2525 }
2526
2527 /*******************************************************************
2528 reads or writes a structure.
2529 ********************************************************************/
2530 static BOOL net_io_sam_privs_info(char *desc, SAM_DELTA_PRIVS *info,
2531                                       prs_struct *ps, int depth)
2532 {
2533         int i;
2534
2535         prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2536         depth++;
2537
2538         if(!prs_align(ps))
2539                 return False;
2540
2541         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2542                 return False;
2543
2544         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2545                 return False;
2546
2547         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2548                 return False;
2549
2550         if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2551                 return False;
2552         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2553                 return False;
2554
2555         if(!prs_uint32("ptr1", ps, depth, &info->ptr1))
2556                 return False;
2557         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2558                 return False;
2559
2560         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2561                 return False;
2562         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2563                 return False;
2564         if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2565                 return False;
2566         if(!prs_uint32("unknown4", ps, depth, &info->unknown4))
2567                 return False;
2568         if(!prs_uint32("unknown5", ps, depth, &info->unknown5))
2569                 return False;
2570         if(!prs_uint32("unknown6", ps, depth, &info->unknown6))
2571                 return False;
2572         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2573                 return False;
2574         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2575                 return False;
2576         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2577                 return False;
2578
2579         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2580                 return False;
2581         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2582                 return False;
2583
2584         for (i=0; i<12; i++)
2585                 if(!prs_uint32("unknown10", ps, depth, &info->unknown10))
2586                         return False;
2587
2588         if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2589                 return False;
2590
2591         info->attributes = talloc(ps->mem_ctx, sizeof(uint32) * info->attribute_count);
2592
2593         for (i=0; i<info->attribute_count; i++)
2594                 if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2595                         return False;
2596
2597         if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2598                 return False;
2599
2600         info->hdr_privslist = talloc(ps->mem_ctx, sizeof(UNIHDR) * info->privlist_count);
2601         info->uni_privslist = talloc(ps->mem_ctx, sizeof(UNISTR2) * info->privlist_count);
2602
2603         for (i=0; i<info->privlist_count; i++)
2604                 if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2605                         return False;
2606
2607         for (i=0; i<info->privlist_count; i++)
2608                 if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2609                         return False;
2610
2611         return True;
2612 }
2613
2614 /*******************************************************************
2615 reads or writes a structure.
2616 ********************************************************************/
2617 static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
2618                                  SAM_DELTA_CTR * delta, uint16 type,
2619                                  prs_struct *ps, int depth)
2620 {
2621         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2622         depth++;
2623
2624         switch (type) {
2625                 /* Seen in sam deltas */
2626                 case SAM_DELTA_SAM_STAMP:
2627                         if (!net_io_sam_delta_stamp("", &delta->stamp, ps, depth))
2628                                 return False;
2629                         break;
2630
2631                 case SAM_DELTA_DOMAIN_INFO:
2632                         if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2633                                 return False;
2634                         break;
2635
2636                 case SAM_DELTA_GROUP_INFO:
2637                         if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2638                                 return False;
2639                         break;
2640
2641                 case SAM_DELTA_ACCOUNT_INFO:
2642                         if (!net_io_sam_account_info("", sess_key, &delta->account_info, ps, depth))
2643                                 return False;
2644                         break;
2645
2646                 case SAM_DELTA_GROUP_MEM:
2647                         if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2648                                 return False;
2649                         break;
2650
2651                 case SAM_DELTA_ALIAS_INFO:
2652                         if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2653                                 return False;
2654                         break;
2655
2656                 case SAM_DELTA_DOM_INFO:
2657                         if (!net_io_sam_dom_info("", &delta->dom_info, ps, depth))
2658                                 return False;
2659                         break;
2660
2661                 case SAM_DELTA_ALIAS_MEM:
2662                         if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2663                                 return False;
2664                         break;
2665
2666                 case SAM_DELTA_PRIVS_INFO:
2667                         if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2668                                 return False;
2669                         break;
2670
2671                 case SAM_DELTA_UNK0E_INFO:
2672                         if (!net_io_sam_unk0e_info("", &delta->unk0e_info, ps, depth))
2673                                 return False;
2674                         break;
2675
2676                 case SAM_DELTA_UNK12_INFO:
2677                         if (!net_io_sam_unk12_info("", &delta->unk12_info, ps, depth))
2678                                 return False;
2679                         break;
2680
2681                 default:
2682                         DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
2683                         break;
2684         }
2685
2686         return True;
2687 }
2688
2689 /*******************************************************************
2690 reads or writes a structure.
2691 ********************************************************************/
2692 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
2693                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2694 {
2695         uint32 i;
2696
2697         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2698         depth++;
2699
2700         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2701                 return False;
2702         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2703                 return False;
2704
2705         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2706                 return False;
2707         if (r_s->ptr_deltas != 0)
2708         {
2709                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2710                         return False;
2711                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2712                         return False;
2713                 if (r_s->ptr_deltas2 != 0)
2714                 {
2715                         if (!prs_uint32("num_deltas2", ps, depth,
2716                                         &r_s->num_deltas2))
2717                                 return False;
2718
2719                         if (r_s->num_deltas2 != r_s->num_deltas)
2720                         {
2721                                 /* RPC fault */
2722                                 return False;
2723                         }
2724
2725                         if (r_s->num_deltas2 > 0) {
2726                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2727                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2728                                                sizeof(SAM_DELTA_HDR));
2729                           
2730                                 if (r_s->hdr_deltas == NULL) {
2731                                         DEBUG(0, ("error tallocating memory "
2732                                                   "for %d delta headers\n", 
2733                                                   r_s->num_deltas2));
2734                                         return False;
2735                                 }
2736                         }
2737
2738                         for (i = 0; i < r_s->num_deltas2; i++)
2739                         {
2740                                 if (!net_io_sam_delta_hdr("", 
2741                                                           &r_s->hdr_deltas[i],
2742                                                           ps, depth))
2743                                         return False;
2744                         }
2745
2746                         if (r_s->num_deltas2 > 0) {
2747                                 r_s->deltas = (SAM_DELTA_CTR *)
2748                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2749                                                sizeof(SAM_DELTA_CTR));
2750
2751                                 if (r_s->deltas == NULL) {
2752                                         DEBUG(0, ("error tallocating memory "
2753                                                   "for %d deltas\n", 
2754                                                   r_s->num_deltas2));
2755                                         return False;
2756                                 }
2757                         }
2758
2759                         for (i = 0; i < r_s->num_deltas2; i++)
2760                         {
2761                                 if (!net_io_sam_delta_ctr(
2762                                         "", sess_key, &r_s->deltas[i],
2763                                         r_s->hdr_deltas[i].type3,
2764                                         ps, depth)) {
2765                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
2766                                         return False;
2767                                 }
2768                         }
2769                 }
2770         }
2771
2772         prs_align(ps);
2773         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
2774                 return False;
2775
2776         return True;
2777 }
2778
2779 /*******************************************************************
2780 makes a NET_Q_SAM_DELTAS structure.
2781 ********************************************************************/
2782 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
2783                            const char *cli_name, DOM_CRED *cli_creds, 
2784                            uint32 database_id, UINT64_S dom_mod_count)
2785 {
2786         DEBUG(5, ("init_net_q_sam_deltas\n"));
2787
2788         init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
2789         init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
2790
2791         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
2792         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
2793
2794         q_s->database_id = database_id;
2795         q_s->dom_mod_count.low = dom_mod_count.low;
2796         q_s->dom_mod_count.high = dom_mod_count.high;
2797         q_s->max_size = 0xffff;
2798
2799         return True;
2800 }
2801
2802 /*******************************************************************
2803 reads or writes a structure.
2804 ********************************************************************/
2805 BOOL net_io_q_sam_deltas(char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
2806                          int depth)
2807 {
2808         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
2809         depth++;
2810
2811         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
2812                 return False;
2813         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
2814                 return False;
2815
2816         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
2817                 return False;
2818         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
2819                 return False;
2820
2821         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
2822                 return False;
2823         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
2824                 return False;
2825         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
2826                 return False;
2827
2828         return True;
2829 }
2830
2831 /*******************************************************************
2832 reads or writes a structure.
2833 ********************************************************************/
2834 BOOL net_io_r_sam_deltas(char *desc, uint8 sess_key[16],
2835                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
2836 {
2837         int i;
2838
2839         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
2840         depth++;
2841
2842         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2843                 return False;
2844         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
2845                 return False;
2846
2847         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2848                 return False;
2849         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
2850                 return False;
2851         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
2852                 return False;
2853
2854         if (r_s->num_deltas2 != 0)
2855         {
2856                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
2857                         return False;
2858
2859                 if (r_s->ptr_deltas != 0)
2860                 {
2861                         if (r_s->num_deltas > 0) {
2862                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2863                                         talloc(ps->mem_ctx, r_s->num_deltas *
2864                                                sizeof(SAM_DELTA_HDR));
2865                                 if (r_s->hdr_deltas == NULL) {
2866                                         DEBUG(0, ("error tallocating memory "
2867                                                   "for %d delta headers\n", 
2868                                                   r_s->num_deltas));
2869                                         return False;
2870                                 }
2871                         }
2872
2873                         for (i = 0; i < r_s->num_deltas; i++)
2874                         {
2875                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
2876                                                       ps, depth);
2877                         }
2878                         
2879                         if (r_s->num_deltas > 0) {
2880                                 r_s->deltas = (SAM_DELTA_CTR *)
2881                                         talloc(ps->mem_ctx, r_s->num_deltas *
2882                                                sizeof(SAM_DELTA_CTR));
2883
2884                                 if (r_s->deltas == NULL) {
2885                                         DEBUG(0, ("error tallocating memory "
2886                                                   "for %d deltas\n", 
2887                                                   r_s->num_deltas));
2888                                         return False;
2889                                 }
2890                         }
2891
2892                         for (i = 0; i < r_s->num_deltas; i++)
2893                         {
2894                                 if (!net_io_sam_delta_ctr(
2895                                         "", sess_key,
2896                                         &r_s->deltas[i],
2897                                         r_s->hdr_deltas[i].type2,
2898                                         ps, depth))
2899                                         
2900                                         return False;
2901                         }
2902                 }
2903         }
2904
2905         prs_align(ps);
2906         if (!prs_ntstatus("status", ps, depth, &r_s->status))
2907                 return False;
2908
2909         return True;
2910 }