a netlogon enum trust query doesn't have a function_code at end.
[samba.git] / source3 / rpc_parse / parse_samr.c
1 #define OLD_NTDOMAIN 1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30
31 /*******************************************************************
32  Inits a SAMR_Q_CLOSE_HND structure.
33 ********************************************************************/
34
35 void init_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd)
36 {
37         DEBUG(5,("init_samr_q_close_hnd\n"));
38
39         memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
40 }
41
42 /*******************************************************************
43  Reads or writes a structure.
44 ********************************************************************/
45
46 BOOL samr_io_q_close_hnd(char *desc,  SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth)
47 {
48         if (q_u == NULL)
49                 return False;
50
51         prs_debug(ps, depth, desc, "samr_io_q_close_hnd");
52         depth++;
53
54         if(!prs_align(ps))
55                 return False;
56
57         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
58                 return False;
59         if(!prs_align(ps))
60                 return False;
61
62         return True;
63 }
64
65 /*******************************************************************
66  Reads or writes a structure.
67 ********************************************************************/
68
69 BOOL samr_io_r_close_hnd(char *desc,  SAMR_R_CLOSE_HND *r_u, 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         if(!prs_align(ps))
83                 return False;
84
85         if(!prs_uint32("status", ps, depth, &r_u->status))
86                 return False;
87
88         return True;
89 }
90
91
92 /*******************************************************************
93  Reads or writes a structure.
94 ********************************************************************/
95
96 void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
97                                 POLICY_HND *connect_pol, uint32 rid,
98                                 DOM_SID *sid)
99 {
100         DEBUG(5,("samr_init_q_open_domain\n"));
101
102         memcpy(&q_u->connect_pol, connect_pol, sizeof(q_u->connect_pol));
103         q_u->rid = rid;
104         init_dom_sid2(&q_u->dom_sid, sid);
105 }
106
107 /*******************************************************************
108  Reads or writes a structure.
109 ********************************************************************/
110
111 BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth)
112 {
113         if (q_u == NULL)
114                 return False;
115
116         prs_debug(ps, depth, desc, "samr_io_q_open_domain");
117         depth++;
118
119         if(!prs_align(ps))
120                 return False;
121
122         if(!smb_io_pol_hnd("connect_pol", &q_u->connect_pol, ps, depth))
123                 return False;
124         if(!prs_align(ps))
125                 return False;
126
127         if(!prs_uint32("rid", ps, depth, &q_u->rid))
128                 return False;
129
130         if(!smb_io_dom_sid2("sid", &q_u->dom_sid, ps, depth))
131                 return False;
132         if(!prs_align(ps))
133                 return False;
134
135         return True;
136 }
137
138
139 /*******************************************************************
140  Reads or writes a structure.
141 ********************************************************************/
142
143 BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth)
144 {
145         if (r_u == NULL)
146                 return False;
147
148         prs_debug(ps, depth, desc, "samr_io_r_open_domain");
149         depth++;
150
151         if(!prs_align(ps))
152                 return False;
153
154         if(!smb_io_pol_hnd("domain_pol", &r_u->domain_pol, ps, depth))
155                 return False;
156         if(!prs_align(ps))
157                 return False;
158
159         if(!prs_uint32("status", ps, depth, &r_u->status))
160                 return False;
161
162         return True;
163 }
164
165 /*******************************************************************
166  Reads or writes a structure.
167 ********************************************************************/
168
169 void init_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol)
170 {
171         DEBUG(5,("samr_init_q_unknown_2c\n"));
172
173         memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
174 }
175
176
177 /*******************************************************************
178  Reads or writes a structure.
179 ********************************************************************/
180
181 BOOL samr_io_q_unknown_2c(char *desc,  SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth)
182 {
183         if (q_u == NULL)
184                 return False;
185
186         prs_debug(ps, depth, desc, "samr_io_q_unknown_2c");
187         depth++;
188
189         if(!prs_align(ps))
190                 return False;
191
192         if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
193                 return False;
194         if(!prs_align(ps))
195                 return False;
196
197         return True;
198 }
199
200 /*******************************************************************
201  Inits a structure.
202 ********************************************************************/
203
204 void init_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status)
205 {
206         DEBUG(5,("samr_init_r_unknown_2c\n"));
207
208         q_u->unknown_0 = 0x00160000;
209         q_u->unknown_1 = 0x00000000;
210         q_u->status    = status;
211 }
212
213
214 /*******************************************************************
215  Reads or writes a structure.
216 ********************************************************************/
217
218 BOOL samr_io_r_unknown_2c(char *desc,  SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth)
219 {
220         if (r_u == NULL)
221                 return False;
222
223         prs_debug(ps, depth, desc, "samr_io_r_unknown_2c");
224         depth++;
225
226         if(!prs_align(ps))
227                 return False;
228
229         if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
230                 return False;
231         if(!prs_uint32("unknown_1", ps, depth, &r_u->unknown_1))
232                 return False;
233         if(!prs_uint32("status   ", ps, depth, &r_u->status))
234                 return False;
235
236         return True;
237 }
238
239 /*******************************************************************
240  Inits a SAMR_Q_UNKNOWN_3 structure.
241 ********************************************************************/
242
243 void init_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
244                                 POLICY_HND *user_pol, uint16 switch_value)
245 {
246         DEBUG(5,("samr_init_q_unknown_3\n"));
247
248         memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
249         q_u->switch_value = switch_value;
250 }
251
252
253 /*******************************************************************
254  Reads or writes a structure.
255 ********************************************************************/
256
257 BOOL samr_io_q_unknown_3(char *desc,  SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth)
258 {
259         if (q_u == NULL)
260                 return False;
261
262         prs_debug(ps, depth, desc, "samr_io_q_unknown_3");
263         depth++;
264
265         if(!prs_align(ps))
266                 return False;
267
268         if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
269                 return False;
270
271         if(!prs_align(ps))
272                 return False;
273
274         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
275                 return False;
276         if(!prs_align(ps))
277                 return False;
278
279         return True;
280 }
281
282 /*******************************************************************
283  Inits a SAMR_Q_QUERY_DOMAIN_INFO structure.
284 ********************************************************************/
285
286 void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
287                                 POLICY_HND *domain_pol, uint16 switch_value)
288 {
289         DEBUG(5,("init_samr_q_query_dom_info\n"));
290
291         memcpy(&q_u->domain_pol, domain_pol, sizeof(q_u->domain_pol));
292         q_u->switch_value = switch_value;
293 }
294
295 /*******************************************************************
296  Reads or writes a structure.
297 ********************************************************************/
298
299 BOOL samr_io_q_query_dom_info(char *desc,  SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth)
300 {
301         if (q_u == NULL)
302                 return False;
303
304         prs_debug(ps, depth, desc, "samr_io_q_query_dom_info");
305         depth++;
306
307         if(!prs_align(ps))
308                 return False;
309
310         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
311                 return False;
312         if(!prs_align(ps))
313                 return False;
314
315         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
316                 return False;
317
318         return True;
319 }
320
321 /*******************************************************************
322 Inits a structure.
323 ********************************************************************/
324 BOOL init_unk_info1(SAM_UNK_INFO_1 *u_1)
325 {
326         if (u_1 == NULL)
327                 return False;
328
329         memset(u_1->padding, 0, sizeof(u_1->padding));  /* 12 bytes zeros */
330         u_1->unknown_1 = 0x80000000;
331         u_1->unknown_2 = 0x00000000;
332
333         return True;
334 }
335
336 /*******************************************************************
337 reads or writes a structure.
338 ********************************************************************/
339 static BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth)
340 {
341         if (u_1 == NULL)
342                 return False;
343
344         prs_debug(ps, depth, desc, "sam_io_unk_info1");
345         depth++;
346
347         if(!prs_uint8s(False, "padding", ps, depth, u_1->padding, sizeof(u_1->padding)))
348                 return False;
349
350         if(!prs_uint32("unknown_1", ps, depth, &u_1->unknown_1))        /* 0x8000 0000 */
351                 return False;
352         if(!prs_uint32("unknown_2", ps, depth, &u_1->unknown_2))        /* 0x0000 0000 */
353                 return False;
354
355         if(!prs_align(ps))
356                 return False;
357
358         return True;
359 }
360
361 /*******************************************************************
362  Inits a structure.
363 ********************************************************************/
364
365 void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
366 {
367         int len_domain = strlen(domain);
368         int len_server = strlen(server);
369
370         u_2->unknown_0 = 0x00000000;
371         u_2->unknown_1 = 0x80000000;
372         u_2->unknown_2 = 0x00000000;
373
374         u_2->ptr_0 = 1;
375         init_uni_hdr(&u_2->hdr_domain, len_domain);
376         init_uni_hdr(&u_2->hdr_server, len_server);
377
378         u_2->seq_num = 0x10000000;
379         u_2->unknown_3 = 0x00000000;
380         
381         u_2->unknown_4  = 0x00000001;
382         u_2->unknown_5  = 0x00000003;
383         u_2->unknown_6  = 0x00000001;
384         u_2->num_domain_usrs  = 0x00000008;
385         u_2->num_domain_grps = 0x00000003;
386         u_2->num_local_grps = 0x00000003;
387
388         memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
389
390         init_unistr2(&u_2->uni_domain, domain, len_domain);
391         init_unistr2(&u_2->uni_server, server, len_server);
392 }
393
394 /*******************************************************************
395  Reads or writes a structure.
396 ********************************************************************/
397
398 BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth)
399 {
400         if (u_2 == NULL)
401                 return False;
402
403         prs_debug(ps, depth, desc, "sam_io_unk_info2");
404         depth++;
405
406         if(!prs_uint32("unknown_0", ps, depth, &u_2->unknown_0)) /* 0x0000 0000 */
407                 return False;
408         if(!prs_uint32("unknown_1", ps, depth, &u_2->unknown_1)) /* 0x8000 0000 */
409                 return False;
410         if(!prs_uint32("unknown_2", ps, depth, &u_2->unknown_2)) /* 0x0000 0000 */
411                 return False;
412
413         if(!prs_uint32("ptr_0", ps, depth, &u_2->ptr_0))     /* pointer to unknown structure */
414                 return False;
415         if(!smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth)) /* domain name unicode header */
416                 return False;
417         if(!smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth)) /* server name unicode header */
418                 return False;
419
420         /* put all the data in here, at the moment, including what the above
421            pointer is referring to
422          */
423
424         if(!prs_uint32("seq_num ", ps, depth, &u_2->seq_num )) /* 0x0000 0099 or 0x1000 0000 */
425                 return False;
426         if(!prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3 )) /* 0x0000 0000 */
427                 return False;
428         
429         if(!prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 )) /* 0x0000 0001 */
430                 return False;
431         if(!prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 )) /* 0x0000 0003 */
432                 return False;
433         if(!prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 )) /* 0x0000 0001 */
434                 return False;
435         if(!prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs )) /* 0x0000 0008 */
436                 return False;
437         if(!prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps)) /* 0x0000 0003 */
438                 return False;
439         if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps)) /* 0x0000 0003 */
440                 return False;
441
442         if(!prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding))) /* 12 bytes zeros */
443                 return False;
444
445         if(!smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth)) /* domain name unicode string */
446                 return False;
447         if(!prs_align(ps))
448                 return False;
449
450         if(!smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth)) /* server name unicode string */
451                 return False;
452
453         if(!prs_align(ps))
454                 return False;
455
456         return True;
457 }
458
459 /*******************************************************************
460 Inits a structure.
461 ********************************************************************/
462 BOOL init_unk_info3(SAM_UNK_INFO_3 * u_3)
463 {
464         if (u_3 == NULL)
465                 return False;
466
467         u_3->unknown_0 = 0x00000000;
468         u_3->unknown_1 = 0x80000000;
469
470         return True;
471 }
472
473 /*******************************************************************
474 reads or writes a structure.
475 ********************************************************************/
476 static BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 *u_3, prs_struct *ps, int depth)
477 {
478         if (u_3 == NULL)
479                 return False;
480
481         prs_debug(ps, depth, desc, "sam_io_unk_info3");
482         depth++;
483
484         if(!prs_uint32("unknown_0", ps, depth, &u_3->unknown_0))        /* 0x0000 0000 */
485                 return False;
486         if(!prs_uint32("unknown_1", ps, depth, &u_3->unknown_1))        /* 0x8000 0000 */
487                 return False;
488
489         if(!prs_align(ps))
490                 return False;
491
492         return True;
493 }
494
495 /*******************************************************************
496 Inits a structure.
497 ********************************************************************/
498 BOOL init_unk_info6(SAM_UNK_INFO_6 * u_6)
499 {
500         if (u_6 == NULL)
501                 return False;
502
503         u_6->unknown_0 = 0x00000000;
504         u_6->ptr_0 = 1;
505         memset(u_6->padding, 0, sizeof(u_6->padding));  /* 12 bytes zeros */
506
507         return True;
508 }
509
510 /*******************************************************************
511 reads or writes a structure.
512 ********************************************************************/
513 static BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 *u_6, prs_struct *ps, int depth)
514 {
515         if (u_6 == NULL)
516                 return False;
517
518         prs_debug(ps, depth, desc, "sam_io_unk_info6");
519         depth++;
520
521         if(!prs_uint32("unknown_0", ps, depth, &u_6->unknown_0))        /* 0x0000 0000 */
522                 return False;
523         if(!prs_uint32("ptr_0", ps, depth, &u_6->ptr_0))        /* pointer to unknown structure */
524                 return False;
525         if(!prs_uint8s(False, "padding", ps, depth, u_6->padding, sizeof(u_6->padding)))        /* 12 bytes zeros */
526                 return False;
527
528         if(!prs_align(ps))
529                 return False;
530
531         return True;
532 }
533
534 /*******************************************************************
535 Inits a structure.
536 ********************************************************************/
537 BOOL init_unk_info7(SAM_UNK_INFO_7 *u_7)
538 {
539         if (u_7 == NULL)
540                 return False;
541
542         u_7->unknown_0 = 0x0003;
543
544         return True;
545 }
546
547 /*******************************************************************
548 reads or writes a structure.
549 ********************************************************************/
550 static BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 *u_7, prs_struct *ps, int depth)
551 {
552         if (u_7 == NULL)
553                 return False;
554
555         prs_debug(ps, depth, desc, "sam_io_unk_info7");
556         depth++;
557
558         if(!prs_uint16("unknown_0", ps, depth, &u_7->unknown_0))        /* 0x0003 */
559                 return False;
560         if(!prs_align(ps))
561                 return False;
562
563         return True;
564 }
565
566 /*******************************************************************
567 Inits a structure.
568 ********************************************************************/
569 BOOL init_unk_info12(SAM_UNK_INFO_12 * u_12)
570 {
571         if (u_12 == NULL)
572                 return False;
573
574         u_12->unknown_0 = 0xcf1dcc00;
575         u_12->unknown_1 = 0xfffffffb;
576         u_12->unknown_2 = 0xcf1dcc00;
577         u_12->unknown_3 = 0xfffffffb;
578
579         u_12->unknown_4 = 0x8a880000;
580
581         return True;
582 }
583
584 /*******************************************************************
585 reads or writes a structure.
586 ********************************************************************/
587 static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12,
588                              prs_struct *ps, int depth)
589 {
590         if (u_12 == NULL)
591                 return False;
592
593         prs_debug(ps, depth, desc, "sam_io_unk_info12");
594         depth++;
595
596         if(!prs_uint32("unknown_0", ps, depth, &u_12->unknown_0))
597                 return False;
598         if(!prs_uint32("unknown_1", ps, depth, &u_12->unknown_1))
599                 return False;
600         if(!prs_uint32("unknown_2", ps, depth, &u_12->unknown_2))
601                 return False;
602         if(!prs_uint32("unknown_3", ps, depth, &u_12->unknown_3))
603                 return False;
604         if(!prs_uint32("unknown_4", ps, depth, &u_12->unknown_4))
605                 return False;
606
607         if(!prs_align(ps))
608                 return False;
609
610         return True;
611 }
612
613 /*******************************************************************
614  Inits a SAMR_R_QUERY_DOMAIN_INFO structure.
615 ********************************************************************/
616
617 void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u, 
618                                 uint16 switch_value, SAM_UNK_CTR *ctr,
619                                 uint32 status)
620 {
621         DEBUG(5,("init_samr_r_query_dom_info\n"));
622
623         r_u->ptr_0 = 0;
624         r_u->switch_value = 0;
625         r_u->status = status; /* return status */
626
627         if (status == 0) {
628                 r_u->switch_value = switch_value;
629                 r_u->ptr_0 = 1;
630                 r_u->ctr = ctr;
631         }
632 }
633
634 /*******************************************************************
635  Reads or writes a structure.
636 ********************************************************************/
637
638 BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth)
639 {
640         if (r_u == NULL)
641                 return False;
642
643         prs_debug(ps, depth, desc, "samr_io_r_query_dom_info");
644         depth++;
645
646         if(!prs_align(ps))
647                 return False;
648
649         if(!prs_uint32("ptr_0       ", ps, depth, &r_u->ptr_0))
650                 return False;
651
652         if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
653                 if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
654                         return False;
655                 if(!prs_align(ps))
656                         return False;
657
658                 switch (r_u->switch_value) {
659                 case 0x01:
660                         if(!sam_io_unk_info1("unk_inf1", &r_u->ctr->info.inf1, ps, depth))
661                                 return False;
662                         break;
663                 case 0x02:
664                         if(!sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth))
665                                 return False;
666                         break;
667                 case 0x03:
668                         if(!sam_io_unk_info3("unk_inf3", &r_u->ctr->info.inf3, ps, depth))
669                                 return False;
670                         break;
671                 case 0x06:
672                         if(!sam_io_unk_info6("unk_inf6", &r_u->ctr->info.inf6, ps, depth))
673                                 return False;
674                         break;
675                 case 0x07:
676                         if(!sam_io_unk_info7("unk_inf7", &r_u->ctr->info.inf7, ps, depth))
677                                 return False;
678                         break;
679                 case 0x0c:
680                         if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
681                                 return False;
682                         break;
683                 default:
684                         DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
685                                   r_u->switch_value));
686                         return False;
687                 }
688         }
689
690         if(!prs_uint32("status", ps, depth, &r_u->status))
691                 return False;
692
693         return True;
694 }
695
696
697 /*******************************************************************
698  Inits a DOM_SID3 structure.
699  Calculate length by adding up the size of the components.
700  ********************************************************************/
701
702 void init_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid)
703 {
704         sid3->sid = *sid;
705         sid3->len = 2 + 8 + sid3->sid.num_auths * 4;
706 }
707
708 /*******************************************************************
709  Reads or writes a SAM_SID3 structure.
710
711  this one's odd, because the length (in bytes) is specified at the beginning.
712  the length _includes_ the length of the length, too :-)
713
714 ********************************************************************/
715
716 static BOOL sam_io_dom_sid3(char *desc,  DOM_SID3 *sid3, prs_struct *ps, int depth)
717 {
718         if (sid3 == NULL)
719                 return False;
720
721         prs_debug(ps, depth, desc, "sam_io_dom_sid3");
722         depth++;
723
724         if(!prs_uint16("len", ps, depth, &sid3->len))
725                 return False;
726         if(!prs_align(ps))
727                 return False;
728         if(!smb_io_dom_sid("", &sid3->sid, ps, depth))
729                 return False;
730
731         return True;
732 }
733
734 /*******************************************************************
735  Inits a SAMR_R_UNKNOWN3 structure.
736
737 unknown_2   : 0x0001
738 unknown_3   : 0x8004
739
740 unknown_4,5 : 0x0000 0014
741
742 unknown_6   : 0x0002
743 unknown_7   : 0x5800 or 0x0070
744
745 ********************************************************************/
746
747 static void init_sam_sid_stuff(SAM_SID_STUFF *stf,
748                                 uint16 unknown_2, uint16 unknown_3,
749                                 uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
750                                 int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS])
751 {
752         stf->unknown_2 = unknown_2;
753         stf->unknown_3 = unknown_3;
754
755         memset((char *)stf->padding1, '\0', sizeof(stf->padding1));
756
757         stf->unknown_4 = unknown_4;
758         stf->unknown_5 = unknown_4;
759
760         stf->unknown_6 = unknown_6;
761         stf->unknown_7 = unknown_7;
762
763         stf->num_sids  = num_sid3s;
764
765         stf->padding2  = 0x0000;
766
767         memcpy(stf->sid, sid3, sizeof(DOM_SID3) * num_sid3s);
768 }
769
770 /*******************************************************************
771  Reads or writes a SAM_SID_STUFF structure.
772 ********************************************************************/
773
774 static BOOL sam_io_sid_stuff(char *desc,  SAM_SID_STUFF *stf, prs_struct *ps, int depth)
775 {
776         int i;
777
778         if (stf == NULL)
779                 return False;
780
781         DEBUG(5,("init_sam_sid_stuff\n"));
782
783         if(!prs_uint16("unknown_2", ps, depth, &stf->unknown_2))
784                 return False;
785         if(!prs_uint16("unknown_3", ps, depth, &stf->unknown_3))
786                 return False;
787
788         if(!prs_uint8s(False, "padding1", ps, depth, stf->padding1, sizeof(stf->padding1)))
789                 return False;
790         
791         if(!prs_uint32("unknown_4", ps, depth, &stf->unknown_4))
792                 return False;
793         if(!prs_uint32("unknown_5", ps, depth, &stf->unknown_5))
794                 return False;
795         if(!prs_uint16("unknown_6", ps, depth, &stf->unknown_6))
796                 return False;
797         if(!prs_uint16("unknown_7", ps, depth, &stf->unknown_7))
798                 return False;
799
800         if(!prs_uint32("num_sids ", ps, depth, &stf->num_sids ))
801                 return False;
802         if(!prs_uint16("padding2 ", ps, depth, &stf->padding2 ))
803                 return False;
804
805         SMB_ASSERT_ARRAY(stf->sid, stf->num_sids);
806
807         for (i = 0; i < stf->num_sids; i++) {
808                 if(!sam_io_dom_sid3("", &(stf->sid[i]), ps, depth))
809                         return False;
810         }
811
812         return True;
813 }
814
815 /*******************************************************************
816  Inits or writes a SAMR_R_UNKNOWN3 structure.
817 ********************************************************************/
818
819 void init_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
820                                 uint16 unknown_2, uint16 unknown_3,
821                                 uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
822                                 int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
823                                 uint32 status)
824 {
825         DEBUG(5,("samr_init_r_unknown_3\n"));
826
827         r_u->ptr_0 = 0;
828         r_u->ptr_1 = 0;
829
830         if (status == 0x0) {
831                 r_u->ptr_0 = 1;
832                 r_u->ptr_1 = 1;
833                 init_sam_sid_stuff(&(r_u->sid_stuff), unknown_2, unknown_3,
834                        unknown_4, unknown_6, unknown_7,
835                        num_sid3s, sid3);
836         }
837
838         r_u->status = status;
839 }
840
841 /*******************************************************************
842  Reads or writes a SAMR_R_UNKNOWN_3 structure.
843
844 this one's odd, because the daft buggers use a different mechanism
845 for writing out the array of sids. they put the number of sids in
846 only one place: they've calculated the length of each sid and jumped
847 by that amount.  then, retrospectively, the length of the whole buffer
848 is put at the beginning of the data stream.
849
850 wierd.  
851
852 ********************************************************************/
853
854 BOOL samr_io_r_unknown_3(char *desc,  SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth)
855 {
856         int ptr_len0=0;
857         int ptr_len1=0;
858         int ptr_sid_stuff = 0;
859
860         if (r_u == NULL)
861                 return False;
862
863         prs_debug(ps, depth, desc, "samr_io_r_unknown_3");
864         depth++;
865
866         if(!prs_align(ps))
867                 return False;
868
869         if(!prs_uint32("ptr_0         ", ps, depth, &r_u->ptr_0))
870                 return False;
871
872         if (ps->io) {
873                 /* reading.  do the length later */
874                 if(!prs_uint32("sid_stuff_len0", ps, depth, &r_u->sid_stuff_len0))
875                         return False;
876         } else {
877                 /* storing */
878                 ptr_len0 = prs_offset(ps);
879                 if(!prs_set_offset(ps, ptr_len0 + 4))
880                         return False;
881         }
882
883         if (r_u->ptr_0 != 0) {
884                 if(!prs_uint32("ptr_1         ", ps, depth, &r_u->ptr_1))
885                         return False;
886                 if (ps->io) {
887                         /* reading.  do the length later */
888                         if(!prs_uint32("sid_stuff_len1", ps, depth, &r_u->sid_stuff_len1))
889                                 return False;
890                 } else {
891                         /* storing */
892                         ptr_len1 = prs_offset(ps);
893                         if(!prs_set_offset(ps, ptr_len1 + 4))
894                                 return False;
895                 }
896
897                 if (r_u->ptr_1 != 0) {
898                         ptr_sid_stuff = prs_offset(ps);
899                         if(!sam_io_sid_stuff("", &r_u->sid_stuff, ps, depth))
900                                 return False;
901                 }
902         }
903
904         if (!(ps->io)) {
905                 /* storing not reading.  do the length, now. */
906
907                 if (ptr_sid_stuff != 0) {
908                         int old_len = prs_offset(ps);
909                         uint32 sid_stuff_len = old_len - ptr_sid_stuff;
910
911                         if(!prs_set_offset(ps, ptr_len0))
912                                 return False;
913                         if(!prs_uint32("sid_stuff_len0", ps, depth, &sid_stuff_len))
914                                 return False;
915
916                         if(!prs_set_offset(ps, ptr_len1))
917                                 return False;
918                         if(!prs_uint32("sid_stuff_len1", ps, depth, &sid_stuff_len))
919                                 return False;
920
921                         if(!prs_set_offset(ps, old_len))
922                                 return False;
923                 }
924         }
925
926         if(!prs_uint32("status", ps, depth, &r_u->status))
927                 return False;
928
929         return True;
930 }
931
932 /*******************************************************************
933  Reads or writes a SAM_STR1 structure.
934 ********************************************************************/
935
936 static BOOL sam_io_sam_str1(char *desc, SAM_STR1 *sam, uint32 acct_buf,
937                                 uint32 name_buf, uint32 desc_buf, prs_struct *ps, int depth)
938 {
939         if (sam == NULL)
940                 return False;
941
942         prs_debug(ps, depth, desc, "sam_io_sam_str1");
943         depth++;
944
945         if(!prs_align(ps))
946                 return False;
947
948         if(!smb_io_unistr2("unistr2", &sam->uni_acct_name, acct_buf, ps, depth)) /* account name unicode string */
949                 return False;
950         if(!smb_io_unistr2("unistr2", &sam->uni_full_name, name_buf, ps, depth)) /* full name unicode string */
951                 return False;
952         if(!smb_io_unistr2("unistr2", &sam->uni_acct_desc, desc_buf, ps, depth)) /* account description unicode string */
953                 return False;
954
955         return True;
956 }
957
958 /*******************************************************************
959  Inits a SAM_ENTRY1 structure.
960 ********************************************************************/
961
962 static void init_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx, 
963                                 uint32 len_sam_name, uint32 len_sam_full, uint32 len_sam_desc,
964                                 uint32 rid_user, uint16 acb_info)
965 {
966         DEBUG(5,("init_sam_entry1\n"));
967
968         sam->user_idx = user_idx;
969         sam->rid_user = rid_user;
970         sam->acb_info = acb_info;
971         sam->pad      = 0;
972
973         init_uni_hdr(&sam->hdr_acct_name, len_sam_name);
974         init_uni_hdr(&sam->hdr_user_name, len_sam_full);
975         init_uni_hdr(&sam->hdr_user_desc, len_sam_desc);
976 }
977
978 /*******************************************************************
979  Reads or writes a SAM_ENTRY1 structure.
980 ********************************************************************/
981
982 static BOOL sam_io_sam_entry1(char *desc,  SAM_ENTRY1 *sam, prs_struct *ps, int depth)
983 {
984         if (sam == NULL)
985                 return False;
986
987         prs_debug(ps, depth, desc, "sam_io_sam_entry1");
988         depth++;
989
990         if(!prs_align(ps))
991                 return False;
992
993         if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
994                 return False;
995
996         if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
997                 return False;
998         if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
999                 return False;
1000         if(!prs_uint16("pad      ", ps, depth, &sam->pad))
1001                 return False;
1002
1003         if(!smb_io_unihdr("unihdr", &sam->hdr_acct_name, ps, depth)) /* account name unicode string header */
1004                 return False;
1005         if(!smb_io_unihdr("unihdr", &sam->hdr_user_name, ps, depth)) /* account name unicode string header */
1006                 return False;
1007         if(!smb_io_unihdr("unihdr", &sam->hdr_user_desc, ps, depth)) /* account name unicode string header */
1008                 return False;
1009
1010         return True;
1011 }
1012
1013 /*******************************************************************
1014  Reads or writes a SAM_STR2 structure.
1015 ********************************************************************/
1016
1017 static BOOL sam_io_sam_str2(char *desc,  SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
1018 {
1019         if (sam == NULL)
1020                 return False;
1021
1022         prs_debug(ps, depth, desc, "sam_io_sam_str2");
1023         depth++;
1024
1025         if(!prs_align(ps))
1026                 return False;
1027
1028         if(!smb_io_unistr2("unistr2", &sam->uni_srv_name, acct_buf, ps, depth)) /* account name unicode string */
1029                 return False;
1030         if(!smb_io_unistr2("unistr2", &sam->uni_srv_desc, desc_buf, ps, depth)) /* account description unicode string */
1031                 return False;
1032
1033         return True;
1034 }
1035
1036 /*******************************************************************
1037  Inits a SAM_ENTRY2 structure.
1038 ********************************************************************/
1039
1040 static void init_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx, 
1041                                 uint32 len_sam_name, uint32 len_sam_desc,
1042                                 uint32 rid_user, uint16 acb_info)
1043 {
1044         DEBUG(5,("init_sam_entry2\n"));
1045
1046         sam->user_idx = user_idx;
1047         sam->rid_user = rid_user;
1048         sam->acb_info = acb_info;
1049         sam->pad      = 0;
1050
1051         init_uni_hdr(&sam->hdr_srv_name, len_sam_name);
1052         init_uni_hdr(&sam->hdr_srv_desc, len_sam_desc);
1053 }
1054
1055 /*******************************************************************
1056  Reads or writes a SAM_ENTRY2 structure.
1057 ********************************************************************/
1058
1059 static BOOL sam_io_sam_entry2(char *desc,  SAM_ENTRY2 *sam, prs_struct *ps, int depth)
1060 {
1061         if (sam == NULL)
1062                 return False;
1063
1064         prs_debug(ps, depth, desc, "sam_io_sam_entry2");
1065         depth++;
1066
1067         if(!prs_align(ps))
1068                 return False;
1069
1070         if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
1071                 return False;
1072
1073         if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
1074                 return False;
1075         if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
1076                 return False;
1077         if(!prs_uint16("pad      ", ps, depth, &sam->pad))
1078                 return False;
1079
1080         if(!smb_io_unihdr("unihdr", &sam->hdr_srv_name, ps, depth)) /* account name unicode string header */
1081                 return False;
1082         if(!smb_io_unihdr("unihdr", &sam->hdr_srv_desc, ps, depth)) /* account name unicode string header */
1083                 return False;
1084
1085         return True;
1086 }
1087
1088 /*******************************************************************
1089  Reads or writes a SAM_STR3 structure.
1090 ********************************************************************/
1091
1092 static BOOL sam_io_sam_str3(char *desc,  SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
1093 {
1094         if (sam == NULL)
1095                 return False;
1096
1097         prs_debug(ps, depth, desc, "sam_io_sam_str3");
1098         depth++;
1099
1100         if(!prs_align(ps))
1101                 return False;
1102
1103         if(!smb_io_unistr2("unistr2", &sam->uni_grp_name, acct_buf, ps, depth)) /* account name unicode string */
1104                 return False;
1105         if(!smb_io_unistr2("unistr2", &sam->uni_grp_desc, desc_buf, ps, depth)) /* account description unicode string */
1106                 return False;
1107
1108         return True;
1109 }
1110
1111 /*******************************************************************
1112  Inits a SAM_ENTRY3 structure.
1113 ********************************************************************/
1114
1115 static void init_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx, 
1116                                 uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp)
1117 {
1118         DEBUG(5,("init_sam_entry3\n"));
1119
1120         ZERO_STRUCTP(sam);
1121         sam->grp_idx = grp_idx;
1122         sam->rid_grp = rid_grp;
1123         sam->attr    = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
1124
1125         init_uni_hdr(&sam->hdr_grp_name, len_grp_name);
1126         init_uni_hdr(&sam->hdr_grp_desc, len_grp_desc);
1127 }
1128
1129 /*******************************************************************
1130  Reads or writes a SAM_ENTRY3 structure.
1131 ********************************************************************/
1132
1133 static BOOL sam_io_sam_entry3(char *desc,  SAM_ENTRY3 *sam, prs_struct *ps, int depth)
1134 {
1135         if (sam == NULL)
1136                 return False;
1137
1138         prs_debug(ps, depth, desc, "sam_io_sam_entry3");
1139         depth++;
1140
1141         if(!prs_align(ps))
1142                 return False;
1143
1144         if(!prs_uint32("grp_idx", ps, depth, &sam->grp_idx))
1145                 return False;
1146
1147         if(!prs_uint32("rid_grp", ps, depth, &sam->rid_grp))
1148                 return False;
1149         if(!prs_uint32("attr   ", ps, depth, &sam->attr))
1150                 return False;
1151
1152         if(!smb_io_unihdr("unihdr", &sam->hdr_grp_name, ps, depth)) /* account name unicode string header */
1153                 return False;
1154         if(!smb_io_unihdr("unihdr", &sam->hdr_grp_desc, ps, depth)) /* account name unicode string header */
1155                 return False;
1156
1157         return True;
1158 }
1159
1160 /*******************************************************************
1161  Inits a SAM_ENTRY structure.
1162 ********************************************************************/
1163
1164 static void init_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
1165 {
1166         DEBUG(5,("init_sam_entry\n"));
1167
1168         sam->rid = rid;
1169         init_uni_hdr(&sam->hdr_name, len_sam_name);
1170 }
1171
1172 /*******************************************************************
1173  Reads or writes a SAM_ENTRY structure.
1174 ********************************************************************/
1175
1176 static BOOL sam_io_sam_entry(char *desc,  SAM_ENTRY *sam, prs_struct *ps, int depth)
1177 {
1178         if (sam == NULL)
1179                 return False;
1180
1181         prs_debug(ps, depth, desc, "sam_io_sam_entry");
1182         depth++;
1183
1184         if(!prs_align(ps))
1185                 return False;
1186         if(!prs_uint32("rid", ps, depth, &sam->rid))
1187                 return False;
1188         if(!smb_io_unihdr("unihdr", &sam->hdr_name, ps, depth)) /* account name unicode string header */
1189                 return False;
1190
1191         return True;
1192 }
1193
1194
1195 /*******************************************************************
1196  Inits a SAMR_Q_ENUM_DOM_USERS structure.
1197 ********************************************************************/
1198
1199 void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
1200                                 uint16 req_num_entries, uint16 unk_0,
1201                                 uint16 acb_mask, uint16 unk_1, uint32 size)
1202 {
1203         DEBUG(5,("init_q_enum_dom_users\n"));
1204
1205         memcpy(&q_e->pol, pol, sizeof(*pol));
1206
1207         q_e->req_num_entries = req_num_entries; /* zero indicates lots */
1208         q_e->unknown_0 = unk_0; /* this gets returned in the response */
1209         q_e->acb_mask  = acb_mask;
1210         q_e->unknown_1 = unk_1;
1211         q_e->max_size = size;
1212 }
1213
1214 /*******************************************************************
1215  Reads or writes a structure.
1216 ********************************************************************/
1217
1218 BOOL samr_io_q_enum_dom_users(char *desc,  SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth)
1219 {
1220         if (q_e == NULL)
1221                 return False;
1222
1223         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
1224         depth++;
1225
1226         if(!prs_align(ps))
1227                 return False;
1228
1229         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
1230                 return False;
1231         if(!prs_align(ps))
1232                 return False;
1233
1234         if(!prs_uint16("req_num_entries", ps, depth, &q_e->req_num_entries))
1235                 return False;
1236         if(!prs_uint16("unknown_0      ", ps, depth, &q_e->unknown_0))
1237                 return False;
1238
1239         if(!prs_uint16("acb_mask       ", ps, depth, &q_e->acb_mask))
1240                 return False;
1241         if(!prs_uint16("unknown_1      ", ps, depth, &q_e->unknown_1))
1242                 return False;
1243
1244         if(!prs_uint32("max_size       ", ps, depth, &q_e->max_size))
1245                 return False;
1246
1247         if(!prs_align(ps))
1248                 return False;
1249
1250         return True;
1251 }
1252
1253
1254 /*******************************************************************
1255  Inits a SAMR_R_ENUM_DOM_USERS structure.
1256 ********************************************************************/
1257
1258 void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
1259                 uint16 total_num_entries, uint16 unk_0,
1260                 uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status)
1261 {
1262         int i;
1263
1264         DEBUG(5,("init_samr_r_enum_dom_users\n"));
1265
1266         if (num_sam_entries >= MAX_SAM_ENTRIES) {
1267                 num_sam_entries = MAX_SAM_ENTRIES;
1268                 DEBUG(5,("limiting number of entries to %d\n",
1269                          num_sam_entries));
1270         }
1271
1272         r_u->total_num_entries = total_num_entries;
1273         r_u->unknown_0         = unk_0;
1274
1275         if (total_num_entries > 0) {
1276                 r_u->ptr_entries1 = 1;
1277                 r_u->ptr_entries2 = 1;
1278                 r_u->num_entries2 = num_sam_entries;
1279                 r_u->num_entries3 = num_sam_entries;
1280
1281                 SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
1282                 SMB_ASSERT_ARRAY(r_u->uni_acct_name, num_sam_entries);
1283
1284                 for (i = 0; i < num_sam_entries; i++) {
1285                         init_sam_entry(&(r_u->sam[i]),
1286                                        pass[i].uni_user_name.uni_str_len,
1287                                        pass[i].user_rid);
1288
1289                         copy_unistr2(&r_u->uni_acct_name[i], &(pass[i].uni_user_name));
1290                 }
1291
1292                 r_u->num_entries4 = num_sam_entries;
1293         } else {
1294                 r_u->ptr_entries1 = 0;
1295                 r_u->num_entries2 = num_sam_entries;
1296                 r_u->ptr_entries2 = 1;
1297         }
1298
1299         r_u->status = status;
1300 }
1301
1302 /*******************************************************************
1303  Reads or writes a structure.
1304 ********************************************************************/
1305
1306 BOOL samr_io_r_enum_dom_users(char *desc,  SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth)
1307 {
1308         int i;
1309
1310         if (r_u == NULL)
1311                 return False;
1312
1313         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
1314         depth++;
1315
1316         if(!prs_align(ps))
1317                 return False;
1318
1319         if(!prs_uint16("total_num_entries", ps, depth, &r_u->total_num_entries))
1320                 return False;
1321         if(!prs_uint16("unknown_0        ", ps, depth, &r_u->unknown_0))
1322                 return False;
1323         if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
1324                 return False;
1325
1326         if (r_u->total_num_entries != 0 && r_u->ptr_entries1 != 0) {
1327                 if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
1328                         return False;
1329                 if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
1330                         return False;
1331                 if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
1332                         return False;
1333
1334                 SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries2);
1335
1336                 for (i = 0; i < r_u->num_entries2; i++) {
1337                         if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
1338                                 return False;
1339                 }
1340
1341                 SMB_ASSERT_ARRAY(r_u->uni_acct_name, r_u->num_entries2);
1342
1343                 for (i = 0; i < r_u->num_entries2; i++) {
1344                         if(!smb_io_unistr2("", &r_u->uni_acct_name[i],
1345                                         r_u->sam[i].hdr_name.buffer, ps, depth))
1346                                 return False;
1347                 }
1348
1349                 if(!prs_align(ps))
1350                         return False;
1351
1352                 if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
1353                         return False;
1354         }
1355
1356         if(!prs_uint32("status", ps, depth, &r_u->status))
1357                 return False;
1358
1359         return True;
1360 }
1361
1362 /*******************************************************************
1363  Inits a SAMR_Q_ENUM_DOM_ALIASES structure.
1364 ********************************************************************/
1365
1366 void init_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size)
1367 {
1368         DEBUG(5,("init_q_enum_dom_aliases\n"));
1369
1370         memcpy(&q_e->pol, pol, sizeof(*pol));
1371
1372         q_e->unknown_0 = 0;
1373         q_e->max_size = size;
1374 }
1375
1376
1377 /*******************************************************************
1378  Reads or writes a structure.
1379 ********************************************************************/
1380
1381 BOOL samr_io_q_enum_dom_aliases(char *desc,  SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth)
1382 {
1383         if (q_e == NULL)
1384                 return False;
1385
1386         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
1387         depth++;
1388
1389         if(!prs_align(ps))
1390                 return False;
1391
1392         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
1393                 return False;
1394         if(!prs_align(ps))
1395                 return False;
1396
1397         if(!prs_uint32("unknown_0", ps, depth, &q_e->unknown_0))
1398                 return False;
1399         if(!prs_uint32("max_size ", ps, depth, &q_e->max_size ))
1400                 return False;
1401
1402         if(!prs_align(ps))
1403                 return False;
1404
1405         return True;
1406 }
1407
1408
1409 /*******************************************************************
1410  Inits a SAMR_R_ENUM_DOM_ALIASES structure.
1411 ********************************************************************/
1412
1413 void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
1414                 uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
1415                 uint32 status)
1416 {
1417         int i;
1418
1419         DEBUG(5,("init_samr_r_enum_dom_aliases\n"));
1420
1421         if (num_sam_entries >= MAX_SAM_ENTRIES) {
1422                 num_sam_entries = MAX_SAM_ENTRIES;
1423                 DEBUG(5,("limiting number of entries to %d\n", 
1424                          num_sam_entries));
1425         }
1426
1427         r_u->num_entries  = num_sam_entries;
1428
1429         if (num_sam_entries > 0) {
1430                 r_u->ptr_entries  = 1;
1431                 r_u->num_entries2 = num_sam_entries;
1432                 r_u->ptr_entries2 = 1;
1433                 r_u->num_entries3 = num_sam_entries;
1434
1435                 SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
1436
1437                 for (i = 0; i < num_sam_entries; i++) {
1438                         init_sam_entry(&r_u->sam[i],
1439                                        grps[i].uni_user_name.uni_str_len,
1440                                        grps[i].user_rid);
1441
1442                         copy_unistr2(&r_u->uni_grp_name[i], &(grps[i].uni_user_name));
1443                 }
1444
1445                 r_u->num_entries4 = num_sam_entries;
1446         } else {
1447                 r_u->ptr_entries = 0;
1448         }
1449
1450         r_u->status = status;
1451 }
1452
1453 /*******************************************************************
1454  Reads or writes a structure.
1455 ********************************************************************/
1456
1457 BOOL samr_io_r_enum_dom_aliases(char *desc,  SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth)
1458 {
1459         int i;
1460
1461         if (r_u == NULL)
1462                 return False;
1463
1464         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
1465         depth++;
1466
1467         if(!prs_align(ps))
1468                 return False;
1469
1470         if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
1471                 return False;
1472         if(!prs_uint32("ptr_entries", ps, depth, &r_u->ptr_entries))
1473                 return False;
1474
1475         if (r_u->num_entries != 0 && r_u->ptr_entries != 0) {
1476                 if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
1477                         return False;
1478                 if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
1479                         return False;
1480                 if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
1481                         return False;
1482
1483                 SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
1484
1485                 for (i = 0; i < r_u->num_entries; i++) {
1486                         if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
1487                                 return False;
1488                 }
1489
1490                 for (i = 0; i < r_u->num_entries; i++) {
1491                         if(!smb_io_unistr2("", &r_u->uni_grp_name[i], r_u->sam[i].hdr_name.buffer, ps, depth))
1492                                 return False;
1493                 }
1494
1495                 if(!prs_align(ps))
1496                         return False;
1497
1498                 if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
1499                         return False;
1500         }
1501
1502         if(!prs_uint32("status", ps, depth, &r_u->status))
1503                 return False;
1504
1505         return True;
1506 }
1507
1508
1509 /*******************************************************************
1510  Inits a SAMR_Q_QUERY_DISPINFO structure.
1511 ********************************************************************/
1512
1513 void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
1514                                 uint16 switch_level, uint32 start_idx, uint32 size)
1515 {
1516         DEBUG(5,("init_q_query_dispinfo\n"));
1517
1518         memcpy(&q_e->pol, pol, sizeof(*pol));
1519
1520         q_e->switch_level = switch_level;
1521
1522         q_e->start_idx = start_idx;
1523         q_e->max_entries = 0;
1524         q_e->max_size  = size;
1525 }
1526
1527 /*******************************************************************
1528  Reads or writes a structure.
1529 ********************************************************************/
1530
1531 BOOL samr_io_q_query_dispinfo(char *desc,  SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
1532 {
1533         if (q_e == NULL)
1534                 return False;
1535
1536         prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
1537         depth++;
1538
1539         if(!prs_align(ps))
1540                 return False;
1541
1542         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
1543                 return False;
1544         if(!prs_align(ps))
1545                 return False;
1546
1547         if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
1548                 return False;
1549 #if 0
1550         if(!prs_uint16("unknown_0   ", ps, depth, &q_e->unknown_0))
1551                 return False;
1552 #else
1553         prs_align(ps);
1554 #endif
1555         if(!prs_uint32("start_idx   ", ps, depth, &q_e->start_idx))
1556                 return False;
1557         if(!prs_uint32("max_entries ", ps, depth, &q_e->max_entries))
1558                 return False;
1559         if(!prs_uint32("max_size    ", ps, depth, &q_e->max_size))
1560                 return False;
1561
1562         if(!prs_align(ps))
1563                 return False;
1564
1565         return True;
1566 }
1567
1568
1569 /*******************************************************************
1570  Inits a SAM_INFO_2 structure.
1571 ********************************************************************/
1572
1573 void init_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
1574                 uint32 start_idx, uint32 num_sam_entries,
1575                 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
1576 {
1577         int i;
1578         int entries_added;
1579
1580         DEBUG(5,("init_sam_info_2\n"));
1581
1582         if (num_sam_entries >= MAX_SAM_ENTRIES) {
1583                 num_sam_entries = MAX_SAM_ENTRIES;
1584                 DEBUG(5,("limiting number of entries to %d\n", 
1585                          num_sam_entries));
1586         }
1587
1588         for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
1589                 if ((pass[i].acb_info & acb_mask) == acb_mask) {
1590                         init_sam_entry2(&sam->sam[entries_added],
1591                                         start_idx + entries_added + 1,
1592                                         pass[i].uni_user_name.uni_str_len,
1593                                         pass[i].uni_acct_desc.uni_str_len,
1594                                         pass[i].user_rid,
1595                                         pass[i].acb_info);
1596
1597                         copy_unistr2(&sam->str[entries_added].uni_srv_name, &pass[i].uni_user_name);
1598                         copy_unistr2(&sam->str[entries_added].uni_srv_desc, &pass[i].uni_acct_desc);
1599
1600                         entries_added++;
1601                 }
1602
1603                 sam->num_entries   = entries_added;
1604                 sam->ptr_entries   = 1;
1605                 sam->num_entries2  = entries_added;
1606         }
1607 }
1608
1609 /*******************************************************************
1610  Reads or writes a structure.
1611 ********************************************************************/
1612
1613 static BOOL sam_io_sam_info_2(char *desc,  SAM_INFO_2 *sam, prs_struct *ps, int depth)
1614 {
1615         int i;
1616
1617         if (sam == NULL)
1618                 return False;
1619
1620         prs_debug(ps, depth, desc, "sam_io_sam_info_2");
1621         depth++;
1622
1623         if(!prs_align(ps))
1624                 return False;
1625
1626         if(!prs_uint32("num_entries  ", ps, depth, &sam->num_entries))
1627                 return False;
1628         if(!prs_uint32("ptr_entries  ", ps, depth, &sam->ptr_entries))
1629                 return False;
1630
1631         if(!prs_uint32("num_entries2 ", ps, depth, &sam->num_entries2))
1632                 return False;
1633
1634         SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
1635
1636         for (i = 0; i < sam->num_entries; i++) {
1637                 if(!sam_io_sam_entry2("", &sam->sam[i], ps, depth))
1638                         return False;
1639         }
1640
1641         for (i = 0; i < sam->num_entries; i++) {
1642                 if(!sam_io_sam_str2 ("", &sam->str[i],
1643                                  sam->sam[i].hdr_srv_name.buffer,
1644                                  sam->sam[i].hdr_srv_desc.buffer,
1645                                  ps, depth))
1646                         return False;
1647         }
1648
1649         return True;
1650 }
1651
1652 /*******************************************************************
1653  Inits a SAM_INFO_1 structure.
1654 ********************************************************************/
1655
1656 void init_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
1657                 uint32 start_idx, uint32 num_sam_entries,
1658                 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
1659 {
1660         int i;
1661         int entries_added;
1662
1663         DEBUG(5,("init_sam_info_1\n"));
1664
1665         if (num_sam_entries >= MAX_SAM_ENTRIES) {
1666                 num_sam_entries = MAX_SAM_ENTRIES;
1667                 DEBUG(5,("limiting number of entries to %d\n", 
1668                          num_sam_entries));
1669         }
1670         DEBUG(5,("num_sam_entries: %u, start_idx: %u\n",num_sam_entries,
1671                  num_sam_entries));
1672
1673         for (i = 0, entries_added = 0; 
1674              i < num_sam_entries; i++) {
1675                 if ((pass[i].acb_info & acb_mask) == acb_mask) {
1676                         init_sam_entry1(&sam->sam[entries_added],
1677                                                 start_idx + entries_added + 1,
1678                                                 pass[i].uni_user_name.uni_str_len,
1679                                                 pass[i].uni_full_name.uni_str_len, 
1680                                                 pass[i].uni_acct_desc.uni_str_len,
1681                                                 pass[i].user_rid,
1682                                                 pass[i].acb_info);
1683
1684                         copy_unistr2(&sam->str[entries_added].uni_acct_name, &pass[i].uni_user_name);
1685                         copy_unistr2(&sam->str[entries_added].uni_full_name, &pass[i].uni_full_name);
1686                         copy_unistr2(&sam->str[entries_added].uni_acct_desc, &pass[i].uni_acct_desc);
1687
1688                         entries_added++;
1689                 } 
1690         }
1691
1692         sam->num_entries   = entries_added;
1693         sam->ptr_entries   = 1;
1694         sam->num_entries2  = entries_added;
1695 }
1696
1697 /*******************************************************************
1698  Reads or writes a structure.
1699 ********************************************************************/
1700
1701 static BOOL sam_io_sam_info_1(char *desc,  SAM_INFO_1 *sam, prs_struct *ps, int depth)
1702 {
1703         int i;
1704
1705         if (sam == NULL)
1706                 return False;
1707
1708         prs_debug(ps, depth, desc, "sam_io_sam_info_1");
1709         depth++;
1710
1711         if(!prs_align(ps))
1712                 return False;
1713
1714         if(!prs_uint32("num_entries  ", ps, depth, &sam->num_entries))
1715                 return False;
1716         if(!prs_uint32("ptr_entries  ", ps, depth, &sam->ptr_entries))
1717                 return False;
1718
1719         if(!prs_uint32("num_entries2 ", ps, depth, &sam->num_entries2))
1720                 return False;
1721
1722         SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
1723
1724         for (i = 0; i < sam->num_entries; i++) {
1725                 if(!sam_io_sam_entry1("", &sam->sam[i], ps, depth))
1726                         return False;
1727         }
1728
1729         for (i = 0; i < sam->num_entries; i++) {
1730                 if(!sam_io_sam_str1 ("", &sam->str[i],
1731                                                          sam->sam[i].hdr_acct_name.buffer,
1732                                                          sam->sam[i].hdr_user_name.buffer,
1733                                                          sam->sam[i].hdr_user_desc.buffer,
1734                                                          ps, depth))
1735                 return False;
1736         }
1737
1738         return True;
1739 }
1740
1741 /*******************************************************************
1742  Inits a SAMR_R_QUERY_DISPINFO structure.
1743 ********************************************************************/
1744
1745 void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
1746                 uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status)
1747 {
1748         DEBUG(5,("init_samr_r_query_dispinfo\n"));
1749
1750         if (status == 0x0 || status == 0x105) {
1751                 r_u->unknown_0 = 0x0000001;
1752                 r_u->unknown_1 = 0x0000001;
1753         } else {
1754                 r_u->unknown_0 = 0x0;
1755                 r_u->unknown_1 = 0x0;
1756         }
1757
1758         r_u->switch_level = switch_level;
1759         r_u->ctr = ctr;
1760         r_u->status = status;
1761 }
1762
1763 /*******************************************************************
1764  Reads or writes a structure.
1765 ********************************************************************/
1766
1767 BOOL samr_io_r_query_dispinfo(char *desc,  SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
1768 {
1769         if (r_u == NULL)
1770                 return False;
1771
1772         prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
1773         depth++;
1774
1775         if(!prs_align(ps))
1776                 return False;
1777
1778         if(!prs_uint32("unknown_0    ", ps, depth, &r_u->unknown_0))
1779                 return False;
1780         if(!prs_uint32("unknown_1    ", ps, depth, &r_u->unknown_1))
1781                 return False;
1782         if(!prs_uint16("switch_level ", ps, depth, &r_u->switch_level))
1783                 return False;
1784
1785         if(!prs_align(ps))
1786                 return False;
1787
1788         switch (r_u->switch_level) {
1789         case 0x1:
1790                 if(!sam_io_sam_info_1("users", r_u->ctr->sam.info1, ps, depth))
1791                         return False;
1792                 break;
1793         case 0x2:
1794                 if(!sam_io_sam_info_2("servers", r_u->ctr->sam.info2, ps, depth))
1795                         return False;
1796                 break;
1797         default:
1798                 DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
1799                 break;
1800         }
1801
1802         if(!prs_uint32("status", ps, depth, &r_u->status))
1803                 return False;
1804
1805         return True;
1806 }
1807
1808 /*******************************************************************
1809  Inits a SAMR_Q_ENUM_DOM_GROUPS structure.
1810 ********************************************************************/
1811
1812 void init_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
1813                                 uint16 switch_level, uint32 start_idx, uint32 size)
1814 {
1815         DEBUG(5,("init_q_enum_dom_groups\n"));
1816
1817         memcpy(&q_e->pol, pol, sizeof(*pol));
1818
1819         q_e->switch_level = switch_level;
1820
1821         q_e->unknown_0 = 0;
1822         q_e->start_idx = start_idx;
1823         q_e->unknown_1 = 0x000007d0;
1824         q_e->max_size  = size;
1825 }
1826
1827 /*******************************************************************
1828  Reads or writes a structure.
1829 ********************************************************************/
1830
1831 BOOL samr_io_q_enum_dom_groups(char *desc,  SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth)
1832 {
1833         if (q_e == NULL)
1834                 return False;
1835
1836         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
1837         depth++;
1838
1839         if(!prs_align(ps))
1840                 return False;
1841
1842         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
1843                 return False;
1844         if(!prs_align(ps))
1845                 return False;
1846
1847         if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
1848                 return False;
1849         if(!prs_uint16("unknown_0   ", ps, depth, &q_e->unknown_0))
1850                 return False;
1851         if(!prs_uint32("start_idx   ", ps, depth, &q_e->start_idx))
1852                 return False;
1853         if(!prs_uint32("unknown_1   ", ps, depth, &q_e->unknown_1))
1854                 return False;
1855         if(!prs_uint32("max_size    ", ps, depth, &q_e->max_size))
1856                 return False;
1857
1858         if(!prs_align(ps))
1859                 return False;
1860
1861         return True;
1862 }
1863
1864
1865 /*******************************************************************
1866  Inits a SAMR_R_ENUM_DOM_GROUPS structure.
1867 ********************************************************************/
1868
1869 void init_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
1870                 uint32 start_idx, uint32 num_sam_entries,
1871                 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
1872                 uint32 status)
1873 {
1874         int i;
1875         int entries_added;
1876
1877         DEBUG(5,("init_samr_r_enum_dom_groups\n"));
1878
1879         if (num_sam_entries >= MAX_SAM_ENTRIES) {
1880                 num_sam_entries = MAX_SAM_ENTRIES;
1881                 DEBUG(5,("limiting number of entries to %d\n", 
1882                          num_sam_entries));
1883         }
1884
1885         if (status == 0x0) {
1886                 for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
1887                         init_sam_entry3(&r_u->sam[entries_added],
1888                                         start_idx + entries_added + 1,
1889                                         pass[i].uni_user_name.uni_str_len,
1890                                         pass[i].uni_acct_desc.uni_str_len,
1891                                         pass[i].user_rid);
1892
1893                         copy_unistr2(&r_u->str[entries_added].uni_grp_name, 
1894                                                 &pass[i].uni_user_name);
1895                         copy_unistr2(&r_u->str[entries_added].uni_grp_desc, 
1896                                                 &pass[i].uni_acct_desc);
1897
1898                         entries_added++;
1899                 }
1900
1901                 if (entries_added > 0) {
1902                         r_u->unknown_0 = 0x0000492;
1903                         r_u->unknown_1 = 0x000049a;
1904                 } else {
1905                         r_u->unknown_0 = 0x0;
1906                         r_u->unknown_1 = 0x0;
1907                 }
1908                 r_u->switch_level  = 3;
1909                 r_u->num_entries   = entries_added;
1910                 r_u->ptr_entries   = 1;
1911                 r_u->num_entries2  = entries_added;
1912         } else {
1913                 r_u->switch_level = 0;
1914         }
1915
1916         r_u->status = status;
1917 }
1918
1919 /*******************************************************************
1920  Reads or writes a structure.
1921 ********************************************************************/
1922
1923 BOOL samr_io_r_enum_dom_groups(char *desc,  SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth)
1924 {
1925         int i;
1926
1927         if (r_u == NULL)
1928                 return False;
1929
1930         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
1931         depth++;
1932
1933         if(!prs_align(ps))
1934                 return False;
1935
1936         if(!prs_uint32("unknown_0    ", ps, depth, &r_u->unknown_0))
1937                 return False;
1938         if(!prs_uint32("unknown_1    ", ps, depth, &r_u->unknown_1))
1939                 return False;
1940         if(!prs_uint32("switch_level ", ps, depth, &r_u->switch_level))
1941                 return False;
1942
1943         if (r_u->switch_level != 0) {
1944                 if(!prs_uint32("num_entries  ", ps, depth, &r_u->num_entries))
1945                         return False;
1946                 if(!prs_uint32("ptr_entries  ", ps, depth, &r_u->ptr_entries))
1947                         return False;
1948
1949                 if(!prs_uint32("num_entries2 ", ps, depth, &r_u->num_entries2))
1950                         return False;
1951
1952                 SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
1953
1954                 for (i = 0; i < r_u->num_entries; i++) {
1955                         if(!sam_io_sam_entry3("", &r_u->sam[i], ps, depth))
1956                                 return False;
1957                 }
1958
1959                 for (i = 0; i < r_u->num_entries; i++) {
1960                         if(!sam_io_sam_str3 ("", &r_u->str[i],
1961                                              r_u->sam[i].hdr_grp_name.buffer,
1962                                              r_u->sam[i].hdr_grp_desc.buffer,
1963                                              ps, depth))
1964                                 return False;
1965                 }
1966         }
1967
1968         if(!prs_uint32("status", ps, depth, &r_u->status))
1969                 return False;
1970
1971         return True;
1972 }
1973
1974 /*******************************************************************
1975  Inits a SAMR_Q_QUERY_ALIASINFO structure.
1976 ********************************************************************/
1977
1978 void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
1979                                 POLICY_HND *pol,
1980                                 uint16 switch_level)
1981 {
1982         DEBUG(5,("init_q_query_aliasinfo\n"));
1983
1984         memcpy(&q_e->pol, pol, sizeof(*pol));
1985
1986         q_e->switch_level = switch_level;
1987 }
1988
1989 /*******************************************************************
1990  Reads or writes a structure.
1991 ********************************************************************/
1992
1993 BOOL samr_io_q_query_aliasinfo(char *desc,  SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth)
1994 {
1995         if (q_e == NULL)
1996                 return False;
1997
1998         prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
1999         depth++;
2000
2001         if(!prs_align(ps))
2002                 return False;
2003
2004         if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
2005                 return False;
2006         if(!prs_align(ps))
2007                 return False;
2008
2009         if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
2010                 return False;
2011
2012         return True;
2013 }
2014
2015 /*******************************************************************
2016  Inits a SAMR_R_QUERY_ALIASINFO structure.
2017 ********************************************************************/
2018
2019 void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u, uint32 switch_level,
2020                                  char* alias, char* alias_desc)
2021                                  
2022 {
2023   int alias_desc_len, alias_len;
2024
2025   if(r_u == NULL)
2026     return;
2027
2028   alias_len = alias?strlen(alias):0;
2029   alias_desc_len = alias_desc?strlen(alias_desc):0;
2030
2031   DEBUG(5,("init_samr_r_query_aliasinfo\n"));
2032
2033   r_u->switch_value = switch_level;
2034
2035   if(r_u->status == 0)
2036     {
2037       switch(switch_level)
2038         {
2039         case 1: 
2040           {
2041             r_u->ptr = 1;
2042             init_uni_hdr(&r_u->alias.info1.hdr_alias_name, alias_len);
2043             init_unistr2(&r_u->alias.info1.uni_alias_name, alias, alias_len);
2044             r_u->alias.info1.switch_value_1 = switch_level;
2045             init_uni_hdr(&r_u->alias.info1.hdr_alias_desc, alias_desc_len);
2046             init_unistr2(&r_u->alias.info1.uni_alias_desc, alias_desc, alias_desc_len);
2047             break;
2048           }
2049         case 3:
2050           {
2051             r_u->ptr = 1;
2052             init_uni_hdr(&r_u->alias.info3.hdr_acct_desc, alias_desc_len);
2053             init_unistr2(&r_u->alias.info3.uni_acct_desc, alias_desc, alias_desc_len);
2054             break;
2055           }
2056         default:
2057           {
2058             r_u->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2059           }
2060         }
2061     }
2062 }
2063
2064           
2065
2066 /*******************************************************************
2067  Reads or writes a structure.
2068 ********************************************************************/
2069
2070 BOOL samr_io_r_query_aliasinfo(char *desc,  SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
2071 {
2072   if (r_u == NULL)
2073     return False;
2074
2075   prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
2076   depth++;
2077
2078   if(!prs_align(ps))
2079     return False;
2080
2081   if(!prs_uint32("ptr         ", ps, depth, &r_u->ptr))
2082     return False;
2083         
2084   if (r_u->ptr != 0) {
2085     if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
2086       return False;
2087     if(!prs_align(ps))
2088       return False;
2089
2090     if (r_u->switch_value != 0) {
2091       switch (r_u->switch_value) {
2092       case 1:
2093         smb_io_unihdr("",&r_u->alias.info1.hdr_alias_name, ps, depth);
2094         prs_uint32("switch_value_1", ps, depth, &r_u->alias.info1.switch_value_1);
2095         smb_io_unihdr("",&r_u->alias.info1.hdr_alias_desc, ps, depth);
2096         
2097         smb_io_unistr2("", &r_u->alias.info1.uni_alias_name, 
2098                        r_u->alias.info1.hdr_alias_name.buffer, ps, depth);
2099         smb_io_unistr2("", &r_u->alias.info1.uni_alias_desc,
2100                        r_u->alias.info1.hdr_alias_desc.buffer, ps, depth);
2101         break;
2102       case 3:
2103         if(!smb_io_unihdr ("", &r_u->alias.info3.hdr_acct_desc, ps, depth))
2104           return False;
2105         if(!smb_io_unistr2("", &r_u->alias.info3.uni_acct_desc, 
2106                            r_u->alias.info3.hdr_acct_desc.buffer, ps, depth))
2107           return False;
2108         break;
2109       default:
2110         DEBUG(4,("samr_io_r_query_aliasinfo: unsupported switch level\n"));
2111         break;
2112       }
2113     }
2114   }
2115
2116   if(!prs_align(ps))
2117     return False;
2118
2119   if(!prs_uint32("status", ps, depth, &r_u->status))
2120     return False;
2121
2122   return True;
2123 }
2124
2125 /*******************************************************************
2126  Reads or writes a SAMR_Q_LOOKUP_IDS structure.
2127 ********************************************************************/
2128
2129 BOOL samr_io_q_lookup_ids(char *desc,  SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth)
2130 {
2131         fstring tmp;
2132         int i;
2133
2134         if (q_u == NULL)
2135                 return False;
2136
2137         prs_debug(ps, depth, desc, "samr_io_q_lookup_ids");
2138         depth++;
2139
2140         if(!prs_align(ps))
2141                 return False;
2142
2143         if(!smb_io_pol_hnd("pol", &(q_u->pol), ps, depth))
2144                 return False;
2145         if(!prs_align(ps))
2146                 return False;
2147
2148         if(!prs_uint32("num_sids1", ps, depth, &q_u->num_sids1))
2149                 return False;
2150         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
2151                 return False;
2152         if(!prs_uint32("num_sids2", ps, depth, &q_u->num_sids2))
2153                 return False;
2154
2155         SMB_ASSERT_ARRAY(q_u->ptr_sid, q_u->num_sids2);
2156
2157         for (i = 0; i < q_u->num_sids2; i++) {
2158                 slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
2159                 if(!prs_uint32(tmp, ps, depth, &q_u->ptr_sid[i]))
2160                         return False;
2161         }
2162
2163         for (i = 0; i < q_u->num_sids2; i++) {
2164                 if (q_u->ptr_sid[i] != 0) {
2165                         slprintf(tmp, sizeof(tmp)-1, "sid[%02d]", i);
2166                         if(!smb_io_dom_sid2(tmp, &q_u->sid[i], ps, depth))
2167                                 return False;
2168                 }
2169         }
2170
2171         if(!prs_align(ps))
2172                 return False;
2173
2174         return True;
2175 }
2176
2177 /*******************************************************************
2178  Inits a SAMR_R_LOOKUP_IDS structure.
2179 ********************************************************************/
2180
2181 void init_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
2182                 uint32 num_rids, uint32 *rid, uint32 status)
2183 {
2184         int i;
2185
2186         DEBUG(5,("init_samr_r_lookup_ids\n"));
2187
2188         if (status == 0x0) {
2189                 r_u->num_entries  = num_rids;
2190                 r_u->ptr = 1;
2191                 r_u->num_entries2 = num_rids;
2192
2193                 SMB_ASSERT_ARRAY(r_u->rid, num_rids);
2194
2195                 for (i = 0; i < num_rids; i++) {
2196                         r_u->rid[i] = rid[i];
2197                 }
2198         } else {
2199                 r_u->num_entries  = 0;
2200                 r_u->ptr = 0;
2201                 r_u->num_entries2 = 0;
2202         }
2203
2204         r_u->status = status;
2205 }
2206
2207 /*******************************************************************
2208  Reads or writes a structure.
2209 ********************************************************************/
2210
2211 BOOL samr_io_r_lookup_ids(char *desc,  SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth)
2212 {
2213         fstring tmp;
2214         int i;
2215
2216         if (r_u == NULL)
2217                 return False;
2218
2219         prs_debug(ps, depth, desc, "samr_io_r_lookup_ids");
2220         depth++;
2221
2222         if(!prs_align(ps))
2223                 return False;
2224
2225         if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
2226                 return False;
2227         if(!prs_uint32("ptr        ", ps, depth, &r_u->ptr))
2228                 return False;
2229         if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
2230                 return False;
2231
2232         if (r_u->num_entries != 0) {
2233                 SMB_ASSERT_ARRAY(r_u->rid, r_u->num_entries2);
2234
2235                 for (i = 0; i < r_u->num_entries2; i++) {
2236                         slprintf(tmp, sizeof(tmp)-1, "rid[%02d]", i);
2237                         if(!prs_uint32(tmp, ps, depth, &r_u->rid[i]))
2238                                 return False;
2239                 }
2240         }
2241
2242         if(!prs_uint32("status", ps, depth, &r_u->status))
2243                 return False;
2244
2245         return True;
2246 }
2247
2248 /*******************************************************************
2249  Reads or writes a structure.
2250 ********************************************************************/
2251
2252 BOOL samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
2253 {
2254         int i;
2255
2256         if (q_u == NULL)
2257                 return False;
2258
2259         prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
2260         depth++;
2261
2262         prs_align(ps);
2263
2264         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
2265                 return False;
2266         if(!prs_align(ps))
2267                 return False;
2268
2269         if(!prs_uint32("num_names1", ps, depth, &q_u->num_names1))
2270                 return False;
2271         if(!prs_uint32("flags     ", ps, depth, &q_u->flags))
2272                 return False;
2273         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
2274                 return False;
2275         if(!prs_uint32("num_names2", ps, depth, &q_u->num_names2))
2276                 return False;
2277
2278         SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2);
2279
2280         for (i = 0; i < q_u->num_names2; i++) {
2281                 if(!smb_io_unihdr ("", &q_u->hdr_name[i], ps, depth))
2282                         return False;
2283         }
2284         for (i = 0; i < q_u->num_names2; i++) {
2285                 if(!smb_io_unistr2("", &q_u->uni_name[i], q_u->hdr_name[i].buffer, ps, depth))
2286                         return False;
2287         }
2288
2289         return True;
2290 }
2291
2292
2293 /*******************************************************************
2294  Inits a SAMR_R_LOOKUP_NAMES structure.
2295 ********************************************************************/
2296
2297 void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
2298                         uint32 num_rids, uint32 *rid, enum SID_NAME_USE *type, uint32 status)
2299 {
2300         int i;
2301
2302         DEBUG(5,("init_samr_r_lookup_names\n"));
2303
2304         if (status == 0x0) {
2305                 r_u->num_types1 = num_rids;
2306                 r_u->ptr_types  = 1;
2307                 r_u->num_types2 = num_rids;
2308
2309                 r_u->num_rids1 = num_rids;
2310                 r_u->ptr_rids  = 1;
2311                 r_u->num_rids2 = num_rids;
2312
2313                 SMB_ASSERT_ARRAY(r_u->rid, num_rids);
2314
2315                 for (i = 0; i < num_rids; i++) {
2316                         r_u->rid [i] = rid [i];
2317                         r_u->type[i] = type[i];
2318                 }
2319         } else {
2320                 r_u->num_types1 = 0;
2321                 r_u->ptr_types  = 0;
2322                 r_u->num_types2 = 0;
2323
2324                 r_u->num_rids1 = 0;
2325                 r_u->ptr_rids  = 0;
2326                 r_u->num_rids2 = 0;
2327         }
2328
2329         r_u->status = status;
2330 }
2331
2332 /*******************************************************************
2333  Reads or writes a structure.
2334 ********************************************************************/
2335
2336 BOOL samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
2337 {
2338         int i;
2339         fstring tmp;
2340
2341         if (r_u == NULL)
2342                 return False;
2343
2344         prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
2345         depth++;
2346
2347         if(!prs_align(ps))
2348                 return False;
2349
2350         if(!prs_uint32("num_rids1", ps, depth, &r_u->num_rids1))
2351                 return False;
2352         if(!prs_uint32("ptr_rids ", ps, depth, &r_u->ptr_rids ))
2353                 return False;
2354
2355         if (r_u->ptr_rids != 0) {
2356                 if(!prs_uint32("num_rids2", ps, depth, &r_u->num_rids2))
2357                         return False;
2358
2359                 if (r_u->num_rids2 != r_u->num_rids1) {
2360                         /* RPC fault */
2361                         return False;
2362                 }
2363
2364                 for (i = 0; i < r_u->num_rids2; i++) {
2365                         slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
2366                         if(!prs_uint32(tmp, ps, depth, &r_u->rid[i]))
2367                                 return False;
2368                 }
2369         }
2370
2371         if(!prs_uint32("num_types1", ps, depth, &r_u->num_types1))
2372                 return False;
2373         if(!prs_uint32("ptr_types ", ps, depth, &r_u->ptr_types))
2374                 return False;
2375
2376         if (r_u->ptr_types != 0) {
2377                 if(!prs_uint32("num_types2", ps, depth, &r_u->num_types2))
2378                         return False;
2379
2380                 if (r_u->num_types2 != r_u->num_types1) {
2381                         /* RPC fault */
2382                         return False;
2383                 }
2384
2385                 for (i = 0; i < r_u->num_types2; i++) {
2386                         slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
2387                         if(!prs_uint32(tmp, ps, depth, &r_u->type[i]))
2388                                 return False;
2389                 }
2390         }
2391
2392         if(!prs_uint32("status", ps, depth, &r_u->status))
2393                 return False;
2394
2395         return True;
2396 }
2397
2398 /*******************************************************************
2399  Reads or writes a structure.
2400 ********************************************************************/
2401
2402 BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth)
2403 {
2404         int i;
2405         fstring tmp;
2406
2407         if (q_u == NULL)
2408                 return False;
2409
2410         prs_debug(ps, depth, desc, "samr_io_q_lookup_rids");
2411         depth++;
2412
2413         if(!prs_align(ps))
2414                 return False;
2415
2416         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
2417                 return False;
2418         if(!prs_align(ps))
2419                 return False;
2420
2421         if(!prs_uint32("num_gids1", ps, depth, &q_u->num_gids1))
2422                 return False;
2423         if(!prs_uint32("rid      ", ps, depth, &q_u->rid))
2424                 return False;
2425         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
2426                 return False;
2427         if(!prs_uint32("num_gids2", ps, depth, &q_u->num_gids2))
2428                 return False;
2429
2430         SMB_ASSERT_ARRAY(q_u->gid, q_u->num_gids2);
2431
2432         for (i = 0; i < q_u->num_gids2; i++) {
2433                 slprintf(tmp, sizeof(tmp) - 1, "gid[%02d]  ", i);
2434                 if(!prs_uint32(tmp, ps, depth, &q_u->gid[i]))
2435                         return False;
2436         }
2437
2438         return True;
2439 }
2440
2441 /*******************************************************************
2442  Inits a SAMR_R_UNKNOWN_12 structure.
2443 ********************************************************************/
2444
2445 void init_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
2446                 uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
2447                 uint32 status)
2448 {
2449         int i;
2450
2451         DEBUG(5,("init_samr_r_lookup_rids\n"));
2452
2453         if (status == 0x0) {
2454                 r_u->num_aliases1 = num_aliases;
2455                 r_u->ptr_aliases  = 1;
2456                 r_u->num_aliases2 = num_aliases;
2457
2458                 r_u->num_als_usrs1 = num_aliases;
2459                 r_u->ptr_als_usrs  = 1;
2460                 r_u->num_als_usrs2 = num_aliases;
2461
2462                 SMB_ASSERT_ARRAY(r_u->hdr_als_name, num_aliases);
2463
2464                 for (i = 0; i < num_aliases; i++) {
2465                         int als_len = als_name[i] != NULL ? strlen(als_name[i]) : 0;
2466                         init_uni_hdr(&r_u->hdr_als_name[i], als_len);
2467                         init_unistr2(&r_u->uni_als_name[i], als_name[i], als_len);
2468                         r_u->num_als_usrs[i] = num_als_usrs[i];
2469                 }
2470         } else {
2471                 r_u->num_aliases1 = num_aliases;
2472                 r_u->ptr_aliases  = 0;
2473                 r_u->num_aliases2 = num_aliases;
2474
2475                 r_u->num_als_usrs1 = num_aliases;
2476                 r_u->ptr_als_usrs  = 0;
2477                 r_u->num_als_usrs2 = num_aliases;
2478         }
2479
2480         r_u->status = status;
2481 }
2482
2483 /*******************************************************************
2484  Reads or writes a structure.
2485 ********************************************************************/
2486
2487 BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth)
2488 {
2489         int i;
2490         fstring tmp;
2491
2492         if (r_u == NULL)
2493                 return False;
2494
2495         prs_debug(ps, depth, desc, "samr_io_r_lookup_rids");
2496         depth++;
2497
2498         if(!prs_align(ps))
2499                 return False;
2500
2501         if(!prs_uint32("num_aliases1", ps, depth, &r_u->num_aliases1))
2502                 return False;
2503         if(!prs_uint32("ptr_aliases ", ps, depth, &r_u->ptr_aliases ))
2504                 return False;
2505         if(!prs_uint32("num_aliases2", ps, depth, &r_u->num_aliases2))
2506                 return False;
2507
2508         if (r_u->ptr_aliases != 0 && r_u->num_aliases1 != 0) {
2509                 SMB_ASSERT_ARRAY(r_u->hdr_als_name, r_u->num_aliases2);
2510
2511                 for (i = 0; i < r_u->num_aliases2; i++) {
2512                         slprintf(tmp, sizeof(tmp) - 1, "als_hdr[%02d]  ", i);
2513                         if(!smb_io_unihdr ("", &r_u->hdr_als_name[i], ps, depth))
2514                                 return False;
2515                 }
2516                 for (i = 0; i < r_u->num_aliases2; i++) {
2517                         slprintf(tmp, sizeof(tmp) - 1, "als_str[%02d]  ", i);
2518                         if(!smb_io_unistr2("", &r_u->uni_als_name[i], r_u->hdr_als_name[i].buffer, ps, depth))
2519                                 return False;
2520                         if(!prs_align(ps))
2521                                 return False;
2522                 }
2523         }
2524
2525         if(!prs_align(ps))
2526                 return False;
2527
2528         if(!prs_uint32("num_als_usrs1", ps, depth, &r_u->num_als_usrs1))
2529                 return False;
2530         if(!prs_uint32("ptr_als_usrs ", ps, depth, &r_u->ptr_als_usrs))
2531                 return False;
2532         if(!prs_uint32("num_als_usrs2", ps, depth, &r_u->num_als_usrs2))
2533                 return False;
2534
2535         if (r_u->ptr_als_usrs != 0 && r_u->num_als_usrs1 != 0) {
2536                 SMB_ASSERT_ARRAY(r_u->num_als_usrs, r_u->num_als_usrs2);
2537
2538                 for (i = 0; i < r_u->num_als_usrs2; i++) {
2539                         slprintf(tmp, sizeof(tmp) - 1, "als_usrs[%02d]  ", i);
2540                         if(!prs_uint32(tmp, ps, depth, &r_u->num_als_usrs[i]))
2541                                 return False;
2542                 }
2543         }
2544
2545         if(!prs_uint32("status", ps, depth, &r_u->status))
2546                 return False;
2547
2548         return True;
2549 }
2550
2551
2552 /*******************************************************************
2553  Inits a SAMR_Q_OPEN_USER struct.
2554 ********************************************************************/
2555
2556 void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
2557                                 POLICY_HND *pol,
2558                                 uint32 unk_0, uint32 rid)
2559 {
2560         DEBUG(5,("samr_init_q_open_user\n"));
2561
2562         memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
2563         
2564         q_u->unknown_0 = unk_0;
2565         q_u->user_rid  = rid;
2566 }
2567
2568 /*******************************************************************
2569  Reads or writes a structure.
2570 ********************************************************************/
2571
2572 BOOL samr_io_q_open_user(char *desc,  SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
2573 {
2574         if (q_u == NULL)
2575                 return False;
2576
2577         prs_debug(ps, depth, desc, "samr_io_q_open_user");
2578         depth++;
2579
2580         if(!prs_align(ps))
2581                 return False;
2582
2583         if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
2584                 return False;
2585         if(!prs_align(ps))
2586                 return False;
2587
2588         if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
2589                 return False;
2590         if(!prs_uint32("user_rid ", ps, depth, &q_u->user_rid))
2591                 return False;
2592
2593         if(!prs_align(ps))
2594                 return False;
2595
2596         return True;
2597 }
2598
2599 /*******************************************************************
2600  Reads or writes a structure.
2601 ********************************************************************/
2602
2603 BOOL samr_io_r_open_user(char *desc,  SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
2604 {
2605         if (r_u == NULL)
2606                 return False;
2607
2608         prs_debug(ps, depth, desc, "samr_io_r_open_user");
2609         depth++;
2610
2611         if(!prs_align(ps))
2612                 return False;
2613
2614         if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
2615                 return False;
2616         if(!prs_align(ps))
2617                 return False;
2618
2619         if(!prs_uint32("status", ps, depth, &r_u->status))
2620                 return False;
2621
2622         return True;
2623 }
2624
2625 /*******************************************************************
2626  Inits a SAMR_Q_QUERY_USERGROUPS structure.
2627 ********************************************************************/
2628
2629 void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
2630                                 POLICY_HND *hnd)
2631 {
2632         DEBUG(5,("init_samr_q_query_usergroups\n"));
2633
2634         memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
2635 }
2636
2637 /*******************************************************************
2638  Reads or writes a structure.
2639 ********************************************************************/
2640
2641 BOOL samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
2642 {
2643         if (q_u == NULL)
2644                 return False;
2645
2646         prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
2647         depth++;
2648
2649         if(!prs_align(ps))
2650                 return False;
2651
2652         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
2653                 return False;
2654         if(!prs_align(ps))
2655                 return False;
2656
2657         return True;
2658 }
2659
2660 /*******************************************************************
2661  Inits a SAMR_R_QUERY_USERGROUPS structure.
2662 ********************************************************************/
2663
2664 void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
2665                 uint32 num_gids, DOM_GID *gid, uint32 status)
2666 {
2667         DEBUG(5,("init_samr_r_query_usergroups\n"));
2668
2669         if (status == 0x0) {
2670                 r_u->ptr_0        = 1;
2671                 r_u->num_entries  = num_gids;
2672                 r_u->ptr_1        = 1;
2673                 r_u->num_entries2 = num_gids;
2674
2675                 r_u->gid = gid;
2676         } else {
2677                 r_u->ptr_0       = 0;
2678                 r_u->num_entries = 0;
2679                 r_u->ptr_1       = 0;
2680         }
2681
2682         r_u->status = status;
2683 }
2684
2685 /*******************************************************************
2686  Reads or writes a structure.
2687 ********************************************************************/
2688
2689 BOOL samr_io_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
2690 {
2691         int i;
2692
2693         if (r_u == NULL)
2694                 return False;
2695
2696         prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
2697         depth++;
2698
2699         if(!prs_align(ps))
2700                 return False;
2701
2702         if(!prs_uint32("ptr_0       ", ps, depth, &r_u->ptr_0))
2703                 return False;
2704
2705         if (r_u->ptr_0 != 0) {
2706                 if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
2707                         return False;
2708                 if(!prs_uint32("ptr_1       ", ps, depth, &r_u->ptr_1))
2709                         return False;
2710
2711                 if (r_u->num_entries != 0) {
2712                         if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
2713                                 return False;
2714
2715                         for (i = 0; i < r_u->num_entries2; i++) {
2716                                 if(!smb_io_gid("", &r_u->gid[i], ps, depth))
2717                                         return False;
2718                         }
2719                 }
2720         }
2721
2722         if(!prs_uint32("status", ps, depth, &r_u->status))
2723                 return False;
2724
2725         return True;
2726 }
2727
2728 /*******************************************************************
2729  Inits a SAMR_Q_QUERY_USERINFO structure.
2730 ********************************************************************/
2731
2732 void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
2733                                 POLICY_HND *hnd, uint16 switch_value)
2734 {
2735         DEBUG(5,("init_samr_q_query_userinfo\n"));
2736
2737         memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
2738         q_u->switch_value = switch_value;
2739 }
2740
2741 /*******************************************************************
2742  Reads or writes a structure.
2743 ********************************************************************/
2744
2745 BOOL samr_io_q_query_userinfo(char *desc,  SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth)
2746 {
2747         if (q_u == NULL)
2748                 return False;
2749
2750         prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
2751         depth++;
2752
2753         if(!prs_align(ps))
2754                 return False;
2755
2756         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
2757                 return False;
2758         if(!prs_align(ps))
2759                 return False;
2760
2761         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value)) /* 0x0015 or 0x0011 */
2762                 return False;
2763
2764         return True;
2765 }
2766
2767 /*******************************************************************
2768  Reads or writes a LOGON_HRS structure.
2769 ********************************************************************/
2770
2771 static BOOL sam_io_logon_hrs(char *desc,  LOGON_HRS *hrs, prs_struct *ps, int depth)
2772 {
2773         if (hrs == NULL)
2774                 return False;
2775
2776         prs_debug(ps, depth, desc, "sam_io_logon_hrs");
2777         depth++;
2778
2779         if(!prs_align(ps))
2780                 return False;
2781         
2782         if(!prs_uint32 ("len  ", ps, depth, &hrs->len))
2783                 return False;
2784
2785         if (hrs->len > 64) {
2786                 DEBUG(5,("sam_io_logon_hrs: truncating length\n"));
2787                 hrs->len = 64;
2788         }
2789
2790         if(!prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len))
2791                 return False;
2792
2793         return True;
2794 }
2795
2796 /*******************************************************************
2797  Inits a SAM_USER_INFO_10 structure.
2798 ********************************************************************/
2799
2800 void init_sam_user_info10(SAM_USER_INFO_10 *usr,
2801                                 uint32 acb_info)
2802 {
2803         DEBUG(5,("init_sam_user_info10\n"));
2804
2805         usr->acb_info = acb_info;
2806 }
2807
2808 /*******************************************************************
2809  Reads or writes a structure.
2810 ********************************************************************/
2811
2812 BOOL sam_io_user_info10(char *desc,  SAM_USER_INFO_10 *usr, prs_struct *ps, int depth)
2813 {
2814         if (usr == NULL)
2815                 return False;
2816
2817         prs_debug(ps, depth, desc, "samr_io_r_user_info10");
2818         depth++;
2819
2820         if(!prs_align(ps))
2821                 return False;
2822
2823         if(!prs_uint32("acb_info", ps, depth, &usr->acb_info))
2824                 return False;
2825
2826         return True;
2827 }
2828
2829 /*******************************************************************
2830  Inits a SAM_USER_INFO_11 structure.
2831 ********************************************************************/
2832
2833 void init_sam_user_info11(SAM_USER_INFO_11 *usr,
2834                                 NTTIME *expiry,
2835                                 char *mach_acct,
2836                                 uint32 rid_user,
2837                                 uint32 rid_group,
2838                                 uint16 acct_ctrl)
2839                                 
2840 {
2841         int len_mach_acct;
2842
2843         DEBUG(5,("init_sam_user_info11\n"));
2844
2845         len_mach_acct = strlen(mach_acct);
2846
2847         memcpy(&usr->expiry,expiry, sizeof(usr->expiry)); /* expiry time or something? */
2848         memset((char *)usr->padding_1, '\0', sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
2849
2850         init_uni_hdr(&usr->hdr_mach_acct, len_mach_acct);  /* unicode header for machine account */
2851         usr->padding_2 = 0;               /* 0 - padding 4 bytes */
2852
2853         usr->ptr_1        = 1;            /* pointer */
2854         memset((char *)usr->padding_3, '\0', sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
2855         usr->padding_4    = 0;            /* 0 - padding 4 bytes */
2856
2857         usr->ptr_2        = 1;            /* pointer */
2858         usr->padding_5    = 0;            /* 0 - padding 4 bytes */
2859
2860         usr->ptr_3        = 1;          /* pointer */
2861         memset((char *)usr->padding_6, '\0', sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
2862
2863         usr->rid_user     = rid_user; 
2864         usr->rid_group    = rid_group;
2865
2866         usr->acct_ctrl    = acct_ctrl;
2867         usr->unknown_3    = 0x0000;
2868
2869         usr->unknown_4    = 0x003f;       /* 0x003f      - 16 bit unknown */
2870         usr->unknown_5    = 0x003c;       /* 0x003c      - 16 bit unknown */
2871
2872         memset((char *)usr->padding_7, '\0', sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
2873         usr->padding_8    = 0;            /* 0 - padding 4 bytes */
2874         
2875         init_unistr2(&usr->uni_mach_acct, mach_acct, len_mach_acct);  /* unicode string for machine account */
2876
2877         memset((char *)usr->padding_9, '\0', sizeof(usr->padding_9)); /* 0 - padding 48 bytes */
2878 }
2879
2880 /*******************************************************************
2881  Reads or writes a structure.
2882 ********************************************************************/
2883
2884 BOOL sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps, int depth)
2885 {
2886         if (usr == NULL)
2887                 return False;
2888
2889         prs_debug(ps, depth, desc, "samr_io_r_unknown_24");
2890         depth++;
2891
2892         if(!prs_align(ps))
2893                 return False;
2894
2895         if(!prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0))) 
2896                 return False;
2897
2898         if(!smb_io_time("time", &(usr->expiry), ps, depth))
2899                 return False;
2900
2901         if(!prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1)))
2902                 return False;
2903
2904         if(!smb_io_unihdr ("unihdr", &usr->hdr_mach_acct, ps, depth))
2905                 return False;
2906         if(!prs_uint32(        "padding_2", ps, depth, &usr->padding_2))
2907                 return False;
2908
2909         if(!prs_uint32(        "ptr_1    ", ps, depth, &usr->ptr_1))
2910                 return False;
2911         if(!prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3)))
2912                 return False;
2913         if(!prs_uint32(        "padding_4", ps, depth, &usr->padding_4))
2914                 return False;
2915
2916         if(!prs_uint32(        "ptr_2    ", ps, depth, &usr->ptr_2))
2917                 return False;
2918         if(!prs_uint32(        "padding_5", ps, depth, &usr->padding_5))
2919                 return False;
2920
2921         if(!prs_uint32(        "ptr_3    ", ps, depth, &usr->ptr_3))
2922                 return False;
2923         if(!prs_uint8s(False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6)))
2924                 return False;
2925
2926         if(!prs_uint32(        "rid_user ", ps, depth, &usr->rid_user))
2927                 return False;
2928         if(!prs_uint32(        "rid_group", ps, depth, &usr->rid_group))
2929                 return False;
2930         if(!prs_uint16(        "acct_ctrl", ps, depth, &usr->acct_ctrl))
2931                 return False;
2932         if(!prs_uint16(        "unknown_3", ps, depth, &usr->unknown_3))
2933                 return False;
2934         if(!prs_uint16(        "unknown_4", ps, depth, &usr->unknown_4))
2935                 return False;
2936         if(!prs_uint16(        "unknown_5", ps, depth, &usr->unknown_5))
2937                 return False;
2938
2939         if(!prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7)))
2940                 return False;
2941         if(!prs_uint32(        "padding_8", ps, depth, &usr->padding_8))
2942                 return False;
2943         
2944         if(!smb_io_unistr2("unistr2", &usr->uni_mach_acct, True, ps, depth))
2945                 return False;
2946         if(!prs_align(ps))
2947                 return False;
2948
2949         if(!prs_uint8s(False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9)))
2950                 return False;
2951
2952         return True;
2953 }
2954
2955 /*************************************************************************
2956  init_sam_user_info21
2957
2958  unknown_3 = 0x00ff ffff
2959  unknown_5 = 0x0002 0000
2960  unknown_6 = 0x0000 04ec 
2961
2962  *************************************************************************/
2963
2964 void init_sam_user_info21(SAM_USER_INFO_21 *usr,
2965         NTTIME *logon_time,
2966         NTTIME *logoff_time,
2967         NTTIME *kickoff_time,
2968         NTTIME *pass_last_set_time,
2969         NTTIME *pass_can_change_time,
2970         NTTIME *pass_must_change_time,
2971
2972         char *user_name,
2973         char *full_name,
2974         char *home_dir,
2975         char *dir_drive,
2976         char *logon_script,
2977         char *profile_path,
2978         char *description,
2979         char *workstations,
2980         char *unknown_str,
2981         char *munged_dial,
2982
2983         uint32 user_rid,
2984         uint32 group_rid,
2985         uint16 acb_info, 
2986
2987         uint32 unknown_3,
2988         uint16 logon_divs,
2989         LOGON_HRS *hrs,
2990         uint32 unknown_5,
2991         uint32 unknown_6)
2992 {
2993         int len_user_name    = user_name    != NULL ? strlen(user_name   ) : 0;
2994         int len_full_name    = full_name    != NULL ? strlen(full_name   ) : 0;
2995         int len_home_dir     = home_dir     != NULL ? strlen(home_dir    ) : 0;
2996         int len_dir_drive    = dir_drive    != NULL ? strlen(dir_drive   ) : 0;
2997         int len_logon_script = logon_script != NULL ? strlen(logon_script) : 0;
2998         int len_profile_path = profile_path != NULL ? strlen(profile_path) : 0;
2999         int len_description  = description  != NULL ? strlen(description ) : 0;
3000         int len_workstations = workstations != NULL ? strlen(workstations) : 0;
3001         int len_unknown_str  = unknown_str  != NULL ? strlen(unknown_str ) : 0;
3002         int len_munged_dial  = munged_dial  != NULL ? strlen(munged_dial ) : 0;
3003
3004         usr->logon_time            = *logon_time;
3005         usr->logoff_time           = *logoff_time;
3006         usr->kickoff_time          = *kickoff_time;
3007         usr->pass_last_set_time    = *pass_last_set_time;
3008         usr->pass_can_change_time  = *pass_can_change_time;
3009         usr->pass_must_change_time = *pass_must_change_time;
3010
3011         init_uni_hdr(&usr->hdr_user_name, len_user_name);
3012         init_uni_hdr(&usr->hdr_full_name, len_full_name);
3013         init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
3014         init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
3015         init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
3016         init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
3017         init_uni_hdr(&usr->hdr_acct_desc, len_description);
3018         init_uni_hdr(&usr->hdr_workstations, len_workstations);
3019         init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
3020         init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
3021
3022         memset((char *)usr->nt_pwd, '\0', sizeof(usr->nt_pwd));
3023         memset((char *)usr->lm_pwd, '\0', sizeof(usr->lm_pwd));
3024
3025         usr->user_rid  = user_rid;
3026         usr->group_rid = group_rid;
3027         usr->acb_info = acb_info;
3028         usr->unknown_3 = unknown_3; /* 0x00ff ffff */
3029
3030         usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
3031         usr->ptr_logon_hrs = hrs ? 1 : 0;
3032         usr->unknown_5 = unknown_5; /* 0x0002 0000 */
3033
3034         memset((char *)usr->padding1, '\0', sizeof(usr->padding1));
3035
3036         init_unistr2(&usr->uni_user_name, user_name, len_user_name);
3037         init_unistr2(&usr->uni_full_name, full_name, len_full_name);
3038         init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
3039         init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
3040         init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
3041         init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
3042         init_unistr2(&usr->uni_acct_desc, description, len_description);
3043         init_unistr2(&usr->uni_workstations, workstations, len_workstations);
3044         init_unistr2(&usr->uni_unknown_str, unknown_str, len_unknown_str);
3045         init_unistr2(&usr->uni_munged_dial, munged_dial, len_munged_dial);
3046
3047         usr->unknown_6 = unknown_6; /* 0x0000 04ec */
3048         usr->padding4 = 0;
3049
3050         if (hrs)
3051                 memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
3052         else
3053                 memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
3054 }
3055
3056
3057 /*******************************************************************
3058  Reads or writes a structure.
3059 ********************************************************************/
3060
3061 static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
3062 {
3063         if (usr == NULL)
3064                 return False;
3065
3066         prs_debug(ps, depth, desc, "sam_io_user_info21");
3067         depth++;
3068
3069         if(!prs_align(ps))
3070                 return False;
3071         
3072         if(!smb_io_time("logon_time           ", &usr->logon_time, ps, depth))
3073                 return False;
3074         if(!smb_io_time("logoff_time          ", &usr->logoff_time, ps, depth)) 
3075                 return False;
3076         if(!smb_io_time("kickoff_time         ", &usr->kickoff_time, ps, depth)) 
3077                 return False;
3078         if(!smb_io_time("pass_last_set_time   ", &usr->pass_last_set_time, ps, depth)) 
3079                 return False;
3080         if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth)) 
3081                 return False;
3082         if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth)) 
3083                 return False;
3084
3085         if(!smb_io_unihdr("hdr_user_name   ", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
3086                 return False;
3087         if(!smb_io_unihdr("hdr_full_name   ", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
3088                 return False;
3089         if(!smb_io_unihdr("hdr_home_dir    ", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
3090                 return False;
3091         if(!smb_io_unihdr("hdr_dir_drive   ", &usr->hdr_dir_drive, ps, depth)) /* home directory drive */
3092                 return False;
3093         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
3094                 return False;
3095         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
3096                 return False;
3097         if(!smb_io_unihdr("hdr_acct_desc   ", &usr->hdr_acct_desc, ps, depth)) /* account description */
3098                 return False;
3099         if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth)) /* workstations user can log on from */
3100                 return False;
3101         if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth)) /* unknown string */
3102                 return False;
3103         if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* workstations user can log on from */
3104                 return False;
3105
3106         if(!prs_uint8s (False, "lm_pwd        ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
3107                 return False;
3108         if(!prs_uint8s (False, "nt_pwd        ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
3109                 return False;
3110
3111         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User ID */
3112                 return False;
3113         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group ID */
3114                 return False;
3115         if(!prs_uint32("acb_info      ", ps, depth, &usr->acb_info))      /* Group ID */
3116                 return False;
3117
3118         if(!prs_uint32("unknown_3     ", ps, depth, &usr->unknown_3))
3119                 return False;
3120         if(!prs_uint16("logon_divs    ", ps, depth, &usr->logon_divs))     /* logon divisions per week */
3121                 return False;
3122         if(!prs_align(ps))
3123                 return False;
3124         if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
3125                 return False;
3126         if(!prs_uint32("unknown_5     ", ps, depth, &usr->unknown_5))
3127                 return False;
3128
3129         if(!prs_uint8s (False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1)))
3130                 return False;
3131
3132         /* here begins pointed-to data */
3133
3134         if(!smb_io_unistr2("uni_user_name   ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
3135                 return False;
3136         if(!prs_align(ps))
3137                 return False;
3138         if(!smb_io_unistr2("uni_full_name   ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
3139                 return False;
3140         if(!prs_align(ps))
3141                 return False;
3142         if(!smb_io_unistr2("uni_home_dir    ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
3143                 return False;
3144         if(!prs_align(ps))
3145                 return False;
3146         if(!smb_io_unistr2("uni_dir_drive   ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
3147                 return False;
3148         if(!prs_align(ps))
3149                 return False;
3150         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
3151                 return False;
3152         if(!prs_align(ps))
3153                 return False;
3154         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
3155                 return False;
3156         if(!prs_align(ps))
3157                 return False;
3158         if(!smb_io_unistr2("uni_acct_desc   ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user description unicode string */
3159                 return False;
3160         if(!prs_align(ps))
3161                 return False;
3162         if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth)) /* worksations user can log on from */
3163                 return False;
3164         if(!prs_align(ps))
3165                 return False;
3166         if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str .buffer, ps, depth)) /* unknown string */
3167                 return False;
3168         if(!prs_align(ps))
3169                 return False;
3170         if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial .buffer, ps, depth)) /* worksations user can log on from */
3171                 return False;
3172
3173         if(!prs_align(ps))
3174                 return False;
3175         if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
3176                 return False;
3177         if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
3178                 return False;
3179
3180         if (usr->ptr_logon_hrs)
3181                 if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
3182                         return False;
3183
3184         return True;
3185 }
3186
3187 /*******************************************************************
3188  Inits a SAMR_R_QUERY_USERINFO structure.
3189 ********************************************************************/
3190
3191 void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
3192                                 uint16 switch_value, void *info, uint32 status)
3193 {
3194         DEBUG(5,("init_samr_r_query_userinfo\n"));
3195
3196         r_u->ptr = 0;
3197         r_u->switch_value = 0;
3198
3199         if (status == 0) {
3200                 r_u->switch_value = switch_value;
3201
3202                 switch (switch_value) {
3203                 case 0x10:
3204                         r_u->ptr = 1;
3205                         r_u->info.id10 = (SAM_USER_INFO_10*)info;
3206                         break;
3207
3208                 case 0x11:
3209                         r_u->ptr = 1;
3210                         r_u->info.id11 = (SAM_USER_INFO_11*)info;
3211                         break;
3212
3213                 case 21:
3214                         r_u->ptr = 1;
3215                         r_u->info.id21 = (SAM_USER_INFO_21*)info;
3216                         break;
3217
3218                 default:
3219                         DEBUG(4,("init_samr_r_query_aliasinfo: unsupported switch level\n"));
3220                         break;
3221                 }
3222         }
3223
3224         r_u->status = status;         /* return status */
3225 }
3226
3227 /*******************************************************************
3228  Reads or writes a structure.
3229 ********************************************************************/
3230
3231 BOOL samr_io_r_query_userinfo(char *desc,  SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
3232 {
3233         if (r_u == NULL)
3234                 return False;
3235
3236         prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
3237         depth++;
3238
3239         if(!prs_align(ps))
3240                 return False;
3241
3242         if(!prs_uint32("ptr         ", ps, depth, &r_u->ptr))
3243                 return False;
3244         if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
3245                 return False;
3246         if(!prs_align(ps))
3247                 return False;
3248
3249         if (r_u->ptr != 0 && r_u->switch_value != 0) {
3250                 switch (r_u->switch_value) {
3251                 case 0x10:
3252                         if (r_u->info.id10 != NULL) {
3253                                 if(!sam_io_user_info10("", r_u->info.id10, ps, depth))
3254                                         return False;
3255                         } else {
3256                                 DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
3257                                 return False;
3258                         }
3259                         break;
3260 /*
3261                 case 0x11:
3262                         if (r_u->info.id11 != NULL) {
3263                                 if(!sam_io_user_info11("", r_u->info.id11, ps, depth))
3264                                         return False;
3265                         } else {
3266                                 DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
3267                                 return False;
3268                         }
3269                         break;
3270 */
3271                 case 21:
3272                         if (r_u->info.id21 != NULL) {
3273                                 if(!sam_io_user_info21("", r_u->info.id21, ps, depth))
3274                                         return False;
3275                         } else {
3276                                 DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
3277                                 return False;
3278                         }
3279                         break;
3280                 default:
3281                         DEBUG(2,("samr_io_r_query_userinfo: unknown switch level\n"));
3282                         break;
3283                 }
3284         }
3285
3286         if(!prs_align(ps))
3287                 return False;
3288
3289         if(!prs_uint32("status", ps, depth, &r_u->status))
3290                 return False;
3291
3292         return True;
3293 }
3294
3295 /*******************************************************************
3296  Reads or writes a structure.
3297 ********************************************************************/
3298
3299 BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth)
3300 {
3301         if (q_u == NULL)
3302                 return False;
3303
3304         prs_debug(ps, depth, desc, "samr_io_q_create_user");
3305         depth++;
3306
3307         if(!prs_align(ps))
3308                 return False;
3309
3310         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
3311                 return False;
3312         if(!prs_align(ps))
3313                 return False;
3314
3315         if(!smb_io_unihdr ("", &q_u->hdr_mach_acct, ps, depth))
3316                 return False;
3317         if(!smb_io_unistr2("", &q_u->uni_mach_acct, q_u->hdr_mach_acct.buffer, ps, depth))
3318                 return False;
3319
3320         if(!prs_align(ps))
3321                 return False;
3322
3323         if(!prs_uint32("acb_info", ps, depth, &q_u->acb_info))
3324                 return False;
3325         if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
3326                 return False;
3327
3328         return True;
3329 }
3330
3331 /*******************************************************************
3332  Reads or writes a structure.
3333 ********************************************************************/
3334
3335 BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth)
3336 {
3337         if (r_u == NULL)
3338                 return False;
3339
3340         prs_debug(ps, depth, desc, "samr_io_r_unknown_32");
3341         depth++;
3342
3343         if(!prs_align(ps))
3344                 return False;
3345
3346         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
3347                 return False;
3348
3349         if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
3350                 return False;
3351         if(!prs_uint32("user_rid", ps, depth, &r_u->user_rid))
3352                 return False;
3353
3354         if(!prs_uint32("status", ps, depth, &r_u->status))
3355                 return False;
3356
3357         return True;
3358 }
3359
3360 /*******************************************************************
3361  Inits a SAMR_Q_CONNECT structure.
3362 ********************************************************************/
3363
3364 void init_samr_q_connect(SAMR_Q_CONNECT *q_u,
3365                                 char *srv_name, uint32 unknown_0)
3366 {
3367         int len_srv_name = strlen(srv_name);
3368
3369         DEBUG(5,("init_q_connect\n"));
3370
3371         /* make PDC server name \\server */
3372         q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0; 
3373         init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name+1);  
3374
3375         /* example values: 0x0000 0002 */
3376         q_u->unknown_0 = unknown_0; 
3377 }
3378
3379 /*******************************************************************
3380  Reads or writes a structure.
3381 ********************************************************************/
3382
3383 BOOL samr_io_q_connect(char *desc,  SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
3384 {
3385         if (q_u == NULL)
3386                 return False;
3387
3388         prs_debug(ps, depth, desc, "samr_io_q_connect");
3389         depth++;
3390
3391         if(!prs_align(ps))
3392                 return False;
3393
3394         if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
3395                 return False;
3396         if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
3397                 return False;
3398
3399         if(!prs_align(ps))
3400                 return False;
3401
3402         if(!prs_uint32("unknown_0   ", ps, depth, &q_u->unknown_0))
3403                 return False;
3404
3405         return True;
3406 }
3407
3408 /*******************************************************************
3409  Reads or writes a structure.
3410 ********************************************************************/
3411
3412 BOOL samr_io_r_connect(char *desc,  SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
3413 {
3414         if (r_u == NULL)
3415                 return False;
3416
3417         prs_debug(ps, depth, desc, "samr_io_r_connect");
3418         depth++;
3419
3420         if(!prs_align(ps))
3421                 return False;
3422
3423         if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
3424                 return False;
3425         if(!prs_align(ps))
3426                 return False;
3427
3428         if(!prs_uint32("status", ps, depth, &r_u->status))
3429                 return False;
3430
3431         return True;
3432 }
3433
3434 /*******************************************************************
3435  Inits a SAMR_Q_CONNECT_ANON structure.
3436 ********************************************************************/
3437
3438 void init_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u)
3439 {
3440         DEBUG(5,("init_q_connect_anon\n"));
3441
3442         q_u->ptr       = 1;
3443         q_u->unknown_0 = 0x5c; /* server name (?!!) */
3444         q_u->unknown_1 = 0x01;
3445         q_u->unknown_2 = 0x20;
3446 }
3447
3448
3449 /*******************************************************************
3450  Reads or writes a structure.
3451 ********************************************************************/
3452
3453 BOOL samr_io_q_connect_anon(char *desc,  SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth)
3454 {
3455         if (q_u == NULL)
3456                 return False;
3457
3458         prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
3459         depth++;
3460
3461         if(!prs_align(ps))
3462                 return False;
3463
3464         if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
3465                 return False;
3466         if(!prs_uint16("unknown_0", ps, depth, &q_u->unknown_0))
3467                 return False;
3468         if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
3469                 return False;
3470         if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
3471                 return False;
3472
3473         return True;
3474 }
3475
3476 /*******************************************************************
3477  Reads or writes a structure.
3478 ********************************************************************/
3479
3480 BOOL samr_io_r_connect_anon(char *desc,  SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth)
3481 {
3482         if (r_u == NULL)
3483                 return False;
3484
3485         prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
3486         depth++;
3487
3488         if(!prs_align(ps))
3489                 return False;
3490
3491         if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
3492                 return False;
3493         if(!prs_align(ps))
3494                 return False;
3495
3496         if(!prs_uint32("status", ps, depth, &r_u->status))
3497                 return False;
3498
3499         return True;
3500 }
3501
3502 /*******************************************************************
3503  Inits a SAMR_Q_OPEN_ALIAS structure.
3504 ********************************************************************/
3505 void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
3506                                 uint32 unknown_0, uint32 rid)
3507 {
3508         DEBUG(5,("init_q_open_alias\n"));
3509
3510         /* example values: 0x0000 0008 */
3511         q_u->unknown_0 = unknown_0; 
3512
3513         q_u->rid_alias = rid; 
3514 }
3515
3516 /*******************************************************************
3517  Reads or writes a structure.
3518 ********************************************************************/
3519
3520 BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
3521 {
3522         if (q_u == NULL)
3523                 return False;
3524
3525         prs_debug(ps, depth, desc, "samr_io_q_open_alias");
3526         depth++;
3527
3528         if(!prs_align(ps))
3529                 return False;
3530
3531         if(!smb_io_pol_hnd("domain_pol", &(q_u->dom_pol), ps, depth))
3532                 return False;
3533
3534         if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
3535                 return False;
3536         if(!prs_uint32("rid_alias", ps, depth, &q_u->rid_alias))
3537                 return False;
3538
3539         return True;
3540 }
3541
3542 /*******************************************************************
3543  Reads or writes a structure.
3544 ********************************************************************/
3545
3546 BOOL samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
3547 {
3548         if (r_u == NULL)
3549                 return False;
3550
3551         prs_debug(ps, depth, desc, "samr_io_r_open_alias");
3552         depth++;
3553
3554         if(!prs_align(ps))
3555                 return False;
3556
3557         if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
3558                 return False;
3559         if(!prs_align(ps))
3560                 return False;
3561
3562         if(!prs_uint32("status", ps, depth, &r_u->status))
3563                 return False;
3564
3565         return True;
3566 }
3567
3568 /*******************************************************************
3569  Inits a SAMR_Q_UNKNOWN_12 structure.
3570 ********************************************************************/
3571
3572 void init_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
3573                 POLICY_HND *pol, uint32 rid,
3574                 uint32 num_gids, uint32 *gid)
3575 {
3576         int i;
3577
3578         DEBUG(5,("init_samr_q_lookup_rids\n"));
3579
3580         memcpy(&q_u->pol, pol, sizeof(*pol));
3581
3582         q_u->num_gids1 = num_gids;
3583         q_u->rid       = rid;
3584         q_u->ptr       = 0;
3585         q_u->num_gids2 = num_gids;
3586
3587         for (i = 0; i < num_gids; i++) {
3588                 q_u->gid[i] = gid[i];
3589         }
3590 }
3591
3592 /*******************************************************************
3593  Inits a SAMR_Q_UNKNOWN_21 structure.
3594 ********************************************************************/
3595
3596 void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
3597                                 POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
3598 {
3599         DEBUG(5,("init_samr_q_unknown_21\n"));
3600
3601         memcpy(&q_c->group_pol, hnd, sizeof(q_c->group_pol));
3602         q_c->unknown_1 = unk_1;
3603         q_c->unknown_2 = unk_2;
3604 }
3605
3606
3607 /*******************************************************************
3608  Inits a SAMR_Q_UNKNOWN_13 structure.
3609 ********************************************************************/
3610
3611 void init_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
3612                                 POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
3613 {
3614         DEBUG(5,("init_samr_q_unknown_13\n"));
3615
3616         memcpy(&q_c->alias_pol, hnd, sizeof(q_c->alias_pol));
3617         q_c->unknown_1 = unk_1;
3618         q_c->unknown_2 = unk_2;
3619 }
3620
3621 /*******************************************************************
3622  Inits a SAMR_Q_UNKNOWN_38 structure.
3623 ********************************************************************/
3624 void init_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name)
3625 {
3626         int len_srv_name = strlen(srv_name);
3627
3628         DEBUG(5,("init_q_unknown_38\n"));
3629
3630         q_u->ptr = 1;
3631         init_uni_hdr(&q_u->hdr_srv_name, len_srv_name);
3632         init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name);  
3633
3634 }
3635
3636 /*******************************************************************
3637  Reads or writes a structure.
3638 ********************************************************************/
3639
3640 BOOL samr_io_q_unknown_38(char *desc,  SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth)
3641 {
3642         if (q_u == NULL)
3643                 return False;
3644
3645         prs_debug(ps, depth, desc, "samr_io_q_unknown_38");
3646         depth++;
3647
3648         if(!prs_align(ps))
3649                 return False;
3650
3651         if(!prs_uint32("ptr", ps, depth, &q_u->ptr))
3652                 return False;
3653
3654         if (q_u->ptr != 0) {
3655                 if(!smb_io_unihdr ("", &q_u->hdr_srv_name, ps, depth))
3656                         return False;
3657                 if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->hdr_srv_name.buffer, ps, depth))
3658                         return False;
3659         }
3660
3661         return True;
3662 }
3663
3664 /*******************************************************************
3665  Inits a SAMR_R_UNKNOWN_38 structure.
3666 ********************************************************************/
3667
3668 void init_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u)
3669 {
3670         DEBUG(5,("init_r_unknown_38\n"));
3671
3672         r_u->unk_0 = 0;
3673         r_u->unk_1 = 0;
3674         r_u->unk_2 = 0;
3675         r_u->unk_3 = 0;
3676 }
3677
3678 /*******************************************************************
3679  Reads or writes a structure.
3680 ********************************************************************/
3681
3682 BOOL samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth)
3683 {
3684         if (r_u == NULL)
3685                 return False;
3686
3687         prs_debug(ps, depth, desc, "samr_io_r_unknown_38");
3688         depth++;
3689
3690         if(!prs_align(ps))
3691                 return False;
3692
3693         if(!prs_uint16("unk_0", ps, depth, &r_u->unk_0))
3694                 return False;
3695         if(!prs_align(ps))
3696                 return False;
3697         if(!prs_uint16("unk_1", ps, depth, &r_u->unk_1))
3698                 return False;
3699         if(!prs_align(ps))
3700                 return False;
3701         if(!prs_uint16("unk_2", ps, depth, &r_u->unk_2))
3702                 return False;
3703         if(!prs_align(ps))
3704                 return False;
3705         if(!prs_uint16("unk_3", ps, depth, &r_u->unk_3))
3706                 return False;
3707         if(!prs_align(ps))
3708                 return False;
3709
3710         return True;
3711 }
3712
3713 /*******************************************************************
3714 make a SAMR_ENC_PASSWD structure.
3715 ********************************************************************/
3716
3717 void init_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512])
3718 {
3719         pwd->ptr = 1;
3720         memcpy(pwd->pass, pass, sizeof(pwd->pass)); 
3721 }
3722
3723 /*******************************************************************
3724  Reads or writes a SAMR_ENC_PASSWD structure.
3725 ********************************************************************/
3726
3727 BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth)
3728 {
3729         if (pwd == NULL)
3730                 return False;
3731
3732         prs_debug(ps, depth, desc, "samr_io_enc_passwd");
3733         depth++;
3734
3735         if(!prs_align(ps))
3736                 return False;
3737
3738         if(!prs_uint32("ptr", ps, depth, &pwd->ptr))
3739                 return False;
3740         if(!prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)))
3741                 return False;
3742
3743         return True;
3744 }
3745
3746 /*******************************************************************
3747  Inits a SAMR_ENC_HASH structure.
3748 ********************************************************************/
3749
3750 void init_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16])
3751 {
3752         hsh->ptr = 1;
3753         memcpy(hsh->hash, hash, sizeof(hsh->hash));
3754 }
3755
3756 /*******************************************************************
3757  Reads or writes a SAMR_ENC_HASH structure.
3758 ********************************************************************/
3759
3760 BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth)
3761 {
3762         if (hsh == NULL)
3763                 return False;
3764
3765         prs_debug(ps, depth, desc, "samr_io_enc_hash");
3766         depth++;
3767
3768         if(!prs_align(ps))
3769                 return False;
3770
3771         if(!prs_uint32("ptr ", ps, depth, &hsh->ptr))
3772                 return False;
3773         if(!prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash))) 
3774                 return False;
3775
3776         return True;
3777 }
3778
3779 /*******************************************************************
3780  Inits a SAMR_R_UNKNOWN_38 structure.
3781 ********************************************************************/
3782
3783 void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
3784                                 char *dest_host, char *user_name,
3785                                 char nt_newpass[516], uchar nt_oldhash[16],
3786                                 char lm_newpass[516], uchar lm_oldhash[16])
3787 {
3788         int len_dest_host = strlen(dest_host);
3789         int len_user_name = strlen(user_name);
3790
3791         DEBUG(5,("init_samr_q_chgpasswd_user\n"));
3792
3793         q_u->ptr_0 = 1;
3794         init_uni_hdr(&q_u->hdr_dest_host, len_dest_host);
3795         init_unistr2(&q_u->uni_dest_host, dest_host, len_dest_host);  
3796         init_uni_hdr(&q_u->hdr_user_name, len_user_name);
3797         init_unistr2(&q_u->uni_user_name, user_name, len_user_name);  
3798
3799         init_enc_passwd(&q_u->nt_newpass, nt_newpass);
3800         init_enc_hash(&q_u->nt_oldhash, nt_oldhash);
3801
3802         q_u->unknown = 0x01;
3803
3804         init_enc_passwd(&q_u->lm_newpass, lm_newpass);
3805         init_enc_hash  (&q_u->lm_oldhash, lm_oldhash);
3806 }
3807
3808 /*******************************************************************
3809  Reads or writes a structure.
3810 ********************************************************************/
3811
3812 BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth)
3813 {
3814         if (q_u == NULL)
3815                 return False;
3816
3817         prs_debug(ps, depth, desc, "samr_io_q_chgpasswd_user");
3818         depth++;
3819
3820         if(!prs_align(ps))
3821                 return False;
3822
3823         if(!prs_uint32("ptr_0", ps, depth, &q_u->ptr_0))
3824                 return False;
3825
3826         if(!smb_io_unihdr ("", &q_u->hdr_dest_host, ps, depth))
3827                 return False;
3828         if(!smb_io_unistr2("", &q_u->uni_dest_host, q_u->hdr_dest_host.buffer, ps, depth))
3829                 return False;
3830         if(!smb_io_unihdr ("", &q_u->hdr_user_name, ps, depth))
3831                 return False;
3832         if(!smb_io_unistr2("", &q_u->uni_user_name, q_u->hdr_user_name.buffer, ps, depth))
3833                 return False;
3834
3835         if(!samr_io_enc_passwd("nt_newpass", &q_u->nt_newpass, ps, depth))
3836                 return False;
3837         if(!samr_io_enc_hash  ("nt_oldhash", &q_u->nt_oldhash, ps, depth))
3838                 return False;
3839
3840         if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
3841                 return False;
3842
3843         if(!samr_io_enc_passwd("lm_newpass", &q_u->lm_newpass, ps, depth))
3844                 return False;
3845         if(!samr_io_enc_hash("lm_oldhash", &q_u->lm_oldhash, ps, depth))
3846                 return False;
3847
3848         return True;
3849 }
3850
3851 /*******************************************************************
3852  Inits a SAMR_R_CHGPASSWD_USER structure.
3853 ********************************************************************/
3854
3855 void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status)
3856 {
3857         DEBUG(5,("init_r_chgpasswd_user\n"));
3858
3859         r_u->status = status;
3860 }
3861
3862 /*******************************************************************
3863  Reads or writes a structure.
3864 ********************************************************************/
3865
3866 BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth)
3867 {
3868         if (r_u == NULL)
3869                 return False;
3870
3871         prs_debug(ps, depth, desc, "samr_io_r_chgpasswd_user");
3872         depth++;
3873
3874         if(!prs_align(ps))
3875                 return False;
3876
3877         if(!prs_uint32("status", ps, depth, &r_u->status))
3878                 return False;
3879
3880         return True;
3881 }
3882
3883 /**********************************************************************
3884  Reads or writes a structure
3885  **********************************************************************/
3886 BOOL samr_io_q_lookup_domain(char* desc, SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct *ps, int depth)
3887 {
3888   if (q_u == NULL)
3889     return False;
3890
3891   prs_debug(ps, depth, desc, "samr_io_q_lookup_domain");
3892   depth++;
3893
3894   prs_align(ps);
3895
3896   smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth);
3897
3898   smb_io_unihdr("hdr_domain", &(q_u->hdr_domain), ps, depth);
3899   smb_io_unistr2("uni_domain", &(q_u->uni_domain),
3900                  q_u->hdr_domain.buffer, ps, depth);
3901   prs_align(ps);
3902
3903   return True;
3904
3905
3906 /*******************************************************************
3907 makes a SAMR_R_LOOKUP_DOMAIN structure.
3908 ********************************************************************/
3909 BOOL init_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
3910                                DOM_SID *dom_sid, uint32 status)
3911 {
3912         if (r_u == NULL)
3913                 return False;
3914
3915         DEBUG(5, ("make_samr_r_lookup_domain\n"));
3916
3917         r_u->status = status;
3918         r_u->ptr_sid = 0;
3919         if (status == 0x0)
3920         {
3921                 r_u->ptr_sid = 1;
3922                 init_dom_sid2(&r_u->dom_sid, dom_sid);
3923         }
3924
3925         return True;
3926 }
3927
3928 /*******************************************************************
3929 reads or writes a structure.
3930 ********************************************************************/
3931 BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
3932                              prs_struct *ps, int depth)
3933 {
3934         if (r_u == NULL)
3935                 return False;
3936
3937         prs_debug(ps, depth, desc, "samr_io_r_lookup_domain");
3938         depth++;
3939
3940         prs_align(ps);
3941
3942         prs_uint32("ptr", ps, depth, &(r_u->ptr_sid));
3943
3944         if (r_u->ptr_sid != 0)
3945         {
3946                 smb_io_dom_sid2("sid", &(r_u->dom_sid), ps, depth);
3947                 prs_align(ps);
3948         }
3949
3950         prs_uint32("status", ps, depth, &(r_u->status));
3951
3952         return True;
3953 }  
3954
3955 /*******************************************************************
3956 reads or writes a structure.
3957 ********************************************************************/
3958 BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
3959                             prs_struct *ps, int depth)
3960 {
3961         if (q_e == NULL)
3962                 return False;
3963
3964         prs_debug(ps, depth, desc, "samr_io_q_enum_domains");
3965         depth++;
3966
3967         prs_align(ps);
3968
3969         smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
3970
3971         prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
3972         prs_uint32("max_size ", ps, depth, &(q_e->max_size));
3973
3974         prs_align(ps);
3975
3976         return True;
3977
3978
3979 /*******************************************************************
3980 makes a SAMR_R_ENUM_DOMAINS structure.
3981 ********************************************************************/
3982 BOOL init_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
3983                               uint32 next_idx, fstring* domains, uint32 num_sam_entries)
3984 {
3985   int i=0;
3986
3987   if (r_u == NULL)
3988     return False;
3989
3990   DEBUG(5, ("init_samr_r_enum_domains\n"));
3991
3992   r_u->next_idx = next_idx;
3993
3994   r_u->uni_dom_name = (UNISTR2*) malloc(sizeof(UNISTR2) * num_sam_entries);
3995   r_u->sam = (SAM_ENTRY*) malloc(sizeof(SAM_ENTRY) * num_sam_entries);
3996   if(r_u->uni_dom_name == NULL || r_u->sam == NULL)
3997     {
3998       free(r_u->uni_dom_name);
3999       free(r_u->sam);
4000       r_u->status = NT_STATUS_MEMORY_NOT_ALLOCATED;
4001     }
4002
4003   if(r_u->status == 0)
4004     for(i=0;i<num_sam_entries;i++) /* only two domains to send */
4005       {
4006         init_unistr2(&r_u->uni_dom_name[i],domains[i], strlen(domains[i]));
4007         init_sam_entry(&(r_u->sam[i]), strlen(domains[i]), 0);
4008       }
4009   else
4010     {
4011       num_sam_entries = 0;
4012     }
4013   
4014   if (num_sam_entries != 0)
4015     {
4016       r_u->ptr_entries1 = 1;
4017       r_u->ptr_entries2 = 1;
4018       r_u->num_entries2 = num_sam_entries;
4019       r_u->num_entries3 = num_sam_entries;
4020
4021       r_u->num_entries4 = num_sam_entries;
4022     }
4023   else
4024     {
4025       r_u->ptr_entries1 = 0;
4026       r_u->num_entries2 = num_sam_entries;
4027       r_u->ptr_entries2 = 1;
4028     }
4029   
4030   return True;
4031 }
4032
4033 /*******************************************************************
4034 reads or writes a structure.
4035 ********************************************************************/
4036 BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
4037                             prs_struct *ps, int depth)
4038 {
4039         uint32 i;
4040
4041         if (r_u == NULL)
4042                 return False;
4043
4044         prs_debug(ps, depth, desc, "samr_io_r_enum_domains");
4045         depth++;
4046
4047         prs_align(ps);
4048
4049         prs_uint32("next_idx    ", ps, depth, &(r_u->next_idx));
4050         prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
4051
4052         if (r_u->ptr_entries1 != 0)
4053         {
4054                 prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
4055                 prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
4056                 prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
4057
4058                 if (UNMARSHALLING(ps))
4059                 {
4060                         r_u->sam = (SAM_ENTRY*) malloc(sizeof(SAM_ENTRY)*
4061                                                        r_u->num_entries2);
4062                         r_u->uni_dom_name = (UNISTR2*) malloc(sizeof(UNISTR2)*
4063                                                               r_u->num_entries2);
4064                 }
4065
4066                 if ((r_u->sam == NULL || r_u->uni_dom_name == NULL)
4067                     && r_u->num_entries2 != 0)
4068                 {
4069                         DEBUG(0, ("NULL pointers in SAMR_R_ENUM_DOMAINS\n"));
4070                         r_u->num_entries4 = 0;
4071                         r_u->status = NT_STATUS_MEMORY_NOT_ALLOCATED;
4072                         return False;
4073                 }
4074
4075                 for (i = 0; i < r_u->num_entries2; i++)
4076                 {
4077                         fstring tmp;
4078                         slprintf(tmp, sizeof(tmp) - 1, "domains[%d]", i);
4079                         sam_io_sam_entry(tmp, &(r_u->sam[i]), ps, depth);
4080                 }
4081
4082                 for (i = 0; i < r_u->num_entries2; i++)
4083                 {
4084                         fstring tmp;
4085                         slprintf(tmp, sizeof(tmp) - 1, "domains[%d]", i);
4086                         smb_io_unistr2(tmp, &(r_u->uni_dom_name[i]),           
4087                                        r_u->sam[i].hdr_name.buffer, ps,
4088                                        depth);
4089                         prs_align(ps);
4090                 }
4091
4092                 prs_align(ps);
4093
4094         }
4095
4096         prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
4097         prs_uint32("status", ps, depth, &(r_u->status));
4098
4099         return True;
4100 }
4101
4102 /*******************************************************************
4103 reads or writes a structure.
4104 ********************************************************************/
4105 static BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 *u, prs_struct *ps, int depth)
4106 {
4107         if (u == NULL)
4108                 return False;
4109
4110         DEBUG(0, ("possible security breach!\n"));
4111
4112         prs_debug(ps, depth, desc, "samr_io_r_user_info12");
4113         depth++;
4114
4115         if(!prs_align(ps))
4116                 return False;
4117
4118         if(!prs_uint8s(False, "lm_pwd", ps, depth, u->lm_pwd, sizeof(u->lm_pwd)))
4119                 return False;
4120         if(!prs_uint8s(False, "nt_pwd", ps, depth, u->nt_pwd, sizeof(u->nt_pwd)))
4121                 return False;
4122
4123         if(!prs_uint8("lm_pwd_active", ps, depth, &u->lm_pwd_active))
4124                 return False;
4125         if(!prs_uint8("nt_pwd_active", ps, depth, &u->nt_pwd_active))
4126                 return False;
4127
4128         return True;
4129 }
4130
4131 /*******************************************************************
4132 reads or writes a structure.
4133 ********************************************************************/
4134 static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 *usr, prs_struct *ps, int depth)
4135 {
4136         if (usr == NULL)
4137                 return False;
4138
4139         prs_debug(ps, depth, desc, "sam_io_user_info23");
4140         depth++;
4141
4142         if(!prs_align(ps))
4143                 return False;
4144
4145         if(!smb_io_time("logon_time", &usr->logon_time, ps, depth))
4146                 return False;
4147         if(!smb_io_time("logoff_time", &usr->logoff_time, ps, depth))
4148                 return False;
4149         if(!smb_io_time("kickoff_time", &usr->kickoff_time, ps, depth))
4150                 return False;
4151         if(!smb_io_time("pass_last_set_time", &usr->pass_last_set_time, ps, depth))
4152                 return False;
4153         if(!smb_io_time("pass_can_change_time", &usr->pass_can_change_time, ps, depth))
4154                 return False;
4155         if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth))
4156                 return False;
4157
4158         if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth))     /* username unicode string header */
4159                 return False;
4160         if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth))     /* user's full name unicode string header */
4161                 return False;
4162         if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth))       /* home directory unicode string header */
4163                 return False;
4164         if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth))     /* home directory drive */
4165                 return False;
4166         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth))       /* logon script unicode string header */
4167                 return False;
4168         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth))       /* profile path unicode string header */
4169                 return False;
4170         if(!smb_io_unihdr("hdr_acct_desc", &usr->hdr_acct_desc, ps, depth))     /* account desc */
4171                 return False;
4172         if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth))       /* wkstas user can log on from */
4173                 return False;
4174         if(!smb_io_unihdr("hdr_unknown_str", &usr->hdr_unknown_str, ps, depth)) /* unknown string */
4175                 return False;
4176         if(!smb_io_unihdr("hdr_munged_dial", &usr->hdr_munged_dial, ps, depth)) /* wkstas user can log on from */
4177                 return False;
4178
4179         if(!prs_uint8s(False, "lm_pwd", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
4180                 return False;
4181         if(!prs_uint8s(False, "nt_pwd", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
4182                 return False;
4183
4184         if(!prs_uint32("user_rid", ps, depth, &usr->user_rid))  /* User ID */
4185                 return False;
4186         if(!prs_uint32("group_rid", ps, depth, &usr->group_rid))        /* Group ID */
4187                 return False;
4188         if(!prs_uint32("acb_info", ps, depth, &usr->acb_info))
4189                 return False;
4190
4191         if(!prs_uint32("unknown_3", ps, depth, &usr->unknown_3))
4192                 return False;
4193         if(!prs_uint16("logon_divs", ps, depth, &usr->logon_divs))      /* logon divisions per week */
4194                 return False;
4195         if(!prs_align(ps))
4196                 return False;
4197         if(!prs_uint32("ptr_logon_hrs", ps, depth, &usr->ptr_logon_hrs))
4198                 return False;
4199         if(!prs_uint8s(False, "padding1", ps, depth, usr->padding1, sizeof(usr->padding1)))
4200                 return False;
4201         if(!prs_uint32("unknown_5", ps, depth, &usr->unknown_5))
4202                 return False;
4203
4204         if(!prs_uint8s(False, "password", ps, depth, usr->pass, sizeof(usr->pass)))
4205                 return False;
4206
4207         /* here begins pointed-to data */
4208
4209         if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
4210                 return False;
4211         if(!prs_align(ps))
4212                 return False;
4213         if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
4214                 return False;
4215         if(!prs_align(ps))
4216                 return False;
4217         if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth))    /* home directory unicode string */
4218                 return False;
4219         if(!prs_align(ps))
4220                 return False;
4221         if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
4222                 return False;
4223         if(!prs_align(ps))
4224                 return False;
4225         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth))        /* logon script unicode string */
4226                 return False;
4227         if(!prs_align(ps))
4228                 return False;
4229         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth))        /* profile path unicode string */
4230                 return False;
4231         if(!prs_align(ps))
4232                 return False;
4233         if(!smb_io_unistr2("uni_acct_desc", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user desc unicode string */
4234                 return False;
4235         if(!prs_align(ps))
4236                 return False;
4237         if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth))        /* worksations user can log on from */
4238                 return False;
4239         if(!prs_align(ps))
4240                 return False;
4241         if(!smb_io_unistr2("uni_unknown_str", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth))   /* unknown string */
4242                 return False;
4243         if(!prs_align(ps))
4244                 return False;
4245         if(!smb_io_unistr2("uni_munged_dial", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))   /* worksations user can log on from */
4246                 return False;
4247         if(!prs_align(ps))
4248                 return False;
4249
4250         /* ok, this is only guess-work (as usual) */
4251         if (usr->unknown_5 != 0x0) {
4252                 if(!prs_uint32("unknown_6", ps, depth, &usr->unknown_6))
4253                         return False;
4254                 if(!prs_uint32("padding4", ps, depth, &usr->padding4))
4255                         return False;
4256         } else if (UNMARSHALLING(ps)) {
4257                 usr->unknown_6 = 0;
4258                 usr->padding4 = 0;
4259         }
4260
4261         if (usr->ptr_logon_hrs) {
4262                 if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
4263                         return False;
4264         }
4265
4266         return True;
4267 }
4268
4269 /*******************************************************************
4270 reads or writes a structure.
4271 ********************************************************************/
4272 static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *ps, int depth)
4273 {
4274         if (usr == NULL)
4275                 return False;
4276
4277         prs_debug(ps, depth, desc, "sam_io_user_info24");
4278         depth++;
4279
4280         if(!prs_align(ps))
4281                 return False;
4282
4283         if(!prs_uint8s(False, "password", ps, depth, usr->pass, sizeof(usr->pass)))
4284                 return False;
4285
4286         return True;
4287 }
4288
4289 /*******************************************************************
4290 reads or writes a structure.
4291 ********************************************************************/
4292 static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR *ctr, prs_struct *ps, int depth)
4293 {
4294         if (ctr == NULL)
4295                 return False;
4296
4297         prs_debug(ps, depth, desc, "samr_io_userinfo_ctr");
4298         depth++;
4299
4300         /* lkclXXXX DO NOT ALIGN BEFORE READING SWITCH VALUE! */
4301
4302         if(!prs_uint16("switch_value", ps, depth, &ctr->switch_value))
4303                 return False;
4304         if(!prs_align(ps))
4305                 return False;
4306
4307         switch (ctr->switch_value) {
4308                 case 0x10:
4309                         if (UNMARSHALLING(ps)) /* reading */
4310                                 ctr->info.id10 = (SAM_USER_INFO_10 *)malloc(sizeof(SAM_USER_INFO_10));
4311                         if (ctr->info.id10 == NULL) {
4312                                 DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
4313                                 return False;
4314                         }
4315                         if(!sam_io_user_info10("", ctr->info.id10, ps, depth))
4316                                 return False;
4317                         break;
4318                 case 0x11:
4319                         if (UNMARSHALLING(ps)) /* reading */
4320                                 ctr->info.id11 = (SAM_USER_INFO_11 *)malloc(sizeof(SAM_USER_INFO_11));
4321                         if (ctr->info.id11 == NULL) {
4322                                 DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
4323                                 return False;
4324                         }
4325                         if(!sam_io_user_info11("", ctr->info.id11, ps, depth))
4326                                 return False;
4327                         break;
4328                 case 0x12:
4329                         if (UNMARSHALLING(ps)) /* reading */
4330                                 ctr->info.id12 = (SAM_USER_INFO_12 *)malloc(sizeof(SAM_USER_INFO_12));
4331                         if (ctr->info.id12 == NULL) {
4332                                 DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
4333                                 return False;
4334                         }
4335                         if(!sam_io_user_info12("", ctr->info.id12, ps, depth))
4336                                 return False;
4337                         break;
4338                 case 21:
4339                         if (UNMARSHALLING(ps)) /* reading */
4340                                 ctr->info.id21 = (SAM_USER_INFO_21 *)malloc(sizeof(SAM_USER_INFO_21));
4341                         if (ctr->info.id21 == NULL) {
4342                                 DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
4343                                 return False;
4344                         }
4345                         if(!sam_io_user_info21("", ctr->info.id21, ps, depth))
4346                                 return False;
4347                         break;
4348                 case 23:
4349                         if (UNMARSHALLING(ps)) /* reading */
4350                                 ctr->info.id23 = (SAM_USER_INFO_23 *)malloc(sizeof(SAM_USER_INFO_23));
4351                         if (ctr->info.id23 == NULL) {
4352                                 DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
4353                                 return False;
4354                         }
4355                         if(!sam_io_user_info23("", ctr->info.id23, ps, depth))
4356                                 return False;
4357                         break;
4358                 case 24:
4359                         if (UNMARSHALLING(ps)) /* reading */
4360                                 ctr->info.id24 = (SAM_USER_INFO_24 *)malloc(sizeof(SAM_USER_INFO_24));
4361                         if (ctr->info.id24 == NULL) {
4362                                 DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
4363                                 return False;
4364                         }
4365                         if(!sam_io_user_info24("", ctr->info.id24, ps, depth))
4366                                 return False;
4367                         break;
4368                 default:
4369                         DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
4370                         return False;
4371                         break;
4372
4373         }
4374
4375         return True;
4376 }
4377
4378 /*******************************************************************
4379 frees a structure.
4380 ********************************************************************/
4381 void free_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr)
4382 {
4383         if (ctr == NULL)
4384                 return;
4385         safe_free(ctr->info.id);
4386         ctr->info.id = NULL;
4387 }
4388
4389 /*******************************************************************
4390 reads or writes a structure.
4391 ********************************************************************/
4392 BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth)
4393 {
4394         if (q_u == NULL)
4395                 return False;
4396
4397         prs_debug(ps, depth, desc, "samr_io_q_set_userinfo");
4398         depth++;
4399
4400         if(!prs_align(ps))
4401                 return False;
4402
4403         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
4404                 return False;
4405
4406         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
4407                 return False;
4408         if(!samr_io_userinfo_ctr("ctr", q_u->ctr, ps, depth))
4409                 return False;
4410
4411         return True;
4412 }
4413
4414 /*******************************************************************
4415 frees a structure.
4416 ********************************************************************/
4417 void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u)
4418 {
4419        if (q_u == NULL)
4420                return;
4421        free_samr_userinfo_ctr(q_u->ctr);
4422 }
4423
4424 /*******************************************************************
4425 reads or writes a structure.
4426 ********************************************************************/
4427 BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth)
4428 {
4429         if (r_u == NULL)
4430                 return False;
4431
4432         prs_debug(ps, depth, desc, "samr_io_r_set_userinfo");
4433         depth++;
4434
4435         if(!prs_align(ps))
4436                 return False;
4437
4438         if(!prs_uint32("status", ps, depth, &r_u->status))
4439                 return False;
4440
4441         return True;
4442 }
4443
4444 /*******************************************************************
4445 reads or writes a structure.
4446 ********************************************************************/
4447 BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth)
4448 {
4449         if (q_u == NULL)
4450                 return False;
4451
4452         prs_debug(ps, depth, desc, "samr_io_q_set_userinfo2");
4453         depth++;
4454
4455         if(!prs_align(ps))
4456                 return False;
4457
4458         if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
4459                 return False;
4460
4461         if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
4462                 return False;
4463         if(!samr_io_userinfo_ctr("ctr", q_u->ctr, ps, depth))
4464                 return False;
4465
4466         return True;
4467 }
4468
4469 /*******************************************************************
4470 frees a structure.
4471 ********************************************************************/
4472 void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u)
4473 {
4474         free_samr_userinfo_ctr(q_u->ctr);
4475 }
4476
4477 /*******************************************************************
4478 makes a SAMR_R_SET_USERINFO2 structure.
4479 ********************************************************************/
4480 BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u, uint32 status)
4481 {
4482         if (r_u == NULL)
4483                 return False;
4484
4485         DEBUG(5, ("make_samr_r_set_userinfo2\n"));
4486
4487         r_u->status = status;   /* return status */
4488
4489         return True;
4490 }
4491
4492 /*******************************************************************
4493 reads or writes a structure.
4494 ********************************************************************/
4495 BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth)
4496 {
4497         if (r_u == NULL)
4498                 return False;
4499
4500         prs_debug(ps, depth, desc, "samr_io_r_set_userinfo2");
4501         depth++;
4502
4503         if(!prs_align(ps))
4504                 return False;
4505
4506         if(!prs_uint32("status", ps, depth, &r_u->status))
4507                 return False;
4508
4509         return True;
4510 }
4511
4512
4513 #undef OLD_NTDOMAIN