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