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