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