This adds client-side support for the unicode/SAMR password change scheme.
[kai/samba.git] / source3 / rpc_parse / parse_samr.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Paul Ashton                  1997-2000,
7  *  Copyright (C) Elrond                            2000,
8  *  Copyright (C) Jeremy Allison                    2001,
9  *  Copyright (C) Jean François Micouleau      1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002.
11  *  
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *  
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *  
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26
27 #include "includes.h"
28 #include "rpc_parse.h"
29 #include "nterr.h"
30
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_PARSE
33
34 /*******************************************************************
35 inits a SAMR_Q_CLOSE_HND structure.
36 ********************************************************************/
37
38 void init_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND *hnd)
39 {
40         DEBUG(5, ("init_samr_q_close_hnd\n"));
41         
42         q_c->pol = *hnd;
43 }
44
45 /*******************************************************************
46 reads or writes a structure.
47 ********************************************************************/
48
49 BOOL samr_io_q_close_hnd(const char *desc, SAMR_Q_CLOSE_HND * q_u,
50                          prs_struct *ps, int depth)
51 {
52         if (q_u == NULL)
53                 return False;
54
55         prs_debug(ps, depth, desc, "samr_io_q_close_hnd");
56         depth++;
57
58         if(!prs_align(ps))
59                 return False;
60
61         return smb_io_pol_hnd("pol", &q_u->pol, ps, depth);
62 }
63
64 /*******************************************************************
65 reads or writes a structure.
66 ********************************************************************/
67
68 BOOL samr_io_r_close_hnd(const char *desc, SAMR_R_CLOSE_HND * r_u,
69                          prs_struct *ps, int depth)
70 {
71         if (r_u == NULL)
72                 return False;
73
74         prs_debug(ps, depth, desc, "samr_io_r_close_hnd");
75         depth++;
76
77         if(!prs_align(ps))
78                 return False;
79
80         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
81                 return False;
82
83         if(!prs_ntstatus("status", ps, depth, &r_u->status))
84                 return False;
85
86         return True;
87 }
88
89 /*******************************************************************
90 inits a SAMR_Q_LOOKUP_DOMAIN structure.
91 ********************************************************************/
92
93 void init_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
94                                POLICY_HND *pol, char *dom_name)
95 {
96         DEBUG(5, ("init_samr_q_lookup_domain\n"));
97
98         q_u->connect_pol = *pol;
99
100         init_unistr2(&q_u->uni_domain, dom_name, UNI_FLAGS_NONE);
101         init_uni_hdr(&q_u->hdr_domain, &q_u->uni_domain);
102 }
103
104 /*******************************************************************
105 reads or writes a structure.
106 ********************************************************************/
107 BOOL samr_io_q_lookup_domain(const char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
108                              prs_struct *ps, int depth)
109 {
110         if (q_u == NULL)
111                 return False;
112
113         prs_debug(ps, depth, desc, "samr_io_q_lookup_domain");
114         depth++;
115
116         if(!prs_align(ps))
117                 return False;
118
119         if(!smb_io_pol_hnd("connect_pol", &q_u->connect_pol, ps, depth))
120                 return False;
121
122         if(!smb_io_unihdr("hdr_domain", &q_u->hdr_domain, ps, depth))
123                 return False;
124
125         if(!smb_io_unistr2("uni_domain", &q_u->uni_domain, q_u->hdr_domain.buffer, ps, depth))
126                 return False;
127
128         return True;
129 }
130
131 /*******************************************************************
132 inits a SAMR_R_LOOKUP_DOMAIN structure.
133 ********************************************************************/
134
135 void init_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
136                                DOM_SID *dom_sid, NTSTATUS status)
137 {
138         DEBUG(5, ("init_samr_r_lookup_domain\n"));
139
140         r_u->status = status;
141         r_u->ptr_sid = 0;
142         if (NT_STATUS_IS_OK(status)) {
143                 r_u->ptr_sid = 1;
144                 init_dom_sid2(&r_u->dom_sid, dom_sid);
145         }
146 }
147
148 /*******************************************************************
149 reads or writes a structure.
150 ********************************************************************/
151
152 BOOL samr_io_r_lookup_domain(const char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
153                              prs_struct *ps, int depth)
154 {
155         if (r_u == NULL)
156                 return False;
157
158         prs_debug(ps, depth, desc, "samr_io_r_lookup_domain");
159         depth++;
160
161         if(!prs_align(ps))
162                 return False;
163
164         if(!prs_uint32("ptr", ps, depth, &r_u->ptr_sid))
165                 return False;
166
167         if (r_u->ptr_sid != 0) {
168                 if(!smb_io_dom_sid2("sid", &r_u->dom_sid, ps, depth))
169                         return False;
170                 if(!prs_align(ps))
171                         return False;
172         }
173
174         if(!prs_ntstatus("status", ps, depth, &r_u->status))
175                 return False;
176
177         return True;
178 }
179
180 /*******************************************************************
181 reads or writes a structure.
182 ********************************************************************/
183
184 void init_samr_q_remove_sid_foreign_domain(SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u, POLICY_HND *dom_pol, DOM_SID *sid)
185 {
186         DEBUG(5, ("samr_init_samr_q_remove_sid_foreign_domain\n"));
187
188         q_u->dom_pol = *dom_pol;
189         init_dom_sid2(&q_u->sid, sid);
190 }
191
192 /*******************************************************************
193 reads or writes a structure.
194 ********************************************************************/
195
196 BOOL samr_io_q_remove_sid_foreign_domain(const char *desc, SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u,
197                           prs_struct *ps, int depth)
198 {
199         if (q_u == NULL)
200                 return False;
201
202         prs_debug(ps, depth, desc, "samr_io_q_remove_sid_foreign_domain");
203         depth++;
204
205         if(!prs_align(ps))
206                 return False;
207
208         if(!smb_io_pol_hnd("domain_pol", &q_u->dom_pol, ps, depth))
209                 return False;
210
211         if(!smb_io_dom_sid2("sid", &q_u->sid, ps, depth))
212                 return False;
213
214         if(!prs_align(ps))
215                 return False;
216
217         return True;
218 }
219
220 /*******************************************************************
221 reads or writes a structure.
222 ********************************************************************/
223
224 BOOL samr_io_r_remove_sid_foreign_domain(const char *desc, SAMR_R_REMOVE_SID_FOREIGN_DOMAIN * r_u,
225                           prs_struct *ps, int depth)
226 {
227         if (r_u == NULL)
228                 return False;
229
230         prs_debug(ps, depth, desc, "samr_io_r_remove_sid_foreign_domain");
231         depth++;
232
233         if(!prs_align(ps))
234                 return False;
235
236         if(!prs_ntstatus("status", ps, depth, &r_u->status))
237                 return False;
238
239         return True;
240 }
241
242 /*******************************************************************
243 reads or writes a structure.
244 ********************************************************************/
245
246 void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
247                              POLICY_HND *pol, uint32 flags,
248                              const DOM_SID *sid)
249 {
250         DEBUG(5, ("samr_init_samr_q_open_domain\n"));
251
252         q_u->pol = *pol;
253         q_u->flags = flags;
254         init_dom_sid2(&q_u->dom_sid, sid);
255 }
256
257 /*******************************************************************
258 reads or writes a structure.
259 ********************************************************************/
260
261 BOOL samr_io_q_open_domain(const char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
262                            prs_struct *ps, int depth)
263 {
264         if (q_u == NULL)
265                 return False;
266
267         prs_debug(ps, depth, desc, "samr_io_q_open_domain");
268         depth++;
269
270         if(!prs_align(ps))
271                 return False;
272
273         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
274                 return False;
275
276         if(!prs_uint32("flags", ps, depth, &q_u->flags))
277                 return False;
278
279         if(!smb_io_dom_sid2("sid", &q_u->dom_sid, ps, depth))
280                 return False;
281
282         return True;
283 }
284
285 /*******************************************************************
286 reads or writes a structure.
287 ********************************************************************/
288
289 BOOL samr_io_r_open_domain(const char *desc, SAMR_R_OPEN_DOMAIN * r_u,
290                            prs_struct *ps, int depth)
291 {
292         if (r_u == NULL)
293                 return False;
294
295         prs_debug(ps, depth, desc, "samr_io_r_open_domain");
296         depth++;
297
298         if(!prs_align(ps))
299                 return False;
300
301         if(!smb_io_pol_hnd("domain_pol", &r_u->domain_pol, ps, depth))
302                 return False;
303
304         if(!prs_ntstatus("status", ps, depth, &r_u->status))
305                 return False;
306
307         return True;
308 }
309
310 /*******************************************************************
311 reads or writes a structure.
312 ********************************************************************/
313
314 void init_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
315                                    POLICY_HND *user_pol)
316 {
317         DEBUG(5, ("samr_init_samr_q_get_usrdom_pwinfo\n"));
318
319         q_u->user_pol = *user_pol;
320 }
321
322 /*******************************************************************
323 reads or writes a structure.
324 ********************************************************************/
325
326 BOOL samr_io_q_get_usrdom_pwinfo(const char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
327                                  prs_struct *ps, int depth)
328 {
329         if (q_u == NULL)
330                 return False;
331
332         prs_debug(ps, depth, desc, "samr_io_q_get_usrdom_pwinfo");
333         depth++;
334
335         if(!prs_align(ps))
336                 return False;
337
338         return smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth);
339 }
340
341 /*******************************************************************
342  Init.
343 ********************************************************************/
344
345 void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, NTSTATUS status)
346 {
347         DEBUG(5, ("init_samr_r_get_usrdom_pwinfo\n"));
348         
349         r_u->unknown_0 = 0x0000;
350
351         /*
352          * used to be   
353          * r_u->unknown_1 = 0x0015;
354          * but for trusts.
355          */
356         r_u->unknown_1 = 0x01D1;
357         r_u->unknown_1 = 0x0015;
358
359         r_u->unknown_2 = 0x00000000;
360
361         r_u->status = status;
362 }
363
364 /*******************************************************************
365 reads or writes a structure.
366 ********************************************************************/
367
368 BOOL samr_io_r_get_usrdom_pwinfo(const char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
369                                  prs_struct *ps, int depth)
370 {
371         if (r_u == NULL)
372                 return False;
373
374         prs_debug(ps, depth, desc, "samr_io_r_get_usrdom_pwinfo");
375         depth++;
376
377         if(!prs_align(ps))
378                 return False;
379
380         if(!prs_uint16("unknown_0", ps, depth, &r_u->unknown_0))
381                 return False;
382         if(!prs_uint16("unknown_1", ps, depth, &r_u->unknown_1))
383                 return False;
384         if(!prs_uint32("unknown_2", ps, depth, &r_u->unknown_2))
385                 return False;
386         if(!prs_ntstatus("status   ", ps, depth, &r_u->status))
387                 return False;
388
389         return True;
390 }
391
392
393 /*******************************************************************
394 reads or writes a structure.
395 ********************************************************************/
396
397 BOOL samr_io_q_set_sec_obj(const char *desc, SAMR_Q_SET_SEC_OBJ * q_u,
398                              prs_struct *ps, int depth)
399 {
400         if (q_u == NULL)
401                 return False;
402
403         prs_debug(ps, depth, desc, "samr_io_q_set_sec_obj");
404         depth++;
405
406         if(!prs_align(ps))
407                 return False;
408
409         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
410                 return False;
411
412         if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
413                 return False;
414                 
415         if(!sec_io_desc_buf("sec_desc", &q_u->buf, ps, depth))
416                 return False;
417         
418         return True;
419 }
420
421
422 /*******************************************************************
423 reads or writes a structure.
424 ********************************************************************/
425
426 void init_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
427                                POLICY_HND *user_pol, uint32 sec_info)
428 {
429         DEBUG(5, ("samr_init_samr_q_query_sec_obj\n"));
430
431         q_u->user_pol = *user_pol;
432         q_u->sec_info = sec_info;
433 }
434
435
436 /*******************************************************************
437 reads or writes a structure.
438 ********************************************************************/
439
440 BOOL samr_io_q_query_sec_obj(const char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
441                              prs_struct *ps, int depth)
442 {
443         if (q_u == NULL)
444                 return False;
445
446         prs_debug(ps, depth, desc, "samr_io_q_query_sec_obj");
447         depth++;
448
449         if(!prs_align(ps))
450                 return False;
451
452         if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
453                 return False;
454
455         if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
456                 return False;
457
458         return True;
459 }
460
461 /*******************************************************************
462 reads or writes a structure.
463 ********************************************************************/
464
465 void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
466                                 POLICY_HND *domain_pol, uint16 switch_value)
467 {
468         DEBUG(5, ("samr_init_samr_q_query_dom_info\n"));
469
470         q_u->domain_pol = *domain_pol;
471         q_u->switch_value = switch_value;
472 }
473
474 /*******************************************************************
475 reads or writes a structure.
476 ********************************************************************/
477
478 BOOL samr_io_q_query_dom_info(const char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
479                               prs_struct *ps, int depth)
480 {
481         if (q_u == NULL)
482                 return False;
483
484         prs_debug(ps, depth, desc, "samr_io_q_query_dom_info");
485         depth++;
486
487         if(!prs_align(ps))
488                 return False;
489
490         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
491                 return False;
492
493         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
494                 return False;
495
496         return True;
497 }
498
499
500 /*******************************************************************
501 inits a structure.
502 ********************************************************************/
503
504 void init_unk_info3(SAM_UNK_INFO_3 *u_3, NTTIME nt_logout)
505 {
506         u_3->logout.low = nt_logout.low;
507         u_3->logout.high = nt_logout.high;
508 }
509
510 /*******************************************************************
511 reads or writes a structure.
512 ********************************************************************/
513
514 static BOOL sam_io_unk_info3(const char *desc, SAM_UNK_INFO_3 * u_3,
515                              prs_struct *ps, int depth)
516 {
517         if (u_3 == NULL)
518                 return False;
519
520         prs_debug(ps, depth, desc, "sam_io_unk_info3");
521         depth++;
522
523         if(!smb_io_time("logout", &u_3->logout, ps, depth))
524                 return False;
525
526         return True;
527 }
528
529 /*******************************************************************
530 inits a structure.
531 ********************************************************************/
532
533 void init_unk_info6(SAM_UNK_INFO_6 * u_6)
534 {
535         u_6->unknown_0 = 0x00000000;
536         u_6->ptr_0 = 1;
537         memset(u_6->padding, 0, sizeof(u_6->padding));  /* 12 bytes zeros */
538 }
539
540 /*******************************************************************
541 reads or writes a structure.
542 ********************************************************************/
543
544 static BOOL sam_io_unk_info6(const char *desc, SAM_UNK_INFO_6 * u_6,
545                              prs_struct *ps, int depth)
546 {
547         if (u_6 == NULL)
548                 return False;
549
550         prs_debug(ps, depth, desc, "sam_io_unk_info6");
551         depth++;
552
553         if(!prs_uint32("unknown_0", ps, depth, &u_6->unknown_0)) /* 0x0000 0000 */
554                 return False;
555         if(!prs_uint32("ptr_0", ps, depth, &u_6->ptr_0)) /* pointer to unknown structure */
556                 return False;
557         if(!prs_uint8s(False, "padding", ps, depth, u_6->padding, sizeof(u_6->padding)))        /* 12 bytes zeros */
558                 return False;
559
560         return True;
561 }
562
563 /*******************************************************************
564 inits a structure.
565 ********************************************************************/
566
567 void init_unk_info7(SAM_UNK_INFO_7 * u_7)
568 {
569         u_7->unknown_0 = 0x0003;
570 }
571
572 /*******************************************************************
573 reads or writes a structure.
574 ********************************************************************/
575
576 static BOOL sam_io_unk_info7(const char *desc, SAM_UNK_INFO_7 * u_7,
577                              prs_struct *ps, int depth)
578 {
579         if (u_7 == NULL)
580                 return False;
581
582         prs_debug(ps, depth, desc, "sam_io_unk_info7");
583         depth++;
584
585         if(!prs_uint16("unknown_0", ps, depth, &u_7->unknown_0)) /* 0x0003 */
586                 return False;
587
588         return True;
589 }
590
591 /*******************************************************************
592 inits a structure.
593 ********************************************************************/
594
595 void init_unk_info12(SAM_UNK_INFO_12 * u_12, NTTIME nt_lock_duration, NTTIME nt_reset_time, uint16 lockout)
596 {
597         u_12->duration.low = nt_lock_duration.low;
598         u_12->duration.high = nt_lock_duration.high;
599         u_12->reset_count.low = nt_reset_time.low;
600         u_12->reset_count.high = nt_reset_time.high;
601
602         u_12->bad_attempt_lockout = lockout;
603 }
604
605 /*******************************************************************
606 reads or writes a structure.
607 ********************************************************************/
608
609 static BOOL sam_io_unk_info12(const char *desc, SAM_UNK_INFO_12 * u_12,
610                               prs_struct *ps, int depth)
611 {
612         if (u_12 == NULL)
613                 return False;
614
615         prs_debug(ps, depth, desc, "sam_io_unk_info12");
616         depth++;
617
618         if(!smb_io_time("duration", &u_12->duration, ps, depth))
619                 return False;
620         if(!smb_io_time("reset_count", &u_12->reset_count, ps, depth))
621                 return False;
622         if(!prs_uint16("bad_attempt_lockout", ps, depth, &u_12->bad_attempt_lockout))
623                 return False;
624
625         return True;
626 }
627
628 /*******************************************************************
629 inits a structure.
630 ********************************************************************/
631
632 void init_unk_info5(SAM_UNK_INFO_5 * u_5,const char *server)
633 {
634         init_unistr2(&u_5->uni_server, server, UNI_FLAGS_NONE);
635         init_uni_hdr(&u_5->hdr_server, &u_5->uni_server);
636 }
637
638 /*******************************************************************
639 reads or writes a structure.
640 ********************************************************************/
641
642 static BOOL sam_io_unk_info5(const char *desc, SAM_UNK_INFO_5 * u_5,
643                              prs_struct *ps, int depth)
644 {
645         if (u_5 == NULL)
646                 return False;
647
648         prs_debug(ps, depth, desc, "sam_io_unk_info5");
649         depth++;
650
651         if(!smb_io_unihdr("hdr_server", &u_5->hdr_server, ps, depth))
652                 return False;
653
654         if(!smb_io_unistr2("uni_server", &u_5->uni_server, u_5->hdr_server.buffer, ps, depth))
655                 return False;
656
657         return True;
658 }
659
660 /*******************************************************************
661 inits a structure.
662 ********************************************************************/
663
664 void init_unk_info2(SAM_UNK_INFO_2 * u_2,
665                         const char *domain, const char *server,
666                         uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias)
667 {
668         u_2->unknown_0 = 0x00000000;
669         u_2->unknown_1 = 0x80000000;
670         u_2->unknown_2 = 0x00000000;
671
672         u_2->ptr_0 = 1;
673
674         u_2->seq_num = seq_num;
675         u_2->unknown_3 = 0x00000000;
676
677         u_2->unknown_4 = 0x00000001;
678         u_2->unknown_5 = 0x00000003;
679         u_2->unknown_6 = 0x00000001;
680         u_2->num_domain_usrs = num_users;
681         u_2->num_domain_grps = num_groups;
682         u_2->num_local_grps = num_alias;
683
684         memset(u_2->padding, 0, sizeof(u_2->padding));  /* 12 bytes zeros */
685
686         init_unistr2(&u_2->uni_domain, domain, UNI_FLAGS_NONE);
687         init_uni_hdr(&u_2->hdr_domain, &u_2->uni_domain);
688         init_unistr2(&u_2->uni_server, server, UNI_FLAGS_NONE);
689         init_uni_hdr(&u_2->hdr_server, &u_2->uni_server);
690 }
691
692 /*******************************************************************
693 reads or writes a structure.
694 ********************************************************************/
695
696 static BOOL sam_io_unk_info2(const char *desc, SAM_UNK_INFO_2 * u_2,
697                              prs_struct *ps, int depth)
698 {
699         if (u_2 == NULL)
700                 return False;
701
702         prs_debug(ps, depth, desc, "sam_io_unk_info2");
703         depth++;
704
705         if(!prs_uint32("unknown_0", ps, depth, &u_2->unknown_0)) /* 0x0000 0000 */
706                 return False;
707         if(!prs_uint32("unknown_1", ps, depth, &u_2->unknown_1)) /* 0x8000 0000 */
708                 return False;
709         if(!prs_uint32("unknown_2", ps, depth, &u_2->unknown_2))        /* 0x0000 0000 */
710                 return False;
711
712         if(!prs_uint32("ptr_0", ps, depth, &u_2->ptr_0))
713                 return False;
714         if(!smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth))
715                 return False;
716         if(!smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth))
717                 return False;
718
719         /* put all the data in here, at the moment, including what the above
720            pointer is referring to
721          */
722
723         if(!prs_uint32("seq_num ", ps, depth, &u_2->seq_num))   /* 0x0000 0099 or 0x1000 0000 */
724                 return False;
725         if(!prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3))       /* 0x0000 0000 */
726                 return False;
727
728         if(!prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4)) /* 0x0000 0001 */
729                 return False;
730         if(!prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5)) /* 0x0000 0003 */
731                 return False;
732         if(!prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6)) /* 0x0000 0001 */
733                 return False;
734         if(!prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs))
735                 return False;
736         if(!prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps))
737                 return False;
738         if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps))
739                 return False;
740
741         if (u_2->ptr_0) {
742                 /* this was originally marked as 'padding'. It isn't
743                    padding, it is some sort of optional 12 byte
744                    structure. When it is present it contains zeros
745                    !? */
746                 if(!prs_uint8s(False, "unknown", ps, depth, u_2->padding,sizeof(u_2->padding)))
747                         return False;
748         }
749
750         if(!smb_io_unistr2("uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth))
751                 return False;
752         if(!smb_io_unistr2("uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth))
753                 return False;
754
755         return True;
756 }
757
758 /*******************************************************************
759 inits a structure.
760 ********************************************************************/
761
762 void init_unk_info1(SAM_UNK_INFO_1 *u_1, uint16 min_pass_len, uint16 pass_hist, 
763                     uint32 flag, NTTIME nt_expire, NTTIME nt_min_age)
764 {
765         u_1->min_length_password = min_pass_len;
766         u_1->password_history = pass_hist;
767         u_1->flag = flag;
768         
769         /* password never expire */
770         u_1->expire.high = nt_expire.high;
771         u_1->expire.low = nt_expire.low;
772         
773         /* can change the password now */
774         u_1->min_passwordage.high = nt_min_age.high;
775         u_1->min_passwordage.low = nt_min_age.low;
776         
777 }
778
779 /*******************************************************************
780 reads or writes a structure.
781 ********************************************************************/
782
783 static BOOL sam_io_unk_info1(const char *desc, SAM_UNK_INFO_1 * u_1,
784                              prs_struct *ps, int depth)
785 {
786         if (u_1 == NULL)
787           return False;
788
789         prs_debug(ps, depth, desc, "sam_io_unk_info1");
790         depth++;
791
792         if(!prs_uint16("min_length_password", ps, depth, &u_1->min_length_password))
793                 return False;
794         if(!prs_uint16("password_history", ps, depth, &u_1->password_history))
795                 return False;
796         if(!prs_uint32("flag", ps, depth, &u_1->flag))
797                 return False;
798         if(!smb_io_time("expire", &u_1->expire, ps, depth))
799                 return False;
800         if(!smb_io_time("min_passwordage", &u_1->min_passwordage, ps, depth))
801                 return False;
802
803         return True;
804 }
805
806 /*******************************************************************
807 inits a SAMR_R_QUERY_DOMAIN_INFO structure.
808 ********************************************************************/
809
810 void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
811                                 uint16 switch_value, SAM_UNK_CTR * ctr,
812                                 NTSTATUS status)
813 {
814         DEBUG(5, ("init_samr_r_query_dom_info\n"));
815
816         r_u->ptr_0 = 0;
817         r_u->switch_value = 0;
818         r_u->status = status;   /* return status */
819
820         if (NT_STATUS_IS_OK(status)) {
821                 r_u->switch_value = switch_value;
822                 r_u->ptr_0 = 1;
823                 r_u->ctr = ctr;
824         }
825 }
826
827 /*******************************************************************
828 reads or writes a structure.
829 ********************************************************************/
830
831 BOOL samr_io_r_query_dom_info(const char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
832                               prs_struct *ps, int depth)
833 {
834         if (r_u == NULL)
835                 return False;
836
837         prs_debug(ps, depth, desc, "samr_io_r_query_dom_info");
838         depth++;
839
840         if(!prs_align(ps))
841                 return False;
842
843         if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
844                 return False;
845
846         if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
847                 if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
848                         return False;
849                 if(!prs_align(ps))
850                         return False;
851
852                 switch (r_u->switch_value) {
853                 case 0x0c:
854                         if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
855                                 return False;
856                         break;
857                 case 0x07:
858                         if(!sam_io_unk_info7("unk_inf7",&r_u->ctr->info.inf7, ps,depth))
859                                 return False;
860                         break;
861                 case 0x06:
862                         if(!sam_io_unk_info6("unk_inf6",&r_u->ctr->info.inf6, ps,depth))
863                                 return False;
864                         break;
865                 case 0x05:
866                         if(!sam_io_unk_info5("unk_inf5",&r_u->ctr->info.inf5, ps,depth))
867                                 return False;
868                         break;
869                 case 0x03:
870                         if(!sam_io_unk_info3("unk_inf3",&r_u->ctr->info.inf3, ps,depth))
871                                 return False;
872                         break;
873                 case 0x02:
874                         if(!sam_io_unk_info2("unk_inf2",&r_u->ctr->info.inf2, ps,depth))
875                                 return False;
876                         break;
877                 case 0x01:
878                         if(!sam_io_unk_info1("unk_inf1",&r_u->ctr->info.inf1, ps,depth))
879                                 return False;
880                         break;
881                 default:
882                         DEBUG(0, ("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
883                                 r_u->switch_value));
884                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
885                         return False;
886                 }
887         }
888         
889         if(!prs_align(ps))
890                 return False;
891
892         if(!prs_ntstatus("status", ps, depth, &r_u->status))
893                 return False;
894         
895         return True;
896 }
897
898 /*******************************************************************
899 reads or writes a SAMR_R_SET_SEC_OBJ structure.
900 ********************************************************************/
901
902 BOOL samr_io_r_set_sec_obj(const char *desc, SAMR_R_SET_SEC_OBJ * r_u,
903                              prs_struct *ps, int depth)
904 {
905         if (r_u == NULL)
906                 return False;
907   
908         prs_debug(ps, depth, desc, "samr_io_r_set_sec_obj");
909         depth++;
910
911         if(!prs_align(ps))
912                 return False;
913
914         if(!prs_ntstatus("status", ps, depth, &r_u->status))
915                 return False;
916
917         return True;
918 }
919
920 /*******************************************************************
921 reads or writes a SAMR_R_QUERY_SEC_OBJ structure.
922 ********************************************************************/
923
924 BOOL samr_io_r_query_sec_obj(const char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
925                              prs_struct *ps, int depth)
926 {
927         if (r_u == NULL)
928                 return False;
929   
930         prs_debug(ps, depth, desc, "samr_io_r_query_sec_obj");
931         depth++;
932
933         if(!prs_align(ps))
934                 return False;
935
936         if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
937                 return False;
938         if (r_u->ptr != 0) {
939                 if(!sec_io_desc_buf("sec", &r_u->buf, ps, depth))
940                         return False;
941         }
942
943         if(!prs_ntstatus("status", ps, depth, &r_u->status))
944                 return False;
945
946         return True;
947 }
948
949 /*******************************************************************
950 reads or writes a SAM_STR1 structure.
951 ********************************************************************/
952
953 static BOOL sam_io_sam_str1(const char *desc, SAM_STR1 * sam, uint32 acct_buf,
954                             uint32 name_buf, uint32 desc_buf,
955                             prs_struct *ps, int depth)
956 {
957         if (sam == NULL)
958                 return False;
959
960         prs_debug(ps, depth, desc, "sam_io_sam_str1");
961         depth++;
962
963         if(!prs_align(ps))
964                 return False;
965         if (!smb_io_unistr2("name", &sam->uni_acct_name, acct_buf, ps, depth))
966                 return False;
967
968         if (!smb_io_unistr2("desc", &sam->uni_acct_desc, desc_buf, ps, depth))
969                 return False;
970
971         if (!smb_io_unistr2("full", &sam->uni_full_name, name_buf, ps, depth))
972                 return False;
973
974         return True;
975 }
976
977 /*******************************************************************
978 inits a SAM_ENTRY1 structure.
979 ********************************************************************/
980
981 static void init_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx,
982                             UNISTR2 *sam_name, UNISTR2 *sam_full,
983                             UNISTR2 *sam_desc, uint32 rid_user,
984                             uint16 acb_info)
985 {
986         DEBUG(5, ("init_sam_entry1\n"));
987
988         ZERO_STRUCTP(sam);
989
990         sam->user_idx = user_idx;
991         sam->rid_user = rid_user;
992         sam->acb_info = acb_info;
993
994         init_uni_hdr(&sam->hdr_acct_name, sam_name);
995         init_uni_hdr(&sam->hdr_user_name, sam_full);
996         init_uni_hdr(&sam->hdr_user_desc, sam_desc);
997 }
998
999 /*******************************************************************
1000 reads or writes a SAM_ENTRY1 structure.
1001 ********************************************************************/
1002
1003 static BOOL sam_io_sam_entry1(const char *desc, SAM_ENTRY1 * sam,
1004                               prs_struct *ps, int depth)
1005 {
1006         if (sam == NULL)
1007                 return False;
1008
1009         prs_debug(ps, depth, desc, "sam_io_sam_entry1");
1010         depth++;
1011
1012         if(!prs_align(ps))
1013                 return False;
1014
1015         if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
1016                 return False;
1017
1018         if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
1019                 return False;
1020         if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
1021                 return False;
1022
1023         if(!prs_align(ps))
1024                 return False;
1025
1026         if (!smb_io_unihdr("hdr_acct_name", &sam->hdr_acct_name, ps, depth))
1027                 return False;
1028         if (!smb_io_unihdr("hdr_user_desc", &sam->hdr_user_desc, ps, depth))
1029                 return False;
1030         if (!smb_io_unihdr("hdr_user_name", &sam->hdr_user_name, ps, depth))
1031                 return False;
1032
1033         return True;
1034 }
1035
1036 /*******************************************************************
1037 reads or writes a SAM_STR2 structure.
1038 ********************************************************************/
1039
1040 static BOOL sam_io_sam_str2(const char *desc, SAM_STR2 * sam, uint32 acct_buf,
1041                             uint32 desc_buf, prs_struct *ps, int depth)
1042 {
1043         if (sam == NULL)
1044                 return False;
1045
1046         prs_debug(ps, depth, desc, "sam_io_sam_str2");
1047         depth++;
1048
1049         if(!prs_align(ps))
1050                 return False;
1051
1052         if(!smb_io_unistr2("uni_srv_name", &sam->uni_srv_name, acct_buf, ps, depth)) /* account name unicode string */
1053                 return False;
1054         if(!smb_io_unistr2("uni_srv_desc", &sam->uni_srv_desc, desc_buf, ps, depth))    /* account desc unicode string */
1055                 return False;
1056
1057         return True;
1058 }
1059
1060 /*******************************************************************
1061 inits a SAM_ENTRY2 structure.
1062 ********************************************************************/
1063 static void init_sam_entry2(SAM_ENTRY2 * sam, uint32 user_idx,
1064                             UNISTR2 *sam_name, UNISTR2 *sam_desc,
1065                             uint32 rid_user, uint16 acb_info)
1066 {
1067         DEBUG(5, ("init_sam_entry2\n"));
1068
1069         sam->user_idx = user_idx;
1070         sam->rid_user = rid_user;
1071         sam->acb_info = acb_info;
1072
1073         init_uni_hdr(&sam->hdr_srv_name, sam_name);
1074         init_uni_hdr(&sam->hdr_srv_desc, sam_desc);
1075 }
1076
1077 /*******************************************************************
1078 reads or writes a SAM_ENTRY2 structure.
1079 ********************************************************************/
1080
1081 static BOOL sam_io_sam_entry2(const char *desc, SAM_ENTRY2 * sam,
1082                               prs_struct *ps, int depth)
1083 {
1084         if (sam == NULL)
1085                 return False;
1086
1087         prs_debug(ps, depth, desc, "sam_io_sam_entry2");
1088         depth++;
1089
1090         if(!prs_align(ps))
1091                 return False;
1092
1093         if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
1094                 return False;
1095
1096         if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
1097                 return False;
1098         if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
1099                 return False;
1100
1101         if(!prs_align(ps))
1102                 return False;
1103
1104         if(!smb_io_unihdr("unihdr", &sam->hdr_srv_name, ps, depth))     /* account name unicode string header */
1105                 return False;
1106         if(!smb_io_unihdr("unihdr", &sam->hdr_srv_desc, ps, depth))     /* account name unicode string header */
1107                 return False;
1108
1109         return True;
1110 }
1111
1112 /*******************************************************************
1113 reads or writes a SAM_STR3 structure.
1114 ********************************************************************/
1115
1116 static BOOL sam_io_sam_str3(const char *desc, SAM_STR3 * sam, uint32 acct_buf,
1117                             uint32 desc_buf, prs_struct *ps, int depth)
1118 {
1119         if (sam == NULL)
1120                 return False;
1121
1122         prs_debug(ps, depth, desc, "sam_io_sam_str3");
1123         depth++;
1124
1125         if(!prs_align(ps))
1126                 return False;
1127
1128         if(!smb_io_unistr2("uni_grp_name", &sam->uni_grp_name, acct_buf, ps, depth))    /* account name unicode string */
1129                 return False;
1130         if(!smb_io_unistr2("uni_grp_desc", &sam->uni_grp_desc, desc_buf, ps, depth))    /* account desc unicode string */
1131                 return False;
1132
1133         return True;
1134 }
1135
1136 /*******************************************************************
1137 inits a SAM_ENTRY3 structure.
1138 ********************************************************************/
1139
1140 static void init_sam_entry3(SAM_ENTRY3 * sam, uint32 grp_idx,
1141                             UNISTR2 *grp_name, UNISTR2 *grp_desc,
1142                             uint32 rid_grp)
1143 {
1144         DEBUG(5, ("init_sam_entry3\n"));
1145
1146         sam->grp_idx = grp_idx;
1147         sam->rid_grp = rid_grp;
1148         sam->attr = 0x07;       /* group rid attributes - gets ignored by nt 4.0 */
1149
1150         init_uni_hdr(&sam->hdr_grp_name, grp_name);
1151         init_uni_hdr(&sam->hdr_grp_desc, grp_desc);
1152 }
1153
1154 /*******************************************************************
1155 reads or writes a SAM_ENTRY3 structure.
1156 ********************************************************************/
1157
1158 static BOOL sam_io_sam_entry3(const char *desc, SAM_ENTRY3 * sam,
1159                               prs_struct *ps, int depth)
1160 {
1161         if (sam == NULL)
1162                 return False;
1163
1164         prs_debug(ps, depth, desc, "sam_io_sam_entry3");
1165         depth++;
1166
1167         if(!prs_align(ps))
1168                 return False;
1169
1170         if(!prs_uint32("grp_idx", ps, depth, &sam->grp_idx))
1171                 return False;
1172
1173         if(!prs_uint32("rid_grp", ps, depth, &sam->rid_grp))
1174                 return False;
1175         if(!prs_uint32("attr   ", ps, depth, &sam->attr))
1176                 return False;
1177
1178         if(!smb_io_unihdr("unihdr", &sam->hdr_grp_name, ps, depth))     /* account name unicode string header */
1179                 return False;
1180         if(!smb_io_unihdr("unihdr", &sam->hdr_grp_desc, ps, depth))     /* account name unicode string header */
1181                 return False;
1182
1183         return True;
1184 }
1185
1186 /*******************************************************************
1187 inits a SAM_ENTRY4 structure.
1188 ********************************************************************/
1189
1190 static void init_sam_entry4(SAM_ENTRY4 * sam, uint32 user_idx,
1191                             uint32 len_acct_name)
1192 {
1193         DEBUG(5, ("init_sam_entry4\n"));
1194
1195         sam->user_idx = user_idx;
1196         init_str_hdr(&sam->hdr_acct_name, len_acct_name+1, len_acct_name, len_acct_name != 0);
1197 }
1198
1199 /*******************************************************************
1200 reads or writes a SAM_ENTRY4 structure.
1201 ********************************************************************/
1202
1203 static BOOL sam_io_sam_entry4(const char *desc, SAM_ENTRY4 * sam,
1204                               prs_struct *ps, int depth)
1205 {
1206         if (sam == NULL)
1207                 return False;
1208
1209         prs_debug(ps, depth, desc, "sam_io_sam_entry4");
1210         depth++;
1211
1212         if(!prs_align(ps))
1213                 return False;
1214
1215         if(!prs_uint32("user_idx", ps, depth, &sam->user_idx))
1216                 return False;
1217         if(!smb_io_strhdr("strhdr", &sam->hdr_acct_name, ps, depth))
1218                 return False;
1219
1220         return True;
1221 }
1222
1223 /*******************************************************************
1224 inits a SAM_ENTRY5 structure.
1225 ********************************************************************/
1226
1227 static void init_sam_entry5(SAM_ENTRY5 * sam, uint32 grp_idx,
1228                             uint32 len_grp_name)
1229 {
1230         DEBUG(5, ("init_sam_entry5\n"));
1231
1232         sam->grp_idx = grp_idx;
1233         init_str_hdr(&sam->hdr_grp_name, len_grp_name, len_grp_name,
1234                      len_grp_name != 0);
1235 }
1236
1237 /*******************************************************************
1238 reads or writes a SAM_ENTRY5 structure.
1239 ********************************************************************/
1240
1241 static BOOL sam_io_sam_entry5(const char *desc, SAM_ENTRY5 * sam,
1242                               prs_struct *ps, int depth)
1243 {
1244         if (sam == NULL)
1245                 return False;
1246
1247         prs_debug(ps, depth, desc, "sam_io_sam_entry5");
1248         depth++;
1249
1250         if(!prs_align(ps))
1251                 return False;
1252
1253         if(!prs_uint32("grp_idx", ps, depth, &sam->grp_idx))
1254                 return False;
1255         if(!smb_io_strhdr("strhdr", &sam->hdr_grp_name, ps, depth))
1256                 return False;
1257
1258         return True;
1259 }
1260
1261 /*******************************************************************
1262 inits a SAM_ENTRY structure.
1263 ********************************************************************/
1264
1265 void init_sam_entry(SAM_ENTRY *sam, UNISTR2 *uni2, uint32 rid)
1266 {
1267         DEBUG(10, ("init_sam_entry: %d\n", rid));
1268
1269         sam->rid = rid;
1270         init_uni_hdr(&sam->hdr_name, uni2);
1271 }
1272
1273 /*******************************************************************
1274 reads or writes a SAM_ENTRY structure.
1275 ********************************************************************/
1276
1277 static BOOL sam_io_sam_entry(const char *desc, SAM_ENTRY * sam,
1278                              prs_struct *ps, int depth)
1279 {
1280         if (sam == NULL)
1281                 return False;
1282
1283         prs_debug(ps, depth, desc, "sam_io_sam_entry");
1284         depth++;
1285
1286         if(!prs_align(ps))
1287                 return False;
1288         if(!prs_uint32("rid", ps, depth, &sam->rid))
1289                 return False;
1290         if(!smb_io_unihdr("unihdr", &sam->hdr_name, ps, depth)) /* account name unicode string header */
1291                 return False;
1292
1293         return True;
1294 }
1295
1296 /*******************************************************************
1297 inits a SAMR_Q_ENUM_DOM_USERS structure.
1298 ********************************************************************/
1299
1300 void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND *pol,
1301                                 uint32 start_idx,
1302                                 uint16 acb_mask, uint16 unk_1, uint32 size)
1303 {
1304         DEBUG(5, ("init_samr_q_enum_dom_users\n"));
1305
1306         q_e->pol = *pol;
1307
1308         q_e->start_idx = start_idx;     /* zero indicates lots */
1309         q_e->acb_mask = acb_mask;
1310         q_e->unknown_1 = unk_1;
1311         q_e->max_size = size;
1312 }
1313
1314 /*******************************************************************
1315 reads or writes a structure.
1316 ********************************************************************/
1317
1318 BOOL samr_io_q_enum_dom_users(const char *desc, SAMR_Q_ENUM_DOM_USERS * q_e,
1319                               prs_struct *ps, int depth)
1320 {
1321         if (q_e == NULL)
1322                 return False;
1323
1324         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
1325         depth++;
1326
1327         if(!prs_align(ps))
1328                 return False;
1329
1330         if(!smb_io_pol_hnd("domain_pol", &q_e->pol, ps, depth))
1331                 return False;
1332
1333         if(!prs_uint32("start_idx", ps, depth, &q_e->start_idx))
1334                 return False;
1335         if(!prs_uint16("acb_mask ", ps, depth, &q_e->acb_mask))
1336                 return False;
1337         if(!prs_uint16("unknown_1", ps, depth, &q_e->unknown_1))
1338                 return False;
1339
1340         if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
1341                 return False;
1342
1343         return True;
1344 }
1345
1346
1347 /*******************************************************************
1348 inits a SAMR_R_ENUM_DOM_USERS structure.
1349 ********************************************************************/
1350
1351 void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS * r_u,
1352                                 uint32 next_idx, uint32 num_sam_entries)
1353 {
1354         DEBUG(5, ("init_samr_r_enum_dom_users\n"));
1355
1356         r_u->next_idx = next_idx;
1357
1358         if (num_sam_entries != 0) {
1359                 r_u->ptr_entries1 = 1;
1360                 r_u->ptr_entries2 = 1;
1361                 r_u->num_entries2 = num_sam_entries;
1362                 r_u->num_entries3 = num_sam_entries;
1363
1364                 r_u->num_entries4 = num_sam_entries;
1365         } else {
1366                 r_u->ptr_entries1 = 0;
1367                 r_u->num_entries2 = num_sam_entries;
1368                 r_u->ptr_entries2 = 1;
1369         }
1370 }
1371
1372 /*******************************************************************
1373 reads or writes a structure.
1374 ********************************************************************/
1375
1376 BOOL samr_io_r_enum_dom_users(const char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
1377                               prs_struct *ps, int depth)
1378 {
1379         uint32 i;
1380
1381         if (r_u == NULL)
1382                 return False;
1383
1384         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
1385         depth++;
1386
1387         if(!prs_align(ps))
1388                 return False;
1389
1390         if(!prs_uint32("next_idx    ", ps, depth, &r_u->next_idx))
1391                 return False;
1392         if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
1393                 return False;
1394
1395         if (r_u->ptr_entries1 != 0) {
1396                 if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
1397                         return False;
1398                 if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
1399                         return False;
1400                 if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
1401                         return False;
1402
1403                 if (UNMARSHALLING(ps) && (r_u->num_entries2 != 0)) {
1404                         r_u->sam = (SAM_ENTRY *)prs_alloc_mem(ps,sizeof(SAM_ENTRY)*r_u->num_entries2);
1405                         r_u->uni_acct_name = (UNISTR2 *)prs_alloc_mem(ps,sizeof(UNISTR2)*r_u->num_entries2);
1406                 }
1407
1408                 if ((r_u->sam == NULL || r_u->uni_acct_name == NULL) && r_u->num_entries2 != 0) {
1409                         DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_USERS\n"));
1410                         r_u->num_entries4 = 0;
1411                         r_u->status = NT_STATUS_MEMORY_NOT_ALLOCATED;
1412                         return False;
1413                 }
1414
1415                 for (i = 0; i < r_u->num_entries2; i++) {
1416                         if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
1417                                 return False;
1418                 }
1419
1420                 for (i = 0; i < r_u->num_entries2; i++) {
1421                         if(!smb_io_unistr2("", &r_u->uni_acct_name[i],r_u->sam[i].hdr_name.buffer, ps,depth))
1422                                 return False;
1423                 }
1424
1425         }
1426
1427         if(!prs_align(ps))
1428                 return False;
1429                 
1430         if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
1431                 return False;
1432         if(!prs_ntstatus("status", ps, depth, &r_u->status))
1433                 return False;
1434
1435         return True;
1436 }
1437
1438 /*******************************************************************
1439 inits a SAMR_Q_QUERY_DISPINFO structure.
1440 ********************************************************************/
1441
1442 void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol,
1443                                 uint16 switch_level, uint32 start_idx,
1444                                 uint32 max_entries, uint32 max_size)
1445 {
1446         DEBUG(5, ("init_samr_q_query_dispinfo\n"));
1447
1448         q_e->domain_pol = *pol;
1449
1450         q_e->switch_level = switch_level;
1451
1452         q_e->start_idx = start_idx;
1453         q_e->max_entries = max_entries;
1454         q_e->max_size = max_size;
1455 }
1456
1457 /*******************************************************************
1458 reads or writes a structure.
1459 ********************************************************************/
1460
1461 BOOL samr_io_q_query_dispinfo(const char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
1462                               prs_struct *ps, int depth)
1463 {
1464         if (q_e == NULL)
1465                 return False;
1466
1467         prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
1468         depth++;
1469
1470         if(!prs_align(ps))
1471                 return False;
1472
1473         if(!smb_io_pol_hnd("domain_pol", &q_e->domain_pol, ps, depth))
1474                 return False;
1475
1476         if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
1477                 return False;
1478         if(!prs_align(ps))
1479                 return False;
1480
1481         if(!prs_uint32("start_idx   ", ps, depth, &q_e->start_idx))
1482                 return False;
1483         if(!prs_uint32("max_entries ", ps, depth, &q_e->max_entries))
1484                 return False;
1485         if(!prs_uint32("max_size    ", ps, depth, &q_e->max_size))
1486                 return False;
1487
1488         return True;
1489 }
1490
1491 /*******************************************************************
1492 inits a SAM_DISPINFO_1 structure.
1493 ********************************************************************/
1494
1495 NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
1496                              uint32 start_idx, SAM_ACCOUNT *disp_user_info,
1497                              DOM_SID *domain_sid)
1498 {
1499         uint32 i;
1500
1501         SAM_ACCOUNT *pwd = NULL;
1502         ZERO_STRUCTP(sam);
1503
1504         DEBUG(10, ("init_sam_dispinfo_1: num_entries: %d\n", num_entries));
1505
1506         if (num_entries==0)
1507                 return NT_STATUS_OK;
1508
1509         sam->sam=(SAM_ENTRY1 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY1));
1510         if (!sam->sam)
1511                 return NT_STATUS_NO_MEMORY;
1512
1513         sam->str=(SAM_STR1 *)talloc(ctx, num_entries*sizeof(SAM_STR1));
1514         if (!sam->str)
1515                 return NT_STATUS_NO_MEMORY;
1516
1517         ZERO_STRUCTP(sam->sam);
1518         ZERO_STRUCTP(sam->str);
1519
1520         for (i = 0; i < num_entries ; i++) {
1521                 const char *username;
1522                 const char *fullname;
1523                 const char *acct_desc;
1524                 uint32 user_rid;
1525                 const DOM_SID *user_sid;
1526                 fstring user_sid_string, domain_sid_string;                     
1527
1528                 DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
1529                 
1530                 pwd=&disp_user_info[i+start_idx];
1531                 
1532                 username = pdb_get_username(pwd);
1533                 fullname = pdb_get_fullname(pwd);
1534                 acct_desc = pdb_get_acct_desc(pwd);
1535                 
1536                 if (!username) 
1537                         username = "";
1538
1539                 if (!fullname) 
1540                         fullname = "";
1541                 
1542                 if (!acct_desc) 
1543                         acct_desc = "";
1544
1545                 user_sid = pdb_get_user_sid(pwd);
1546
1547                 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
1548                         DEBUG(0, ("init_sam_dispinfo_1: User %s has SID %s, which conflicts with "
1549                                   "the domain sid %s.  Failing operation.\n", 
1550                                   username, 
1551                                   sid_to_string(user_sid_string, user_sid),
1552                                   sid_to_string(domain_sid_string, domain_sid)));
1553                         return NT_STATUS_UNSUCCESSFUL;
1554                 }
1555                         
1556                 init_unistr2(&sam->str[i].uni_acct_name, pdb_get_username(pwd), UNI_FLAGS_NONE);
1557                 init_unistr2(&sam->str[i].uni_full_name, pdb_get_fullname(pwd), UNI_FLAGS_NONE);
1558                 init_unistr2(&sam->str[i].uni_acct_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
1559
1560                 init_sam_entry1(&sam->sam[i], start_idx + i + 1,
1561                                 &sam->str[i].uni_acct_name, &sam->str[i].uni_full_name, &sam->str[i].uni_acct_desc,
1562                                 user_rid, pdb_get_acct_ctrl(pwd));
1563                 
1564         }
1565
1566         return NT_STATUS_OK;
1567 }
1568
1569 /*******************************************************************
1570 reads or writes a structure.
1571 ********************************************************************/
1572
1573 static BOOL sam_io_sam_dispinfo_1(const char *desc, SAM_DISPINFO_1 * sam,
1574                                   uint32 num_entries,
1575                                   prs_struct *ps, int depth)
1576 {
1577         uint32 i;
1578
1579         prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_1");
1580         depth++;
1581
1582         if(!prs_align(ps))
1583                 return False;
1584
1585         if (UNMARSHALLING(ps) && num_entries > 0) {
1586
1587                 if ((sam->sam = (SAM_ENTRY1 *)
1588                      prs_alloc_mem(ps, sizeof(SAM_ENTRY1) *
1589                                    num_entries)) == NULL) {
1590                         DEBUG(0, ("out of memory allocating SAM_ENTRY1\n"));
1591                         return False;
1592                 }
1593
1594                 if ((sam->str = (SAM_STR1 *)
1595                      prs_alloc_mem(ps, sizeof(SAM_STR1) * 
1596                                    num_entries)) == NULL) {
1597                         DEBUG(0, ("out of memory allocating SAM_STR1\n"));
1598                         return False;
1599                 }
1600         }
1601
1602         for (i = 0; i < num_entries; i++) {
1603                 if(!sam_io_sam_entry1("", &sam->sam[i], ps, depth))
1604                         return False;
1605         }
1606
1607         for (i = 0; i < num_entries; i++) {
1608                 if(!sam_io_sam_str1("", &sam->str[i],
1609                               sam->sam[i].hdr_acct_name.buffer,
1610                               sam->sam[i].hdr_user_name.buffer,
1611                               sam->sam[i].hdr_user_desc.buffer, ps, depth))
1612                         return False;
1613         }
1614
1615         return True;
1616 }
1617
1618 /*******************************************************************
1619 inits a SAM_DISPINFO_2 structure.
1620 ********************************************************************/
1621
1622 NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
1623                              uint32 start_idx, SAM_ACCOUNT *disp_user_info, 
1624                              DOM_SID *domain_sid )
1625 {
1626         uint32 i;
1627
1628         SAM_ACCOUNT *pwd = NULL;
1629         ZERO_STRUCTP(sam);
1630
1631         DEBUG(10, ("init_sam_dispinfo_2: num_entries: %d\n", num_entries));
1632
1633         if (num_entries==0)
1634                 return NT_STATUS_OK;
1635
1636         if (!(sam->sam=(SAM_ENTRY2 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY2))))
1637                 return NT_STATUS_NO_MEMORY;
1638
1639         if (!(sam->str=(SAM_STR2 *)talloc(ctx, num_entries*sizeof(SAM_STR2))))
1640                 return NT_STATUS_NO_MEMORY;
1641
1642         ZERO_STRUCTP(sam->sam);
1643         ZERO_STRUCTP(sam->str);
1644
1645         for (i = 0; i < num_entries; i++) {
1646                 uint32 user_rid;
1647                 const DOM_SID *user_sid;
1648                 const char *username;
1649                 const char *acct_desc;
1650                 fstring user_sid_string, domain_sid_string;                     
1651
1652                 DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
1653                 pwd=&disp_user_info[i+start_idx];
1654
1655                 username = pdb_get_username(pwd);
1656                 acct_desc = pdb_get_acct_desc(pwd);
1657                 user_sid = pdb_get_user_sid(pwd);
1658
1659                 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
1660                         DEBUG(0, ("init_sam_dispinfo_2: User %s has SID %s, which conflicts with "
1661                                   "the domain sid %s.  Failing operation.\n", 
1662                                   username, 
1663                                   sid_to_string(user_sid_string, user_sid),
1664                                   sid_to_string(domain_sid_string, domain_sid)));
1665                         return NT_STATUS_UNSUCCESSFUL;
1666                 }
1667                         
1668                 init_unistr2(&sam->str[i].uni_srv_name, username, UNI_FLAGS_NONE);
1669                 init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
1670
1671                 init_sam_entry2(&sam->sam[i], start_idx + i + 1,
1672                           &sam->str[i].uni_srv_name, &sam->str[i].uni_srv_desc,
1673                           user_rid, pdb_get_acct_ctrl(pwd));
1674         }
1675
1676         return NT_STATUS_OK;
1677 }
1678
1679 /*******************************************************************
1680 reads or writes a structure.
1681 ********************************************************************/
1682
1683 static BOOL sam_io_sam_dispinfo_2(const char *desc, SAM_DISPINFO_2 * sam,
1684                                   uint32 num_entries,
1685                                   prs_struct *ps, int depth)
1686 {
1687         uint32 i;
1688
1689         if (sam == NULL)
1690                 return False;
1691
1692         prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_2");
1693         depth++;
1694
1695         if(!prs_align(ps))
1696                 return False;
1697
1698         if (UNMARSHALLING(ps) && num_entries > 0) {
1699
1700                 if ((sam->sam = (SAM_ENTRY2 *)
1701                      prs_alloc_mem(ps, sizeof(SAM_ENTRY2) *
1702                                    num_entries)) == NULL) {
1703                         DEBUG(0, ("out of memory allocating SAM_ENTRY2\n"));
1704                         return False;
1705                 }
1706
1707                 if ((sam->str = (SAM_STR2 *)
1708                      prs_alloc_mem(ps, sizeof(SAM_STR2) * 
1709                                    num_entries)) == NULL) {
1710                         DEBUG(0, ("out of memory allocating SAM_STR2\n"));
1711                         return False;
1712                 }
1713         }
1714
1715         for (i = 0; i < num_entries; i++) {
1716                 if(!sam_io_sam_entry2("", &sam->sam[i], ps, depth))
1717                         return False;
1718         }
1719
1720         for (i = 0; i < num_entries; i++) {
1721                 if(!sam_io_sam_str2("", &sam->str[i],
1722                               sam->sam[i].hdr_srv_name.buffer,
1723                               sam->sam[i].hdr_srv_desc.buffer, ps, depth))
1724                         return False;
1725         }
1726
1727         return True;
1728 }
1729
1730 /*******************************************************************
1731 inits a SAM_DISPINFO_3 structure.
1732 ********************************************************************/
1733
1734 NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
1735                          uint32 start_idx, DOMAIN_GRP *disp_group_info)
1736 {
1737         uint32 i;
1738
1739         ZERO_STRUCTP(sam);
1740
1741         DEBUG(5, ("init_sam_dispinfo_3: num_entries: %d\n", num_entries));
1742
1743         if (num_entries==0)
1744                 return NT_STATUS_OK;
1745
1746         if (!(sam->sam=(SAM_ENTRY3 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY3))))
1747                 return NT_STATUS_NO_MEMORY;
1748
1749         if (!(sam->str=(SAM_STR3 *)talloc(ctx, num_entries*sizeof(SAM_STR3))))
1750                 return NT_STATUS_NO_MEMORY;
1751
1752         ZERO_STRUCTP(sam->sam);
1753         ZERO_STRUCTP(sam->str);
1754
1755         for (i = 0; i < num_entries; i++) {
1756                 DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
1757
1758                 DEBUG(11, ("init_sam_dispinfo_3: entry: %d\n",i));
1759
1760                 init_unistr2(&sam->str[i].uni_grp_name, grp->name, UNI_FLAGS_NONE);
1761                 init_unistr2(&sam->str[i].uni_grp_desc, grp->comment, UNI_FLAGS_NONE);
1762
1763                 init_sam_entry3(&sam->sam[i], start_idx + i + 1, &sam->str[i].uni_grp_name,
1764                                 &sam->str[i].uni_grp_desc, grp->rid);
1765         }
1766
1767         return NT_STATUS_OK;
1768 }
1769
1770 /*******************************************************************
1771 reads or writes a structure.
1772 ********************************************************************/
1773
1774 static BOOL sam_io_sam_dispinfo_3(const char *desc, SAM_DISPINFO_3 * sam,
1775                                   uint32 num_entries,
1776                                   prs_struct *ps, int depth)
1777 {
1778         uint32 i;
1779
1780         if (sam == NULL)
1781                 return False;
1782
1783         prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_3");
1784         depth++;
1785
1786         if(!prs_align(ps))
1787                 return False;
1788
1789         if (UNMARSHALLING(ps) && num_entries > 0) {
1790
1791                 if ((sam->sam = (SAM_ENTRY3 *)
1792                      prs_alloc_mem(ps, sizeof(SAM_ENTRY3) *
1793                                    num_entries)) == NULL) {
1794                         DEBUG(0, ("out of memory allocating SAM_ENTRY3\n"));
1795                         return False;
1796                 }
1797
1798                 if ((sam->str = (SAM_STR3 *)
1799                      prs_alloc_mem(ps, sizeof(SAM_STR3) * 
1800                                    num_entries)) == NULL) {
1801                         DEBUG(0, ("out of memory allocating SAM_STR3\n"));
1802                         return False;
1803                 }
1804         }
1805
1806         for (i = 0; i < num_entries; i++) {
1807                 if(!sam_io_sam_entry3("", &sam->sam[i], ps, depth))
1808                         return False;
1809         }
1810
1811         for (i = 0; i < num_entries; i++) {
1812                 if(!sam_io_sam_str3("", &sam->str[i],
1813                               sam->sam[i].hdr_grp_name.buffer,
1814                               sam->sam[i].hdr_grp_desc.buffer, ps, depth))
1815                         return False;
1816         }
1817
1818         return True;
1819 }
1820
1821 /*******************************************************************
1822 inits a SAM_DISPINFO_4 structure.
1823 ********************************************************************/
1824
1825 NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
1826                          uint32 start_idx, SAM_ACCOUNT *disp_user_info)
1827 {
1828         uint32 len_sam_name;
1829         uint32 i;
1830
1831         SAM_ACCOUNT *pwd = NULL;
1832         ZERO_STRUCTP(sam);
1833
1834         DEBUG(5, ("init_sam_dispinfo_4: num_entries: %d\n", num_entries));
1835
1836         if (num_entries==0)
1837                 return NT_STATUS_OK;
1838
1839         if (!(sam->sam=(SAM_ENTRY4 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY4))))
1840                 return NT_STATUS_NO_MEMORY;
1841
1842         if (!(sam->str=(SAM_STR4 *)talloc(ctx, num_entries*sizeof(SAM_STR4))))
1843                 return NT_STATUS_NO_MEMORY;
1844
1845         ZERO_STRUCTP(sam->sam);
1846         ZERO_STRUCTP(sam->str);
1847
1848         for (i = 0; i < num_entries; i++) {
1849                 DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
1850                 pwd=&disp_user_info[i+start_idx];
1851
1852                 len_sam_name = strlen(pdb_get_username(pwd));
1853           
1854                 init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name);
1855
1856                 init_string2(&sam->str[i].acct_name, pdb_get_username(pwd), len_sam_name+1, len_sam_name);
1857         }
1858         
1859         return NT_STATUS_OK;
1860 }
1861
1862 /*******************************************************************
1863 reads or writes a structure.
1864 ********************************************************************/
1865
1866 static BOOL sam_io_sam_dispinfo_4(const char *desc, SAM_DISPINFO_4 * sam,
1867                                   uint32 num_entries,
1868                                   prs_struct *ps, int depth)
1869 {
1870         uint32 i;
1871
1872         if (sam == NULL)
1873                 return False;
1874
1875         prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_4");
1876         depth++;
1877
1878         if(!prs_align(ps))
1879                 return False;
1880
1881         if (UNMARSHALLING(ps) && num_entries > 0) {
1882
1883                 if ((sam->sam = (SAM_ENTRY4 *)
1884                      prs_alloc_mem(ps, sizeof(SAM_ENTRY4) *
1885                                    num_entries)) == NULL) {
1886                         DEBUG(0, ("out of memory allocating SAM_ENTRY4\n"));
1887                         return False;
1888                 }
1889
1890                 if ((sam->str = (SAM_STR4 *)
1891                      prs_alloc_mem(ps, sizeof(SAM_STR4) * 
1892                                    num_entries)) == NULL) {
1893                         DEBUG(0, ("out of memory allocating SAM_STR4\n"));
1894                         return False;
1895                 }
1896         }
1897
1898         for (i = 0; i < num_entries; i++) {
1899                 if(!sam_io_sam_entry4("", &sam->sam[i], ps, depth))
1900                         return False;
1901         }
1902
1903         for (i = 0; i < num_entries; i++) {
1904                 if(!smb_io_string2("acct_name", &sam->str[i].acct_name,
1905                              sam->sam[i].hdr_acct_name.buffer, ps, depth))
1906                         return False;
1907         }
1908
1909         return True;
1910 }
1911
1912 /*******************************************************************
1913 inits a SAM_DISPINFO_5 structure.
1914 ********************************************************************/
1915
1916 NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
1917                          uint32 start_idx, DOMAIN_GRP *disp_group_info)
1918 {
1919         uint32 len_sam_name;
1920         uint32 i;
1921
1922         ZERO_STRUCTP(sam);
1923
1924         DEBUG(5, ("init_sam_dispinfo_5: num_entries: %d\n", num_entries));
1925
1926         if (num_entries==0)
1927                 return NT_STATUS_OK;
1928
1929         if (!(sam->sam=(SAM_ENTRY5 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY5))))
1930                 return NT_STATUS_NO_MEMORY;
1931
1932         if (!(sam->str=(SAM_STR5 *)talloc(ctx, num_entries*sizeof(SAM_STR5))))
1933                 return NT_STATUS_NO_MEMORY;
1934
1935         ZERO_STRUCTP(sam->sam);
1936         ZERO_STRUCTP(sam->str);
1937
1938         for (i = 0; i < num_entries; i++) {
1939                 DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
1940
1941                 DEBUG(11, ("init_sam_dispinfo_5: entry: %d\n",i));
1942
1943                 len_sam_name = strlen(grp->name);
1944           
1945                 init_sam_entry5(&sam->sam[i], start_idx + i + 1, len_sam_name);
1946                 init_string2(&sam->str[i].grp_name, grp->name, len_sam_name+1, len_sam_name);
1947         }
1948
1949         return NT_STATUS_OK;
1950 }
1951
1952 /*******************************************************************
1953 reads or writes a structure.
1954 ********************************************************************/
1955
1956 static BOOL sam_io_sam_dispinfo_5(const char *desc, SAM_DISPINFO_5 * sam,
1957                                   uint32 num_entries,
1958                                   prs_struct *ps, int depth)
1959 {
1960         uint32 i;
1961
1962         if (sam == NULL)
1963                 return False;
1964
1965         prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_5");
1966         depth++;
1967
1968         if(!prs_align(ps))
1969                 return False;
1970
1971         if (UNMARSHALLING(ps) && num_entries > 0) {
1972
1973                 if ((sam->sam = (SAM_ENTRY5 *)
1974                      prs_alloc_mem(ps, sizeof(SAM_ENTRY5) *
1975                                    num_entries)) == NULL) {
1976                         DEBUG(0, ("out of memory allocating SAM_ENTRY5\n"));
1977                         return False;
1978                 }
1979
1980                 if ((sam->str = (SAM_STR5 *)
1981                      prs_alloc_mem(ps, sizeof(SAM_STR5) * 
1982                                    num_entries)) == NULL) {
1983                         DEBUG(0, ("out of memory allocating SAM_STR5\n"));
1984                         return False;
1985                 }
1986         }
1987
1988         for (i = 0; i < num_entries; i++) {
1989                 if(!sam_io_sam_entry5("", &sam->sam[i], ps, depth))
1990                         return False;
1991         }
1992
1993         for (i = 0; i < num_entries; i++) {
1994                 if(!smb_io_string2("grp_name", &sam->str[i].grp_name,
1995                              sam->sam[i].hdr_grp_name.buffer, ps, depth))
1996                         return False;
1997         }
1998
1999         return True;
2000 }
2001
2002 /*******************************************************************
2003 inits a SAMR_R_QUERY_DISPINFO structure.
2004 ********************************************************************/
2005
2006 void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
2007                                 uint32 num_entries, uint32 total_size, uint32 data_size,
2008                                 uint16 switch_level, SAM_DISPINFO_CTR * ctr,
2009                                 NTSTATUS status)
2010 {
2011         DEBUG(5, ("init_samr_r_query_dispinfo: level %d\n", switch_level));
2012
2013         r_u->total_size = total_size;
2014
2015         r_u->data_size = data_size;
2016
2017         r_u->switch_level = switch_level;
2018         r_u->num_entries = num_entries;
2019
2020         if (num_entries==0)
2021                 r_u->ptr_entries = 0;
2022         else
2023                 r_u->ptr_entries = 1;
2024
2025         r_u->num_entries2 = num_entries;
2026         r_u->ctr = ctr;
2027
2028         r_u->status = status;
2029 }
2030
2031 /*******************************************************************
2032 reads or writes a structure.
2033 ********************************************************************/
2034
2035 BOOL samr_io_r_query_dispinfo(const char *desc, SAMR_R_QUERY_DISPINFO * r_u,
2036                               prs_struct *ps, int depth)
2037 {
2038         if (r_u == NULL)
2039                 return False;
2040
2041         prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
2042         depth++;
2043
2044         if(!prs_align(ps))
2045                 return False;
2046
2047         if(!prs_uint32("total_size  ", ps, depth, &r_u->total_size))
2048                 return False;
2049         if(!prs_uint32("data_size   ", ps, depth, &r_u->data_size))
2050                 return False;
2051         if(!prs_uint16("switch_level", ps, depth, &r_u->switch_level))
2052                 return False;
2053         if(!prs_align(ps))
2054                 return False;
2055
2056         if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
2057                 return False;
2058         if(!prs_uint32("ptr_entries ", ps, depth, &r_u->ptr_entries))
2059                 return False;
2060
2061         if (r_u->ptr_entries==0) {
2062                 if(!prs_align(ps))
2063                         return False;
2064                 if(!prs_ntstatus("status", ps, depth, &r_u->status))
2065                         return False;
2066
2067                 return True;
2068         }
2069
2070         if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
2071                 return False;
2072
2073         switch (r_u->switch_level) {
2074         case 0x1:
2075                 if(!sam_io_sam_dispinfo_1("users", r_u->ctr->sam.info1,
2076                                 r_u->num_entries, ps, depth))
2077                         return False;
2078                 break;
2079         case 0x2:
2080                 if(!sam_io_sam_dispinfo_2("servers", r_u->ctr->sam.info2,
2081                                 r_u->num_entries, ps, depth))
2082                         return False;
2083                 break;
2084         case 0x3:
2085                 if(!sam_io_sam_dispinfo_3("groups", r_u->ctr->sam.info3,
2086                                     r_u->num_entries, ps, depth))
2087                         return False;
2088                 break;
2089         case 0x4:
2090                 if(!sam_io_sam_dispinfo_4("user list",
2091                                     r_u->ctr->sam.info4,
2092                                     r_u->num_entries, ps, depth))
2093                         return False;
2094                 break;
2095         case 0x5:
2096                 if(!sam_io_sam_dispinfo_5("group list",
2097                                     r_u->ctr->sam.info5,
2098                                     r_u->num_entries, ps, depth))
2099                         return False;
2100                 break;
2101         default:
2102                 DEBUG(0,("samr_io_r_query_dispinfo: unknown switch value\n"));
2103                 break;
2104         }
2105         
2106         if(!prs_align(ps))
2107                 return False;
2108         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2109                 return False;
2110
2111         return True;
2112 }
2113
2114 /*******************************************************************
2115 inits a SAMR_Q_OPEN_GROUP structure.
2116 ********************************************************************/
2117
2118 void init_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
2119                             POLICY_HND *hnd,
2120                             uint32 access_mask, uint32 rid)
2121 {
2122         DEBUG(5, ("init_samr_q_open_group\n"));
2123
2124         q_c->domain_pol = *hnd;
2125         q_c->access_mask = access_mask;
2126         q_c->rid_group = rid;
2127 }
2128
2129 /*******************************************************************
2130 reads or writes a structure.
2131 ********************************************************************/
2132
2133 BOOL samr_io_q_open_group(const char *desc, SAMR_Q_OPEN_GROUP * q_u,
2134                           prs_struct *ps, int depth)
2135 {
2136         if (q_u == NULL)
2137                 return False;
2138
2139         prs_debug(ps, depth, desc, "samr_io_q_open_group");
2140         depth++;
2141
2142         if(!prs_align(ps))
2143                 return False;
2144
2145         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
2146                 return False;
2147
2148         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
2149                 return False;
2150         if(!prs_uint32("rid_group", ps, depth, &q_u->rid_group))
2151                 return False;
2152
2153         return True;
2154 }
2155
2156 /*******************************************************************
2157 reads or writes a structure.
2158 ********************************************************************/
2159
2160 BOOL samr_io_r_open_group(const char *desc, SAMR_R_OPEN_GROUP * r_u,
2161                           prs_struct *ps, int depth)
2162 {
2163         if (r_u == NULL)
2164                 return False;
2165
2166         prs_debug(ps, depth, desc, "samr_io_r_open_group");
2167         depth++;
2168
2169         if(!prs_align(ps))
2170                 return False;
2171
2172         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
2173                 return False;
2174
2175         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2176                 return False;
2177
2178         return True;
2179 }
2180
2181 /*******************************************************************
2182 inits a GROUP_INFO1 structure.
2183 ********************************************************************/
2184
2185 void init_samr_group_info1(GROUP_INFO1 * gr1,
2186                            char *acct_name, char *acct_desc,
2187                            uint32 num_members)
2188 {
2189         DEBUG(5, ("init_samr_group_info1\n"));
2190
2191         gr1->unknown_1 = 0x3;
2192         gr1->num_members = num_members;
2193
2194         init_unistr2(&gr1->uni_acct_name, acct_name, UNI_FLAGS_NONE);
2195         init_uni_hdr(&gr1->hdr_acct_name, &gr1->uni_acct_name);
2196         init_unistr2(&gr1->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
2197         init_uni_hdr(&gr1->hdr_acct_desc, &gr1->uni_acct_desc);
2198 }
2199
2200 /*******************************************************************
2201 reads or writes a structure.
2202 ********************************************************************/
2203
2204 BOOL samr_io_group_info1(const char *desc, GROUP_INFO1 * gr1,
2205                          prs_struct *ps, int depth)
2206 {
2207         if (gr1 == NULL)
2208                 return False;
2209
2210         prs_debug(ps, depth, desc, "samr_io_group_info1");
2211         depth++;
2212
2213         if(!prs_align(ps))
2214                 return False;
2215
2216         if(!smb_io_unihdr("hdr_acct_name", &gr1->hdr_acct_name, ps, depth))
2217                 return False;
2218
2219         if(!prs_uint32("unknown_1", ps, depth, &gr1->unknown_1))
2220                 return False;
2221         if(!prs_uint32("num_members", ps, depth, &gr1->num_members))
2222                 return False;
2223
2224         if(!smb_io_unihdr("hdr_acct_desc", &gr1->hdr_acct_desc, ps, depth))
2225                 return False;
2226
2227         if(!smb_io_unistr2("uni_acct_name", &gr1->uni_acct_name,
2228                            gr1->hdr_acct_name.buffer, ps, depth))
2229                 return False;
2230
2231         if(!smb_io_unistr2("uni_acct_desc", &gr1->uni_acct_desc,
2232                            gr1->hdr_acct_desc.buffer, ps, depth))
2233                 return False;
2234
2235         return True;
2236 }
2237
2238 /*******************************************************************
2239 inits a GROUP_INFO3 structure.
2240 ********************************************************************/
2241
2242 void init_samr_group_info3(GROUP_INFO3 *gr3)
2243 {
2244         DEBUG(5, ("init_samr_group_info3\n"));
2245
2246         gr3->unknown_1 = 0x3;
2247 }
2248
2249 /*******************************************************************
2250 reads or writes a structure.
2251 ********************************************************************/
2252
2253 BOOL samr_io_group_info3(const char *desc, GROUP_INFO3 *gr3, prs_struct *ps, int depth)
2254 {
2255         if (gr3 == NULL)
2256                 return False;
2257
2258         prs_debug(ps, depth, desc, "samr_io_group_info3");
2259         depth++;
2260
2261         if(!prs_align(ps))
2262                 return False;
2263
2264         if(!prs_uint32("unknown_1", ps, depth, &gr3->unknown_1))
2265                 return False;
2266
2267         return True;
2268 }
2269
2270 /*******************************************************************
2271 inits a GROUP_INFO4 structure.
2272 ********************************************************************/
2273
2274 void init_samr_group_info4(GROUP_INFO4 * gr4, char *acct_desc)
2275 {
2276         DEBUG(5, ("init_samr_group_info4\n"));
2277
2278         init_unistr2(&gr4->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
2279         init_uni_hdr(&gr4->hdr_acct_desc, &gr4->uni_acct_desc);
2280 }
2281
2282 /*******************************************************************
2283 reads or writes a structure.
2284 ********************************************************************/
2285
2286 BOOL samr_io_group_info4(const char *desc, GROUP_INFO4 * gr4,
2287                          prs_struct *ps, int depth)
2288 {
2289         if (gr4 == NULL)
2290                 return False;
2291
2292         prs_debug(ps, depth, desc, "samr_io_group_info4");
2293         depth++;
2294
2295         if(!prs_align(ps))
2296                 return False;
2297
2298         if(!smb_io_unihdr("hdr_acct_desc", &gr4->hdr_acct_desc, ps, depth))
2299                 return False;
2300         if(!smb_io_unistr2("uni_acct_desc", &gr4->uni_acct_desc,
2301                            gr4->hdr_acct_desc.buffer, ps, depth))
2302                 return False;
2303
2304         return True;
2305 }
2306
2307 /*******************************************************************
2308 reads or writes a structure.
2309 ********************************************************************/
2310
2311 static BOOL samr_group_info_ctr(const char *desc, GROUP_INFO_CTR **ctr,
2312                                 prs_struct *ps, int depth)
2313 {
2314         if (UNMARSHALLING(ps))
2315                 *ctr = (GROUP_INFO_CTR *)prs_alloc_mem(ps,sizeof(GROUP_INFO_CTR));
2316
2317         if (*ctr == NULL)
2318                 return False;
2319
2320         prs_debug(ps, depth, desc, "samr_group_info_ctr");
2321         depth++;
2322
2323         if(!prs_uint16("switch_value1", ps, depth, &(*ctr)->switch_value1))
2324                 return False;
2325
2326         switch ((*ctr)->switch_value1) {
2327         case 1:
2328                 if(!samr_io_group_info1("group_info1", &(*ctr)->group.info1, ps, depth))
2329                         return False;
2330                 break;
2331         case 3:
2332                 if(!samr_io_group_info3("group_info3", &(*ctr)->group.info3, ps, depth))
2333                         return False;
2334                 break;
2335         case 4:
2336                 if(!samr_io_group_info4("group_info4", &(*ctr)->group.info4, ps, depth))
2337                         return False;
2338                 break;
2339         default:
2340                 DEBUG(0,("samr_group_info_ctr: unsupported switch level\n"));
2341                 break;
2342         }
2343
2344         return True;
2345 }
2346
2347 /*******************************************************************
2348 inits a SAMR_Q_CREATE_DOM_GROUP structure.
2349 ********************************************************************/
2350
2351 void init_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
2352                                   POLICY_HND *pol, char *acct_desc,
2353                                   uint32 access_mask)
2354 {
2355         DEBUG(5, ("init_samr_q_create_dom_group\n"));
2356
2357         q_e->pol = *pol;
2358
2359         init_unistr2(&q_e->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
2360         init_uni_hdr(&q_e->hdr_acct_desc, &q_e->uni_acct_desc);
2361
2362         q_e->access_mask = access_mask;
2363 }
2364
2365 /*******************************************************************
2366 reads or writes a structure.
2367 ********************************************************************/
2368
2369 BOOL samr_io_q_create_dom_group(const char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
2370                                 prs_struct *ps, int depth)
2371 {
2372         if (q_e == NULL)
2373                 return False;
2374
2375         prs_debug(ps, depth, desc, "samr_io_q_create_dom_group");
2376         depth++;
2377
2378         if(!prs_align(ps))
2379                 return False;
2380
2381         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
2382                 return False;
2383
2384         if(!smb_io_unihdr("hdr_acct_desc", &q_e->hdr_acct_desc, ps, depth))
2385                 return False;
2386         if(!smb_io_unistr2("uni_acct_desc", &q_e->uni_acct_desc,
2387                        q_e->hdr_acct_desc.buffer, ps, depth))
2388                 return False;
2389
2390         if(!prs_align(ps))
2391                 return False;
2392         if(!prs_uint32("access", ps, depth, &q_e->access_mask))
2393                 return False;
2394
2395         return True;
2396 }
2397
2398 /*******************************************************************
2399 reads or writes a structure.
2400 ********************************************************************/
2401
2402 BOOL samr_io_r_create_dom_group(const char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
2403                                 prs_struct *ps, int depth)
2404 {
2405         if (r_u == NULL)
2406                 return False;
2407
2408         prs_debug(ps, depth, desc, "samr_io_r_create_dom_group");
2409         depth++;
2410
2411         if(!prs_align(ps))
2412                 return False;
2413
2414         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
2415                 return False;
2416
2417         if(!prs_uint32("rid   ", ps, depth, &r_u->rid))
2418                 return False;
2419         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2420                 return False;
2421
2422         return True;
2423 }
2424
2425 /*******************************************************************
2426 inits a SAMR_Q_DELETE_DOM_GROUP structure.
2427 ********************************************************************/
2428
2429 void init_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
2430                                   POLICY_HND *hnd)
2431 {
2432         DEBUG(5, ("init_samr_q_delete_dom_group\n"));
2433
2434         q_c->group_pol = *hnd;
2435 }
2436
2437 /*******************************************************************
2438 reads or writes a structure.
2439 ********************************************************************/
2440
2441 BOOL samr_io_q_delete_dom_group(const char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
2442                                 prs_struct *ps, int depth)
2443 {
2444         if (q_u == NULL)
2445                 return False;
2446
2447         prs_debug(ps, depth, desc, "samr_io_q_delete_dom_group");
2448         depth++;
2449
2450         if(!prs_align(ps))
2451                 return False;
2452
2453         if(!smb_io_pol_hnd("group_pol", &q_u->group_pol, ps, depth))
2454                 return False;
2455
2456         return True;
2457 }
2458
2459 /*******************************************************************
2460 reads or writes a structure.
2461 ********************************************************************/
2462
2463 BOOL samr_io_r_delete_dom_group(const char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
2464                                 prs_struct *ps, int depth)
2465 {
2466         if (r_u == NULL)
2467                 return False;
2468
2469         prs_debug(ps, depth, desc, "samr_io_r_delete_dom_group");
2470         depth++;
2471
2472         if(!prs_align(ps))
2473                 return False;
2474
2475         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
2476                 return False;
2477
2478         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2479                 return False;
2480
2481         return True;
2482 }
2483
2484 /*******************************************************************
2485 inits a SAMR_Q_DEL_GROUPMEM structure.
2486 ********************************************************************/
2487
2488 void init_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
2489                               POLICY_HND *pol, uint32 rid)
2490 {
2491         DEBUG(5, ("init_samr_q_del_groupmem\n"));
2492
2493         q_e->pol = *pol;
2494         q_e->rid = rid;
2495 }
2496
2497 /*******************************************************************
2498 reads or writes a structure.
2499 ********************************************************************/
2500
2501 BOOL samr_io_q_del_groupmem(const char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
2502                             prs_struct *ps, int depth)
2503 {
2504         if (q_e == NULL)
2505                 return False;
2506
2507         prs_debug(ps, depth, desc, "samr_io_q_del_groupmem");
2508         depth++;
2509
2510         if(!prs_align(ps))
2511                 return False;
2512
2513         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
2514                 return False;
2515
2516         if(!prs_uint32("rid", ps, depth, &q_e->rid))
2517                 return False;
2518
2519         return True;
2520 }
2521
2522 /*******************************************************************
2523 inits a SAMR_R_DEL_GROUPMEM structure.
2524 ********************************************************************/
2525
2526 void init_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
2527                               NTSTATUS status)
2528 {
2529         DEBUG(5, ("init_samr_r_del_groupmem\n"));
2530
2531         r_u->status = status;
2532 }
2533
2534 /*******************************************************************
2535 reads or writes a structure.
2536 ********************************************************************/
2537
2538 BOOL samr_io_r_del_groupmem(const char *desc, SAMR_R_DEL_GROUPMEM * r_u,
2539                             prs_struct *ps, int depth)
2540 {
2541         if (r_u == NULL)
2542                 return False;
2543
2544         prs_debug(ps, depth, desc, "samr_io_r_del_groupmem");
2545         depth++;
2546
2547         if(!prs_align(ps))
2548                 return False;
2549
2550         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2551                 return False;
2552
2553         return True;
2554 }
2555
2556 /*******************************************************************
2557 inits a SAMR_Q_ADD_GROUPMEM structure.
2558 ********************************************************************/
2559
2560 void init_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
2561                               POLICY_HND *pol, uint32 rid)
2562 {
2563         DEBUG(5, ("init_samr_q_add_groupmem\n"));
2564
2565         q_e->pol = *pol;
2566         q_e->rid = rid;
2567         q_e->unknown = 0x0005;
2568 }
2569
2570 /*******************************************************************
2571 reads or writes a structure.
2572 ********************************************************************/
2573
2574 BOOL samr_io_q_add_groupmem(const char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
2575                             prs_struct *ps, int depth)
2576 {
2577         if (q_e == NULL)
2578                 return False;
2579
2580         prs_debug(ps, depth, desc, "samr_io_q_add_groupmem");
2581         depth++;
2582
2583         if(!prs_align(ps))
2584                 return False;
2585
2586         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
2587                 return False;
2588
2589         if(!prs_uint32("rid    ", ps, depth, &q_e->rid))
2590                 return False;
2591         if(!prs_uint32("unknown", ps, depth, &q_e->unknown))
2592                 return False;
2593
2594         return True;
2595 }
2596
2597 /*******************************************************************
2598 inits a SAMR_R_ADD_GROUPMEM structure.
2599 ********************************************************************/
2600
2601 void init_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
2602                               NTSTATUS status)
2603 {
2604         DEBUG(5, ("init_samr_r_add_groupmem\n"));
2605
2606         r_u->status = status;
2607 }
2608
2609 /*******************************************************************
2610 reads or writes a structure.
2611 ********************************************************************/
2612
2613 BOOL samr_io_r_add_groupmem(const char *desc, SAMR_R_ADD_GROUPMEM * r_u,
2614                             prs_struct *ps, int depth)
2615 {
2616         if (r_u == NULL)
2617                 return False;
2618
2619         prs_debug(ps, depth, desc, "samr_io_r_add_groupmem");
2620         depth++;
2621
2622         if(!prs_align(ps))
2623                 return False;
2624
2625         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2626                 return False;
2627
2628         return True;
2629 }
2630
2631 /*******************************************************************
2632 inits a SAMR_Q_SET_GROUPINFO structure.
2633 ********************************************************************/
2634
2635 void init_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
2636                                POLICY_HND *pol, GROUP_INFO_CTR * ctr)
2637 {
2638         DEBUG(5, ("init_samr_q_set_groupinfo\n"));
2639
2640         q_e->pol = *pol;
2641         q_e->ctr = ctr;
2642 }
2643
2644 /*******************************************************************
2645 reads or writes a structure.
2646 ********************************************************************/
2647
2648 BOOL samr_io_q_set_groupinfo(const char *desc, SAMR_Q_SET_GROUPINFO * q_e,
2649                              prs_struct *ps, int depth)
2650 {
2651         if (q_e == NULL)
2652                 return False;
2653
2654         prs_debug(ps, depth, desc, "samr_io_q_set_groupinfo");
2655         depth++;
2656
2657         if(!prs_align(ps))
2658                 return False;
2659
2660         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
2661                 return False;
2662         
2663         if(!samr_group_info_ctr("ctr", &q_e->ctr, ps, depth))
2664                 return False;
2665
2666         return True;
2667 }
2668
2669 /*******************************************************************
2670 inits a SAMR_R_SET_GROUPINFO structure.
2671 ********************************************************************/
2672
2673 void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, NTSTATUS status)
2674 {
2675         DEBUG(5, ("init_samr_r_set_groupinfo\n"));
2676
2677         r_u->status = status;
2678 }
2679
2680 /*******************************************************************
2681 reads or writes a structure.
2682 ********************************************************************/
2683
2684 BOOL samr_io_r_set_groupinfo(const char *desc, SAMR_R_SET_GROUPINFO * r_u,
2685                              prs_struct *ps, int depth)
2686 {
2687         if (r_u == NULL)
2688                 return False;
2689
2690         prs_debug(ps, depth, desc, "samr_io_r_set_groupinfo");
2691         depth++;
2692
2693         if(!prs_align(ps))
2694                 return False;
2695
2696         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2697                 return False;
2698
2699         return True;
2700 }
2701
2702 /*******************************************************************
2703 inits a SAMR_Q_QUERY_GROUPINFO structure.
2704 ********************************************************************/
2705
2706 void init_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
2707                                  POLICY_HND *pol, uint16 switch_level)
2708 {
2709         DEBUG(5, ("init_samr_q_query_groupinfo\n"));
2710
2711         q_e->pol = *pol;
2712
2713         q_e->switch_level = switch_level;
2714 }
2715
2716 /*******************************************************************
2717 reads or writes a structure.
2718 ********************************************************************/
2719
2720 BOOL samr_io_q_query_groupinfo(const char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
2721                                prs_struct *ps, int depth)
2722 {
2723         if (q_e == NULL)
2724                 return False;
2725
2726         prs_debug(ps, depth, desc, "samr_io_q_query_groupinfo");
2727         depth++;
2728
2729         if(!prs_align(ps))
2730                 return False;
2731
2732         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
2733                 return False;
2734
2735         if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
2736                 return False;
2737
2738         return True;
2739 }
2740
2741 /*******************************************************************
2742 inits a SAMR_R_QUERY_GROUPINFO structure.
2743 ********************************************************************/
2744
2745 void init_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
2746                                  GROUP_INFO_CTR * ctr, NTSTATUS status)
2747 {
2748         DEBUG(5, ("init_samr_r_query_groupinfo\n"));
2749
2750         r_u->ptr = (NT_STATUS_IS_OK(status) && ctr != NULL) ? 1 : 0;
2751         r_u->ctr = ctr;
2752         r_u->status = status;
2753 }
2754
2755 /*******************************************************************
2756 reads or writes a structure.
2757 ********************************************************************/
2758
2759 BOOL samr_io_r_query_groupinfo(const char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
2760                                prs_struct *ps, int depth)
2761 {
2762         if (r_u == NULL)
2763                 return False;
2764
2765         prs_debug(ps, depth, desc, "samr_io_r_query_groupinfo");
2766         depth++;
2767
2768         if(!prs_align(ps))
2769                 return False;
2770
2771         if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
2772                 return False;
2773
2774         if (r_u->ptr != 0) {
2775                 if(!samr_group_info_ctr("ctr", &r_u->ctr, ps, depth))
2776                         return False;
2777         }
2778
2779         if(!prs_align(ps))
2780                 return False;
2781         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2782                 return False;
2783
2784         return True;
2785 }
2786
2787 /*******************************************************************
2788 inits a SAMR_Q_QUERY_GROUPMEM structure.
2789 ********************************************************************/
2790
2791 void init_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd)
2792 {
2793         DEBUG(5, ("init_samr_q_query_groupmem\n"));
2794
2795         q_c->group_pol = *hnd;
2796 }
2797
2798 /*******************************************************************
2799 reads or writes a structure.
2800 ********************************************************************/
2801
2802 BOOL samr_io_q_query_groupmem(const char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
2803                               prs_struct *ps, int depth)
2804 {
2805         if (q_u == NULL)
2806                 return False;
2807
2808         prs_debug(ps, depth, desc, "samr_io_q_query_groupmem");
2809         depth++;
2810
2811         if(!prs_align(ps))
2812                 return False;
2813
2814         if(!smb_io_pol_hnd("group_pol", &q_u->group_pol, ps, depth))
2815                 return False;
2816
2817         return True;
2818 }
2819
2820 /*******************************************************************
2821 inits a SAMR_R_QUERY_GROUPMEM structure.
2822 ********************************************************************/
2823
2824 void init_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
2825                                 uint32 num_entries, uint32 *rid,
2826                                 uint32 *attr, NTSTATUS status)
2827 {
2828         DEBUG(5, ("init_samr_r_query_groupmem\n"));
2829
2830         if (NT_STATUS_IS_OK(status)) {
2831                 r_u->ptr = 1;
2832                 r_u->num_entries = num_entries;
2833
2834                 r_u->ptr_attrs = attr != NULL ? 1 : 0;
2835                 r_u->ptr_rids = rid != NULL ? 1 : 0;
2836
2837                 r_u->num_rids = num_entries;
2838                 r_u->rid = rid;
2839
2840                 r_u->num_attrs = num_entries;
2841                 r_u->attr = attr;
2842         } else {
2843                 r_u->ptr = 0;
2844                 r_u->num_entries = 0;
2845         }
2846
2847         r_u->status = status;
2848 }
2849
2850 /*******************************************************************
2851 reads or writes a structure.
2852 ********************************************************************/
2853
2854 BOOL samr_io_r_query_groupmem(const char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
2855                               prs_struct *ps, int depth)
2856 {
2857         uint32 i;
2858
2859         if (r_u == NULL)
2860                 return False;
2861
2862         if (UNMARSHALLING(ps))
2863                 ZERO_STRUCTP(r_u);
2864
2865         prs_debug(ps, depth, desc, "samr_io_r_query_groupmem");
2866         depth++;
2867
2868         if(!prs_align(ps))
2869                 return False;
2870
2871         if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
2872                 return False;
2873         if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
2874                 return False;
2875
2876         if (r_u->ptr != 0) {
2877                 if(!prs_uint32("ptr_rids ", ps, depth, &r_u->ptr_rids))
2878                         return False;
2879                 if(!prs_uint32("ptr_attrs", ps, depth, &r_u->ptr_attrs))
2880                         return False;
2881
2882                 if (r_u->ptr_rids != 0) {
2883                         if(!prs_uint32("num_rids", ps, depth, &r_u->num_rids))
2884                                 return False;
2885                         if (UNMARSHALLING(ps) && r_u->num_rids != 0) {
2886                                 r_u->rid = (uint32 *)prs_alloc_mem(ps,sizeof(r_u->rid[0])*r_u->num_rids);
2887                                 if (r_u->rid == NULL)
2888                                         return False;
2889                         }
2890
2891                         for (i = 0; i < r_u->num_rids; i++) {
2892                                 if(!prs_uint32("", ps, depth, &r_u->rid[i]))
2893                                         return False;
2894                         }
2895                 }
2896
2897                 if (r_u->ptr_attrs != 0) {
2898                         if(!prs_uint32("num_attrs", ps, depth, &r_u->num_attrs))
2899                                 return False;
2900
2901                         if (UNMARSHALLING(ps) && r_u->num_attrs != 0) {
2902                                 r_u->attr = (uint32 *)prs_alloc_mem(ps,sizeof(r_u->attr[0])*r_u->num_attrs);
2903                                 if (r_u->attr == NULL)
2904                                         return False;
2905                         }
2906
2907                         for (i = 0; i < r_u->num_attrs; i++) {
2908                                 if(!prs_uint32("", ps, depth, &r_u->attr[i]))
2909                                         return False;
2910                         }
2911                 }
2912         }
2913
2914         if(!prs_ntstatus("status", ps, depth, &r_u->status))
2915                 return False;
2916
2917         return True;
2918 }
2919
2920 /*******************************************************************
2921 inits a SAMR_Q_QUERY_USERGROUPS structure.
2922 ********************************************************************/
2923
2924 void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
2925                                   POLICY_HND *hnd)
2926 {
2927         DEBUG(5, ("init_samr_q_query_usergroups\n"));
2928
2929         q_u->pol = *hnd;
2930 }
2931
2932 /*******************************************************************
2933 reads or writes a structure.
2934 ********************************************************************/
2935
2936 BOOL samr_io_q_query_usergroups(const char *desc, SAMR_Q_QUERY_USERGROUPS * q_u,
2937                                 prs_struct *ps, int depth)
2938 {
2939         if (q_u == NULL)
2940                 return False;
2941
2942         prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
2943         depth++;
2944
2945         if(!prs_align(ps))
2946                 return False;
2947
2948         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
2949                 return False;
2950
2951         return True;
2952 }
2953
2954 /*******************************************************************
2955 inits a SAMR_R_QUERY_USERGROUPS structure.
2956 ********************************************************************/
2957
2958 void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
2959                                   uint32 num_gids, DOM_GID * gid,
2960                                   NTSTATUS status)
2961 {
2962         DEBUG(5, ("init_samr_r_query_usergroups\n"));
2963
2964         if (NT_STATUS_IS_OK(status)) {
2965                 r_u->ptr_0 = 1;
2966                 r_u->num_entries = num_gids;
2967                 r_u->ptr_1 = (num_gids != 0) ? 1 : 0;
2968                 r_u->num_entries2 = num_gids;
2969
2970                 r_u->gid = gid;
2971         } else {
2972                 r_u->ptr_0 = 0;
2973                 r_u->num_entries = 0;
2974                 r_u->ptr_1 = 0;
2975                 r_u->gid = NULL;
2976         }
2977
2978         r_u->status = status;
2979 }
2980
2981 /*******************************************************************
2982 reads or writes a structure.
2983 ********************************************************************/
2984
2985 BOOL samr_io_gids(const char *desc, uint32 *num_gids, DOM_GID ** gid,
2986                   prs_struct *ps, int depth)
2987 {
2988         uint32 i;
2989         if (gid == NULL)
2990                 return False;
2991
2992         prs_debug(ps, depth, desc, "samr_io_gids");
2993         depth++;
2994
2995         if(!prs_align(ps))
2996                 return False;
2997
2998         if(!prs_uint32("num_gids", ps, depth, num_gids))
2999                 return False;
3000
3001         if ((*num_gids) != 0) {
3002                 if (UNMARSHALLING(ps)) {
3003                         (*gid) = (DOM_GID *)prs_alloc_mem(ps,sizeof(DOM_GID)*(*num_gids));
3004                 }
3005
3006                 if ((*gid) == NULL) {
3007                         return False;
3008                 }
3009
3010                 for (i = 0; i < (*num_gids); i++) {
3011                         if(!smb_io_gid("gids", &(*gid)[i], ps, depth))
3012                                 return False;
3013                 }
3014         }
3015
3016         return True;
3017 }
3018
3019 /*******************************************************************
3020 reads or writes a structure.
3021 ********************************************************************/
3022
3023 BOOL samr_io_r_query_usergroups(const char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
3024                                 prs_struct *ps, int depth)
3025 {
3026         if (r_u == NULL)
3027                 return False;
3028
3029         prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
3030         depth++;
3031
3032         if(!prs_align(ps))
3033                 return False;
3034
3035         if(!prs_uint32("ptr_0       ", ps, depth, &r_u->ptr_0))
3036                 return False;
3037
3038         if (r_u->ptr_0 != 0) {
3039                 if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
3040                         return False;
3041                 if(!prs_uint32("ptr_1       ", ps, depth, &r_u->ptr_1))
3042                         return False;
3043
3044                 if (r_u->num_entries != 0 && r_u->ptr_1 != 0) {
3045                         if(!samr_io_gids("gids", &r_u->num_entries2, &r_u->gid, ps, depth))
3046                                 return False;
3047                 }
3048         }
3049
3050         if(!prs_align(ps))
3051                 return False;
3052         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3053           return False;
3054
3055         return True;
3056 }
3057
3058 /*******************************************************************
3059 inits a SAMR_Q_ENUM_DOMAINS structure.
3060 ********************************************************************/
3061
3062 void init_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
3063                               POLICY_HND *pol,
3064                               uint32 start_idx, uint32 size)
3065 {
3066         DEBUG(5, ("init_samr_q_enum_domains\n"));
3067
3068         q_e->pol = *pol;
3069
3070         q_e->start_idx = start_idx;
3071         q_e->max_size = size;
3072 }
3073
3074 /*******************************************************************
3075 reads or writes a structure.
3076 ********************************************************************/
3077
3078 BOOL samr_io_q_enum_domains(const char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
3079                             prs_struct *ps, int depth)
3080 {
3081         if (q_e == NULL)
3082                 return False;
3083
3084         prs_debug(ps, depth, desc, "samr_io_q_enum_domains");
3085         depth++;
3086
3087         if(!prs_align(ps))
3088                 return False;
3089
3090         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
3091                 return False;
3092
3093         if(!prs_uint32("start_idx", ps, depth, &q_e->start_idx))
3094                 return False;
3095         if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
3096                 return False;
3097
3098         return True;
3099 }
3100
3101 /*******************************************************************
3102 inits a SAMR_R_ENUM_DOMAINS structure.
3103 ********************************************************************/
3104
3105 void init_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
3106                               uint32 next_idx, uint32 num_sam_entries)
3107 {
3108         DEBUG(5, ("init_samr_r_enum_domains\n"));
3109
3110         r_u->next_idx = next_idx;
3111
3112         if (num_sam_entries != 0) {
3113                 r_u->ptr_entries1 = 1;
3114                 r_u->ptr_entries2 = 1;
3115                 r_u->num_entries2 = num_sam_entries;
3116                 r_u->num_entries3 = num_sam_entries;
3117
3118                 r_u->num_entries4 = num_sam_entries;
3119         } else {
3120                 r_u->ptr_entries1 = 0;
3121                 r_u->num_entries2 = num_sam_entries;
3122                 r_u->ptr_entries2 = 1;
3123         }
3124 }
3125
3126 /*******************************************************************
3127 reads or writes a structure.
3128 ********************************************************************/
3129
3130 BOOL samr_io_r_enum_domains(const char *desc, SAMR_R_ENUM_DOMAINS * r_u,
3131                             prs_struct *ps, int depth)
3132 {
3133         uint32 i;
3134
3135         if (r_u == NULL)
3136                 return False;
3137
3138         prs_debug(ps, depth, desc, "samr_io_r_enum_domains");
3139         depth++;
3140
3141         if(!prs_align(ps))
3142                 return False;
3143
3144         if(!prs_uint32("next_idx    ", ps, depth, &r_u->next_idx))
3145                 return False;
3146         if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
3147                 return False;
3148
3149         if (r_u->ptr_entries1 != 0) {
3150                 if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
3151                         return False;
3152                 if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
3153                         return False;
3154                 if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
3155                         return False;
3156
3157                 if (UNMARSHALLING(ps)) {
3158                         r_u->sam = (SAM_ENTRY *)prs_alloc_mem(ps,sizeof(SAM_ENTRY)*r_u->num_entries2);
3159                         r_u->uni_dom_name = (UNISTR2 *)prs_alloc_mem(ps,sizeof(UNISTR2)*r_u->num_entries2);
3160                 }
3161
3162                 if ((r_u->sam == NULL || r_u->uni_dom_name == NULL) && r_u->num_entries2 != 0) {
3163                         DEBUG(0, ("NULL pointers in SAMR_R_ENUM_DOMAINS\n"));
3164                         r_u->num_entries4 = 0;
3165                         r_u->status = NT_STATUS_MEMORY_NOT_ALLOCATED;
3166                         return False;
3167                 }
3168
3169                 for (i = 0; i < r_u->num_entries2; i++) {
3170                         fstring tmp;
3171                         slprintf(tmp, sizeof(tmp) - 1, "dom[%d]", i);
3172                         if(!sam_io_sam_entry(tmp, &r_u->sam[i], ps, depth))
3173                                 return False;
3174                 }
3175
3176                 for (i = 0; i < r_u->num_entries2; i++) {
3177                         fstring tmp;
3178                         slprintf(tmp, sizeof(tmp) - 1, "dom[%d]", i);
3179                         if(!smb_io_unistr2(tmp, &r_u->uni_dom_name[i],
3180                                        r_u->sam[i].hdr_name.buffer, ps,
3181                                        depth))
3182                                 return False;
3183                 }
3184
3185         }
3186
3187         if(!prs_align(ps))
3188                 return False;
3189         if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
3190                 return False;
3191         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3192                 return False;
3193
3194         return True;
3195 }
3196
3197 /*******************************************************************
3198 inits a SAMR_Q_ENUM_DOM_GROUPS structure.
3199 ********************************************************************/
3200
3201 void init_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS * q_e,
3202                                  POLICY_HND *pol,
3203                                  uint32 start_idx, uint32 size)
3204 {
3205         DEBUG(5, ("init_samr_q_enum_dom_groups\n"));
3206
3207         q_e->pol = *pol;
3208
3209         q_e->start_idx = start_idx;
3210         q_e->max_size = size;
3211 }
3212
3213 /*******************************************************************
3214 reads or writes a structure.
3215 ********************************************************************/
3216
3217 BOOL samr_io_q_enum_dom_groups(const char *desc, SAMR_Q_ENUM_DOM_GROUPS * q_e,
3218                                prs_struct *ps, int depth)
3219 {
3220         if (q_e == NULL)
3221                 return False;
3222
3223         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
3224         depth++;
3225
3226         if(!prs_align(ps))
3227                 return False;
3228
3229         if(!smb_io_pol_hnd("pol", &(q_e->pol), ps, depth))
3230                 return False;
3231
3232         if(!prs_uint32("start_idx", ps, depth, &q_e->start_idx))
3233                 return False;
3234         if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
3235                 return False;
3236
3237         return True;
3238 }
3239
3240 /*******************************************************************
3241 inits a SAMR_R_ENUM_DOM_GROUPS structure.
3242 ********************************************************************/
3243
3244 void init_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS * r_u,
3245                                  uint32 next_idx, uint32 num_sam_entries)
3246 {
3247         DEBUG(5, ("init_samr_r_enum_dom_groups\n"));
3248
3249         r_u->next_idx = next_idx;
3250
3251         if (num_sam_entries != 0) {
3252                 r_u->ptr_entries1 = 1;
3253                 r_u->ptr_entries2 = 1;
3254                 r_u->num_entries2 = num_sam_entries;
3255                 r_u->num_entries3 = num_sam_entries;
3256
3257                 r_u->num_entries4 = num_sam_entries;
3258         } else {
3259                 r_u->ptr_entries1 = 0;
3260                 r_u->num_entries2 = num_sam_entries;
3261                 r_u->ptr_entries2 = 1;
3262         }
3263 }
3264
3265 /*******************************************************************
3266 reads or writes a structure.
3267 ********************************************************************/
3268
3269 BOOL samr_io_r_enum_dom_groups(const char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
3270                                prs_struct *ps, int depth)
3271 {
3272         uint32 i;
3273
3274         if (r_u == NULL)
3275                 return False;
3276
3277         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
3278         depth++;
3279
3280         if(!prs_align(ps))
3281                 return False;
3282
3283         if(!prs_uint32("next_idx    ", ps, depth, &r_u->next_idx))
3284                 return False;
3285         if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
3286                 return False;
3287
3288         if (r_u->ptr_entries1 != 0) {
3289                 if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
3290                         return False;
3291                 if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
3292                         return False;
3293                 if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
3294                         return False;
3295
3296                 if (UNMARSHALLING(ps)) {
3297                         r_u->sam = (SAM_ENTRY *)prs_alloc_mem(ps,sizeof(SAM_ENTRY)*r_u->num_entries2);
3298                         r_u->uni_grp_name = (UNISTR2 *)prs_alloc_mem(ps,sizeof(UNISTR2)*r_u->num_entries2);
3299                 }
3300
3301                 if ((r_u->sam == NULL || r_u->uni_grp_name == NULL) && r_u->num_entries2 != 0) {
3302                         DEBUG(0,
3303                               ("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
3304                         r_u->num_entries4 = 0;
3305                         r_u->status = NT_STATUS_MEMORY_NOT_ALLOCATED;
3306                         return False;
3307                 }
3308
3309                 for (i = 0; i < r_u->num_entries2; i++) {
3310                         if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
3311                                 return False;
3312                 }
3313
3314                 for (i = 0; i < r_u->num_entries2; i++) {
3315                         if(!smb_io_unistr2("", &r_u->uni_grp_name[i],
3316                                        r_u->sam[i].hdr_name.buffer, ps, depth))
3317                                 return False;
3318                 }
3319         }
3320
3321         if(!prs_align(ps))
3322                 return False;
3323         if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
3324                 return False;
3325         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3326                 return False;
3327
3328         return True;
3329 }
3330
3331 /*******************************************************************
3332 inits a SAMR_Q_ENUM_DOM_ALIASES structure.
3333 ********************************************************************/
3334
3335 void init_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES * q_e,
3336                                   POLICY_HND *pol, uint32 start_idx,
3337                                   uint32 size)
3338 {
3339         DEBUG(5, ("init_samr_q_enum_dom_aliases\n"));
3340
3341         q_e->pol = *pol;
3342
3343         q_e->start_idx = start_idx;
3344         q_e->max_size = size;
3345 }
3346
3347
3348 /*******************************************************************
3349 reads or writes a structure.
3350 ********************************************************************/
3351
3352 BOOL samr_io_q_enum_dom_aliases(const char *desc, SAMR_Q_ENUM_DOM_ALIASES * q_e,
3353                                 prs_struct *ps, int depth)
3354 {
3355         if (q_e == NULL)
3356                 return False;
3357
3358         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
3359         depth++;
3360
3361         if(!prs_align(ps))
3362                 return False;
3363
3364         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
3365                 return False;
3366
3367         if(!prs_uint32("start_idx", ps, depth, &q_e->start_idx))
3368                 return False;
3369         if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
3370                 return False;
3371
3372         return True;
3373 }
3374
3375 /*******************************************************************
3376 inits a SAMR_R_ENUM_DOM_ALIASES structure.
3377 ********************************************************************/
3378
3379 void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u, uint32 next_idx, uint32 num_sam_entries)
3380 {
3381         DEBUG(5, ("init_samr_r_enum_dom_aliases\n"));
3382
3383         r_u->next_idx = next_idx;
3384
3385         if (num_sam_entries != 0) {
3386                 r_u->ptr_entries1 = 1;
3387                 r_u->ptr_entries2 = 1;
3388                 r_u->num_entries2 = num_sam_entries;
3389                 r_u->num_entries3 = num_sam_entries;
3390
3391                 r_u->num_entries4 = num_sam_entries;
3392         } else {
3393                 r_u->ptr_entries1 = 0;
3394                 r_u->num_entries2 = num_sam_entries;
3395                 r_u->ptr_entries2 = 1;
3396         }
3397 }
3398
3399 /*******************************************************************
3400 reads or writes a structure.
3401 ********************************************************************/
3402
3403 BOOL samr_io_r_enum_dom_aliases(const char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
3404                                 prs_struct *ps, int depth)
3405 {
3406         uint32 i;
3407
3408         if (r_u == NULL)
3409                 return False;
3410
3411         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
3412         depth++;
3413
3414         if(!prs_align(ps))
3415                 return False;
3416
3417         if(!prs_uint32("next_idx    ", ps, depth, &r_u->next_idx))
3418                 return False;
3419         if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
3420                 return False;
3421
3422         if (r_u->ptr_entries1 != 0) {
3423                 if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
3424                         return False;
3425                 if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
3426                         return False;
3427                 if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
3428                         return False;
3429
3430                 if (UNMARSHALLING(ps) && (r_u->num_entries2 > 0)) {
3431                         r_u->sam = (SAM_ENTRY *)prs_alloc_mem(ps,sizeof(SAM_ENTRY)*r_u->num_entries2);
3432                         r_u->uni_grp_name = (UNISTR2 *)prs_alloc_mem(ps,sizeof(UNISTR2)*r_u->num_entries2);
3433                 }
3434
3435                 if (r_u->num_entries2 != 0 && 
3436                     (r_u->sam == NULL || r_u->uni_grp_name == NULL)) {
3437                         DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
3438                         r_u->num_entries4 = 0;
3439                         r_u->status = NT_STATUS_MEMORY_NOT_ALLOCATED;
3440                         return False;
3441                 }
3442
3443                 for (i = 0; i < r_u->num_entries2; i++) {
3444                         if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
3445                                 return False;
3446                 }
3447
3448                 for (i = 0; i < r_u->num_entries2; i++) {
3449                         if(!smb_io_unistr2("", &r_u->uni_grp_name[i],
3450                                        r_u->sam[i].hdr_name.buffer, ps,
3451                                        depth))
3452                                 return False;
3453                 }
3454         }
3455
3456         if(!prs_align(ps))
3457                 return False;
3458         if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
3459                 return False;
3460         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3461                 return False;
3462
3463         return True;
3464 }
3465
3466 /*******************************************************************
3467 inits a ALIAS_INFO1 structure.
3468 ********************************************************************/
3469
3470 void init_samr_alias_info1(ALIAS_INFO1 * al1, char *acct_name, uint32 num_member, char *acct_desc)
3471 {
3472         DEBUG(5, ("init_samr_alias_info1\n"));
3473
3474         init_unistr2(&al1->uni_acct_name, acct_name, UNI_FLAGS_NONE);
3475         init_uni_hdr(&al1->hdr_acct_name, &al1->uni_acct_name);
3476
3477         al1->num_member=num_member;
3478
3479         init_unistr2(&al1->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
3480         init_uni_hdr(&al1->hdr_acct_desc, &al1->uni_acct_name);
3481 }
3482
3483 /*******************************************************************
3484 reads or writes a structure.
3485 ********************************************************************/
3486
3487 BOOL samr_io_alias_info1(const char *desc, ALIAS_INFO1 * al1,
3488                          prs_struct *ps, int depth)
3489 {
3490         if (al1 == NULL)
3491                 return False;
3492
3493         prs_debug(ps, depth, desc, "samr_io_alias_info1");
3494         depth++;
3495
3496         if(!prs_align(ps))
3497                 return False;
3498
3499         if(!smb_io_unihdr("hdr_acct_name", &al1->hdr_acct_name, ps, depth))
3500                 return False;
3501         if(!prs_uint32("num_member", ps, depth, &al1->num_member))
3502                 return False;
3503         if(!smb_io_unihdr("hdr_acct_desc", &al1->hdr_acct_desc, ps, depth))
3504                 return False;
3505
3506         if(!smb_io_unistr2("uni_acct_name", &al1->uni_acct_name,
3507                        al1->hdr_acct_name.buffer, ps, depth))
3508                 return False;
3509
3510         if(!prs_align(ps))
3511                 return False;
3512
3513         if(!smb_io_unistr2("uni_acct_desc", &al1->uni_acct_desc,
3514                        al1->hdr_acct_desc.buffer, ps, depth))
3515                 return False;
3516
3517         return True;
3518 }
3519
3520 /*******************************************************************
3521 inits a ALIAS_INFO3 structure.
3522 ********************************************************************/
3523
3524 void init_samr_alias_info3(ALIAS_INFO3 * al3, char *acct_desc)
3525 {
3526         DEBUG(5, ("init_samr_alias_info3\n"));
3527
3528         init_unistr2(&al3->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
3529         init_uni_hdr(&al3->hdr_acct_desc, &al3->uni_acct_desc);
3530 }
3531
3532 /*******************************************************************
3533 reads or writes a structure.
3534 ********************************************************************/
3535
3536 BOOL samr_io_alias_info3(const char *desc, ALIAS_INFO3 * al3,
3537                          prs_struct *ps, int depth)
3538 {
3539         if (al3 == NULL)
3540                 return False;
3541
3542         prs_debug(ps, depth, desc, "samr_io_alias_info3");
3543         depth++;
3544
3545         if(!prs_align(ps))
3546                 return False;
3547
3548         if(!smb_io_unihdr("hdr_acct_desc", &al3->hdr_acct_desc, ps, depth))
3549                 return False;
3550         if(!smb_io_unistr2("uni_acct_desc", &al3->uni_acct_desc,
3551                        al3->hdr_acct_desc.buffer, ps, depth))
3552                 return False;
3553
3554         return True;
3555 }
3556
3557 /*******************************************************************
3558 reads or writes a structure.
3559 ********************************************************************/
3560
3561 BOOL samr_alias_info_ctr(const char *desc, ALIAS_INFO_CTR * ctr,
3562                          prs_struct *ps, int depth)
3563 {
3564         if (ctr == NULL)
3565                 return False;
3566
3567         prs_debug(ps, depth, desc, "samr_alias_info_ctr");
3568         depth++;
3569
3570         if(!prs_uint16("switch_value1", ps, depth, &ctr->switch_value1))
3571                 return False;
3572         if(!prs_uint16("switch_value2", ps, depth, &ctr->switch_value2))
3573                 return False;
3574
3575         switch (ctr->switch_value1) {
3576         case 1: 
3577                 if(!samr_io_alias_info1("alias_info1", &ctr->alias.info1, ps, depth))
3578                         return False;
3579                 break;
3580         case 3: 
3581                 if(!samr_io_alias_info3("alias_info3", &ctr->alias.info3, ps, depth))
3582                         return False;
3583                 break;
3584         default:
3585                 DEBUG(0,("samr_alias_info_ctr: unsupported switch level\n"));
3586                 break;
3587         }
3588
3589         return True;
3590 }
3591
3592 /*******************************************************************
3593 inits a SAMR_Q_QUERY_ALIASINFO structure.
3594 ********************************************************************/
3595
3596 void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
3597                                  POLICY_HND *pol, uint16 switch_level)
3598 {
3599         DEBUG(5, ("init_samr_q_query_aliasinfo\n"));
3600
3601         q_e->pol = *pol;
3602         q_e->switch_level = switch_level;
3603 }
3604
3605 /*******************************************************************
3606 reads or writes a structure.
3607 ********************************************************************/
3608
3609 BOOL samr_io_q_query_aliasinfo(const char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
3610                                prs_struct *ps, int depth)
3611 {
3612         if (q_e == NULL)
3613                 return False;
3614
3615         prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
3616         depth++;
3617
3618         if(!prs_align(ps))
3619                 return False;
3620
3621         if(!smb_io_pol_hnd("pol", &(q_e->pol), ps, depth))
3622                 return False;
3623
3624         if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
3625                 return False;
3626
3627         return True;
3628 }
3629
3630 /*******************************************************************
3631 inits a SAMR_R_QUERY_ALIASINFO structure.
3632 ********************************************************************/
3633
3634 void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
3635                                  ALIAS_INFO_CTR * ctr, NTSTATUS status)
3636 {
3637         DEBUG(5, ("init_samr_r_query_aliasinfo\n"));
3638
3639         r_u->ptr = (NT_STATUS_IS_OK(status) && ctr != NULL) ? 1 : 0;
3640         r_u->ctr = *ctr;
3641         r_u->status = status;
3642 }
3643
3644 /*******************************************************************
3645 reads or writes a structure.
3646 ********************************************************************/
3647
3648 BOOL samr_io_r_query_aliasinfo(const char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
3649                                prs_struct *ps, int depth)
3650 {
3651         if (r_u == NULL)
3652                 return False;
3653
3654         prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
3655         depth++;
3656
3657         if(!prs_align(ps))
3658                 return False;
3659
3660         if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
3661                 return False;
3662
3663         if (r_u->ptr != 0) {
3664                 if(!samr_alias_info_ctr("ctr", &r_u->ctr, ps, depth))
3665                         return False;
3666         }
3667
3668         if(!prs_align(ps))
3669                 return False;
3670         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3671                 return False;
3672
3673         return True;
3674 }
3675
3676 /*******************************************************************
3677 inits a SAMR_Q_SET_ALIASINFO structure.
3678 ********************************************************************/
3679
3680 void init_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
3681                                POLICY_HND *hnd, ALIAS_INFO_CTR * ctr)
3682 {
3683         DEBUG(5, ("init_samr_q_set_aliasinfo\n"));
3684
3685         q_u->alias_pol = *hnd;
3686         q_u->ctr = *ctr;
3687 }
3688
3689 /*******************************************************************
3690 reads or writes a structure.
3691 ********************************************************************/
3692
3693 BOOL samr_io_q_set_aliasinfo(const char *desc, SAMR_Q_SET_ALIASINFO * q_u,
3694                              prs_struct *ps, int depth)
3695 {
3696         if (q_u == NULL)
3697                 return False;
3698
3699         prs_debug(ps, depth, desc, "samr_io_q_set_aliasinfo");
3700         depth++;
3701
3702         if(!prs_align(ps))
3703                 return False;
3704
3705         if(!smb_io_pol_hnd("alias_pol", &q_u->alias_pol, ps, depth))
3706                 return False;
3707         if(!samr_alias_info_ctr("ctr", &q_u->ctr, ps, depth))
3708                 return False;
3709
3710         return True;
3711 }
3712
3713 /*******************************************************************
3714 reads or writes a structure.
3715 ********************************************************************/
3716
3717 BOOL samr_io_r_set_aliasinfo(const char *desc, SAMR_R_SET_ALIASINFO * r_u,
3718                              prs_struct *ps, int depth)
3719 {
3720         if (r_u == NULL)
3721                 return False;
3722
3723         prs_debug(ps, depth, desc, "samr_io_r_set_aliasinfo");
3724         depth++;
3725
3726         if(!prs_align(ps))
3727                 return False;
3728         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3729                 return False;
3730
3731         return True;
3732 }
3733
3734 /*******************************************************************
3735 inits a SAMR_Q_QUERY_USERALIASES structure.
3736 ********************************************************************/
3737
3738 void init_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
3739                                    POLICY_HND *hnd,
3740                                    uint32 num_sids,
3741                                    uint32 *ptr_sid, DOM_SID2 * sid)
3742 {
3743         DEBUG(5, ("init_samr_q_query_useraliases\n"));
3744
3745         q_u->pol = *hnd;
3746
3747         q_u->num_sids1 = num_sids;
3748         q_u->ptr = 1;
3749         q_u->num_sids2 = num_sids;
3750
3751         q_u->ptr_sid = ptr_sid;
3752         q_u->sid = sid;
3753 }
3754
3755 /*******************************************************************
3756 reads or writes a SAMR_Q_QUERY_USERALIASES structure.
3757 ********************************************************************/
3758
3759 BOOL samr_io_q_query_useraliases(const char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
3760                                  prs_struct *ps, int depth)
3761 {
3762         fstring tmp;
3763         uint32 i;
3764
3765         if (q_u == NULL)
3766                 return False;
3767
3768         prs_debug(ps, depth, desc, "samr_io_q_query_useraliases");
3769         depth++;
3770
3771         if(!prs_align(ps))
3772                 return False;
3773
3774         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
3775                 return False;
3776
3777         if(!prs_uint32("num_sids1", ps, depth, &q_u->num_sids1))
3778                 return False;
3779         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
3780                 return False;
3781
3782         if (q_u->ptr==0)
3783                 return True;
3784
3785         if(!prs_uint32("num_sids2", ps, depth, &q_u->num_sids2))
3786                 return False;
3787
3788         if (UNMARSHALLING(ps) && (q_u->num_sids2 != 0)) {
3789                 q_u->ptr_sid = (uint32 *)prs_alloc_mem(ps,sizeof(q_u->ptr_sid[0])*q_u->num_sids2);
3790                 if (q_u->ptr_sid == NULL)
3791                         return False;
3792
3793                 q_u->sid = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(q_u->sid[0]) * q_u->num_sids2);
3794                 if (q_u->sid == NULL)
3795                         return False;
3796         }
3797
3798         for (i = 0; i < q_u->num_sids2; i++) {
3799                 slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
3800                 if(!prs_uint32(tmp, ps, depth, &q_u->ptr_sid[i]))
3801                         return False;
3802         }
3803
3804         for (i = 0; i < q_u->num_sids2; i++) {
3805                 if (q_u->ptr_sid[i] != 0) {
3806                         slprintf(tmp, sizeof(tmp) - 1, "sid[%02d]", i);
3807                         if(!smb_io_dom_sid2(tmp, &q_u->sid[i], ps, depth))
3808                                 return False;
3809                 }
3810         }
3811
3812         return True;
3813 }
3814
3815 /*******************************************************************
3816 inits a SAMR_R_QUERY_USERALIASES structure.
3817 ********************************************************************/
3818
3819 void init_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
3820                                    uint32 num_rids, uint32 *rid,
3821                                    NTSTATUS status)
3822 {
3823         DEBUG(5, ("init_samr_r_query_useraliases\n"));
3824
3825         if (NT_STATUS_IS_OK(status)) {
3826                 r_u->num_entries = num_rids;
3827                 r_u->ptr = 1;
3828                 r_u->num_entries2 = num_rids;
3829
3830                 r_u->rid = rid;
3831         } else {
3832                 r_u->num_entries = 0;
3833                 r_u->ptr = 0;
3834                 r_u->num_entries2 = 0;
3835         }
3836
3837         r_u->status = status;
3838 }
3839
3840 /*******************************************************************
3841 reads or writes a structure.
3842 ********************************************************************/
3843
3844 BOOL samr_io_rids(const char *desc, uint32 *num_rids, uint32 **rid,
3845                   prs_struct *ps, int depth)
3846 {
3847         fstring tmp;
3848         uint32 i;
3849         if (rid == NULL)
3850                 return False;
3851
3852         prs_debug(ps, depth, desc, "samr_io_rids");
3853         depth++;
3854
3855         if(!prs_align(ps))
3856                 return False;
3857
3858         if(!prs_uint32("num_rids", ps, depth, num_rids))
3859                 return False;
3860
3861         if ((*num_rids) != 0) {
3862                 if (UNMARSHALLING(ps)) {
3863                         /* reading */
3864                         (*rid) = (uint32 *)prs_alloc_mem(ps,sizeof(uint32)*(*num_rids));
3865                 }
3866                 if ((*rid) == NULL)
3867                         return False;
3868
3869                 for (i = 0; i < (*num_rids); i++) {
3870                         slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]", i);
3871                         if(!prs_uint32(tmp, ps, depth, &((*rid)[i])))
3872                                 return False;
3873                 }
3874         }
3875
3876         return True;
3877 }
3878
3879 /*******************************************************************
3880 reads or writes a structure.
3881 ********************************************************************/
3882
3883 BOOL samr_io_r_query_useraliases(const char *desc, SAMR_R_QUERY_USERALIASES * r_u,
3884                                  prs_struct *ps, int depth)
3885 {
3886         if (r_u == NULL)
3887                 return False;
3888
3889         prs_debug(ps, depth, desc, "samr_io_r_query_useraliases");
3890         depth++;
3891
3892         if(!prs_align(ps))
3893                 return False;
3894
3895         if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
3896                 return False;
3897         if(!prs_uint32("ptr        ", ps, depth, &r_u->ptr))
3898                 return False;
3899
3900         if (r_u->ptr != 0) {
3901                 if(!samr_io_rids("rids", &r_u->num_entries2, &r_u->rid, ps, depth))
3902                         return False;
3903         }
3904
3905         if(!prs_align(ps))
3906                 return False;
3907         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3908                 return False;
3909
3910         return True;
3911 }
3912
3913 /*******************************************************************
3914 inits a SAMR_Q_OPEN_ALIAS structure.
3915 ********************************************************************/
3916
3917 void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, POLICY_HND *pol,
3918                             uint32 access_mask, uint32 rid)
3919 {
3920         DEBUG(5, ("init_samr_q_open_alias\n"));
3921
3922         q_u->dom_pol = *pol;
3923         q_u->access_mask = access_mask;
3924         q_u->rid_alias = rid;
3925 }
3926
3927 /*******************************************************************
3928 reads or writes a structure.
3929 ********************************************************************/
3930
3931 BOOL samr_io_q_open_alias(const char *desc, SAMR_Q_OPEN_ALIAS * q_u,
3932                           prs_struct *ps, int depth)
3933 {
3934         if (q_u == NULL)
3935                 return False;
3936
3937         prs_debug(ps, depth, desc, "samr_io_q_open_alias");
3938         depth++;
3939
3940         if(!prs_align(ps))
3941                 return False;
3942
3943         if(!smb_io_pol_hnd("domain_pol", &q_u->dom_pol, ps, depth))
3944                 return False;
3945
3946         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
3947                 return False;
3948         if(!prs_uint32("rid_alias", ps, depth, &q_u->rid_alias))
3949                 return False;
3950
3951         return True;
3952 }
3953
3954 /*******************************************************************
3955 reads or writes a structure.
3956 ********************************************************************/
3957
3958 BOOL samr_io_r_open_alias(const char *desc, SAMR_R_OPEN_ALIAS * r_u,
3959                           prs_struct *ps, int depth)
3960 {
3961         if (r_u == NULL)
3962                 return False;
3963
3964         prs_debug(ps, depth, desc, "samr_io_r_open_alias");
3965         depth++;
3966
3967         if(!prs_align(ps))
3968                 return False;
3969
3970         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
3971                 return False;
3972
3973         if(!prs_ntstatus("status", ps, depth, &r_u->status))
3974                 return False;
3975
3976         return True;
3977 }
3978
3979 /*******************************************************************
3980 inits a SAMR_Q_LOOKUP_RIDS structure.
3981 ********************************************************************/
3982
3983 void init_samr_q_lookup_rids(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_RIDS * q_u,
3984                              POLICY_HND *pol, uint32 flags,
3985                              uint32 num_rids, uint32 *rid)
3986 {
3987         DEBUG(5, ("init_samr_q_lookup_rids\n"));
3988
3989         q_u->pol = *pol;
3990
3991         q_u->num_rids1 = num_rids;
3992         q_u->flags = flags;
3993         q_u->ptr = 0;
3994         q_u->num_rids2 = num_rids;
3995         q_u->rid = (uint32 *)talloc_zero(ctx, num_rids * sizeof(q_u->rid[0]));
3996         if (q_u->rid == NULL) {
3997                 q_u->num_rids1 = 0;
3998                 q_u->num_rids2 = 0;
3999         } else {
4000                 memcpy(q_u->rid, rid, num_rids * sizeof(q_u->rid[0]));
4001         }
4002 }
4003
4004 /*******************************************************************
4005 reads or writes a structure.
4006 ********************************************************************/
4007
4008 BOOL samr_io_q_lookup_rids(const char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
4009                            prs_struct *ps, int depth)
4010 {
4011         uint32 i;
4012         fstring tmp;
4013
4014         if (q_u == NULL)
4015                 return False;
4016
4017         prs_debug(ps, depth, desc, "samr_io_q_lookup_rids");
4018         depth++;
4019
4020         if (UNMARSHALLING(ps))
4021                 ZERO_STRUCTP(q_u);
4022
4023         if(!prs_align(ps))
4024                 return False;
4025
4026         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
4027                 return False;
4028
4029         if(!prs_uint32("num_rids1", ps, depth, &q_u->num_rids1))
4030                 return False;
4031         if(!prs_uint32("flags    ", ps, depth, &q_u->flags))
4032                 return False;
4033         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
4034                 return False;
4035         if(!prs_uint32("num_rids2", ps, depth, &q_u->num_rids2))
4036                 return False;
4037
4038         if (UNMARSHALLING(ps) && (q_u->num_rids2 != 0)) {
4039                 q_u->rid = (uint32 *)prs_alloc_mem(ps, sizeof(q_u->rid[0])*q_u->num_rids2);
4040                 if (q_u->rid == NULL)
4041                         return False;
4042         }
4043
4044         for (i = 0; i < q_u->num_rids2; i++) {
4045                 slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
4046                 if(!prs_uint32(tmp, ps, depth, &q_u->rid[i]))
4047                         return False;
4048         }
4049
4050         return True;
4051 }
4052
4053 /*******************************************************************
4054 inits a SAMR_R_LOOKUP_RIDS structure.
4055 ********************************************************************/
4056
4057 void init_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
4058                              uint32 num_names, UNIHDR * hdr_name,
4059                              UNISTR2 *uni_name, uint32 *type)
4060 {
4061         DEBUG(5, ("init_samr_r_lookup_rids\n"));
4062
4063         r_u->hdr_name = NULL;
4064         r_u->uni_name = NULL;
4065         r_u->type = NULL;
4066
4067         if (num_names != 0) {
4068                 r_u->num_names1 = num_names;
4069                 r_u->ptr_names = 1;
4070                 r_u->num_names2 = num_names;
4071
4072                 r_u->num_types1 = num_names;
4073                 r_u->ptr_types = 1;
4074                 r_u->num_types2 = num_names;
4075
4076                 r_u->hdr_name = hdr_name;
4077                 r_u->uni_name = uni_name;
4078                 r_u->type = type;
4079         } else {
4080                 r_u->num_names1 = num_names;
4081                 r_u->ptr_names = 0;
4082                 r_u->num_names2 = num_names;
4083
4084                 r_u->num_types1 = num_names;
4085                 r_u->ptr_types = 0;
4086                 r_u->num_types2 = num_names;
4087         }
4088 }
4089
4090 /*******************************************************************
4091 reads or writes a structure.
4092 ********************************************************************/
4093
4094 BOOL samr_io_r_lookup_rids(const char *desc, SAMR_R_LOOKUP_RIDS * r_u,
4095                            prs_struct *ps, int depth)
4096 {
4097         uint32 i;
4098         fstring tmp;
4099         if (r_u == NULL)
4100                 return False;
4101
4102         prs_debug(ps, depth, desc, "samr_io_r_lookup_rids");
4103         depth++;
4104
4105         if(!prs_align(ps))
4106                 return False;
4107
4108         if(!prs_uint32("num_names1", ps, depth, &r_u->num_names1))
4109                 return False;
4110         if(!prs_uint32("ptr_names ", ps, depth, &r_u->ptr_names))
4111                 return False;
4112
4113         if (r_u->ptr_names != 0) {
4114
4115                 if(!prs_uint32("num_names2", ps, depth, &r_u->num_names2))
4116                         return False;
4117
4118
4119                 if (UNMARSHALLING(ps) && (r_u->num_names2 != 0)) {
4120                         r_u->hdr_name = (UNIHDR *) prs_alloc_mem(ps, r_u->num_names2 * sizeof(r_u->hdr_name[0]));
4121                         if (r_u->hdr_name == NULL)
4122                                 return False;
4123
4124                         r_u->uni_name = (UNISTR2 *)prs_alloc_mem(ps, r_u->num_names2 * sizeof(r_u->uni_name[0]));
4125                         if (r_u->uni_name == NULL)
4126                                 return False;
4127                 }
4128                 
4129                 for (i = 0; i < r_u->num_names2; i++) {
4130                         slprintf(tmp, sizeof(tmp) - 1, "hdr[%02d]  ", i);
4131                         if(!smb_io_unihdr("", &r_u->hdr_name[i], ps, depth))
4132                                 return False;
4133                 }
4134                 for (i = 0; i < r_u->num_names2; i++) {
4135                         slprintf(tmp, sizeof(tmp) - 1, "str[%02d]  ", i);
4136                         if(!smb_io_unistr2("", &r_u->uni_name[i], r_u->hdr_name[i].buffer, ps, depth))
4137                                 return False;
4138                 }
4139
4140         }
4141         
4142         if(!prs_align(ps))
4143                 return False;
4144         if(!prs_uint32("num_types1", ps, depth, &r_u->num_types1))
4145                 return False;
4146         if(!prs_uint32("ptr_types ", ps, depth, &r_u->ptr_types))
4147                 return False;
4148
4149         if (r_u->ptr_types != 0) {
4150
4151                 if(!prs_uint32("num_types2", ps, depth, &r_u->num_types2))
4152                         return False;
4153
4154                 if (UNMARSHALLING(ps) && (r_u->num_types2 != 0)) {
4155                         r_u->type = (uint32 *)prs_alloc_mem(ps, r_u->num_types2 * sizeof(r_u->type[0]));
4156                         if (r_u->type == NULL)
4157                                 return False;
4158                 }
4159
4160                 for (i = 0; i < r_u->num_types2; i++) {
4161                         slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
4162                         if(!prs_uint32(tmp, ps, depth, &r_u->type[i]))
4163                                 return False;
4164                 }
4165         }
4166
4167         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4168                 return False;
4169
4170         return True;
4171 }
4172
4173 /*******************************************************************
4174 inits a SAMR_Q_OPEN_ALIAS structure.
4175 ********************************************************************/
4176
4177 void init_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND *hnd)
4178 {
4179         DEBUG(5, ("init_samr_q_delete_alias\n"));
4180
4181         q_u->alias_pol = *hnd;
4182 }
4183
4184 /*******************************************************************
4185 reads or writes a structure.
4186 ********************************************************************/
4187
4188 BOOL samr_io_q_delete_alias(const char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
4189                             prs_struct *ps, int depth)
4190 {
4191         if (q_u == NULL)
4192                 return False;
4193
4194         prs_debug(ps, depth, desc, "samr_io_q_delete_alias");
4195         depth++;
4196
4197         if(!prs_align(ps))
4198                 return False;
4199
4200         if(!smb_io_pol_hnd("alias_pol", &q_u->alias_pol, ps, depth))
4201                 return False;
4202
4203         return True;
4204 }
4205
4206 /*******************************************************************
4207 reads or writes a structure.
4208 ********************************************************************/
4209
4210 BOOL samr_io_r_delete_alias(const char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
4211                             prs_struct *ps, int depth)
4212 {
4213         if (r_u == NULL)
4214                 return False;
4215
4216         prs_debug(ps, depth, desc, "samr_io_r_delete_alias");
4217         depth++;
4218
4219         if(!prs_align(ps))
4220                 return False;
4221
4222         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
4223                 return False;
4224         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4225                 return False;
4226
4227         return True;
4228 }
4229
4230 /*******************************************************************
4231 inits a SAMR_Q_CREATE_DOM_ALIAS structure.
4232 ********************************************************************/
4233
4234 void init_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
4235                                   POLICY_HND *hnd, char *acct_desc)
4236 {
4237         DEBUG(5, ("init_samr_q_create_dom_alias\n"));
4238
4239         q_u->dom_pol = *hnd;
4240
4241         init_unistr2(&q_u->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
4242         init_uni_hdr(&q_u->hdr_acct_desc, &q_u->uni_acct_desc);
4243
4244         q_u->access_mask = 0x001f000f;
4245 }
4246
4247 /*******************************************************************
4248 reads or writes a structure.
4249 ********************************************************************/
4250
4251 BOOL samr_io_q_create_dom_alias(const char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
4252                                 prs_struct *ps, int depth)
4253 {
4254         if (q_u == NULL)
4255                 return False;
4256
4257         prs_debug(ps, depth, desc, "samr_io_q_create_dom_alias");
4258         depth++;
4259
4260         if(!prs_align(ps))
4261                 return False;
4262
4263         if(!smb_io_pol_hnd("dom_pol", &q_u->dom_pol, ps, depth))
4264                 return False;
4265
4266         if(!smb_io_unihdr("hdr_acct_desc", &q_u->hdr_acct_desc, ps, depth))
4267                 return False;
4268         if(!smb_io_unistr2("uni_acct_desc", &q_u->uni_acct_desc,
4269                        q_u->hdr_acct_desc.buffer, ps, depth))
4270                 return False;
4271
4272         if(!prs_align(ps))
4273                 return False;
4274         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
4275                 return False;
4276
4277         return True;
4278 }
4279
4280 /*******************************************************************
4281 reads or writes a structure.
4282 ********************************************************************/
4283
4284 BOOL samr_io_r_create_dom_alias(const char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
4285                                 prs_struct *ps, int depth)
4286 {
4287         if (r_u == NULL)
4288                 return False;
4289
4290         prs_debug(ps, depth, desc, "samr_io_r_create_dom_alias");
4291         depth++;
4292
4293         if(!prs_align(ps))
4294                 return False;
4295
4296         if(!smb_io_pol_hnd("alias_pol", &r_u->alias_pol, ps, depth))
4297                 return False;
4298
4299         if(!prs_uint32("rid", ps, depth, &r_u->rid))
4300                 return False;
4301
4302         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4303                 return False;
4304
4305         return True;
4306 }
4307
4308 /*******************************************************************
4309 inits a SAMR_Q_ADD_ALIASMEM structure.
4310 ********************************************************************/
4311
4312 void init_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND *hnd,
4313                               DOM_SID *sid)
4314 {
4315         DEBUG(5, ("init_samr_q_add_aliasmem\n"));
4316
4317         q_u->alias_pol = *hnd;
4318         init_dom_sid2(&q_u->sid, sid);
4319 }
4320
4321 /*******************************************************************
4322 reads or writes a structure.
4323 ********************************************************************/
4324
4325 BOOL samr_io_q_add_aliasmem(const char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
4326                             prs_struct *ps, int depth)
4327 {
4328         if (q_u == NULL)
4329                 return False;
4330
4331         prs_debug(ps, depth, desc, "samr_io_q_add_aliasmem");
4332         depth++;
4333
4334         if(!prs_align(ps))
4335                 return False;
4336
4337         if(!smb_io_pol_hnd("alias_pol", &q_u->alias_pol, ps, depth))
4338                 return False;
4339         if(!smb_io_dom_sid2("sid      ", &q_u->sid, ps, depth))
4340                 return False;
4341
4342         return True;
4343 }
4344
4345 /*******************************************************************
4346 reads or writes a structure.
4347 ********************************************************************/
4348
4349 BOOL samr_io_r_add_aliasmem(const char *desc, SAMR_R_ADD_ALIASMEM * r_u,
4350                             prs_struct *ps, int depth)
4351 {
4352         if (r_u == NULL)
4353                 return False;
4354
4355         prs_debug(ps, depth, desc, "samr_io_r_add_aliasmem");
4356         depth++;
4357
4358         if(!prs_align(ps))
4359                 return False;
4360
4361         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4362                 return False;
4363
4364         return True;
4365 }
4366
4367 /*******************************************************************
4368 inits a SAMR_Q_DEL_ALIASMEM structure.
4369 ********************************************************************/
4370
4371 void init_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND *hnd,
4372                               DOM_SID *sid)
4373 {
4374         DEBUG(5, ("init_samr_q_del_aliasmem\n"));
4375
4376         q_u->alias_pol = *hnd;
4377         init_dom_sid2(&q_u->sid, sid);
4378 }
4379
4380 /*******************************************************************
4381 reads or writes a structure.
4382 ********************************************************************/
4383
4384 BOOL samr_io_q_del_aliasmem(const char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
4385                             prs_struct *ps, int depth)
4386 {
4387         if (q_u == NULL)
4388                 return False;
4389
4390         prs_debug(ps, depth, desc, "samr_io_q_del_aliasmem");
4391         depth++;
4392
4393         if(!prs_align(ps))
4394                 return False;
4395
4396         if(!smb_io_pol_hnd("alias_pol", &q_u->alias_pol, ps, depth))
4397                 return False;
4398         if(!smb_io_dom_sid2("sid      ", &q_u->sid, ps, depth))
4399                 return False;
4400
4401         return True;
4402 }
4403
4404 /*******************************************************************
4405 reads or writes a structure.
4406 ********************************************************************/
4407
4408 BOOL samr_io_r_del_aliasmem(const char *desc, SAMR_R_DEL_ALIASMEM * r_u,
4409                             prs_struct *ps, int depth)
4410 {
4411         if (r_u == NULL)
4412                 return False;
4413
4414         prs_debug(ps, depth, desc, "samr_io_r_del_aliasmem");
4415         depth++;
4416
4417         if(!prs_align(ps))
4418                 return False;
4419
4420         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4421                 return False;
4422
4423         return True;
4424 }
4425
4426 /*******************************************************************
4427 inits a SAMR_Q_DELETE_DOM_ALIAS structure.
4428 ********************************************************************/
4429
4430 void init_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
4431                                   POLICY_HND *hnd)
4432 {
4433         DEBUG(5, ("init_samr_q_delete_dom_alias\n"));
4434
4435         q_c->alias_pol = *hnd;
4436 }
4437
4438 /*******************************************************************
4439 reads or writes a structure.
4440 ********************************************************************/
4441
4442 BOOL samr_io_q_delete_dom_alias(const char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
4443                                 prs_struct *ps, int depth)
4444 {
4445         if (q_u == NULL)
4446                 return False;
4447
4448         prs_debug(ps, depth, desc, "samr_io_q_delete_dom_alias");
4449         depth++;
4450
4451         if(!prs_align(ps))
4452                 return False;
4453
4454         if(!smb_io_pol_hnd("alias_pol", &q_u->alias_pol, ps, depth))
4455                 return False;
4456
4457         return True;
4458 }
4459
4460 /*******************************************************************
4461 inits a SAMR_R_DELETE_DOM_ALIAS structure.
4462 ********************************************************************/
4463
4464 void init_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
4465                                   NTSTATUS status)
4466 {
4467         DEBUG(5, ("init_samr_r_delete_dom_alias\n"));
4468
4469         r_u->status = status;
4470 }
4471
4472 /*******************************************************************
4473 reads or writes a structure.
4474 ********************************************************************/
4475
4476 BOOL samr_io_r_delete_dom_alias(const char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
4477                                 prs_struct *ps, int depth)
4478 {
4479         if (r_u == NULL)
4480                 return False;
4481
4482         prs_debug(ps, depth, desc, "samr_io_r_delete_dom_alias");
4483         depth++;
4484
4485         if(!prs_align(ps))
4486                 return False;
4487
4488         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4489                 return False;
4490
4491         return True;
4492 }
4493
4494 /*******************************************************************
4495 inits a SAMR_Q_QUERY_ALIASMEM structure.
4496 ********************************************************************/
4497
4498 void init_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
4499                                 POLICY_HND *hnd)
4500 {
4501         DEBUG(5, ("init_samr_q_query_aliasmem\n"));
4502
4503         q_c->alias_pol = *hnd;
4504 }
4505
4506 /*******************************************************************
4507 reads or writes a structure.
4508 ********************************************************************/
4509
4510 BOOL samr_io_q_query_aliasmem(const char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
4511                               prs_struct *ps, int depth)
4512 {
4513         if (q_u == NULL)
4514                 return False;
4515
4516         prs_debug(ps, depth, desc, "samr_io_q_query_aliasmem");
4517         depth++;
4518
4519         if(!prs_align(ps))
4520                 return False;
4521
4522         if(!smb_io_pol_hnd("alias_pol", &q_u->alias_pol, ps, depth))
4523                 return False;
4524
4525         return True;
4526 }
4527
4528 /*******************************************************************
4529 inits a SAMR_R_QUERY_ALIASMEM structure.
4530 ********************************************************************/
4531
4532 void init_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
4533                                 uint32 num_sids, DOM_SID2 * sid,
4534                                 NTSTATUS status)
4535 {
4536         DEBUG(5, ("init_samr_r_query_aliasmem\n"));
4537
4538         if (NT_STATUS_IS_OK(status)) {
4539                 r_u->num_sids = num_sids;
4540                 r_u->ptr = (num_sids != 0) ? 1 : 0;
4541                 r_u->num_sids1 = num_sids;
4542
4543                 r_u->sid = sid;
4544         } else {
4545                 r_u->ptr = 0;
4546                 r_u->num_sids = 0;
4547         }
4548
4549         r_u->status = status;
4550 }
4551
4552 /*******************************************************************
4553 reads or writes a structure.
4554 ********************************************************************/
4555
4556 BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
4557                               prs_struct *ps, int depth)
4558 {
4559         uint32 i;
4560
4561         if (r_u == NULL)
4562                 return False;
4563
4564         prs_debug(ps, depth, desc, "samr_io_r_query_aliasmem");
4565         depth++;
4566
4567         if(!prs_align(ps))
4568                 return False;
4569
4570         if(!prs_uint32("num_sids ", ps, depth, &r_u->num_sids))
4571                 return False;
4572         if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
4573                 return False;
4574
4575         if (r_u->ptr != 0 && r_u->num_sids != 0) {
4576                 uint32 *ptr_sid = NULL;
4577
4578                 if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1))
4579                         return False;
4580
4581                 ptr_sid = talloc(ps->mem_ctx, sizeof(uint32) * r_u->num_sids1);
4582                 if (!ptr_sid) {
4583                         return False;
4584                 }
4585                 
4586                 for (i = 0; i < r_u->num_sids1; i++) {
4587                         ptr_sid[i] = 1;
4588                         if(!prs_uint32("ptr_sid", ps, depth, &ptr_sid[i]))
4589                                 return False;
4590                 }
4591                 
4592                 if (UNMARSHALLING(ps)) {
4593                         r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2));
4594                 }
4595                 
4596                 for (i = 0; i < r_u->num_sids1; i++) {
4597                         if (ptr_sid[i] != 0) {
4598                                 if(!smb_io_dom_sid2("sid", &r_u->sid[i], ps, depth))
4599                                         return False;
4600                         }
4601                 }
4602         }
4603
4604         if(!prs_align(ps))
4605                 return False;
4606         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4607                 return False;
4608
4609         return True;
4610 }
4611
4612 /*******************************************************************
4613 inits a SAMR_Q_LOOKUP_NAMES structure.
4614 ********************************************************************/
4615
4616 NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
4617                               POLICY_HND *pol, uint32 flags,
4618                               uint32 num_names, const char **name)
4619 {
4620         uint32 i;
4621
4622         DEBUG(5, ("init_samr_q_lookup_names\n"));
4623
4624         q_u->pol = *pol;
4625
4626         q_u->num_names1 = num_names;
4627         q_u->flags = flags;
4628         q_u->ptr = 0;
4629         q_u->num_names2 = num_names;
4630
4631         if (!(q_u->hdr_name = (UNIHDR *)talloc_zero(ctx, num_names * sizeof(UNIHDR))))
4632                 return NT_STATUS_NO_MEMORY;
4633
4634         if (!(q_u->uni_name = (UNISTR2 *)talloc_zero(ctx, num_names * sizeof(UNISTR2))))
4635                 return NT_STATUS_NO_MEMORY;
4636
4637         for (i = 0; i < num_names; i++) {
4638                 init_unistr2(&q_u->uni_name[i], name[i], UNI_FLAGS_NONE);       /* unicode string for machine account */
4639                 init_uni_hdr(&q_u->hdr_name[i], &q_u->uni_name[i]);     /* unicode header for user_name */
4640         }
4641
4642         return NT_STATUS_OK;
4643 }
4644
4645 /*******************************************************************
4646 reads or writes a structure.
4647 ********************************************************************/
4648
4649 BOOL samr_io_q_lookup_names(const char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
4650                             prs_struct *ps, int depth)
4651 {
4652         uint32 i;
4653
4654         if (q_u == NULL)
4655                 return False;
4656
4657         prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
4658         depth++;
4659
4660         if (UNMARSHALLING(ps))
4661                 ZERO_STRUCTP(q_u);
4662
4663         if(!prs_align(ps))
4664                 return False;
4665
4666         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
4667                 return False;
4668
4669         if(!prs_uint32("num_names1", ps, depth, &q_u->num_names1))
4670                 return False;
4671         if(!prs_uint32("flags     ", ps, depth, &q_u->flags))
4672                 return False;
4673         if(!prs_uint32("ptr       ", ps, depth, &q_u->ptr))
4674                 return False;
4675         if(!prs_uint32("num_names2", ps, depth, &q_u->num_names2))
4676                 return False;
4677
4678         if (UNMARSHALLING(ps) && (q_u->num_names2 != 0)) {
4679                 q_u->hdr_name = (UNIHDR *)prs_alloc_mem(ps, sizeof(UNIHDR) *
4680                                                         q_u->num_names2);
4681                 q_u->uni_name = (UNISTR2 *)prs_alloc_mem(ps, sizeof(UNISTR2) *
4682                                                          q_u->num_names2);
4683                 if (!q_u->hdr_name || !q_u->uni_name)
4684                         return False;
4685         }
4686
4687         for (i = 0; i < q_u->num_names2; i++) {
4688                 if(!smb_io_unihdr("", &q_u->hdr_name[i], ps, depth))
4689                         return False;
4690         }
4691
4692         for (i = 0; i < q_u->num_names2; i++) {
4693                 if(!smb_io_unistr2("", &q_u->uni_name[i], q_u->hdr_name[i].buffer, ps, depth))
4694                         return False;
4695         }
4696
4697         return True;
4698 }
4699
4700 /*******************************************************************
4701 inits a SAMR_R_LOOKUP_NAMES structure.
4702 ********************************************************************/
4703
4704 NTSTATUS init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
4705                               uint32 num_rids,
4706                               uint32 *rid, uint32 *type,
4707                               NTSTATUS status)
4708 {
4709         DEBUG(5, ("init_samr_r_lookup_names\n"));
4710
4711         if (NT_STATUS_IS_OK(status) && (num_rids != 0)) {
4712                 uint32 i;
4713
4714                 r_u->num_types1 = num_rids;
4715                 r_u->ptr_types = 1;
4716                 r_u->num_types2 = num_rids;
4717
4718                 r_u->num_rids1 = num_rids;
4719                 r_u->ptr_rids = 1;
4720                 r_u->num_rids2 = num_rids;
4721
4722                 if (!(r_u->rids = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids)))
4723                         return NT_STATUS_NO_MEMORY;
4724                 if (!(r_u->types = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids)))
4725                         return NT_STATUS_NO_MEMORY;
4726
4727                 if (!r_u->rids || !r_u->types)
4728                         goto empty;
4729
4730                 for (i = 0; i < num_rids; i++) {
4731                         r_u->rids[i] = rid[i];
4732                         r_u->types[i] = type[i];
4733                 }
4734         } else {
4735
4736   empty:
4737                 r_u->num_types1 = 0;
4738                 r_u->ptr_types = 0;
4739                 r_u->num_types2 = 0;
4740
4741                 r_u->num_rids1 = 0;
4742                 r_u->ptr_rids = 0;
4743                 r_u->num_rids2 = 0;
4744
4745                 r_u->rids = NULL;
4746                 r_u->types = NULL;
4747         }
4748
4749         r_u->status = status;
4750
4751         return NT_STATUS_OK;
4752 }
4753
4754 /*******************************************************************
4755 reads or writes a structure.
4756 ********************************************************************/
4757
4758 BOOL samr_io_r_lookup_names(const char *desc, SAMR_R_LOOKUP_NAMES * r_u,
4759                             prs_struct *ps, int depth)
4760 {
4761         uint32 i;
4762         fstring tmp;
4763
4764         if (r_u == NULL)
4765                 return False;
4766
4767         prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
4768         depth++;
4769
4770         if (UNMARSHALLING(ps))
4771                 ZERO_STRUCTP(r_u);
4772
4773         if(!prs_align(ps))
4774                 return False;
4775
4776         if(!prs_uint32("num_rids1", ps, depth, &r_u->num_rids1))
4777                 return False;
4778         if(!prs_uint32("ptr_rids ", ps, depth, &r_u->ptr_rids))
4779                 return False;
4780
4781         if (r_u->ptr_rids != 0) {
4782                 if(!prs_uint32("num_rids2", ps, depth, &r_u->num_rids2))
4783                         return False;
4784
4785                 if (r_u->num_rids2 != r_u->num_rids1) {
4786                         /* RPC fault */
4787                         return False;
4788                 }
4789
4790                 if (UNMARSHALLING(ps))
4791                         r_u->rids = (uint32 *)prs_alloc_mem(ps, sizeof(uint32)*r_u->num_rids2);
4792
4793                 if (!r_u->rids) {
4794                         DEBUG(0, ("NULL rids in samr_io_r_lookup_names\n"));
4795                         return False;
4796                 }
4797
4798                 for (i = 0; i < r_u->num_rids2; i++) {
4799                         slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
4800                         if(!prs_uint32(tmp, ps, depth, &r_u->rids[i]))
4801                                 return False;
4802                 }
4803         }
4804
4805         if(!prs_uint32("num_types1", ps, depth, &r_u->num_types1))
4806                 return False;
4807         if(!prs_uint32("ptr_types ", ps, depth, &r_u->ptr_types))
4808                 return False;
4809
4810         if (r_u->ptr_types != 0) {
4811                 if(!prs_uint32("num_types2", ps, depth, &r_u->num_types2))
4812                         return False;
4813
4814                 if (r_u->num_types2 != r_u->num_types1) {
4815                         /* RPC fault */
4816                         return False;
4817                 }
4818
4819                 if (UNMARSHALLING(ps))
4820                         r_u->types = (uint32 *)prs_alloc_mem(ps, sizeof(uint32)*r_u->num_types2);
4821
4822                 if (!r_u->types) {
4823                         DEBUG(0, ("NULL types in samr_io_r_lookup_names\n"));
4824                         return False;
4825                 }
4826
4827                 for (i = 0; i < r_u->num_types2; i++) {
4828                         slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
4829                         if(!prs_uint32(tmp, ps, depth, &r_u->types[i]))
4830                                 return False;
4831                 }
4832         }
4833
4834         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4835                 return False;
4836
4837         return True;
4838 }
4839
4840 /*******************************************************************
4841 inits a SAMR_Q_DELETE_DOM_USER structure.
4842 ********************************************************************/
4843
4844 void init_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
4845                                  POLICY_HND *hnd)
4846 {
4847         DEBUG(5, ("init_samr_q_delete_dom_user\n"));
4848
4849         q_c->user_pol = *hnd;
4850 }
4851
4852 /*******************************************************************
4853 reads or writes a structure.
4854 ********************************************************************/
4855
4856 BOOL samr_io_q_delete_dom_user(const char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
4857                                prs_struct *ps, int depth)
4858 {
4859         if (q_u == NULL)
4860                 return False;
4861
4862         prs_debug(ps, depth, desc, "samr_io_q_delete_dom_user");
4863         depth++;
4864
4865         if(!prs_align(ps))
4866                 return False;
4867
4868         if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
4869                 return False;
4870
4871         return True;
4872 }
4873
4874 /*******************************************************************
4875 reads or writes a structure.
4876 ********************************************************************/
4877
4878 BOOL samr_io_r_delete_dom_user(const char *desc, SAMR_R_DELETE_DOM_USER * r_u,
4879                                prs_struct *ps, int depth)
4880 {
4881         if (r_u == NULL)
4882                 return False;
4883
4884         prs_debug(ps, depth, desc, "samr_io_r_delete_dom_user");
4885         depth++;
4886
4887         if(!prs_align(ps))
4888                 return False;
4889
4890         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
4891                 return False;
4892         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4893                 return False;
4894
4895         return True;
4896 }
4897
4898 /*******************************************************************
4899 reads or writes a structure.
4900 ********************************************************************/
4901
4902 void init_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
4903                            POLICY_HND *pol,
4904                            uint32 access_mask, uint32 rid)
4905 {
4906         DEBUG(5, ("samr_init_samr_q_open_user\n"));
4907
4908         q_u->domain_pol = *pol;
4909         q_u->access_mask = access_mask;
4910         q_u->user_rid = rid;
4911 }
4912
4913 /*******************************************************************
4914 reads or writes a structure.
4915 ********************************************************************/
4916
4917 BOOL samr_io_q_open_user(const char *desc, SAMR_Q_OPEN_USER * q_u,
4918                          prs_struct *ps, int depth)
4919 {
4920         if (q_u == NULL)
4921                 return False;
4922
4923         prs_debug(ps, depth, desc, "samr_io_q_open_user");
4924         depth++;
4925
4926         if(!prs_align(ps))
4927                 return False;
4928
4929         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
4930                 return False;
4931
4932         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
4933                 return False;
4934         if(!prs_uint32("user_rid ", ps, depth, &q_u->user_rid))
4935                 return False;
4936
4937         return True;
4938 }
4939
4940 /*******************************************************************
4941 reads or writes a structure.
4942 ********************************************************************/
4943
4944 BOOL samr_io_r_open_user(const char *desc, SAMR_R_OPEN_USER * r_u,
4945                          prs_struct *ps, int depth)
4946 {
4947         if (r_u == NULL)
4948                 return False;
4949
4950         prs_debug(ps, depth, desc, "samr_io_r_open_user");
4951         depth++;
4952
4953         if(!prs_align(ps))
4954                 return False;
4955
4956         if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
4957                 return False;
4958
4959         if(!prs_ntstatus("status", ps, depth, &r_u->status))
4960                 return False;
4961
4962         return True;
4963 }
4964
4965
4966 /*******************************************************************
4967 reads or writes a structure.
4968 ********************************************************************/
4969
4970 void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
4971                              POLICY_HND *pol,
4972                              const char *name,
4973                              uint32 acb_info, uint32 access_mask)
4974 {
4975         DEBUG(5, ("samr_init_samr_q_create_user\n"));
4976
4977         q_u->domain_pol = *pol;
4978
4979         init_unistr2(&q_u->uni_name, name, UNI_FLAGS_NONE);
4980         init_uni_hdr(&q_u->hdr_name, &q_u->uni_name);
4981
4982         q_u->acb_info = acb_info;
4983         q_u->access_mask = access_mask;
4984 }
4985
4986 /*******************************************************************
4987 reads or writes a structure.
4988 ********************************************************************/
4989
4990 BOOL samr_io_q_create_user(const char *desc, SAMR_Q_CREATE_USER * q_u,
4991                            prs_struct *ps, int depth)
4992 {
4993         if (q_u == NULL)
4994                 return False;
4995
4996         prs_debug(ps, depth, desc, "samr_io_q_create_user");
4997         depth++;
4998
4999         if(!prs_align(ps))
5000                 return False;
5001
5002         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
5003                 return False;
5004
5005         if(!smb_io_unihdr("hdr_name", &q_u->hdr_name, ps, depth))
5006                 return False;
5007         if(!smb_io_unistr2("uni_name", &q_u->uni_name, q_u->hdr_name.buffer, ps, depth))
5008                 return False;
5009
5010         if(!prs_align(ps))
5011                 return False;
5012         if(!prs_uint32("acb_info   ", ps, depth, &q_u->acb_info))
5013                 return False;
5014         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
5015                 return False;
5016
5017         return True;
5018 }
5019
5020 /*******************************************************************
5021 reads or writes a structure.
5022 ********************************************************************/
5023
5024 BOOL samr_io_r_create_user(const char *desc, SAMR_R_CREATE_USER * r_u,
5025                            prs_struct *ps, int depth)
5026 {
5027         if (r_u == NULL)
5028                 return False;
5029
5030         prs_debug(ps, depth, desc, "samr_io_r_create_user");
5031         depth++;
5032
5033         if(!prs_align(ps))
5034                 return False;
5035
5036         if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
5037                 return False;
5038
5039         if(!prs_uint32("access_granted", ps, depth, &r_u->access_granted))
5040                 return False;
5041         if(!prs_uint32("user_rid ", ps, depth, &r_u->user_rid))
5042                 return False;
5043         if(!prs_ntstatus("status", ps, depth, &r_u->status))
5044                 return False;
5045
5046         return True;
5047 }
5048
5049 /*******************************************************************
5050 inits a SAMR_Q_QUERY_USERINFO structure.
5051 ********************************************************************/
5052
5053 void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
5054                                 POLICY_HND *hnd, uint16 switch_value)
5055 {
5056         DEBUG(5, ("init_samr_q_query_userinfo\n"));
5057
5058         q_u->pol = *hnd;
5059         q_u->switch_value = switch_value;
5060 }
5061
5062 /*******************************************************************
5063 reads or writes a structure.
5064 ********************************************************************/
5065
5066 BOOL samr_io_q_query_userinfo(const char *desc, SAMR_Q_QUERY_USERINFO * q_u,
5067                               prs_struct *ps, int depth)
5068 {
5069         if (q_u == NULL)
5070                 return False;
5071
5072         prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
5073         depth++;
5074
5075         if(!prs_align(ps))
5076                 return False;
5077
5078         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
5079                 return False;
5080
5081         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value)) /* 0x0015 or 0x0011 */
5082                 return False;
5083
5084         return True;
5085 }
5086
5087 /*******************************************************************
5088 reads or writes a LOGON_HRS structure.
5089 ********************************************************************/
5090
5091 static BOOL sam_io_logon_hrs(const char *desc, LOGON_HRS * hrs,
5092                              prs_struct *ps, int depth)
5093 {
5094         if (hrs == NULL)
5095                 return False;
5096
5097         prs_debug(ps, depth, desc, "sam_io_logon_hrs");
5098         depth++;
5099
5100         if(!prs_align(ps))
5101                 return False;
5102
5103         if(!prs_uint32("len  ", ps, depth, &hrs->len))
5104                 return False;
5105
5106         if (hrs->len > sizeof(hrs->hours)) {
5107                 DEBUG(3, ("sam_io_logon_hrs: truncating length from %d\n", hrs->len));
5108                 hrs->len = sizeof(hrs->hours);
5109         }
5110
5111         if(!prs_uint8s(False, "hours", ps, depth, hrs->hours, hrs->len))
5112                 return False;
5113
5114         return True;
5115 }
5116
5117 /*******************************************************************
5118 inits a SAM_USER_INFO_12 structure.
5119 ********************************************************************/
5120
5121 void init_sam_user_info12(SAM_USER_INFO_12 * usr,
5122                           const uint8 lm_pwd[16], const uint8 nt_pwd[16])
5123 {
5124         DEBUG(5, ("init_sam_user_info12\n"));
5125
5126         usr->lm_pwd_active =
5127                 memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd)) ? 1 : 0;
5128         usr->nt_pwd_active =
5129                 memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd)) ? 1 : 0;
5130 }
5131
5132 /*******************************************************************
5133 reads or writes a structure.
5134 ********************************************************************/
5135
5136 static BOOL sam_io_user_info12(const char *desc, SAM_USER_INFO_12 * u,
5137                         prs_struct *ps, int depth)
5138 {
5139         if (u == NULL)
5140                 return False;
5141
5142         prs_debug(ps, depth, desc, "samr_io_r_user_info12");
5143         depth++;
5144
5145         if(!prs_align(ps))
5146                 return False;
5147
5148         if(!prs_uint8s(False, "lm_pwd", ps, depth, u->lm_pwd, sizeof(u->lm_pwd)))
5149                 return False;
5150         if(!prs_uint8s(False, "nt_pwd", ps, depth, u->nt_pwd, sizeof(u->nt_pwd)))
5151                 return False;
5152
5153         if(!prs_uint8("lm_pwd_active", ps, depth, &u->lm_pwd_active))
5154                 return False;
5155         if(!prs_uint8("nt_pwd_active", ps, depth, &u->nt_pwd_active))
5156                 return False;
5157
5158         return True;
5159 }
5160
5161 /*******************************************************************
5162 inits a SAM_USER_INFO_10 structure.
5163 ********************************************************************/
5164
5165 void init_sam_user_info10(SAM_USER_INFO_10 * usr, uint32 acb_info)
5166 {
5167         DEBUG(5, ("init_sam_user_info10\n"));
5168
5169         usr->acb_info = acb_info;
5170 }
5171
5172 /*******************************************************************
5173 reads or writes a structure.
5174 ********************************************************************/
5175
5176 static BOOL sam_io_user_info10(const char *desc, SAM_USER_INFO_10 * usr,
5177                         prs_struct *ps, int depth)
5178 {
5179         if (usr == NULL)
5180                 return False;
5181
5182         prs_debug(ps, depth, desc, "samr_io_r_user_info10");
5183         depth++;
5184
5185         if(!prs_align(ps))
5186                 return False;
5187
5188         if(!prs_uint32("acb_info", ps, depth, &usr->acb_info))
5189                 return False;
5190
5191         return True;
5192 }
5193
5194 /*******************************************************************
5195 inits a SAM_USER_INFO_11 structure.
5196 ********************************************************************/
5197
5198 void init_sam_user_info11(SAM_USER_INFO_11 * usr,
5199                           NTTIME * expiry,
5200                           char *mach_acct,
5201                           uint32 rid_user, uint32 rid_group, uint16 acct_ctrl)
5202 {
5203         DEBUG(5, ("init_sam_user_info11\n"));
5204
5205         memcpy(&usr->expiry, expiry, sizeof(usr->expiry));      /* expiry time or something? */
5206         ZERO_STRUCT(usr->padding_1);    /* 0 - padding 24 bytes */
5207
5208         usr->padding_2 = 0;     /* 0 - padding 4 bytes */
5209
5210         usr->ptr_1 = 1;         /* pointer */
5211         ZERO_STRUCT(usr->padding_3);    /* 0 - padding 32 bytes */
5212         usr->padding_4 = 0;     /* 0 - padding 4 bytes */
5213
5214         usr->ptr_2 = 1;         /* pointer */
5215         usr->padding_5 = 0;     /* 0 - padding 4 bytes */
5216
5217         usr->ptr_3 = 1;         /* pointer */
5218         ZERO_STRUCT(usr->padding_6);    /* 0 - padding 32 bytes */
5219
5220         usr->rid_user = rid_user;
5221         usr->rid_group = rid_group;
5222
5223         usr->acct_ctrl = acct_ctrl;
5224         usr->unknown_3 = 0x0000;
5225
5226         usr->unknown_4 = 0x003f;        /* 0x003f      - 16 bit unknown */
5227         usr->unknown_5 = 0x003c;        /* 0x003c      - 16 bit unknown */
5228
5229         ZERO_STRUCT(usr->padding_7);    /* 0 - padding 16 bytes */
5230         usr->padding_8 = 0;     /* 0 - padding 4 bytes */
5231
5232         init_unistr2(&usr->uni_mach_acct, mach_acct, UNI_FLAGS_NONE);   /* unicode string for machine account */
5233         init_uni_hdr(&usr->hdr_mach_acct, &usr->uni_mach_acct); /* unicode header for machine account */
5234 }
5235
5236 /*******************************************************************
5237 reads or writes a structure.
5238 ********************************************************************/
5239
5240 static BOOL sam_io_user_info11(const char *desc, SAM_USER_INFO_11 * usr,
5241                         prs_struct *ps, int depth)
5242 {
5243         if (usr == NULL)
5244                 return False;
5245
5246         prs_debug(ps, depth, desc, "samr_io_r_unknown_11");
5247         depth++;
5248
5249         if(!prs_align(ps))
5250                 return False;
5251
5252         if(!prs_uint8s(False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0)))
5253                 return False;
5254
5255         if(!smb_io_time("time", &usr->expiry, ps, depth))
5256                 return False;
5257
5258         if(!prs_uint8s(False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1)))
5259                 return False;
5260
5261         if(!smb_io_unihdr("unihdr", &usr->hdr_mach_acct, ps, depth))
5262                 return False;
5263
5264         if(!prs_uint32("padding_2", ps, depth, &usr->padding_2))
5265                 return False;
5266
5267         if(!prs_uint32("ptr_1    ", ps, depth, &usr->ptr_1))
5268                 return False;
5269         if(!prs_uint8s(False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3)))
5270                 return False;
5271
5272         if(!prs_uint32("padding_4", ps, depth, &usr->padding_4))
5273                 return False;
5274
5275         if(!prs_uint32("ptr_2    ", ps, depth, &usr->ptr_2))
5276                 return False;
5277         if(!prs_uint32("padding_5", ps, depth, &usr->padding_5))
5278                 return False;
5279
5280         if(!prs_uint32("ptr_3    ", ps, depth, &usr->ptr_3))
5281                 return False;
5282         if(!prs_uint8s(False, "padding_6", ps, depth, usr->padding_6,sizeof(usr->padding_6)))
5283                 return False;
5284
5285         if(!prs_uint32("rid_user ", ps, depth, &usr->rid_user))
5286                 return False;
5287         if(!prs_uint32("rid_group", ps, depth, &usr->rid_group))
5288                 return False;
5289         if(!prs_uint16("acct_ctrl", ps, depth, &usr->acct_ctrl))
5290                 return False;
5291         if(!prs_uint16("unknown_3", ps, depth, &usr->unknown_3))
5292                 return False;
5293         if(!prs_uint16("unknown_4", ps, depth, &usr->unknown_4))
5294                 return False;
5295         if(!prs_uint16("unknown_5", ps, depth, &usr->unknown_5))
5296                 return False;
5297
5298         if(!prs_uint8s(False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7)))
5299                 return False;
5300
5301         if(!prs_uint32("padding_8", ps, depth, &(usr->padding_8)))
5302                 return False;
5303
5304         if(!smb_io_unistr2("unistr2", &usr->uni_mach_acct, True, ps, depth))
5305                 return False;
5306
5307         if(!prs_align(ps))
5308                 return False;
5309
5310         if(!prs_uint8s(False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9)))
5311                 return False;
5312
5313         return True;
5314 }
5315
5316 /*************************************************************************
5317  init_sam_user_infoa
5318
5319  unknown_3 = 0x09f8 27fa
5320  unknown_5 = 0x0001 0000
5321  unknown_6 = 0x0000 04ec 
5322
5323  *************************************************************************/
5324
5325 void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len)
5326 {
5327         DEBUG(10, ("init_sam_user_info24:\n"));
5328         memcpy(usr->pass, newpass, sizeof(usr->pass));
5329         usr->pw_len = pw_len;
5330 }
5331
5332 /*******************************************************************
5333 reads or writes a structure.
5334 ********************************************************************/
5335
5336 static BOOL sam_io_user_info24(const char *desc, SAM_USER_INFO_24 * usr,
5337                                prs_struct *ps, int depth)
5338 {
5339         if (usr == NULL)
5340                 return False;
5341
5342         prs_debug(ps, depth, desc, "sam_io_user_info24");
5343         depth++;
5344
5345         if(!prs_align(ps))
5346                 return False;
5347
5348         if(!prs_uint8s(False, "password", ps, depth, usr->pass, 
5349                        sizeof(usr->pass)))
5350                 return False;
5351         
5352         if (MARSHALLING(ps) && (usr->pw_len != 0)) {
5353                 if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
5354                         return False;
5355         }
5356         if(!prs_align(ps))
5357                 return False;
5358
5359         return True;
5360 }
5361
5362 /*************************************************************************
5363  init_sam_user_info23
5364
5365  unknown_3 = 0x09f8 27fa
5366  unknown_6 = 0x0000 04ec 
5367
5368  *************************************************************************/
5369
5370 void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all zeros */
5371                         NTTIME * logoff_time,   /* all zeros */
5372                         NTTIME * kickoff_time,  /* all zeros */
5373                         NTTIME * pass_last_set_time,    /* all zeros */
5374                         NTTIME * pass_can_change_time,  /* all zeros */
5375                         NTTIME * pass_must_change_time, /* all zeros */
5376                         UNISTR2 *user_name,
5377                         UNISTR2 *full_name,
5378                         UNISTR2 *home_dir,
5379                         UNISTR2 *dir_drive,
5380                         UNISTR2 *log_scr,
5381                         UNISTR2 *prof_path,
5382                         UNISTR2 *desc,
5383                         UNISTR2 *wkstas,
5384                         UNISTR2 *unk_str,
5385                         UNISTR2 *mung_dial,
5386                         uint32 user_rid,        /* 0x0000 0000 */
5387                         uint32 group_rid,
5388                         uint32 acb_info,
5389                         uint32 unknown_3,
5390                         uint16 logon_divs,
5391                         LOGON_HRS * hrs,
5392                         uint16 bad_password_count,
5393                         uint16 logon_count,
5394                         char newpass[516], uint32 unknown_6)
5395 {
5396         usr->logon_time = *logon_time;  /* all zeros */
5397         usr->logoff_time = *logoff_time;        /* all zeros */
5398         usr->kickoff_time = *kickoff_time;      /* all zeros */
5399         usr->pass_last_set_time = *pass_last_set_time;  /* all zeros */
5400         usr->pass_can_change_time = *pass_can_change_time;      /* all zeros */
5401         usr->pass_must_change_time = *pass_must_change_time;    /* all zeros */
5402
5403         ZERO_STRUCT(usr->nt_pwd);
5404         ZERO_STRUCT(usr->lm_pwd);
5405
5406         usr->user_rid = user_rid;       /* 0x0000 0000 */
5407         usr->group_rid = group_rid;
5408         usr->acb_info = acb_info;
5409         usr->unknown_3 = unknown_3;     /* 09f8 27fa */
5410
5411         usr->logon_divs = logon_divs;   /* should be 168 (hours/week) */
5412         usr->ptr_logon_hrs = hrs ? 1 : 0;
5413
5414         if (nt_time_is_zero(pass_must_change_time)) {
5415                 usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
5416         } else {
5417                 usr->passmustchange=0;
5418         }
5419
5420         ZERO_STRUCT(usr->padding1);
5421         ZERO_STRUCT(usr->padding2);
5422
5423         usr->bad_password_count = bad_password_count;
5424         usr->logon_count = logon_count;
5425
5426         memcpy(usr->pass, newpass, sizeof(usr->pass));
5427
5428         copy_unistr2(&usr->uni_user_name, user_name);
5429         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
5430
5431         copy_unistr2(&usr->uni_full_name, full_name);
5432         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
5433
5434         copy_unistr2(&usr->uni_home_dir, home_dir);
5435         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
5436
5437         copy_unistr2(&usr->uni_dir_drive, dir_drive);
5438         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
5439
5440         copy_unistr2(&usr->uni_logon_script, log_scr);
5441         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
5442
5443         copy_unistr2(&usr->uni_profile_path, prof_path);
5444         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
5445
5446         copy_unistr2(&usr->uni_acct_desc, desc);
5447         init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
5448
5449         copy_unistr2(&usr->uni_workstations, wkstas);
5450         init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
5451
5452         copy_unistr2(&usr->uni_unknown_str, unk_str);
5453         init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
5454
5455         copy_unistr2(&usr->uni_munged_dial, mung_dial);
5456         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
5457
5458         usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
5459         usr->padding4 = 0;
5460
5461         memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
5462 }
5463
5464 /*************************************************************************
5465  init_sam_user_info23
5466
5467  unknown_3 = 0x09f8 27fa
5468  unknown_6 = 0x0000 04ec 
5469
5470  *************************************************************************/
5471
5472 void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all zeros */
5473                            NTTIME * logoff_time,        /* all zeros */
5474                            NTTIME * kickoff_time,       /* all zeros */
5475                            NTTIME * pass_last_set_time, /* all zeros */
5476                            NTTIME * pass_can_change_time,       /* all zeros */
5477                            NTTIME * pass_must_change_time,      /* all zeros */
5478                            char *user_name,     /* NULL */
5479                            char *full_name,
5480                            char *home_dir, char *dir_drive, char *log_scr,
5481                            char *prof_path, const char *desc, char *wkstas,
5482                            char *unk_str, char *mung_dial, uint32 user_rid,     /* 0x0000 0000 */
5483                            uint32 group_rid, uint32 acb_info,
5484                            uint32 unknown_3, uint16 logon_divs,
5485                            LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count,
5486                            char newpass[516], uint32 unknown_6)
5487 {
5488         DATA_BLOB blob = base64_decode_data_blob(mung_dial);
5489         
5490         usr->logon_time = *logon_time;  /* all zeros */
5491         usr->logoff_time = *logoff_time;        /* all zeros */
5492         usr->kickoff_time = *kickoff_time;      /* all zeros */
5493         usr->pass_last_set_time = *pass_last_set_time;  /* all zeros */
5494         usr->pass_can_change_time = *pass_can_change_time;      /* all zeros */
5495         usr->pass_must_change_time = *pass_must_change_time;    /* all zeros */
5496
5497         ZERO_STRUCT(usr->nt_pwd);
5498         ZERO_STRUCT(usr->lm_pwd);
5499
5500         usr->user_rid = user_rid;       /* 0x0000 0000 */
5501         usr->group_rid = group_rid;
5502         usr->acb_info = acb_info;
5503         usr->unknown_3 = unknown_3;     /* 09f8 27fa */
5504
5505         usr->logon_divs = logon_divs;   /* should be 168 (hours/week) */
5506         usr->ptr_logon_hrs = hrs ? 1 : 0;
5507
5508         if (nt_time_is_zero(pass_must_change_time)) {
5509                 usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
5510         } else {
5511                 usr->passmustchange=0;
5512         }
5513
5514         ZERO_STRUCT(usr->padding1);
5515         ZERO_STRUCT(usr->padding2);
5516
5517         usr->bad_password_count = bad_password_count;
5518         usr->logon_count = logon_count;
5519
5520         memcpy(usr->pass, newpass, sizeof(usr->pass));
5521
5522         init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
5523         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
5524
5525         init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
5526         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
5527
5528         init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
5529         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
5530
5531         init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
5532         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
5533
5534         init_unistr2(&usr->uni_logon_script, log_scr, UNI_FLAGS_NONE);
5535         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
5536
5537         init_unistr2(&usr->uni_profile_path, prof_path, UNI_FLAGS_NONE);
5538         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
5539
5540         init_unistr2(&usr->uni_acct_desc, desc, UNI_FLAGS_NONE);
5541         init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
5542
5543         init_unistr2(&usr->uni_workstations, wkstas, UNI_FLAGS_NONE);
5544         init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
5545
5546         init_unistr2(&usr->uni_unknown_str, unk_str, UNI_FLAGS_NONE);
5547         init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
5548
5549         init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
5550         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
5551
5552         data_blob_free(&blob);
5553         
5554         usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
5555         usr->padding4 = 0;
5556
5557         memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
5558 }
5559
5560 /*******************************************************************
5561 reads or writes a structure.
5562 ********************************************************************/
5563
5564 static BOOL sam_io_user_info23(const char *desc, SAM_USER_INFO_23 * usr,
5565                                prs_struct *ps, int depth)
5566 {
5567         if (usr == NULL)
5568                 return False;
5569
5570         prs_debug(ps, depth, desc, "sam_io_user_info23");
5571         depth++;
5572
5573         if(!prs_align(ps))
5574                 return False;
5575
5576         if(!smb_io_time("logon_time           ", &usr->logon_time, ps, depth))
5577                 return False;
5578         if(!smb_io_time("logoff_time          ", &usr->logoff_time, ps, depth))
5579                 return False;
5580         if(!smb_io_time("kickoff_time         ", &usr->kickoff_time, ps, depth))
5581                 return False;
5582         if(!smb_io_time("pass_last_set_time   ", &usr->pass_last_set_time, ps, depth))
5583                 return False;
5584         if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth))
5585                 return False;
5586         if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth))
5587                 return False;
5588
5589         if(!smb_io_unihdr("hdr_user_name   ", &usr->hdr_user_name, ps, depth))  /* username unicode string header */
5590                 return False;
5591         if(!smb_io_unihdr("hdr_full_name   ", &usr->hdr_full_name, ps, depth))  /* user's full name unicode string header */
5592                 return False;
5593         if(!smb_io_unihdr("hdr_home_dir    ", &usr->hdr_home_dir, ps, depth))   /* home directory unicode string header */
5594                 return False;
5595         if(!smb_io_unihdr("hdr_dir_drive   ", &usr->hdr_dir_drive, ps, depth))  /* home directory drive */
5596                 return False;
5597         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth))       /* logon script unicode string header */
5598                 return False;
5599         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth))       /* profile path unicode string header */
5600                 return False;
5601         if(!smb_io_unihdr("hdr_acct_desc   ", &usr->hdr_acct_desc, ps, depth))  /* account desc */
5602                 return False;
5603         if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth))       /* wkstas user can log on from */
5604                 return False;
5605         if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth))        /* unknown string */
5606                 return False;
5607         if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth))        /* wkstas user can log on from */
5608                 return False;
5609
5610         if(!prs_uint8s(False, "lm_pwd        ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
5611                 return False;
5612         if(!prs_uint8s(False, "nt_pwd        ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
5613                 return False;
5614
5615         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))    /* User ID */
5616                 return False;
5617         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))   /* Group ID */
5618                 return False;
5619         if(!prs_uint32("acb_info      ", ps, depth, &usr->acb_info))
5620                 return False;
5621
5622         if(!prs_uint32("unknown_3     ", ps, depth, &usr->unknown_3))
5623                 return False;
5624         if(!prs_uint16("logon_divs    ", ps, depth, &usr->logon_divs))  /* logon divisions per week */
5625                 return False;
5626         if(!prs_align(ps))
5627                 return False;
5628         if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
5629                 return False;
5630
5631         if(!prs_uint16("bad_password_count     ", ps, depth, &usr->bad_password_count))
5632                 return False;
5633         if(!prs_uint16("logon_count     ", ps, depth, &usr->logon_count))
5634                 return False;
5635
5636         if(!prs_uint8s(False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1)))
5637                 return False;
5638         if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
5639                 return False;
5640         if(!prs_uint8("padding2       ", ps, depth, &usr->padding2))
5641                 return False;
5642
5643
5644         if(!prs_uint8s(False, "password      ", ps, depth, usr->pass, sizeof(usr->pass)))
5645                 return False;
5646
5647         /* here begins pointed-to data */
5648
5649         if(!smb_io_unistr2("uni_user_name   ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth))      /* username unicode string */
5650                 return False;
5651
5652         if(!smb_io_unistr2("uni_full_name   ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth))      /* user's full name unicode string */
5653                 return False;
5654
5655         if(!smb_io_unistr2("uni_home_dir    ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth))        /* home directory unicode string */
5656                 return False;
5657
5658         if(!smb_io_unistr2("uni_dir_drive   ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth))      /* home directory drive unicode string */
5659                 return False;
5660
5661         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth))        /* logon script unicode string */
5662                 return False;
5663
5664         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth))        /* profile path unicode string */
5665                 return False;
5666
5667         if(!smb_io_unistr2("uni_acct_desc   ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth))      /* user desc unicode string */
5668                 return False;
5669
5670         if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth))        /* worksations user can log on from */
5671                 return False;
5672
5673         if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth))  /* unknown string */
5674                 return False;
5675
5676         if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))
5677                 return False;
5678
5679         /* ok, this is only guess-work (as usual) */
5680         if (usr->ptr_logon_hrs) {
5681                 if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
5682                         return False;
5683                 if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
5684                         return False;
5685                 if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
5686                         return False;
5687         } else if (UNMARSHALLING(ps)) {
5688                 usr->unknown_6 = 0;
5689                 usr->padding4 = 0;
5690         }
5691
5692         return True;
5693 }
5694
5695 /*******************************************************************
5696  reads or writes a structure.
5697  NB. This structure is *definately* incorrect. It's my best guess
5698  currently for W2K SP2. The password field is encrypted in a different
5699  way than normal... And there are definately other problems. JRA.
5700 ********************************************************************/
5701
5702 static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_struct *ps, int depth)
5703 {
5704         if (usr == NULL)
5705                 return False;
5706
5707         prs_debug(ps, depth, desc, "sam_io_user_info25");
5708         depth++;
5709
5710         if(!prs_align(ps))
5711                 return False;
5712
5713         if(!smb_io_time("logon_time           ", &usr->logon_time, ps, depth))
5714                 return False;
5715         if(!smb_io_time("logoff_time          ", &usr->logoff_time, ps, depth))
5716                 return False;
5717         if(!smb_io_time("kickoff_time         ", &usr->kickoff_time, ps, depth))
5718                 return False;
5719         if(!smb_io_time("pass_last_set_time   ", &usr->pass_last_set_time, ps, depth))
5720                 return False;
5721         if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth))
5722                 return False;
5723         if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth))
5724                 return False;
5725
5726         if(!smb_io_unihdr("hdr_user_name   ", &usr->hdr_user_name, ps, depth))  /* username unicode string header */
5727                 return False;
5728         if(!smb_io_unihdr("hdr_full_name   ", &usr->hdr_full_name, ps, depth))  /* user's full name unicode string header */
5729                 return False;
5730         if(!smb_io_unihdr("hdr_home_dir    ", &usr->hdr_home_dir, ps, depth))   /* home directory unicode string header */
5731                 return False;
5732         if(!smb_io_unihdr("hdr_dir_drive   ", &usr->hdr_dir_drive, ps, depth))  /* home directory drive */
5733                 return False;
5734         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth))       /* logon script unicode string header */
5735                 return False;
5736         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth))       /* profile path unicode string header */
5737                 return False;
5738         if(!smb_io_unihdr("hdr_acct_desc   ", &usr->hdr_acct_desc, ps, depth))  /* account desc */
5739                 return False;
5740         if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth))       /* wkstas user can log on from */
5741                 return False;
5742         if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth))        /* unknown string */
5743                 return False;
5744         if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth))        /* wkstas user can log on from */
5745                 return False;
5746
5747         if(!prs_uint8s(False, "lm_pwd        ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
5748                 return False;
5749         if(!prs_uint8s(False, "nt_pwd        ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
5750                 return False;
5751
5752         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))    /* User ID */
5753                 return False;
5754         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))   /* Group ID */
5755                 return False;
5756         if(!prs_uint32("acb_info      ", ps, depth, &usr->acb_info))
5757                 return False;
5758
5759         if(!prs_uint32s(False, "unknown_6      ", ps, depth, usr->unknown_6, 6))
5760                 return False;
5761
5762         if(!prs_uint8s(False, "password      ", ps, depth, usr->pass, sizeof(usr->pass)))
5763                 return False;
5764
5765         /* here begins pointed-to data */
5766
5767         if(!smb_io_unistr2("uni_user_name   ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth))      /* username unicode string */
5768                 return False;
5769
5770         if(!smb_io_unistr2("uni_full_name   ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth))      /* user's full name unicode string */
5771                 return False;
5772
5773         if(!smb_io_unistr2("uni_home_dir    ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth))        /* home directory unicode string */
5774                 return False;
5775
5776         if(!smb_io_unistr2("uni_dir_drive   ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth))      /* home directory drive unicode string */
5777                 return False;
5778
5779         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth))        /* logon script unicode string */
5780                 return False;
5781
5782         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth))        /* profile path unicode string */
5783                 return False;
5784
5785         if(!smb_io_unistr2("uni_acct_desc   ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth))      /* user desc unicode string */
5786                 return False;
5787
5788         if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth))        /* worksations user can log on from */
5789                 return False;
5790
5791         if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth))  /* unknown string */
5792                 return False;
5793
5794         if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))
5795                 return False;
5796
5797 #if 0 /* JRA - unknown... */
5798         /* ok, this is only guess-work (as usual) */
5799         if (usr->ptr_logon_hrs) {
5800                 if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
5801                         return False;
5802                 if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
5803                         return False;
5804                 if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
5805                         return False;
5806         } else if (UNMARSHALLING(ps)) {
5807                 usr->unknown_6 = 0;
5808                 usr->padding4 = 0;
5809         }
5810 #endif
5811
5812         return True;
5813 }
5814
5815
5816 /*************************************************************************
5817  init_sam_user_info21W
5818
5819  unknown_3 = 0x00ff ffff
5820  unknown_6 = 0x0000 04ec 
5821
5822  *************************************************************************/
5823
5824 void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
5825                            NTTIME * logon_time,
5826                            NTTIME * logoff_time,
5827                            NTTIME * kickoff_time,
5828                            NTTIME * pass_last_set_time,
5829                            NTTIME * pass_can_change_time,
5830                            NTTIME * pass_must_change_time,
5831                            UNISTR2 *user_name,
5832                            UNISTR2 *full_name,
5833                            UNISTR2 *home_dir,
5834                            UNISTR2 *dir_drive,
5835                            UNISTR2 *log_scr,
5836                            UNISTR2 *prof_path,
5837                            UNISTR2 *desc,
5838                            UNISTR2 *wkstas,
5839                            UNISTR2 *unk_str,
5840                            UNISTR2 *mung_dial,
5841                            uchar lm_pwd[16],
5842                            uchar nt_pwd[16],
5843                            uint32 user_rid,
5844                            uint32 group_rid,
5845                            uint32 acb_info,
5846                            uint32 unknown_3,
5847                            uint16 logon_divs,
5848                            LOGON_HRS * hrs,
5849                            uint16 bad_password_count,
5850                            uint16 logon_count,
5851                            uint32 unknown_6)
5852 {
5853         usr->logon_time = *logon_time;
5854         usr->logoff_time = *logoff_time;
5855         usr->kickoff_time = *kickoff_time;
5856         usr->pass_last_set_time = *pass_last_set_time;
5857         usr->pass_can_change_time = *pass_can_change_time;
5858         usr->pass_must_change_time = *pass_must_change_time;
5859
5860         memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
5861         memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
5862
5863         usr->user_rid = user_rid;
5864         usr->group_rid = group_rid;
5865         usr->acb_info = acb_info;
5866         usr->unknown_3 = unknown_3;     /* 0x00ff ffff */
5867
5868         usr->logon_divs = logon_divs;   /* should be 168 (hours/week) */
5869         usr->ptr_logon_hrs = hrs ? 1 : 0;
5870         usr->bad_password_count = bad_password_count;
5871         usr->logon_count = logon_count;
5872
5873         if (nt_time_is_zero(pass_must_change_time)) {
5874                 usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
5875         } else {
5876                 usr->passmustchange=0;
5877         }
5878
5879         ZERO_STRUCT(usr->padding1);
5880         ZERO_STRUCT(usr->padding2);
5881
5882         copy_unistr2(&usr->uni_user_name, user_name);
5883         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
5884
5885         copy_unistr2(&usr->uni_full_name, full_name);
5886         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
5887
5888         copy_unistr2(&usr->uni_home_dir, home_dir);
5889         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
5890
5891         copy_unistr2(&usr->uni_dir_drive, dir_drive);
5892         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
5893
5894         copy_unistr2(&usr->uni_logon_script, log_scr);
5895         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
5896
5897         copy_unistr2(&usr->uni_profile_path, prof_path);
5898         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
5899
5900         copy_unistr2(&usr->uni_acct_desc, desc);
5901         init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
5902
5903         copy_unistr2(&usr->uni_workstations, wkstas);
5904         init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
5905
5906         copy_unistr2(&usr->uni_unknown_str, unk_str);
5907         init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
5908
5909         copy_unistr2(&usr->uni_munged_dial, mung_dial);
5910         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
5911
5912         usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
5913         usr->padding4 = 0;
5914
5915         memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
5916 }
5917
5918 /*************************************************************************
5919  init_sam_user_info21
5920
5921  unknown_3 = 0x00ff ffff
5922  unknown_6 = 0x0000 04ec 
5923
5924  *************************************************************************/
5925
5926 NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *domain_sid)
5927 {
5928         NTTIME          logon_time, logoff_time, kickoff_time,
5929                         pass_last_set_time, pass_can_change_time,
5930                         pass_must_change_time;
5931                         
5932         const char*             user_name = pdb_get_username(pw);
5933         const char*             full_name = pdb_get_fullname(pw);
5934         const char*             home_dir  = pdb_get_homedir(pw);
5935         const char*             dir_drive = pdb_get_dir_drive(pw);
5936         const char*             logon_script = pdb_get_logon_script(pw);
5937         const char*             profile_path = pdb_get_profile_path(pw);
5938         const char*             description = pdb_get_acct_desc(pw);
5939         const char*             workstations = pdb_get_workstations(pw);
5940         const char*             munged_dial = pdb_get_munged_dial(pw);
5941         DATA_BLOB               munged_dial_blob;
5942
5943         uint32 user_rid;
5944         const DOM_SID *user_sid;
5945
5946         uint32 group_rid;
5947         const DOM_SID *group_sid;
5948
5949         if (munged_dial) {
5950                 munged_dial_blob = base64_decode_data_blob(munged_dial);
5951         } else {
5952                 munged_dial_blob = data_blob(NULL, 0);
5953         }
5954
5955         /* Create NTTIME structs */
5956         unix_to_nt_time (&logon_time,           pdb_get_logon_time(pw));
5957         unix_to_nt_time (&logoff_time,          pdb_get_logoff_time(pw));
5958         unix_to_nt_time (&kickoff_time,         pdb_get_kickoff_time(pw));
5959         unix_to_nt_time (&pass_last_set_time,   pdb_get_pass_last_set_time(pw));
5960         unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(pw));
5961         unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(pw));
5962         
5963         /* structure assignment */
5964         usr->logon_time            = logon_time;
5965         usr->logoff_time           = logoff_time;
5966         usr->kickoff_time          = kickoff_time;
5967         usr->pass_last_set_time    = pass_last_set_time;
5968         usr->pass_can_change_time  = pass_can_change_time;
5969         usr->pass_must_change_time = pass_must_change_time;
5970
5971         ZERO_STRUCT(usr->nt_pwd);
5972         ZERO_STRUCT(usr->lm_pwd);
5973
5974         user_sid = pdb_get_user_sid(pw);
5975         
5976         if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
5977                 fstring user_sid_string;
5978                 fstring domain_sid_string;
5979                 DEBUG(0, ("init_sam_user_info_21A: User %s has SID %s, \nwhich conflicts with "
5980                           "the domain sid %s.  Failing operation.\n", 
5981                           user_name, 
5982                           sid_to_string(user_sid_string, user_sid),
5983                           sid_to_string(domain_sid_string, domain_sid)));
5984                 data_blob_free(&munged_dial_blob);
5985                 return NT_STATUS_UNSUCCESSFUL;
5986         }
5987
5988         group_sid = pdb_get_group_sid(pw);
5989         
5990         if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
5991                 fstring group_sid_string;
5992                 fstring domain_sid_string;
5993                 DEBUG(0, ("init_sam_user_info_21A: User %s has Primary Group SID %s, \n"
5994                           "which conflicts with the domain sid %s.  Failing operation.\n", 
5995                           user_name, 
5996                           sid_to_string(group_sid_string, group_sid),
5997                           sid_to_string(domain_sid_string, domain_sid)));
5998                 data_blob_free(&munged_dial_blob);
5999                 return NT_STATUS_UNSUCCESSFUL;
6000         }
6001
6002         usr->user_rid  = user_rid;
6003         usr->group_rid = group_rid;
6004         usr->acb_info  = pdb_get_acct_ctrl(pw);
6005
6006         /*
6007           Look at a user on a real NT4 PDC with usrmgr, press
6008           'ok'. Then you will see that unknown_3 is set to
6009           0x08f827fa. Look at the user immediately after that again,
6010           and you will see that 0x00fffff is returned. This solves
6011           the problem that you get access denied after having looked
6012           at the user.
6013           -- Volker
6014         */
6015         usr->unknown_3 = 0x00ffffff;
6016
6017         usr->logon_divs = pdb_get_logon_divs(pw); 
6018         usr->ptr_logon_hrs = pdb_get_hours(pw) ? 1 : 0;
6019         usr->bad_password_count = pdb_get_bad_password_count(pw);
6020         usr->logon_count = pdb_get_logon_count(pw);
6021
6022         if (pdb_get_pass_must_change_time(pw) == 0) {
6023                 usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
6024         } else {
6025                 usr->passmustchange=0;
6026         }
6027
6028         ZERO_STRUCT(usr->padding1);
6029         ZERO_STRUCT(usr->padding2);
6030
6031         init_unistr2(&usr->uni_user_name, user_name, UNI_STR_TERMINATE);
6032         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
6033
6034         init_unistr2(&usr->uni_full_name, full_name, UNI_STR_TERMINATE);
6035         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
6036
6037         init_unistr2(&usr->uni_home_dir, home_dir, UNI_STR_TERMINATE);
6038         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
6039
6040         init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_STR_TERMINATE);
6041         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
6042
6043         init_unistr2(&usr->uni_logon_script, logon_script, UNI_STR_TERMINATE);
6044         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
6045
6046         init_unistr2(&usr->uni_profile_path, profile_path, UNI_STR_TERMINATE);
6047         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
6048
6049         init_unistr2(&usr->uni_acct_desc, description, UNI_STR_TERMINATE);
6050         init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
6051
6052         init_unistr2(&usr->uni_workstations, workstations, UNI_STR_TERMINATE);
6053         init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
6054
6055         init_unistr2(&usr->uni_unknown_str, NULL, UNI_STR_TERMINATE);
6056         init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
6057
6058         init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
6059         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
6060         data_blob_free(&munged_dial_blob);
6061
6062         usr->unknown_6 = pdb_get_unknown_6(pw);
6063         usr->padding4 = 0;
6064
6065         if (pdb_get_hours(pw)) {
6066                 usr->logon_hrs.len = pdb_get_hours_len(pw);
6067                 memcpy(&usr->logon_hrs.hours, pdb_get_hours(pw), MAX_HOURS_LEN);
6068         } else
6069                 memset(&usr->logon_hrs, 0xff, sizeof(usr->logon_hrs));
6070
6071         return NT_STATUS_OK;
6072 }
6073
6074 /*******************************************************************
6075 reads or writes a structure.
6076 ********************************************************************/
6077
6078 static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr,
6079                         prs_struct *ps, int depth)
6080 {
6081         if (usr == NULL)
6082                 return False;
6083
6084         prs_debug(ps, depth, desc, "sam_io_user_info21");
6085         depth++;
6086
6087         if(!prs_align(ps))
6088                 return False;
6089
6090         if(!smb_io_time("logon_time           ", &usr->logon_time, ps, depth))
6091                 return False;
6092         if(!smb_io_time("logoff_time          ", &usr->logoff_time, ps, depth))
6093                 return False;
6094         if(!smb_io_time("pass_last_set_time   ", &usr->pass_last_set_time, ps,depth))
6095                 return False;
6096         if(!smb_io_time("kickoff_time         ", &usr->kickoff_time, ps, depth))
6097                 return False;
6098         if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps,depth))
6099                 return False;
6100         if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time,  ps, depth))
6101                 return False;
6102
6103         if(!smb_io_unihdr("hdr_user_name   ", &usr->hdr_user_name, ps, depth))  /* username unicode string header */
6104                 return False;
6105         if(!smb_io_unihdr("hdr_full_name   ", &usr->hdr_full_name, ps, depth))  /* user's full name unicode string header */
6106                 return False;
6107         if(!smb_io_unihdr("hdr_home_dir    ", &usr->hdr_home_dir, ps, depth))   /* home directory unicode string header */
6108                 return False;
6109         if(!smb_io_unihdr("hdr_dir_drive   ", &usr->hdr_dir_drive, ps, depth))  /* home directory drive */
6110                 return False;
6111         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth))       /* logon script unicode string header */
6112                 return False;
6113         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth))       /* profile path unicode string header */
6114                 return False;
6115         if(!smb_io_unihdr("hdr_acct_desc   ", &usr->hdr_acct_desc, ps, depth))  /* account desc */
6116                 return False;
6117         if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth))       /* wkstas user can log on from */
6118                 return False;
6119         if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth))        /* unknown string */
6120                 return False;
6121         if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth))        /* wkstas user can log on from */
6122                 return False;
6123
6124         if(!prs_uint8s(False, "lm_pwd        ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
6125                 return False;
6126         if(!prs_uint8s(False, "nt_pwd        ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
6127                 return False;
6128
6129         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))    /* User ID */
6130                 return False;
6131         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))   /* Group ID */
6132                 return False;
6133         if(!prs_uint32("acb_info      ", ps, depth, &usr->acb_info))
6134                 return False;
6135
6136         if(!prs_uint32("unknown_3     ", ps, depth, &usr->unknown_3))
6137                 return False;
6138         if(!prs_uint16("logon_divs    ", ps, depth, &usr->logon_divs))  /* logon divisions per week */
6139                 return False;
6140         if(!prs_align(ps))
6141                 return False;
6142         if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
6143                 return False;
6144
6145         if(!prs_uint16("bad_password_count     ", ps, depth, &usr->bad_password_count))
6146                 return False;
6147         if(!prs_uint16("logon_count     ", ps, depth, &usr->logon_count))
6148                 return False;
6149
6150         if(!prs_uint8s(False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1)))
6151                 return False;
6152         if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
6153                 return False;
6154         if(!prs_uint8("padding2       ", ps, depth, &usr->padding2))
6155                 return False;
6156
6157         /* here begins pointed-to data */
6158
6159         if(!smb_io_unistr2("uni_user_name   ", &usr->uni_user_name,usr->hdr_user_name.buffer, ps, depth))       /* username unicode string */
6160                 return False;
6161         if(!smb_io_unistr2("uni_full_name   ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth))      /* user's full name unicode string */
6162                 return False;
6163         if(!smb_io_unistr2("uni_home_dir    ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth))        /* home directory unicode string */
6164                 return False;
6165         if(!smb_io_unistr2("uni_dir_drive   ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth))      /* home directory drive unicode string */
6166                 return False;
6167         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth))        /* logon script unicode string */
6168                 return False;
6169         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth))        /* profile path unicode string */
6170                 return False;
6171         if(!smb_io_unistr2("uni_acct_desc   ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth))      /* user desc unicode string */
6172                 return False;
6173         if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth))        /* worksations user can log on from */
6174                 return False;
6175         if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth))  /* unknown string */
6176                 return False;
6177         if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial,usr->hdr_munged_dial.buffer, ps, depth))   /* worksations user can log on from */
6178                 return False;
6179
6180         /* ok, this is only guess-work (as usual) */
6181         if (usr->ptr_logon_hrs) {
6182                 if(!prs_align(ps))
6183                         return False;
6184                 if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
6185                         return False;
6186                 if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
6187                         return False;
6188                 if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
6189                         return False;
6190         } else if (UNMARSHALLING(ps)) {
6191                 usr->unknown_6 = 0;
6192                 usr->padding4 = 0;
6193         }
6194
6195         return True;
6196 }
6197
6198 void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw)
6199 {
6200         const char *munged_dial = pdb_get_munged_dial(pw);
6201         DATA_BLOB blob = base64_decode_data_blob(munged_dial);
6202         
6203         init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
6204         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
6205         data_blob_free(&blob);
6206 }
6207
6208 /*******************************************************************
6209 reads or writes a structure.
6210 ********************************************************************/
6211
6212 static BOOL sam_io_user_info20(const char *desc, SAM_USER_INFO_20 *usr,
6213                         prs_struct *ps, int depth)
6214 {
6215         if (usr == NULL)
6216                 return False;
6217
6218         prs_debug(ps, depth, desc, "sam_io_user_info20");
6219         depth++;
6220
6221         if(!prs_align(ps))
6222                 return False;
6223
6224         if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth))        /* wkstas user can log on from */
6225                 return False;
6226
6227         if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial,usr->hdr_munged_dial.buffer, ps, depth))   /* worksations user can log on from */
6228                 return False;
6229
6230         return True;
6231 }
6232
6233 /*******************************************************************
6234 inits a SAM_USERINFO_CTR structure.
6235 ********************************************************************/
6236
6237 NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
6238                                     uint16 switch_value,
6239                                     SAM_USER_INFO_21 * usr)
6240 {
6241         DEBUG(5, ("init_samr_userinfo_ctr\n"));
6242
6243         ctr->switch_value = switch_value;
6244         ctr->info.id = NULL;
6245
6246         switch (switch_value) {
6247         case 0x10:
6248                 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(ctx,sizeof(SAM_USER_INFO_10));
6249                 if (ctr->info.id10 == NULL)
6250                         return NT_STATUS_NO_MEMORY;
6251
6252                 init_sam_user_info10(ctr->info.id10, usr->acb_info);
6253                 break;
6254 #if 0
6255 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
6256         case 0x11:
6257                 {
6258                         NTTIME expire;
6259                         info = (void *)&id11;
6260
6261                         expire.low = 0xffffffff;
6262                         expire.high = 0x7fffffff;
6263
6264                         ctr->info.id = (SAM_USER_INFO_11 *) talloc_zero(ctx,sizeof(*ctr->info.id11));
6265                         init_sam_user_info11(ctr->info.id11, &expire,
6266                                              "BROOKFIELDS$",    /* name */
6267                                              0x03ef,    /* user rid */
6268                                              0x201,     /* group rid */
6269                                              0x0080);   /* acb info */
6270
6271                         break;
6272                 }
6273 #endif
6274         case 0x12:
6275                 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(ctx,sizeof(SAM_USER_INFO_12));
6276                 if (ctr->info.id12 == NULL)
6277                         return NT_STATUS_NO_MEMORY;
6278
6279                 init_sam_user_info12(ctr->info.id12, usr->lm_pwd, usr->nt_pwd);
6280                 break;
6281         case 21:
6282                 {
6283                         SAM_USER_INFO_21 *cusr;
6284                         cusr = (SAM_USER_INFO_21 *)talloc_zero(ctx,sizeof(SAM_USER_INFO_21));
6285                         ctr->info.id21 = cusr;
6286                         if (ctr->info.id21 == NULL)
6287                                 return NT_STATUS_NO_MEMORY;
6288                         memcpy(cusr, usr, sizeof(*usr));
6289                         memset(cusr->lm_pwd, 0, sizeof(cusr->lm_pwd));
6290                         memset(cusr->nt_pwd, 0, sizeof(cusr->nt_pwd));
6291                         break;
6292                 }
6293         default:
6294                 DEBUG(4,("make_samr_userinfo_ctr: unsupported info\n"));
6295                 return NT_STATUS_INVALID_INFO_CLASS;
6296         }
6297
6298         return NT_STATUS_OK;
6299 }
6300
6301 /*******************************************************************
6302 inits a SAM_USERINFO_CTR structure.
6303 ********************************************************************/
6304
6305 static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key,
6306                                    uint16 switch_value, void *info)
6307 {
6308         DEBUG(5, ("init_samr_userinfo_ctr\n"));
6309
6310         ctr->switch_value = switch_value;
6311         ctr->info.id = info;
6312
6313         switch (switch_value) {
6314         case 0x18:
6315                 SamOEMhashBlob(ctr->info.id24->pass, 516, sess_key);
6316                 dump_data(100, (char *)sess_key->data, sess_key->length);
6317                 dump_data(100, (char *)ctr->info.id24->pass, 516);
6318                 break;
6319         case 0x17:
6320                 SamOEMhashBlob(ctr->info.id23->pass, 516, sess_key);
6321                 dump_data(100, (char *)sess_key->data, sess_key->length);
6322                 dump_data(100, (char *)ctr->info.id23->pass, 516);
6323                 break;
6324         default:
6325                 DEBUG(4,("init_samr_userinfo_ctr: unsupported switch level\n"));
6326         }
6327 }
6328
6329 /*******************************************************************
6330 reads or writes a structure.
6331 ********************************************************************/
6332
6333 static BOOL samr_io_userinfo_ctr(const char *desc, SAM_USERINFO_CTR **ppctr,
6334                                  prs_struct *ps, int depth)
6335 {
6336         BOOL ret;
6337         SAM_USERINFO_CTR *ctr;
6338
6339         prs_debug(ps, depth, desc, "samr_io_userinfo_ctr");
6340         depth++;
6341
6342         if (UNMARSHALLING(ps)) {
6343                 ctr = (SAM_USERINFO_CTR *)prs_alloc_mem(ps,sizeof(SAM_USERINFO_CTR));
6344                 if (ctr == NULL)
6345                         return False;
6346                 *ppctr = ctr;
6347         } else {
6348                 ctr = *ppctr;
6349         }
6350
6351         /* lkclXXXX DO NOT ALIGN BEFORE READING SWITCH VALUE! */
6352
6353         if(!prs_uint16("switch_value", ps, depth, &ctr->switch_value))
6354                 return False;
6355         if(!prs_align(ps))
6356                 return False;
6357
6358         ret = False;
6359
6360         switch (ctr->switch_value) {
6361         case 0x10:
6362                 if (UNMARSHALLING(ps))
6363                         ctr->info.id10 = (SAM_USER_INFO_10 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_10));
6364                 if (ctr->info.id10 == NULL) {
6365                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6366                         return False;
6367                 }
6368                 ret = sam_io_user_info10("", ctr->info.id10, ps, depth);
6369                 break;
6370         case 0x11:
6371                 if (UNMARSHALLING(ps))
6372                         ctr->info.id11 = (SAM_USER_INFO_11 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_11));
6373
6374                 if (ctr->info.id11 == NULL) {
6375                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6376                         return False;
6377                 }
6378                 ret = sam_io_user_info11("", ctr->info.id11, ps, depth);
6379                 break;
6380         case 0x12:
6381                 if (UNMARSHALLING(ps))
6382                         ctr->info.id12 = (SAM_USER_INFO_12 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_12));
6383
6384                 if (ctr->info.id12 == NULL) {
6385                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6386                         return False;
6387                 }
6388                 ret = sam_io_user_info12("", ctr->info.id12, ps, depth);
6389                 break;
6390         case 20:
6391                 if (UNMARSHALLING(ps))
6392                         ctr->info.id20 = (SAM_USER_INFO_20 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_20));
6393
6394                 if (ctr->info.id20 == NULL) {
6395                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6396                         return False;
6397                 }
6398                 ret = sam_io_user_info20("", ctr->info.id20, ps, depth);
6399                 break;
6400         case 21:
6401                 if (UNMARSHALLING(ps))
6402                         ctr->info.id21 = (SAM_USER_INFO_21 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_21));
6403
6404                 if (ctr->info.id21 == NULL) {
6405                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6406                         return False;
6407                 }
6408                 ret = sam_io_user_info21("", ctr->info.id21, ps, depth);
6409                 break;
6410         case 23:
6411                 if (UNMARSHALLING(ps))
6412                         ctr->info.id23 = (SAM_USER_INFO_23 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_23));
6413
6414                 if (ctr->info.id23 == NULL) {
6415                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6416                         return False;
6417                 }
6418                 ret = sam_io_user_info23("", ctr->info.id23, ps, depth);
6419                 break;
6420         case 24:
6421                 if (UNMARSHALLING(ps))
6422                         ctr->info.id24 = (SAM_USER_INFO_24 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_24));
6423
6424                 if (ctr->info.id24 == NULL) {
6425                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6426                         return False;
6427                 }
6428                 ret = sam_io_user_info24("", ctr->info.id24, ps,  depth);
6429                 break;
6430         case 25:
6431                 if (UNMARSHALLING(ps))
6432                         ctr->info.id25 = (SAM_USER_INFO_25 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_25));
6433
6434                 if (ctr->info.id25 == NULL) {
6435                         DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
6436                         return False;
6437                 }
6438                 ret = sam_io_user_info25("", ctr->info.id25, ps, depth);
6439                 break;
6440         default:
6441                 DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
6442                 ret = False;
6443                 break;
6444         }
6445
6446         return ret;
6447 }
6448
6449 /*******************************************************************
6450 inits a SAMR_R_QUERY_USERINFO structure.
6451 ********************************************************************/
6452
6453 void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
6454                                 SAM_USERINFO_CTR * ctr, NTSTATUS status)
6455 {
6456         DEBUG(5, ("init_samr_r_query_userinfo\n"));
6457
6458         r_u->ptr = 0;
6459         r_u->ctr = NULL;
6460
6461         if (NT_STATUS_IS_OK(status)) {
6462                 r_u->ptr = 1;
6463                 r_u->ctr = ctr;
6464         }
6465
6466         r_u->status = status;   /* return status */
6467 }
6468
6469 /*******************************************************************
6470 reads or writes a structure.
6471 ********************************************************************/
6472
6473 BOOL samr_io_r_query_userinfo(const char *desc, SAMR_R_QUERY_USERINFO * r_u,
6474                               prs_struct *ps, int depth)
6475 {
6476         if (r_u == NULL)
6477                 return False;
6478
6479         prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
6480         depth++;
6481
6482         if(!prs_align(ps))
6483                 return False;
6484
6485         if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
6486                 return False;
6487
6488         if (r_u->ptr != 0) {
6489                 if(!samr_io_userinfo_ctr("ctr", &r_u->ctr, ps, depth))
6490                         return False;
6491         }
6492
6493         if(!prs_align(ps))
6494                 return False;
6495         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6496                 return False;
6497
6498         return True;
6499 }
6500
6501 /*******************************************************************
6502 inits a SAMR_Q_SET_USERINFO structure.
6503 ********************************************************************/
6504
6505 void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
6506                               POLICY_HND *hnd, DATA_BLOB *sess_key,
6507                               uint16 switch_value, void *info)
6508 {
6509         DEBUG(5, ("init_samr_q_set_userinfo\n"));
6510
6511         q_u->pol = *hnd;
6512         q_u->switch_value = switch_value;
6513         init_samr_userinfo_ctr(q_u->ctr, sess_key, switch_value, info);
6514 }
6515
6516 /*******************************************************************
6517 reads or writes a structure.
6518 ********************************************************************/
6519
6520 BOOL samr_io_q_set_userinfo(const char *desc, SAMR_Q_SET_USERINFO * q_u,
6521                             prs_struct *ps, int depth)
6522 {
6523         if (q_u == NULL)
6524                 return False;
6525
6526         prs_debug(ps, depth, desc, "samr_io_q_set_userinfo");
6527         depth++;
6528
6529         if(!prs_align(ps))
6530                 return False;
6531
6532         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
6533
6534         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
6535                 return False;
6536         if(!samr_io_userinfo_ctr("ctr", &q_u->ctr, ps, depth))
6537                 return False;
6538
6539         return True;
6540 }
6541
6542 /*******************************************************************
6543 inits a SAMR_R_SET_USERINFO structure.
6544 ********************************************************************/
6545
6546 void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, NTSTATUS status)
6547 {
6548         DEBUG(5, ("init_samr_r_set_userinfo\n"));
6549
6550         r_u->status = status;   /* return status */
6551 }
6552
6553 /*******************************************************************
6554 reads or writes a structure.
6555 ********************************************************************/
6556
6557 BOOL samr_io_r_set_userinfo(const char *desc, SAMR_R_SET_USERINFO * r_u,
6558                             prs_struct *ps, int depth)
6559 {
6560         if (r_u == NULL)
6561                 return False;
6562
6563         prs_debug(ps, depth, desc, "samr_io_r_set_userinfo");
6564         depth++;
6565
6566         if(!prs_align(ps))
6567                 return False;
6568
6569         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6570                 return False;
6571
6572         return True;
6573 }
6574
6575 /*******************************************************************
6576 inits a SAMR_Q_SET_USERINFO2 structure.
6577 ********************************************************************/
6578
6579 void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
6580                                POLICY_HND *hnd, DATA_BLOB *sess_key,
6581                                uint16 switch_value, SAM_USERINFO_CTR * ctr)
6582 {
6583         DEBUG(5, ("init_samr_q_set_userinfo2\n"));
6584
6585         q_u->pol = *hnd;
6586         q_u->switch_value = switch_value;
6587         q_u->ctr = ctr;
6588
6589         if (q_u->ctr != NULL)
6590                 q_u->ctr->switch_value = switch_value;
6591
6592         switch (switch_value) {
6593         case 0x12:
6594                 SamOEMhashBlob(ctr->info.id12->lm_pwd, 16, sess_key);
6595                 SamOEMhashBlob(ctr->info.id12->nt_pwd, 16, sess_key);
6596                 dump_data(100, (char *)sess_key->data, sess_key->length);
6597                 dump_data(100, (char *)ctr->info.id12->lm_pwd, 16);
6598                 dump_data(100, (char *)ctr->info.id12->nt_pwd, 16);
6599                 break;
6600         }
6601 }
6602
6603 /*******************************************************************
6604 reads or writes a structure.
6605 ********************************************************************/
6606
6607 BOOL samr_io_q_set_userinfo2(const char *desc, SAMR_Q_SET_USERINFO2 * q_u,
6608                              prs_struct *ps, int depth)
6609 {
6610         if (q_u == NULL)
6611                 return False;
6612
6613         prs_debug(ps, depth, desc, "samr_io_q_set_userinfo2");
6614         depth++;
6615
6616         if(!prs_align(ps))
6617                 return False;
6618
6619         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
6620                 return False;
6621
6622         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
6623                 return False;
6624         if(!samr_io_userinfo_ctr("ctr", &q_u->ctr, ps, depth))
6625                 return False;
6626
6627         return True;
6628 }
6629
6630 /*******************************************************************
6631 inits a SAMR_R_SET_USERINFO2 structure.
6632 ********************************************************************/
6633
6634 void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, NTSTATUS status)
6635 {
6636         DEBUG(5, ("init_samr_r_set_userinfo2\n"));
6637
6638         r_u->status = status;   /* return status */
6639 }
6640
6641 /*******************************************************************
6642 reads or writes a structure.
6643 ********************************************************************/
6644
6645 BOOL samr_io_r_set_userinfo2(const char *desc, SAMR_R_SET_USERINFO2 * r_u,
6646                              prs_struct *ps, int depth)
6647 {
6648         if (r_u == NULL)
6649                 return False;
6650
6651         prs_debug(ps, depth, desc, "samr_io_r_set_userinfo2");
6652         depth++;
6653
6654         if(!prs_align(ps))
6655                 return False;
6656
6657         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6658                 return False;
6659
6660         return True;
6661 }
6662
6663 /*******************************************************************
6664 inits a SAMR_Q_CONNECT structure.
6665 ********************************************************************/
6666
6667 void init_samr_q_connect(SAMR_Q_CONNECT * q_u,
6668                          char *srv_name, uint32 access_mask)
6669 {
6670         DEBUG(5, ("init_samr_q_connect\n"));
6671
6672         /* make PDC server name \\server */
6673         q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
6674         init_unistr2(&q_u->uni_srv_name, srv_name, UNI_STR_TERMINATE);
6675
6676         /* example values: 0x0000 0002 */
6677         q_u->access_mask = access_mask;
6678 }
6679
6680 /*******************************************************************
6681 reads or writes a structure.
6682 ********************************************************************/
6683
6684 BOOL samr_io_q_connect(const char *desc, SAMR_Q_CONNECT * q_u,
6685                        prs_struct *ps, int depth)
6686 {
6687         if (q_u == NULL)
6688                 return False;
6689
6690         prs_debug(ps, depth, desc, "samr_io_q_connect");
6691         depth++;
6692
6693         if(!prs_align(ps))
6694                 return False;
6695
6696         if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
6697                 return False;
6698         if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
6699                 return False;
6700
6701         if(!prs_align(ps))
6702                 return False;
6703         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
6704                 return False;
6705
6706         return True;
6707 }
6708
6709 /*******************************************************************
6710 reads or writes a structure.
6711 ********************************************************************/
6712
6713 BOOL samr_io_r_connect(const char *desc, SAMR_R_CONNECT * r_u,
6714                        prs_struct *ps, int depth)
6715 {
6716         if (r_u == NULL)
6717                 return False;
6718
6719         prs_debug(ps, depth, desc, "samr_io_r_connect");
6720         depth++;
6721
6722         if(!prs_align(ps))
6723                 return False;
6724
6725         if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
6726                 return False;
6727
6728         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6729                 return False;
6730
6731         return True;
6732 }
6733
6734 /*******************************************************************
6735 inits a SAMR_Q_CONNECT4 structure.
6736 ********************************************************************/
6737
6738 void init_samr_q_connect4(SAMR_Q_CONNECT4 * q_u,
6739                           char *srv_name, uint32 access_mask)
6740 {
6741         DEBUG(5, ("init_samr_q_connect\n"));
6742
6743         /* make PDC server name \\server */
6744         q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
6745         init_unistr2(&q_u->uni_srv_name, srv_name, UNI_STR_TERMINATE);
6746
6747         /* Only value we've seen, possibly an address type ? */
6748         q_u->unk_0 = 2;
6749
6750         /* example values: 0x0000 0002 */
6751         q_u->access_mask = access_mask;
6752 }
6753
6754 /*******************************************************************
6755 reads or writes a structure.
6756 ********************************************************************/
6757
6758 BOOL samr_io_q_connect4(const char *desc, SAMR_Q_CONNECT4 * q_u,
6759                         prs_struct *ps, int depth)
6760 {
6761         if (q_u == NULL)
6762                 return False;
6763
6764         prs_debug(ps, depth, desc, "samr_io_q_connect4");
6765         depth++;
6766
6767         if(!prs_align(ps))
6768                 return False;
6769
6770         if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
6771                 return False;
6772         if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
6773                 return False;
6774
6775         if(!prs_align(ps))
6776                 return False;
6777         if(!prs_uint32("unk_0", ps, depth, &q_u->unk_0))
6778                 return False;
6779         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
6780                 return False;
6781
6782         return True;
6783 }
6784
6785 /*******************************************************************
6786 reads or writes a structure.
6787 ********************************************************************/
6788
6789 BOOL samr_io_r_connect4(const char *desc, SAMR_R_CONNECT4 * r_u,
6790                         prs_struct *ps, int depth)
6791 {
6792         if (r_u == NULL)
6793                 return False;
6794
6795         prs_debug(ps, depth, desc, "samr_io_r_connect4");
6796         depth++;
6797
6798         if(!prs_align(ps))
6799                 return False;
6800
6801         if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
6802                 return False;
6803
6804         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6805                 return False;
6806
6807         return True;
6808 }
6809
6810 /*******************************************************************
6811 inits a SAMR_Q_CONNECT_ANON structure.
6812 ********************************************************************/
6813
6814 void init_samr_q_connect_anon(SAMR_Q_CONNECT_ANON * q_u)
6815 {
6816         DEBUG(5, ("init_samr_q_connect_anon\n"));
6817
6818         q_u->ptr = 1;
6819         q_u->unknown_0 = 0x5c;  /* server name (?!!) */
6820         q_u->unknown_1 = 0x01;
6821         q_u->access_mask = 0x20;
6822 }
6823
6824 /*******************************************************************
6825 reads or writes a structure.
6826 ********************************************************************/
6827
6828 BOOL samr_io_q_connect_anon(const char *desc, SAMR_Q_CONNECT_ANON * q_u,
6829                             prs_struct *ps, int depth)
6830 {
6831         if (q_u == NULL)
6832                 return False;
6833
6834         prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
6835         depth++;
6836
6837         if(!prs_align(ps))
6838                 return False;
6839
6840         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
6841                 return False;
6842         if(!prs_uint16("unknown_0", ps, depth, &q_u->unknown_0))
6843                 return False;
6844         if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
6845                 return False;
6846         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
6847                 return False;
6848
6849         return True;
6850 }
6851
6852 /*******************************************************************
6853 reads or writes a structure.
6854 ********************************************************************/
6855
6856 BOOL samr_io_r_connect_anon(const char *desc, SAMR_R_CONNECT_ANON * r_u,
6857                             prs_struct *ps, int depth)
6858 {
6859         if (r_u == NULL)
6860                 return False;
6861
6862         prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
6863         depth++;
6864
6865         if(!prs_align(ps))
6866                 return False;
6867
6868         if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
6869                 return False;
6870
6871         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6872                 return False;
6873
6874         return True;
6875 }
6876
6877 /*******************************************************************
6878 inits a SAMR_Q_GET_DOM_PWINFO structure.
6879 ********************************************************************/
6880
6881 void init_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO * q_u,
6882                                 char *srv_name)
6883 {
6884         DEBUG(5, ("init_samr_q_get_dom_pwinfo\n"));
6885
6886         q_u->ptr = 1;
6887         init_unistr2(&q_u->uni_srv_name, srv_name, UNI_FLAGS_NONE);
6888         init_uni_hdr(&q_u->hdr_srv_name, &q_u->uni_srv_name);
6889 }
6890
6891 /*******************************************************************
6892 reads or writes a structure.
6893 ********************************************************************/
6894
6895 BOOL samr_io_q_get_dom_pwinfo(const char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
6896                               prs_struct *ps, int depth)
6897 {
6898         if (q_u == NULL)
6899                 return False;
6900
6901         prs_debug(ps, depth, desc, "samr_io_q_get_dom_pwinfo");
6902         depth++;
6903
6904         if(!prs_align(ps))
6905                 return False;
6906
6907         if(!prs_uint32("ptr", ps, depth, &q_u->ptr))
6908                 return False;
6909         if (q_u->ptr != 0) {
6910                 if(!smb_io_unihdr("", &q_u->hdr_srv_name, ps, depth))
6911                         return False;
6912                 if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->hdr_srv_name.buffer, ps, depth))
6913                         return False;
6914         }
6915
6916         return True;
6917 }
6918
6919 /*******************************************************************
6920 reads or writes a structure.
6921 ********************************************************************/
6922
6923 BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
6924                               prs_struct *ps, int depth)
6925 {
6926         if (r_u == NULL)
6927                 return False;
6928
6929         prs_debug(ps, depth, desc, "samr_io_r_get_dom_pwinfo");
6930         depth++;
6931
6932         if(!prs_align(ps))
6933                 return False;
6934
6935         /*
6936          * We need 16 bytes here according to tests.  Don't know
6937          * what they are, but the length is important for the singing
6938         */
6939
6940         if(!prs_uint32("unk_0", ps, depth, &r_u->unk_0))
6941                 return False;
6942         if(!prs_uint32("unk_1", ps, depth, &r_u->unk_1))
6943                 return False;
6944         if(!prs_uint32("unk_2", ps, depth, &r_u->unk_2))
6945                 return False;
6946
6947         if(!prs_ntstatus("status", ps, depth, &r_u->status))
6948                 return False;
6949
6950         return True;
6951 }
6952
6953 /*******************************************************************
6954 make a SAMR_ENC_PASSWD structure.
6955 ********************************************************************/
6956
6957 void init_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512])
6958 {
6959         ZERO_STRUCTP(pwd);
6960
6961         if (pass == NULL) {
6962                 pwd->ptr = 0;
6963         } else {
6964                 pwd->ptr = 1;
6965                 memcpy(pwd->pass, pass, sizeof(pwd->pass));
6966         }
6967 }
6968
6969 /*******************************************************************
6970 reads or writes a SAMR_ENC_PASSWD structure.
6971 ********************************************************************/
6972
6973 BOOL samr_io_enc_passwd(const char *desc, SAMR_ENC_PASSWD * pwd,
6974                         prs_struct *ps, int depth)
6975 {
6976         if (pwd == NULL)
6977                 return False;
6978
6979         prs_debug(ps, depth, desc, "samr_io_enc_passwd");
6980         depth++;
6981
6982         if(!prs_align(ps))
6983                 return False;
6984
6985         if(!prs_uint32("ptr", ps, depth, &pwd->ptr))
6986                 return False;
6987
6988         if (pwd->ptr != 0) {
6989                 if(!prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)))
6990                         return False;
6991         }
6992
6993         return True;
6994 }
6995
6996 /*******************************************************************
6997 inits a SAMR_ENC_HASH structure.
6998 ********************************************************************/
6999
7000 void init_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16])
7001 {
7002         ZERO_STRUCTP(hsh);
7003
7004         if (hash == NULL) {
7005                 hsh->ptr = 0;
7006         } else {
7007                 hsh->ptr = 1;
7008                 memcpy(hsh->hash, hash, sizeof(hsh->hash));
7009         }
7010 }
7011
7012 /*******************************************************************
7013 reads or writes a SAMR_ENC_HASH structure.
7014 ********************************************************************/
7015
7016 BOOL samr_io_enc_hash(const char *desc, SAMR_ENC_HASH * hsh,
7017                       prs_struct *ps, int depth)
7018 {
7019         if (hsh == NULL)
7020                 return False;
7021
7022         prs_debug(ps, depth, desc, "samr_io_enc_hash");
7023         depth++;
7024
7025         if(!prs_align(ps))
7026                 return False;
7027
7028         if(!prs_uint32("ptr ", ps, depth, &hsh->ptr))
7029                 return False;
7030         if (hsh->ptr != 0) {
7031                 if(!prs_uint8s(False, "hash", ps, depth, hsh->hash,sizeof(hsh->hash)))
7032                         return False;
7033         }
7034
7035         return True;
7036 }
7037
7038 /*******************************************************************
7039 inits a SAMR_R_GET_DOM_PWINFO structure.
7040 ********************************************************************/
7041
7042 void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
7043                                 const char *dest_host, const char *user_name,
7044                                 const char nt_newpass[516],
7045                                 const uchar nt_oldhash[16],
7046                                 const char lm_newpass[516],
7047                                 const uchar lm_oldhash[16])
7048 {
7049         DEBUG(5, ("init_samr_q_chgpasswd_user\n"));
7050
7051         q_u->ptr_0 = 1;
7052         init_unistr2(&q_u->uni_dest_host, dest_host, UNI_FLAGS_NONE);
7053         init_uni_hdr(&q_u->hdr_dest_host, &q_u->uni_dest_host);
7054
7055         init_unistr2(&q_u->uni_user_name, user_name, UNI_FLAGS_NONE);
7056         init_uni_hdr(&q_u->hdr_user_name, &q_u->uni_user_name);
7057
7058         init_enc_passwd(&q_u->nt_newpass, nt_newpass);
7059         init_enc_hash(&q_u->nt_oldhash, nt_oldhash);
7060
7061         q_u->unknown = 0x01;
7062
7063         init_enc_passwd(&q_u->lm_newpass, lm_newpass);
7064         init_enc_hash(&q_u->lm_oldhash, lm_oldhash);
7065 }
7066
7067 /*******************************************************************
7068 reads or writes a structure.
7069 ********************************************************************/
7070
7071 BOOL samr_io_q_chgpasswd_user(const char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
7072                               prs_struct *ps, int depth)
7073 {
7074         if (q_u == NULL)
7075                 return False;
7076
7077         prs_debug(ps, depth, desc, "samr_io_q_chgpasswd_user");
7078         depth++;
7079
7080         if(!prs_align(ps))
7081                 return False;
7082
7083         if(!prs_uint32("ptr_0", ps, depth, &q_u->ptr_0))
7084                 return False;
7085
7086         if(!smb_io_unihdr("", &q_u->hdr_dest_host, ps, depth))
7087                 return False;
7088         if(!smb_io_unistr2("", &q_u->uni_dest_host, q_u->hdr_dest_host.buffer, ps, depth))
7089                 return False;
7090
7091         if(!prs_align(ps))
7092                 return False;
7093         if(!smb_io_unihdr("", &q_u->hdr_user_name, ps, depth))
7094                 return False;
7095         if(!smb_io_unistr2("", &q_u->uni_user_name, q_u->hdr_user_name.buffer,ps, depth))
7096                 return False;
7097
7098         if(!samr_io_enc_passwd("nt_newpass", &q_u->nt_newpass, ps, depth))
7099                 return False;
7100         if(!samr_io_enc_hash("nt_oldhash", &q_u->nt_oldhash, ps, depth))
7101                 return False;
7102
7103         if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
7104                 return False;
7105
7106         if(!samr_io_enc_passwd("lm_newpass", &q_u->lm_newpass, ps, depth))
7107                 return False;
7108         if(!samr_io_enc_hash("lm_oldhash", &q_u->lm_oldhash, ps, depth))
7109                 return False;
7110
7111         return True;
7112 }
7113
7114 /*******************************************************************
7115 inits a SAMR_R_CHGPASSWD_USER structure.
7116 ********************************************************************/
7117
7118 void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, NTSTATUS status)
7119 {
7120         DEBUG(5, ("init_r_chgpasswd_user\n"));
7121
7122         r_u->status = status;
7123 }
7124
7125 /*******************************************************************
7126 reads or writes a structure.
7127 ********************************************************************/
7128
7129 BOOL samr_io_r_chgpasswd_user(const char *desc, SAMR_R_CHGPASSWD_USER * r_u,
7130                               prs_struct *ps, int depth)
7131 {
7132         if (r_u == NULL)
7133                 return False;
7134
7135         prs_debug(ps, depth, desc, "samr_io_r_chgpasswd_user");
7136         depth++;
7137
7138         if(!prs_align(ps))
7139                 return False;
7140
7141         if(!prs_ntstatus("status", ps, depth, &r_u->status))
7142                 return False;
7143
7144         return True;
7145 }
7146
7147 /*******************************************************************
7148 reads or writes a structure.
7149 ********************************************************************/
7150
7151 void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u,
7152                                 POLICY_HND *domain_pol, uint16 switch_value)
7153 {
7154         DEBUG(5, ("init_samr_q_unknown_2e\n"));
7155
7156         q_u->domain_pol = *domain_pol;
7157         q_u->switch_value = switch_value;
7158 }
7159
7160 /*******************************************************************
7161 reads or writes a structure.
7162 ********************************************************************/
7163
7164 BOOL samr_io_q_unknown_2e(const char *desc, SAMR_Q_UNKNOWN_2E *q_u,
7165                               prs_struct *ps, int depth)
7166 {
7167         if (q_u == NULL)
7168                 return False;
7169
7170         prs_debug(ps, depth, desc, "samr_io_q_unknown_2e");
7171         depth++;
7172
7173         if(!prs_align(ps))
7174                 return False;
7175
7176         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
7177                 return False;
7178
7179         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
7180                 return False;
7181
7182         return True;
7183 }
7184
7185 /*******************************************************************
7186 inits a SAMR_R_QUERY_DOMAIN_INFO structure.
7187 ********************************************************************/
7188
7189 void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u,
7190                                 uint16 switch_value, SAM_UNK_CTR * ctr,
7191                                 NTSTATUS status)
7192 {
7193         DEBUG(5, ("init_samr_r_samr_unknown_2e\n"));
7194
7195         r_u->ptr_0 = 0;
7196         r_u->switch_value = 0;
7197         r_u->status = status;   /* return status */
7198
7199         if (NT_STATUS_IS_OK(status)) {
7200                 r_u->switch_value = switch_value;
7201                 r_u->ptr_0 = 1;
7202                 r_u->ctr = ctr;
7203         }
7204 }
7205
7206 /*******************************************************************
7207 reads or writes a structure.
7208 ********************************************************************/
7209
7210 BOOL samr_io_r_samr_unknown_2e(const char *desc, SAMR_R_UNKNOWN_2E * r_u,
7211                               prs_struct *ps, int depth)
7212 {
7213         if (r_u == NULL)
7214                 return False;
7215
7216         prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e");
7217         depth++;
7218
7219         if(!prs_align(ps))
7220                 return False;
7221
7222         if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
7223                 return False;
7224
7225         if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
7226                 if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
7227                         return False;
7228                 if(!prs_align(ps))
7229                         return False;
7230
7231                 switch (r_u->switch_value) {
7232                 case 0x0c:
7233                         if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
7234                                 return False;
7235                         break;
7236                 case 0x07:
7237                         if(!sam_io_unk_info7("unk_inf7",&r_u->ctr->info.inf7, ps,depth))
7238                                 return False;
7239                         break;
7240                 case 0x06:
7241                         if(!sam_io_unk_info6("unk_inf6",&r_u->ctr->info.inf6, ps,depth))
7242                                 return False;
7243                         break;
7244                 case 0x05:
7245                         if(!sam_io_unk_info5("unk_inf5",&r_u->ctr->info.inf5, ps,depth))
7246                                 return False;
7247                         break;
7248                 case 0x03:
7249                         if(!sam_io_unk_info3("unk_inf3",&r_u->ctr->info.inf3, ps,depth))
7250                                 return False;
7251                         break;
7252                 case 0x02:
7253                         if(!sam_io_unk_info2("unk_inf2",&r_u->ctr->info.inf2, ps,depth))
7254                                 return False;
7255                         break;
7256                 case 0x01:
7257                         if(!sam_io_unk_info1("unk_inf1",&r_u->ctr->info.inf1, ps,depth))
7258                                 return False;
7259                         break;
7260                 default:
7261                         DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n",
7262                                 r_u->switch_value));
7263                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
7264                         return False;
7265                 }
7266         }
7267         
7268         if(!prs_align(ps))
7269                 return False;
7270
7271         if(!prs_ntstatus("status", ps, depth, &r_u->status))
7272                 return False;
7273         
7274         return True;
7275 }
7276
7277
7278 /*******************************************************************
7279 reads or writes a structure.
7280 ********************************************************************/
7281
7282 void init_samr_q_set_domain_info(SAMR_Q_SET_DOMAIN_INFO *q_u,
7283                                 POLICY_HND *domain_pol, uint16 switch_value, SAM_UNK_CTR *ctr)
7284 {
7285         DEBUG(5, ("init_samr_q_set_domain_info\n"));
7286
7287         q_u->domain_pol = *domain_pol;
7288         q_u->switch_value0 = switch_value;
7289
7290         q_u->switch_value = switch_value;
7291         q_u->ctr = ctr;
7292         
7293 }
7294
7295 /*******************************************************************
7296 reads or writes a structure.
7297 ********************************************************************/
7298
7299 BOOL samr_io_q_set_domain_info(const char *desc, SAMR_Q_SET_DOMAIN_INFO *q_u,
7300                               prs_struct *ps, int depth)
7301 {
7302         if (q_u == NULL)
7303                 return False;
7304
7305         prs_debug(ps, depth, desc, "samr_io_q_set_domain_info");
7306         depth++;
7307
7308         if(!prs_align(ps))
7309                 return False;
7310
7311         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
7312                 return False;
7313
7314         if(!prs_uint16("switch_value0", ps, depth, &q_u->switch_value0))
7315                 return False;
7316
7317         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
7318                 return False;
7319
7320         if(!prs_align(ps))
7321                 return False;
7322
7323         if ((q_u->ctr = (SAM_UNK_CTR *)prs_alloc_mem(ps, sizeof(SAM_UNK_CTR))) == NULL)
7324                 return False;
7325         
7326         switch (q_u->switch_value) {
7327
7328         case 0x0c:
7329                 if(!sam_io_unk_info12("unk_inf12", &q_u->ctr->info.inf12, ps, depth))
7330                         return False;
7331                 break;
7332         case 0x07:
7333                 if(!sam_io_unk_info7("unk_inf7",&q_u->ctr->info.inf7, ps,depth))
7334                         return False;
7335                 break;
7336         case 0x06:
7337                 if(!sam_io_unk_info6("unk_inf6",&q_u->ctr->info.inf6, ps,depth))
7338                         return False;
7339                 break;
7340         case 0x05:
7341                 if(!sam_io_unk_info5("unk_inf5",&q_u->ctr->info.inf5, ps,depth))
7342                         return False;
7343                 break;
7344         case 0x03:
7345                 if(!sam_io_unk_info3("unk_inf3",&q_u->ctr->info.inf3, ps,depth))
7346                         return False;
7347                 break;
7348         case 0x02:
7349                 if(!sam_io_unk_info2("unk_inf2",&q_u->ctr->info.inf2, ps,depth))
7350                         return False;
7351                 break;
7352         case 0x01:
7353                 if(!sam_io_unk_info1("unk_inf1",&q_u->ctr->info.inf1, ps,depth))
7354                         return False;
7355                 break;
7356         default:
7357                 DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n",
7358                         q_u->switch_value));
7359                 return False;
7360         }
7361
7362         return True;
7363 }
7364
7365 /*******************************************************************
7366 inits a SAMR_R_QUERY_DOMAIN_INFO structure.
7367 ********************************************************************/
7368
7369 void init_samr_r_set_domain_info(SAMR_R_SET_DOMAIN_INFO * r_u, NTSTATUS status)
7370 {
7371         DEBUG(5, ("init_samr_r_set_domain_info\n"));
7372
7373         r_u->status = status;   /* return status */
7374 }
7375
7376 /*******************************************************************
7377 reads or writes a structure.
7378 ********************************************************************/
7379
7380 BOOL samr_io_r_set_domain_info(const char *desc, SAMR_R_SET_DOMAIN_INFO * r_u,
7381                               prs_struct *ps, int depth)
7382 {
7383         if (r_u == NULL)
7384                 return False;
7385
7386         prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e");
7387         depth++;
7388
7389         if(!prs_align(ps))
7390                 return False;
7391
7392         if(!prs_ntstatus("status", ps, depth, &r_u->status))
7393                 return False;
7394         
7395         return True;
7396 }