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