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