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