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