added ASSERT() and ASSERT_ARRAY() macros and sprinkled them liberally
[samba.git] / source / 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, DOM_SID *sid)
82 {
83         if (q_u == NULL) return;
84
85         DEBUG(5,("samr_make_q_open_domain\n"));
86
87         memcpy(&q_u->connect_pol, connect_pol, sizeof(q_u->connect_pol));
88         q_u->rid = rid;
89         make_dom_sid2(&(q_u->dom_sid), sid);
90 }
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 /*******************************************************************
135 reads or writes a structure.
136 ********************************************************************/
137 void make_samr_q_unknown_8(SAMR_Q_UNKNOWN_8 *q_u,
138                                 POLICY_HND *domain_pol, uint16 switch_value)
139 {
140         if (q_u == NULL) return;
141
142         DEBUG(5,("samr_make_q_unknown_8\n"));
143
144         memcpy(&q_u->domain_pol, domain_pol, sizeof(q_u->domain_pol));
145         q_u->switch_value = switch_value;
146 }
147
148
149 /*******************************************************************
150 reads or writes a structure.
151 ********************************************************************/
152 void samr_io_q_unknown_8(char *desc,  SAMR_Q_UNKNOWN_8 *q_u, prs_struct *ps, int depth)
153 {
154         if (q_u == NULL) return;
155
156         prs_debug(ps, depth, desc, "samr_io_q_unknown_8");
157         depth++;
158
159         prs_align(ps);
160
161         smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth); 
162         prs_align(ps);
163
164         prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
165         prs_align(ps);
166 }
167
168 /*******************************************************************
169 reads or writes a structure.
170 ********************************************************************/
171 void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
172                                 POLICY_HND *user_pol, uint16 switch_value)
173 {
174         if (q_u == NULL) return;
175
176         DEBUG(5,("samr_make_q_unknown_3\n"));
177
178         memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
179         q_u->switch_value = switch_value;
180 }
181
182
183 /*******************************************************************
184 reads or writes a structure.
185 ********************************************************************/
186 void samr_io_q_unknown_3(char *desc,  SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth)
187 {
188         if (q_u == NULL) return;
189
190         prs_debug(ps, depth, desc, "samr_io_q_unknown_3");
191         depth++;
192
193         prs_align(ps);
194
195         smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth); 
196         prs_align(ps);
197
198         prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
199         prs_align(ps);
200 }
201
202 /*******************************************************************
203  makes a DOM_SID3 structure.
204
205  calculate length by adding up the size of the components.
206  ********************************************************************/
207 void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid)
208 {
209         if (sid3 == NULL) return;
210
211     sid3->sid = *sid;
212         sid3->len = 2 + 8 + sid3->sid.num_auths * 4;
213 }
214
215 /*******************************************************************
216 reads or writes a SAM_SID3 structure.
217
218 this one's odd, because the length (in bytes) is specified at the beginning.
219 the length _includes_ the length of the length, too :-)
220
221 ********************************************************************/
222 void sam_io_dom_sid3(char *desc,  DOM_SID3 *sid3, prs_struct *ps, int depth)
223 {
224         if (sid3 == NULL) return;
225
226         prs_debug(ps, depth, desc, "sam_io_dom_sid3");
227         depth++;
228
229         prs_uint16("len", ps, depth, &(sid3->len));
230         prs_align(ps);
231         smb_io_dom_sid("", &(sid3->sid), ps, depth); 
232 }
233
234 /*******************************************************************
235 makes a SAMR_R_UNKNOWN3 structure.
236
237 unknown_2   : 0x0001
238 unknown_3   : 0x8004
239
240 unknown_4,5 : 0x0000 0014
241
242 unknown_6   : 0x0002
243 unknown_7   : 0x5800 or 0x0070
244
245 ********************************************************************/
246 void make_sam_sid_stuff(SAM_SID_STUFF *stf,
247                                 uint16 unknown_2, uint16 unknown_3,
248                                 uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
249                                 int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS])
250 {
251         stf->unknown_2 = unknown_2;
252         stf->unknown_3 = unknown_3;
253
254         bzero(stf->padding1, sizeof(stf->padding1));
255
256         stf->unknown_4 = unknown_4;
257         stf->unknown_5 = unknown_4;
258
259         stf->unknown_6 = unknown_6;
260         stf->unknown_7 = unknown_7;
261
262         stf->num_sids  = num_sid3s;
263
264         stf->padding2  = 0x0000;
265
266         memcpy(stf->sid, sid3, sizeof(DOM_SID3) * num_sid3s);
267 }
268
269 /*******************************************************************
270 reads or writes a SAM_SID_STUFF structure.
271 ********************************************************************/
272 void sam_io_sid_stuff(char *desc,  SAM_SID_STUFF *stf, prs_struct *ps, int depth)
273 {
274         int i;
275
276         if (stf == NULL) return;
277
278         DEBUG(5,("make_sam_sid_stuff\n"));
279
280         prs_uint16("unknown_2", ps, depth, &(stf->unknown_2));
281         prs_uint16("unknown_3", ps, depth, &(stf->unknown_3));
282
283         prs_uint8s(False, "padding1", ps, depth, stf->padding1, sizeof(stf->padding1)); 
284         
285         prs_uint32("unknown_4", ps, depth, &(stf->unknown_4));
286         prs_uint32("unknown_5", ps, depth, &(stf->unknown_5));
287         prs_uint16("unknown_6", ps, depth, &(stf->unknown_6));
288         prs_uint16("unknown_7", ps, depth, &(stf->unknown_7));
289
290         prs_uint32("num_sids ", ps, depth, &(stf->num_sids ));
291         prs_uint16("padding2 ", ps, depth, &(stf->padding2 ));
292
293         ASSERT_ARRAY(stf->sid, stf->num_sids);
294
295         for (i = 0; i < stf->num_sids; i++)
296         {
297                 sam_io_dom_sid3("", &(stf->sid[i]), ps, depth); 
298         }
299 }
300
301 /*******************************************************************
302 reads or writes a SAMR_R_UNKNOWN3 structure.
303 ********************************************************************/
304 void make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
305                                 uint16 unknown_2, uint16 unknown_3,
306                                 uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
307                                 int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
308                                 uint32 status)
309 {
310         if (r_u == NULL) return;
311
312         DEBUG(5,("samr_make_r_unknown_3\n"));
313
314         r_u->ptr_0 = 0;
315         r_u->ptr_1 = 0;
316
317         if (status == 0x0)
318         {
319                 r_u->ptr_0 = 1;
320                 r_u->ptr_1 = 1;
321                 make_sam_sid_stuff(&(r_u->sid_stuff), unknown_2, unknown_3,
322                        unknown_4, unknown_6, unknown_7,
323                        num_sid3s, sid3);
324         }
325
326         r_u->status = status;
327 }
328
329
330 /*******************************************************************
331 reads or writes a SAMR_R_UNKNOWN_3 structure.
332
333 this one's odd, because the daft buggers use a different mechanism
334 for writing out the array of sids. they put the number of sids in
335 only one place: they've calculated the length of each sid and jumped
336 by that amount.  then, retrospectively, the length of the whole buffer
337 is put at the beginning of the data stream.
338
339 wierd.  
340
341 ********************************************************************/
342 void samr_io_r_unknown_3(char *desc,  SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth)
343 {
344         int ptr_len0=0;
345         int ptr_len1=0;
346         int ptr_sid_stuff = 0;
347
348         if (r_u == NULL) return;
349
350         prs_debug(ps, depth, desc, "samr_io_r_unknown_3");
351         depth++;
352
353         prs_align(ps);
354
355         prs_uint32("ptr_0         ", ps, depth, &(r_u->ptr_0         ));
356
357         if (ps->io) 
358         {
359                 /* reading.  do the length later */
360                 prs_uint32("sid_stuff_len0", ps, depth, &(r_u->sid_stuff_len0));
361         }
362         else
363         {
364                 /* storing */
365                 ptr_len0 = ps->offset; ps->offset += 4;
366         }
367
368         if (r_u->ptr_0 != 0)
369         {
370                 prs_uint32("ptr_1         ", ps, depth, &(r_u->ptr_1         ));
371                 if (ps->io)
372                 {
373                         /* reading.  do the length later */
374                         prs_uint32("sid_stuff_len1", ps, depth, &(r_u->sid_stuff_len1));
375                 }
376                 else
377                 {
378                         /* storing */
379                         ptr_len1 = ps->offset; ps->offset += 4;
380                 }
381
382                 if (r_u->ptr_1 != 0)
383                 {
384                         ptr_sid_stuff = ps->offset;
385                         sam_io_sid_stuff("", &(r_u->sid_stuff), ps, depth); 
386                 }
387         }
388
389         if (!(ps->io)) /* storing not reading.  do the length, now. */
390         {
391                 if (ptr_sid_stuff != 0)
392                 {
393                         uint32 sid_stuff_len = ps->offset - ptr_sid_stuff;
394                         int old_len = ps->offset;
395
396                         ps->offset = ptr_len0;
397                         prs_uint32("sid_stuff_len0", ps, depth, &sid_stuff_len); 
398
399                         ps->offset = ptr_len1;
400                         prs_uint32("sid_stuff_len1", ps, depth, &sid_stuff_len);
401
402                         ps->offset = old_len;
403                 }
404         }
405
406         prs_uint32("status", ps, depth, &(r_u->status));
407 }
408
409
410 /*******************************************************************
411 makes a SAM_STR1 structure.
412 ********************************************************************/
413 void make_sam_str1(SAM_STR1 *sam, char *sam_acct, char *sam_name, char *sam_desc)
414 {
415         int len_sam_acct = sam_acct != NULL ? strlen(sam_acct) : 0;
416         int len_sam_name = sam_name != NULL ? strlen(sam_name) : 0;
417         int len_sam_desc = sam_desc != NULL ? strlen(sam_desc) : 0;
418
419         if (sam == NULL) return;
420
421         DEBUG(5,("make_sam_str1: %d\n", __LINE__));
422
423         make_unistr2(&(sam->uni_acct_name), sam_acct, len_sam_acct);
424         make_unistr2(&(sam->uni_full_name), sam_name, len_sam_name);
425         make_unistr2(&(sam->uni_acct_desc), sam_desc, len_sam_desc);
426 }
427
428 /*******************************************************************
429 reads or writes a SAM_STR1 structure.
430 ********************************************************************/
431 void sam_io_sam_str1(char *desc,  SAM_STR1 *sam, uint32 acct_buf, uint32 name_buf, uint32 desc_buf, prs_struct *ps, int depth)
432 {
433         if (sam == NULL) return;
434
435         prs_debug(ps, depth, desc, "sam_io_sam_str1");
436         depth++;
437
438         prs_align(ps);
439
440         smb_io_unistr2("unistr2", &(sam->uni_acct_name), acct_buf, ps, depth); /* account name unicode string */
441         smb_io_unistr2("unistr2", &(sam->uni_full_name), name_buf, ps, depth); /* full name unicode string */
442         smb_io_unistr2("unistr2", &(sam->uni_acct_desc), desc_buf, ps, depth); /* account description unicode string */
443 }
444
445 /*******************************************************************
446 makes a SAM_ENTRY1 structure.
447 ********************************************************************/
448 void make_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx, 
449                                 uint32 len_sam_name, uint32 len_sam_full, uint32 len_sam_desc,
450                                 uint32 rid_user, uint16 acb_info)
451 {
452         if (sam == NULL) return;
453
454         DEBUG(5,("make_sam_entry1: %d\n", __LINE__));
455
456         sam->user_idx = user_idx;
457         sam->rid_user = rid_user;
458         sam->acb_info = acb_info;
459         sam->pad      = 0;
460
461         make_uni_hdr(&(sam->hdr_acct_name), len_sam_name, len_sam_name, len_sam_name != 0);
462         make_uni_hdr(&(sam->hdr_user_name), len_sam_full, len_sam_full, len_sam_full != 0);
463         make_uni_hdr(&(sam->hdr_user_desc), len_sam_desc, len_sam_desc, len_sam_desc != 0);
464 }
465
466 /*******************************************************************
467 reads or writes a SAM_ENTRY1 structure.
468 ********************************************************************/
469 void sam_io_sam_entry1(char *desc,  SAM_ENTRY1 *sam, prs_struct *ps, int depth)
470 {
471         if (sam == NULL) return;
472
473         prs_debug(ps, depth, desc, "sam_io_sam_entry1");
474         depth++;
475
476         prs_align(ps);
477
478         prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
479
480         prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
481         prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
482         prs_uint16("pad      ", ps, depth, &(sam->pad      ));
483
484         smb_io_unihdr("unihdr", &(sam->hdr_acct_name), ps, depth); /* account name unicode string header */
485         smb_io_unihdr("unihdr", &(sam->hdr_user_name), ps, depth); /* account name unicode string header */
486         smb_io_unihdr("unihdr", &(sam->hdr_user_desc), ps, depth); /* account name unicode string header */
487 }
488
489 /*******************************************************************
490 makes a SAM_STR2 structure.
491 ********************************************************************/
492 void make_sam_str2(SAM_STR2 *sam, char *sam_acct, char *sam_desc)
493 {
494         int len_sam_acct = sam_acct != NULL ? strlen(sam_acct) : 0;
495         int len_sam_desc = sam_desc != NULL ? strlen(sam_desc) : 0;
496
497         if (sam == NULL) return;
498
499         DEBUG(5,("make_sam_str2: %d\n", __LINE__));
500
501         make_unistr2(&(sam->uni_srv_name), sam_acct, len_sam_acct);
502         make_unistr2(&(sam->uni_srv_desc), sam_desc, len_sam_desc);
503 }
504
505 /*******************************************************************
506 reads or writes a SAM_STR2 structure.
507 ********************************************************************/
508 void sam_io_sam_str2(char *desc,  SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
509 {
510         if (sam == NULL) return;
511
512         prs_debug(ps, depth, desc, "sam_io_sam_str2");
513         depth++;
514
515         prs_align(ps);
516
517         smb_io_unistr2("unistr2", &(sam->uni_srv_name), acct_buf, ps, depth); /* account name unicode string */
518         smb_io_unistr2("unistr2", &(sam->uni_srv_desc), desc_buf, ps, depth); /* account description unicode string */
519 }
520
521 /*******************************************************************
522 makes a SAM_ENTRY2 structure.
523 ********************************************************************/
524 void make_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx, 
525                                 uint32 len_sam_name, uint32 len_sam_desc,
526                                 uint32 rid_user, uint16 acb_info)
527 {
528         if (sam == NULL) return;
529
530         DEBUG(5,("make_sam_entry2: %d\n", __LINE__));
531
532         sam->user_idx = user_idx;
533         sam->rid_user = rid_user;
534         sam->acb_info = acb_info;
535         sam->pad      = 0;
536
537         make_uni_hdr(&(sam->hdr_srv_name), len_sam_name, len_sam_name, len_sam_name != 0);
538         make_uni_hdr(&(sam->hdr_srv_desc), len_sam_desc, len_sam_desc, len_sam_desc != 0);
539 }
540
541 /*******************************************************************
542 reads or writes a SAM_ENTRY2 structure.
543 ********************************************************************/
544 void sam_io_sam_entry2(char *desc,  SAM_ENTRY2 *sam, prs_struct *ps, int depth)
545 {
546         if (sam == NULL) return;
547
548         prs_debug(ps, depth, desc, "sam_io_sam_entry2");
549         depth++;
550
551         prs_align(ps);
552
553         prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
554
555         prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
556         prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
557         prs_uint16("pad      ", ps, depth, &(sam->pad      ));
558
559         smb_io_unihdr("unihdr", &(sam->hdr_srv_name), ps, depth); /* account name unicode string header */
560         smb_io_unihdr("unihdr", &(sam->hdr_srv_desc), ps, depth); /* account name unicode string header */
561 }
562
563 /*******************************************************************
564 makes a SAM_STR3 structure.
565 ********************************************************************/
566 void make_sam_str3(SAM_STR3 *sam, char *grp_acct, char *grp_desc)
567 {
568         int len_grp_acct = strlen(grp_acct);
569         int len_grp_desc = strlen(grp_desc);
570
571         if (sam == NULL) return;
572
573         DEBUG(5,("make_sam_str3: %d\n", __LINE__));
574
575         make_unistr2(&(sam->uni_grp_name), grp_acct, len_grp_acct);
576         make_unistr2(&(sam->uni_grp_desc), grp_desc, len_grp_desc);
577 }
578
579 /*******************************************************************
580 reads or writes a SAM_STR3 structure.
581 ********************************************************************/
582 void sam_io_sam_str3(char *desc,  SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
583 {
584         if (sam == NULL) return;
585
586         prs_debug(ps, depth, desc, "sam_io_sam_str3");
587         depth++;
588
589         prs_align(ps);
590
591         smb_io_unistr2("unistr2", &(sam->uni_grp_name), acct_buf, ps, depth); /* account name unicode string */
592         smb_io_unistr2("unistr2", &(sam->uni_grp_desc), desc_buf, ps, depth); /* account description unicode string */
593 }
594
595 /*******************************************************************
596 makes a SAM_ENTRY3 structure.
597 ********************************************************************/
598 void make_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx, 
599                                 uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp)
600 {
601         if (sam == NULL) return;
602
603         DEBUG(5,("make_sam_entry3: %d\n", __LINE__));
604
605         sam->grp_idx = grp_idx;
606         sam->rid_grp = rid_grp;
607         sam->attr    = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
608
609         make_uni_hdr(&(sam->hdr_grp_name), len_grp_name, len_grp_name, len_grp_name != 0);
610         make_uni_hdr(&(sam->hdr_grp_desc), len_grp_desc, len_grp_desc, len_grp_desc != 0);
611 }
612
613 /*******************************************************************
614 reads or writes a SAM_ENTRY3 structure.
615 ********************************************************************/
616 void sam_io_sam_entry3(char *desc,  SAM_ENTRY3 *sam, prs_struct *ps, int depth)
617 {
618         if (sam == NULL) return;
619
620         prs_debug(ps, depth, desc, "sam_io_sam_entry3");
621         depth++;
622
623         prs_align(ps);
624
625         prs_uint32("grp_idx", ps, depth, &(sam->grp_idx));
626
627         prs_uint32("rid_grp", ps, depth, &(sam->rid_grp));
628         prs_uint32("attr   ", ps, depth, &(sam->attr   ));
629
630         smb_io_unihdr("unihdr", &(sam->hdr_grp_name), ps, depth); /* account name unicode string header */
631         smb_io_unihdr("unihdr", &(sam->hdr_grp_desc), ps, depth); /* account name unicode string header */
632 }
633
634 /*******************************************************************
635 makes a SAM_ENTRY structure.
636 ********************************************************************/
637 void make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
638 {
639         if (sam == NULL) return;
640
641         DEBUG(5,("make_sam_entry: %d\n", __LINE__));
642
643         sam->rid = rid;
644         make_uni_hdr(&(sam->hdr_name), len_sam_name, len_sam_name, len_sam_name != 0);
645 }
646
647 /*******************************************************************
648 reads or writes a SAM_ENTRY structure.
649 ********************************************************************/
650 void sam_io_sam_entry(char *desc,  SAM_ENTRY *sam, prs_struct *ps, int depth)
651 {
652         if (sam == NULL) return;
653
654         prs_debug(ps, depth, desc, "sam_io_sam_entry");
655         depth++;
656
657         prs_align(ps);
658         prs_uint32("rid", ps, depth, &(sam->rid ));
659         smb_io_unihdr("unihdr", &(sam->hdr_name), ps, depth); /* account name unicode string header */
660 }
661
662 /*******************************************************************
663 makes a SAMR_Q_ENUM_DOM_USERS structure.
664 ********************************************************************/
665 void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
666                                 uint16 req_num_entries, uint16 unk_0,
667                                 uint16 acb_mask, uint16 unk_1, uint32 size)
668 {
669         if (q_e == NULL || pol == NULL) return;
670
671         DEBUG(5,("make_q_enum_dom_users\n"));
672
673         memcpy(&(q_e->pol), pol, sizeof(*pol));
674
675         q_e->req_num_entries = req_num_entries; /* zero indicates lots */
676         q_e->unknown_0 = unk_0; /* this gets returned in the response */
677         q_e->acb_mask  = acb_mask;
678         q_e->unknown_1 = unk_1;
679         q_e->max_size = size;
680 }
681
682
683 /*******************************************************************
684 reads or writes a structure.
685 ********************************************************************/
686 void samr_io_q_enum_dom_users(char *desc,  SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth)
687 {
688         if (q_e == NULL) return;
689
690         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
691         depth++;
692
693         prs_align(ps);
694
695         smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
696         prs_align(ps);
697
698         prs_uint16("req_num_entries", ps, depth, &(q_e->req_num_entries));
699         prs_uint16("unknown_0      ", ps, depth, &(q_e->unknown_0      ));
700
701         prs_uint16("acb_mask       ", ps, depth, &(q_e->acb_mask       ));
702         prs_uint16("unknown_1      ", ps, depth, &(q_e->unknown_1      ));
703
704         prs_uint32("max_size       ", ps, depth, &(q_e->max_size       ));
705
706         prs_align(ps);
707 }
708
709
710 /*******************************************************************
711 makes a SAMR_R_ENUM_DOM_USERS structure.
712 ********************************************************************/
713 void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
714                 uint16 total_num_entries, uint16 unk_0,
715                 uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status)
716 {
717         int i;
718
719         if (r_u == NULL) return;
720
721         DEBUG(5,("make_samr_r_enum_dom_users\n"));
722
723         if (num_sam_entries >= MAX_SAM_ENTRIES)
724         {
725                 num_sam_entries = MAX_SAM_ENTRIES;
726                 DEBUG(5,("limiting number of entries to %d\n",
727                          num_sam_entries));
728         }
729
730         r_u->total_num_entries = total_num_entries;
731         r_u->unknown_0         = unk_0;
732
733         if (total_num_entries > 0)
734         {
735                 r_u->ptr_entries1 = 1;
736                 r_u->ptr_entries2 = 1;
737                 r_u->num_entries2 = num_sam_entries;
738                 r_u->num_entries3 = num_sam_entries;
739
740                 ASSERT_ARRAY(r_u->sam, num_sam_entries);
741                 ASSERT_ARRAY(r_u->uni_acct_name, num_sam_entries);
742
743                 for (i = 0; i < num_sam_entries; i++)
744                 {
745                         make_sam_entry(&(r_u->sam[i]),
746                                        pass[i].uni_user_name.uni_str_len,
747                                        pass[i].user_rid);
748
749                         copy_unistr2(&(r_u->uni_acct_name[i]), &(pass[i].uni_user_name));
750                 }
751
752                 r_u->num_entries4 = num_sam_entries;
753         }
754         else
755         {
756                 r_u->ptr_entries1 = 0;
757                 r_u->num_entries2 = num_sam_entries;
758                 r_u->ptr_entries2 = 1;
759         }
760
761         r_u->status = status;
762 }
763
764 /*******************************************************************
765 reads or writes a structure.
766 ********************************************************************/
767 void samr_io_r_enum_dom_users(char *desc,  SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth)
768 {
769         int i;
770
771         if (r_u == NULL) return;
772
773         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
774         depth++;
775
776         prs_align(ps);
777
778         prs_uint16("total_num_entries", ps, depth, &(r_u->total_num_entries));
779         prs_uint16("unknown_0        ", ps, depth, &(r_u->unknown_0        ));
780         prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
781
782         if (r_u->total_num_entries != 0 && r_u->ptr_entries1 != 0)
783         {
784                 prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
785                 prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
786                 prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
787
788                 ASSERT_ARRAY(r_u->sam, r_u->num_entries2);
789
790                 for (i = 0; i < r_u->num_entries2; i++)
791                 {
792                         prs_grow(ps);
793                         sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
794                 }
795
796                 ASSERT_ARRAY(r_u->uni_acct_name, r_u->num_entries2);
797
798                 for (i = 0; i < r_u->num_entries2; i++)
799                 {
800                         prs_grow(ps);
801                         smb_io_unistr2("", &(r_u->uni_acct_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
802                 }
803
804                 prs_align(ps);
805
806                 prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
807         }
808
809         prs_uint32("status", ps, depth, &(r_u->status));
810 }
811
812 /*******************************************************************
813 makes a SAMR_Q_ENUM_DOM_ALIASES structure.
814 ********************************************************************/
815 void make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size)
816 {
817         if (q_e == NULL || pol == NULL) return;
818
819         DEBUG(5,("make_q_enum_dom_aliases\n"));
820
821         memcpy(&(q_e->pol), pol, sizeof(*pol));
822
823         q_e->unknown_0 = 0;
824         q_e->max_size = size;
825 }
826
827
828 /*******************************************************************
829 reads or writes a structure.
830 ********************************************************************/
831 void samr_io_q_enum_dom_aliases(char *desc,  SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth)
832 {
833         if (q_e == NULL) return;
834
835         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
836         depth++;
837
838         prs_align(ps);
839
840         smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
841         prs_align(ps);
842
843         prs_uint32("unknown_0", ps, depth, &(q_e->unknown_0));
844         prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
845
846         prs_align(ps);
847 }
848
849
850 /*******************************************************************
851 makes a SAMR_R_ENUM_DOM_ALIASES structure.
852 ********************************************************************/
853 void make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
854                 uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
855                 uint32 status)
856 {
857         int i;
858
859         if (r_u == NULL) return;
860
861         DEBUG(5,("make_samr_r_enum_dom_aliases\n"));
862
863         if (num_sam_entries >= MAX_SAM_ENTRIES)
864         {
865                 num_sam_entries = MAX_SAM_ENTRIES;
866                 DEBUG(5,("limiting number of entries to %d\n", 
867                          num_sam_entries));
868         }
869
870         r_u->num_entries  = num_sam_entries;
871
872         if (num_sam_entries > 0)
873         {
874                 r_u->ptr_entries  = 1;
875                 r_u->num_entries2 = num_sam_entries;
876                 r_u->ptr_entries2 = 1;
877                 r_u->num_entries3 = num_sam_entries;
878
879                 ASSERT_ARRAY(r_u->sam, num_sam_entries);
880
881                 for (i = 0; i < num_sam_entries; i++)
882                 {
883                         make_sam_entry(&(r_u->sam[i]),
884                                        grps[i].uni_user_name.uni_str_len,
885                                        grps[i].user_rid);
886
887                         copy_unistr2(&(r_u->uni_grp_name[i]), &(grps[i].uni_user_name));
888                 }
889
890                 r_u->num_entries4 = num_sam_entries;
891         }
892         else
893         {
894                 r_u->ptr_entries = 0;
895         }
896
897         r_u->status = status;
898 }
899
900 /*******************************************************************
901 reads or writes a structure.
902 ********************************************************************/
903 void samr_io_r_enum_dom_aliases(char *desc,  SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth)
904 {
905         int i;
906
907         if (r_u == NULL) return;
908
909         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
910         depth++;
911
912         prs_align(ps);
913
914         prs_uint32("num_entries", ps, depth, &(r_u->num_entries));
915         prs_uint32("ptr_entries", ps, depth, &(r_u->ptr_entries));
916
917         if (r_u->num_entries != 0 && r_u->ptr_entries != 0)
918         {
919                 prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
920                 prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
921                 prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
922
923                 ASSERT_ARRAY(r_u->sam, r_u->num_entries);
924
925                 for (i = 0; i < r_u->num_entries; i++)
926                 {
927                         sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
928                 }
929
930                 for (i = 0; i < r_u->num_entries; i++)
931                 {
932                         smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
933                 }
934
935                 prs_align(ps);
936
937                 prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
938         }
939
940         prs_uint32("status", ps, depth, &(r_u->status));
941 }
942
943 /*******************************************************************
944 makes a SAMR_Q_QUERY_DISPINFO structure.
945 ********************************************************************/
946 void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
947                                 uint16 switch_level, uint32 start_idx, uint32 size)
948 {
949         if (q_e == NULL || pol == NULL) return;
950
951         DEBUG(5,("make_q_query_dispinfo\n"));
952
953         memcpy(&(q_e->pol), pol, sizeof(*pol));
954
955         q_e->switch_level = switch_level;
956
957         q_e->unknown_0 = 0;
958         q_e->start_idx = start_idx;
959         q_e->unknown_1 = 0x000007d0;
960         q_e->max_size  = size;
961 }
962
963
964 /*******************************************************************
965 reads or writes a structure.
966 ********************************************************************/
967 void samr_io_q_query_dispinfo(char *desc,  SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
968 {
969         if (q_e == NULL) return;
970
971         prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
972         depth++;
973
974         prs_align(ps);
975
976         smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
977         prs_align(ps);
978
979         prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
980         prs_uint16("unknown_0   ", ps, depth, &(q_e->unknown_0   ));
981         prs_uint32("start_idx   ", ps, depth, &(q_e->start_idx   ));
982         prs_uint32("unknown_1   ", ps, depth, &(q_e->unknown_1   ));
983         prs_uint32("max_size    ", ps, depth, &(q_e->max_size    ));
984
985         prs_align(ps);
986 }
987
988
989 /*******************************************************************
990 makes a SAM_INFO_2 structure.
991 ********************************************************************/
992 void make_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
993                 uint32 start_idx, uint32 num_sam_entries,
994                 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
995 {
996         int i;
997         int entries_added;
998
999         if (sam == NULL) return;
1000
1001         DEBUG(5,("make_sam_info_2\n"));
1002
1003         if (num_sam_entries >= MAX_SAM_ENTRIES)
1004         {
1005                 num_sam_entries = MAX_SAM_ENTRIES;
1006                 DEBUG(5,("limiting number of entries to %d\n", 
1007                          num_sam_entries));
1008         }
1009
1010         for (i = start_idx, entries_added = 0; i < num_sam_entries; i++)
1011         {
1012                 if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask))
1013                 {
1014                         make_sam_entry2(&(sam->sam[entries_added]),
1015                                         start_idx + entries_added + 1,
1016                                         pass[i].uni_user_name.uni_str_len,
1017                                         pass[i].uni_acct_desc.uni_str_len,
1018                                         pass[i].user_rid,
1019                                         pass[i].acb_info);
1020
1021                         copy_unistr2(&(sam->str[entries_added].uni_srv_name), &(pass[i].uni_user_name));
1022                         copy_unistr2(&(sam->str[entries_added].uni_srv_desc), &(pass[i].uni_acct_desc));
1023
1024                         entries_added++;
1025                 }
1026
1027                 sam->num_entries   = entries_added;
1028                 sam->ptr_entries   = 1;
1029                 sam->num_entries2  = entries_added;
1030         }
1031 }
1032
1033 /*******************************************************************
1034 reads or writes a structure.
1035 ********************************************************************/
1036 void sam_io_sam_info_2(char *desc,  SAM_INFO_2 *sam, prs_struct *ps, int depth)
1037 {
1038         int i;
1039
1040         if (sam == NULL) return;
1041
1042         prs_debug(ps, depth, desc, "sam_io_sam_info_2");
1043         depth++;
1044
1045         prs_align(ps);
1046
1047         prs_uint32("num_entries  ", ps, depth, &(sam->num_entries  ));
1048         prs_uint32("ptr_entries  ", ps, depth, &(sam->ptr_entries  ));
1049
1050         prs_uint32("num_entries2 ", ps, depth, &(sam->num_entries2 ));
1051
1052         ASSERT_ARRAY(sam->sam, sam->num_entries);
1053
1054         for (i = 0; i < sam->num_entries; i++)
1055         {
1056                 sam_io_sam_entry2("", &(sam->sam[i]), ps, depth);
1057         }
1058
1059         for (i = 0; i < sam->num_entries; i++)
1060         {
1061                 sam_io_sam_str2 ("", &(sam->str[i]),
1062                                                          sam->sam[i].hdr_srv_name.buffer,
1063                                                          sam->sam[i].hdr_srv_desc.buffer,
1064                                                          ps, depth);
1065         }
1066 }
1067
1068
1069 /*******************************************************************
1070 makes a SAM_INFO_1 structure.
1071 ********************************************************************/
1072 void make_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
1073                 uint32 start_idx, uint32 num_sam_entries,
1074                 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
1075 {
1076         int i;
1077         int entries_added;
1078
1079         if (sam == NULL) return;
1080
1081         DEBUG(5,("make_sam_info_1\n"));
1082
1083         if (num_sam_entries >= MAX_SAM_ENTRIES)
1084         {
1085                 num_sam_entries = MAX_SAM_ENTRIES;
1086                 DEBUG(5,("limiting number of entries to %d\n", 
1087                          num_sam_entries));
1088         }
1089
1090         for (i = start_idx, entries_added = 0; i < num_sam_entries; i++)
1091         {
1092                 if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask))
1093                 {
1094                         make_sam_entry1(&(sam->sam[entries_added]),
1095                                                 start_idx + entries_added + 1,
1096                                                 pass[i].uni_user_name.uni_str_len,
1097                                                 pass[i].uni_full_name.uni_str_len, 
1098                                                 pass[i].uni_acct_desc.uni_str_len,
1099                                                 pass[i].user_rid,
1100                                                 pass[i].acb_info);
1101
1102                         copy_unistr2(&(sam->str[entries_added].uni_acct_name), &(pass[i].uni_user_name));
1103                         copy_unistr2(&(sam->str[entries_added].uni_full_name), &(pass[i].uni_full_name));
1104                         copy_unistr2(&(sam->str[entries_added].uni_acct_desc), &(pass[i].uni_acct_desc));
1105
1106                         entries_added++;
1107                 }
1108         }
1109
1110         sam->num_entries   = entries_added;
1111         sam->ptr_entries   = 1;
1112         sam->num_entries2  = entries_added;
1113 }
1114
1115
1116 /*******************************************************************
1117 reads or writes a structure.
1118 ********************************************************************/
1119 void sam_io_sam_info_1(char *desc,  SAM_INFO_1 *sam, prs_struct *ps, int depth)
1120 {
1121         int i;
1122
1123         if (sam == NULL) return;
1124
1125         prs_debug(ps, depth, desc, "sam_io_sam_info_1");
1126         depth++;
1127
1128         prs_align(ps);
1129
1130         prs_uint32("num_entries  ", ps, depth, &(sam->num_entries  ));
1131         prs_uint32("ptr_entries  ", ps, depth, &(sam->ptr_entries  ));
1132
1133         prs_uint32("num_entries2 ", ps, depth, &(sam->num_entries2 ));
1134
1135         ASSERT_ARRAY(sam->sam, sam->num_entries);
1136
1137         for (i = 0; i < sam->num_entries; i++)
1138         {
1139                 sam_io_sam_entry1("", &(sam->sam[i]), ps, depth);
1140         }
1141
1142         for (i = 0; i < sam->num_entries; i++)
1143         {
1144                 sam_io_sam_str1 ("", &(sam->str[i]),
1145                                                          sam->sam[i].hdr_acct_name.buffer,
1146                                                          sam->sam[i].hdr_user_name.buffer,
1147                                                          sam->sam[i].hdr_user_desc.buffer,
1148                                                          ps, depth);
1149         }
1150 }
1151
1152
1153 /*******************************************************************
1154 makes a SAMR_R_QUERY_DISPINFO structure.
1155 ********************************************************************/
1156 void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
1157                 uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status)
1158 {
1159         if (r_u == NULL) return;
1160
1161         DEBUG(5,("make_samr_r_query_dispinfo\n"));
1162
1163         if (status == 0x0)
1164         {
1165                 r_u->unknown_0 = 0x0000001;
1166                 r_u->unknown_1 = 0x0000001;
1167         }
1168         else
1169         {
1170                 r_u->unknown_0 = 0x0;
1171                 r_u->unknown_1 = 0x0;
1172         }
1173
1174         r_u->switch_level = switch_level;
1175         r_u->ctr = ctr;
1176         r_u->status = status;
1177 }
1178
1179
1180 /*******************************************************************
1181 reads or writes a structure.
1182 ********************************************************************/
1183 void samr_io_r_query_dispinfo(char *desc,  SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
1184 {
1185         if (r_u == NULL) return;
1186
1187         prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
1188         depth++;
1189
1190         prs_align(ps);
1191
1192         prs_uint32("unknown_0    ", ps, depth, &(r_u->unknown_0    ));
1193         prs_uint32("unknown_1    ", ps, depth, &(r_u->unknown_1    ));
1194         prs_uint16("switch_level ", ps, depth, &(r_u->switch_level ));
1195
1196         prs_align(ps);
1197
1198         switch (r_u->switch_level)
1199         {
1200                 case 0x1:
1201                 {
1202                         sam_io_sam_info_1("users", r_u->ctr->sam.info1, ps, depth);
1203                         break;
1204                 }
1205                 case 0x2:
1206                 {
1207                         sam_io_sam_info_2("servers", r_u->ctr->sam.info2, ps, depth);
1208                         break;
1209                 }
1210                 default:
1211                 {
1212                         DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
1213                         break;
1214                 }
1215         }
1216
1217         prs_uint32("status", ps, depth, &(r_u->status));
1218 }
1219
1220
1221 /*******************************************************************
1222 makes a SAMR_Q_ENUM_DOM_GROUPS structure.
1223 ********************************************************************/
1224 void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
1225                                 uint16 switch_level, uint32 start_idx, uint32 size)
1226 {
1227         if (q_e == NULL || pol == NULL) return;
1228
1229         DEBUG(5,("make_q_enum_dom_groups\n"));
1230
1231         memcpy(&(q_e->pol), pol, sizeof(*pol));
1232
1233         q_e->switch_level = switch_level;
1234
1235         q_e->unknown_0 = 0;
1236         q_e->start_idx = start_idx;
1237         q_e->unknown_1 = 0x000007d0;
1238         q_e->max_size  = size;
1239 }
1240
1241
1242 /*******************************************************************
1243 reads or writes a structure.
1244 ********************************************************************/
1245 void samr_io_q_enum_dom_groups(char *desc,  SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth)
1246 {
1247         if (q_e == NULL) return;
1248
1249         prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
1250         depth++;
1251
1252         prs_align(ps);
1253
1254         smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
1255         prs_align(ps);
1256
1257         prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
1258         prs_uint16("unknown_0   ", ps, depth, &(q_e->unknown_0   ));
1259         prs_uint32("start_idx   ", ps, depth, &(q_e->start_idx   ));
1260         prs_uint32("unknown_1   ", ps, depth, &(q_e->unknown_1   ));
1261         prs_uint32("max_size    ", ps, depth, &(q_e->max_size    ));
1262
1263         prs_align(ps);
1264 }
1265
1266
1267 /*******************************************************************
1268 makes a SAMR_R_ENUM_DOM_GROUPS structure.
1269 ********************************************************************/
1270 void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
1271                 uint32 start_idx, uint32 num_sam_entries,
1272                 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
1273                 uint32 status)
1274 {
1275         int i;
1276         int entries_added;
1277
1278         if (r_u == NULL) return;
1279
1280         DEBUG(5,("make_samr_r_enum_dom_groups\n"));
1281
1282         if (num_sam_entries >= MAX_SAM_ENTRIES)
1283         {
1284                 num_sam_entries = MAX_SAM_ENTRIES;
1285                 DEBUG(5,("limiting number of entries to %d\n", 
1286                          num_sam_entries));
1287         }
1288
1289         if (status == 0x0)
1290         {
1291                 for (i = start_idx, entries_added = 0; i < num_sam_entries; i++)
1292                 {
1293                         make_sam_entry3(&(r_u->sam[entries_added]),
1294                                         start_idx + entries_added + 1,
1295                                         pass[i].uni_user_name.uni_str_len,
1296                                         pass[i].uni_acct_desc.uni_str_len,
1297                                         pass[i].user_rid);
1298
1299                         copy_unistr2(&(r_u->str[entries_added].uni_grp_name), &(pass[i].uni_user_name));
1300                         copy_unistr2(&(r_u->str[entries_added].uni_grp_desc), &(pass[i].uni_acct_desc));
1301
1302                         entries_added++;
1303                 }
1304
1305                 if (entries_added > 0)
1306                 {
1307                         r_u->unknown_0 = 0x0000492;
1308                         r_u->unknown_1 = 0x000049a;
1309                 }
1310                 else
1311                 {
1312                         r_u->unknown_0 = 0x0;
1313                         r_u->unknown_1 = 0x0;
1314                 }
1315                 r_u->switch_level  = 3;
1316                 r_u->num_entries   = entries_added;
1317                 r_u->ptr_entries   = 1;
1318                 r_u->num_entries2  = entries_added;
1319         }
1320         else
1321         {
1322                 r_u->switch_level = 0;
1323         }
1324
1325         r_u->status = status;
1326 }
1327
1328 /*******************************************************************
1329 reads or writes a structure.
1330 ********************************************************************/
1331 void samr_io_r_enum_dom_groups(char *desc,  SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth)
1332 {
1333         int i;
1334
1335         if (r_u == NULL) return;
1336
1337         prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
1338         depth++;
1339
1340         prs_align(ps);
1341
1342         prs_uint32("unknown_0    ", ps, depth, &(r_u->unknown_0    ));
1343         prs_uint32("unknown_1    ", ps, depth, &(r_u->unknown_1    ));
1344         prs_uint32("switch_level ", ps, depth, &(r_u->switch_level ));
1345
1346         if (r_u->switch_level != 0)
1347         {
1348                 prs_uint32("num_entries  ", ps, depth, &(r_u->num_entries  ));
1349                 prs_uint32("ptr_entries  ", ps, depth, &(r_u->ptr_entries  ));
1350
1351                 prs_uint32("num_entries2 ", ps, depth, &(r_u->num_entries2 ));
1352
1353                 ASSERT_ARRAY(r_u->sam, r_u->num_entries);
1354
1355                 for (i = 0; i < r_u->num_entries; i++)
1356                 {
1357                         sam_io_sam_entry3("", &(r_u->sam[i]), ps, depth);
1358                 }
1359
1360                 for (i = 0; i < r_u->num_entries; i++)
1361                 {
1362                         sam_io_sam_str3 ("", &(r_u->str[i]),
1363                                              r_u->sam[i].hdr_grp_name.buffer,
1364                                              r_u->sam[i].hdr_grp_desc.buffer,
1365                                              ps, depth);
1366                 }
1367         }
1368
1369         prs_uint32("status", ps, depth, &(r_u->status));
1370 }
1371
1372
1373 /*******************************************************************
1374 makes a SAMR_Q_QUERY_ALIASINFO structure.
1375 ********************************************************************/
1376 void make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
1377                                 POLICY_HND *pol,
1378                                 uint16 switch_level)
1379 {
1380         if (q_e == NULL || pol == NULL) return;
1381
1382         DEBUG(5,("make_q_query_aliasinfo\n"));
1383
1384         memcpy(&(q_e->pol), pol, sizeof(*pol));
1385
1386         q_e->switch_level = switch_level;
1387 }
1388
1389
1390 /*******************************************************************
1391 reads or writes a structure.
1392 ********************************************************************/
1393 void samr_io_q_query_aliasinfo(char *desc,  SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth)
1394 {
1395         if (q_e == NULL) return;
1396
1397         prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
1398         depth++;
1399
1400         prs_align(ps);
1401
1402         smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
1403         prs_align(ps);
1404
1405         prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
1406 }
1407
1408
1409 /*******************************************************************
1410 makes a SAMR_R_QUERY_ALIASINFO structure.
1411 ********************************************************************/
1412 void make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
1413                 uint16 switch_value, char *acct_desc,
1414                 uint32 status)
1415 {
1416         if (r_u == NULL) return;
1417
1418         DEBUG(5,("make_samr_r_query_aliasinfo\n"));
1419
1420         r_u->ptr = 0;
1421
1422         if (status == 0)
1423         {
1424                 r_u->switch_value = switch_value;
1425
1426                 switch (switch_value)
1427                 {
1428                         case 3:
1429                         {
1430                                 int acct_len = acct_desc ? strlen(acct_desc) : 0;
1431
1432                                 r_u->ptr = 1;
1433
1434                                 make_uni_hdr(&(r_u->alias.info3.hdr_acct_desc), acct_len , acct_len, acct_desc ? 1 : 0);
1435                                 make_unistr2(&(r_u->alias.info3.uni_acct_desc), acct_desc, acct_len);
1436
1437                                 break;
1438                         }
1439
1440                         default:
1441                         {
1442                                 DEBUG(4,("make_samr_r_query_aliasinfo: unsupported switch level\n"));
1443                                 break;
1444                         }
1445                 }
1446         }
1447
1448         r_u->status = status;
1449 }
1450
1451
1452 /*******************************************************************
1453 reads or writes a structure.
1454 ********************************************************************/
1455 void samr_io_r_query_aliasinfo(char *desc,  SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
1456 {
1457         if (r_u == NULL) return;
1458
1459         prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
1460         depth++;
1461
1462         prs_align(ps);
1463
1464         prs_uint32("ptr         ", ps, depth, &(r_u->ptr         ));
1465         
1466         if (r_u->ptr != 0)
1467         {
1468                 prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
1469                 prs_align(ps);
1470
1471                 if (r_u->switch_value != 0)
1472                 {
1473                         switch (r_u->switch_value)
1474                         {
1475                                 case 3:
1476                                 {
1477                                         smb_io_unihdr ("", &(r_u->alias.info3.hdr_acct_desc), ps, depth);
1478                                         smb_io_unistr2("", &(r_u->alias.info3.uni_acct_desc), r_u->alias.info3.hdr_acct_desc.buffer, ps, depth);
1479                                         break;
1480                                 }
1481                                 default:
1482                                 {
1483                                         DEBUG(4,("samr_io_r_query_aliasinfo: unsupported switch level\n"));
1484                                         break;
1485                                 }
1486                         }
1487                 }
1488         }
1489
1490         prs_align(ps);
1491
1492         prs_uint32("status", ps, depth, &(r_u->status));
1493 }
1494
1495 /*******************************************************************
1496 reads or writes a SAMR_Q_LOOKUP_IDS structure.
1497 ********************************************************************/
1498 void samr_io_q_lookup_ids(char *desc,  SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth)
1499 {
1500         fstring tmp;
1501         int i;
1502
1503         if (q_u == NULL) return;
1504
1505         prs_debug(ps, depth, desc, "samr_io_q_lookup_ids");
1506         depth++;
1507
1508         prs_align(ps);
1509
1510         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
1511         prs_align(ps);
1512
1513         prs_uint32("num_sids1", ps, depth, &(q_u->num_sids1));
1514         prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
1515         prs_uint32("num_sids2", ps, depth, &(q_u->num_sids2));
1516
1517         ASSERT_ARRAY(q_u->ptr_sid, q_u->num_sids2);
1518
1519         for (i = 0; i < q_u->num_sids2; i++)
1520         {
1521                 slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
1522                 prs_uint32(tmp, ps, depth, &(q_u->ptr_sid[i]));
1523         }
1524
1525         for (i = 0; i < q_u->num_sids2; i++)
1526         {
1527                 if (q_u->ptr_sid[i] != 0)
1528                 {
1529                         slprintf(tmp, sizeof(tmp)-1, "sid[%02d]", i);
1530                         smb_io_dom_sid2(tmp, &(q_u->sid[i]), ps, depth); 
1531                 }
1532         }
1533
1534         prs_align(ps);
1535 }
1536
1537
1538 /*******************************************************************
1539 makes a SAMR_R_LOOKUP_IDS structure.
1540 ********************************************************************/
1541 void make_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
1542                 uint32 num_rids, uint32 *rid, uint32 status)
1543 {
1544         int i;
1545         if (r_u == NULL) return;
1546
1547         DEBUG(5,("make_samr_r_lookup_ids\n"));
1548
1549         if (status == 0x0)
1550         {
1551                 r_u->num_entries  = num_rids;
1552                 r_u->ptr = 1;
1553                 r_u->num_entries2 = num_rids;
1554
1555                 ASSERT_ARRAY(r_u->rid, num_rids);
1556
1557                 for (i = 0; i < num_rids; i++)
1558                 {
1559                         r_u->rid[i] = rid[i];
1560                 }
1561         }
1562         else
1563         {
1564                 r_u->num_entries  = 0;
1565                 r_u->ptr = 0;
1566                 r_u->num_entries2 = 0;
1567         }
1568
1569         r_u->status = status;
1570 }
1571
1572 /*******************************************************************
1573 reads or writes a structure.
1574 ********************************************************************/
1575 void samr_io_r_lookup_ids(char *desc,  SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth)
1576 {
1577         fstring tmp;
1578         int i;
1579         if (r_u == NULL) return;
1580
1581         prs_debug(ps, depth, desc, "samr_io_r_lookup_ids");
1582         depth++;
1583
1584         prs_align(ps);
1585
1586         prs_uint32("num_entries", ps, depth, &(r_u->num_entries));
1587         prs_uint32("ptr        ", ps, depth, &(r_u->ptr        ));
1588         prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
1589
1590         if (r_u->num_entries != 0)
1591         {
1592                 ASSERT_ARRAY(r_u->rid, r_u->num_entries2);
1593
1594                 for (i = 0; i < r_u->num_entries2; i++)
1595                 {
1596                         slprintf(tmp, sizeof(tmp)-1, "rid[%02d]", i);
1597                         prs_uint32(tmp, ps, depth, &(r_u->rid[i]));
1598                 }
1599         }
1600
1601         prs_uint32("status", ps, depth, &(r_u->status));
1602 }
1603
1604 /*******************************************************************
1605 reads or writes a structure.
1606 ********************************************************************/
1607 void samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
1608 {
1609         int i;
1610
1611         if (q_u == NULL) return;
1612
1613         prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
1614         depth++;
1615
1616         prs_align(ps);
1617
1618         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
1619         prs_align(ps);
1620
1621         prs_uint32("num_rids1", ps, depth, &(q_u->num_rids1));
1622         prs_uint32("rid      ", ps, depth, &(q_u->rid      ));
1623         prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
1624         prs_uint32("num_rids2", ps, depth, &(q_u->num_rids2));
1625
1626         ASSERT_ARRAY(q_u->hdr_user_name, q_u->num_rids2);
1627
1628         for (i = 0; i < q_u->num_rids2; i++)
1629         {
1630                 smb_io_unihdr ("", &(q_u->hdr_user_name[i]), ps, depth); 
1631         }
1632         for (i = 0; i < q_u->num_rids2; i++)
1633         {
1634                 smb_io_unistr2("", &(q_u->uni_user_name[i]), q_u->hdr_user_name[i].buffer, ps, depth); 
1635         }
1636
1637         prs_align(ps);
1638 }
1639
1640
1641 /*******************************************************************
1642 makes a SAMR_R_LOOKUP_NAMES structure.
1643 ********************************************************************/
1644 void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
1645                 uint32 num_rids, uint32 *rid, uint32 status)
1646 {
1647         int i;
1648         if (r_u == NULL) return;
1649
1650         DEBUG(5,("make_samr_r_lookup_names\n"));
1651
1652         if (status == 0x0)
1653         {
1654                 r_u->num_entries  = num_rids;
1655                 r_u->undoc_buffer = 1;
1656                 r_u->num_entries2 = num_rids;
1657
1658                 ASSERT_ARRAY(r_u->dom_rid, num_rids);
1659
1660                 for (i = 0; i < num_rids; i++)
1661                 {
1662                         make_dom_rid3(&(r_u->dom_rid[i]), rid[i]);
1663                 }
1664
1665                 r_u->num_entries3 = num_rids;
1666         }
1667         else
1668         {
1669                 r_u->num_entries  = 0;
1670                 r_u->undoc_buffer = 0;
1671                 r_u->num_entries2 = 0;
1672                 r_u->num_entries3 = 0;
1673         }
1674
1675         r_u->status = status;
1676 }
1677
1678 /*******************************************************************
1679 reads or writes a structure.
1680 ********************************************************************/
1681 void samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
1682 {
1683         int i;
1684         if (r_u == NULL) return;
1685
1686         prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
1687         depth++;
1688
1689         prs_align(ps);
1690
1691         prs_uint32("num_entries ", ps, depth, &(r_u->num_entries ));
1692         prs_uint32("undoc_buffer", ps, depth, &(r_u->undoc_buffer));
1693         prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
1694
1695         if (r_u->num_entries != 0)
1696         {
1697                 ASSERT_ARRAY(r_u->dom_rid, r_u->num_entries2);
1698
1699                 for (i = 0; i < r_u->num_entries2; i++)
1700                 {
1701                         smb_io_dom_rid3("", &(r_u->dom_rid[i]), ps, depth);
1702                 }
1703
1704         }
1705
1706         prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
1707
1708         prs_uint32("status", ps, depth, &(r_u->status));
1709 }
1710
1711 /*******************************************************************
1712 makes a SAMR_Q_UNKNOWN_12 structure.
1713 ********************************************************************/
1714 void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1715                 POLICY_HND *pol, uint32 rid,
1716                 uint32 num_gids, uint32 *gid)
1717 {
1718         int i;
1719         if (q_u == NULL) return;
1720
1721         DEBUG(5,("make_samr_r_unknwon_12\n"));
1722
1723         memcpy(&(q_u->pol), pol, sizeof(*pol));
1724
1725         q_u->num_gids1 = num_gids;
1726         q_u->rid       = rid;
1727         q_u->ptr       = 0;
1728         q_u->num_gids2 = num_gids;
1729
1730         ASSERT_ARRAY(q_u->gid, num_gids);
1731
1732         for (i = 0; i < num_gids; i++)
1733         {
1734                 q_u->gid[i] = gid[i];
1735         }
1736 }
1737
1738 /*******************************************************************
1739 reads or writes a structure.
1740 ********************************************************************/
1741 void samr_io_q_unknown_12(char *desc,  SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth)
1742 {
1743         int i;
1744         fstring tmp;
1745
1746         if (q_u == NULL) return;
1747
1748         prs_debug(ps, depth, desc, "samr_io_q_unknown_12");
1749         depth++;
1750
1751         prs_align(ps);
1752
1753         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
1754         prs_align(ps);
1755
1756         prs_uint32("num_gids1", ps, depth, &(q_u->num_gids1));
1757         prs_uint32("rid      ", ps, depth, &(q_u->rid      ));
1758         prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
1759         prs_uint32("num_gids2", ps, depth, &(q_u->num_gids2));
1760
1761         ASSERT_ARRAY(q_u->gid, q_u->num_gids2);
1762
1763         for (i = 0; i < q_u->num_gids2; i++)
1764         {
1765                 slprintf(tmp, sizeof(tmp) - 1, "gid[%02d]  ", i);
1766                 prs_uint32(tmp, ps, depth, &(q_u->gid[i]));
1767         }
1768
1769         prs_align(ps);
1770 }
1771
1772
1773 /*******************************************************************
1774 makes a SAMR_R_UNKNOWN_12 structure.
1775 ********************************************************************/
1776 void make_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
1777                 uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
1778                 uint32 status)
1779 {
1780         int i;
1781         if (r_u == NULL || als_name == NULL || num_als_usrs == NULL) return;
1782
1783         DEBUG(5,("make_samr_r_unknown_12\n"));
1784
1785         if (status == 0x0)
1786         {
1787                 r_u->num_aliases1 = num_aliases;
1788                 r_u->ptr_aliases  = 1;
1789                 r_u->num_aliases2 = num_aliases;
1790
1791                 r_u->num_als_usrs1 = num_aliases;
1792                 r_u->ptr_als_usrs  = 1;
1793                 r_u->num_als_usrs2 = num_aliases;
1794
1795                 ASSERT_ARRAY(r_u->hdr_als_name, num_aliases);
1796
1797                 for (i = 0; i < num_aliases; i++)
1798                 {
1799                         int als_len = als_name[i] != NULL ? strlen(als_name[i]) : 0;
1800                         make_uni_hdr(&(r_u->hdr_als_name[i]), als_len    , als_len, als_name[i] ? 1 : 0);
1801                         make_unistr2(&(r_u->uni_als_name[i]), als_name[i], als_len);
1802                         r_u->num_als_usrs[i] = num_als_usrs[i];
1803                 }
1804         }
1805         else
1806         {
1807                 r_u->num_aliases1 = num_aliases;
1808                 r_u->ptr_aliases  = 0;
1809                 r_u->num_aliases2 = num_aliases;
1810
1811                 r_u->num_als_usrs1 = num_aliases;
1812                 r_u->ptr_als_usrs  = 0;
1813                 r_u->num_als_usrs2 = num_aliases;
1814         }
1815
1816         r_u->status = status;
1817 }
1818
1819 /*******************************************************************
1820 reads or writes a structure.
1821 ********************************************************************/
1822 void samr_io_r_unknown_12(char *desc,  SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth)
1823 {
1824         int i;
1825         fstring tmp;
1826         if (r_u == NULL) return;
1827
1828         prs_debug(ps, depth, desc, "samr_io_r_unknown_12");
1829         depth++;
1830
1831         prs_align(ps);
1832
1833         prs_uint32("num_aliases1", ps, depth, &(r_u->num_aliases1));
1834         prs_uint32("ptr_aliases ", ps, depth, &(r_u->ptr_aliases ));
1835         prs_uint32("num_aliases2", ps, depth, &(r_u->num_aliases2));
1836
1837         if (r_u->ptr_aliases != 0 && r_u->num_aliases1 != 0)
1838         {
1839                 ASSERT_ARRAY(r_u->hdr_als_name, r_u->num_aliases2);
1840
1841                 for (i = 0; i < r_u->num_aliases2; i++)
1842                 {
1843                         slprintf(tmp, sizeof(tmp) - 1, "als_hdr[%02d]  ", i);
1844                         smb_io_unihdr ("", &(r_u->hdr_als_name[i]), ps, depth); 
1845                 }
1846                 for (i = 0; i < r_u->num_aliases2; i++)
1847                 {
1848                         slprintf(tmp, sizeof(tmp) - 1, "als_str[%02d]  ", i);
1849                         smb_io_unistr2("", &(r_u->uni_als_name[i]), r_u->hdr_als_name[i].buffer, ps, depth); 
1850                 }
1851         }
1852
1853         prs_align(ps);
1854
1855         prs_uint32("num_als_usrs1", ps, depth, &(r_u->num_als_usrs1));
1856         prs_uint32("ptr_als_usrs ", ps, depth, &(r_u->ptr_als_usrs ));
1857         prs_uint32("num_als_usrs2", ps, depth, &(r_u->num_als_usrs2));
1858
1859         if (r_u->ptr_als_usrs != 0 && r_u->num_als_usrs1 != 0)
1860         {
1861                 ASSERT_ARRAY(r_u->num_als_usrs, r_u->num_als_usrs2);
1862
1863                 for (i = 0; i < r_u->num_als_usrs2; i++)
1864                 {
1865                         slprintf(tmp, sizeof(tmp) - 1, "als_usrs[%02d]  ", i);
1866                         prs_uint32(tmp, ps, depth, &(r_u->num_als_usrs[i]));
1867                 }
1868         }
1869
1870         prs_uint32("status", ps, depth, &(r_u->status));
1871 }
1872
1873 /*******************************************************************
1874 reads or writes a structure.
1875 ********************************************************************/
1876 void make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
1877                                 POLICY_HND *pol,
1878                                 uint32 unk_0, uint32 rid)
1879 {
1880         if (q_u == NULL) return;
1881
1882         DEBUG(5,("samr_make_q_open_user\n"));
1883
1884         memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
1885         
1886         q_u->unknown_0 = unk_0;
1887         q_u->user_rid  = rid;
1888 }
1889
1890
1891 /*******************************************************************
1892 reads or writes a structure.
1893 ********************************************************************/
1894 void samr_io_q_open_user(char *desc,  SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
1895 {
1896         if (q_u == NULL) return;
1897
1898         prs_debug(ps, depth, desc, "samr_io_q_open_user");
1899         depth++;
1900
1901         prs_align(ps);
1902
1903         smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth); 
1904         prs_align(ps);
1905
1906         prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
1907         prs_uint32("user_rid ", ps, depth, &(q_u->user_rid ));
1908
1909         prs_align(ps);
1910 }
1911
1912 /*******************************************************************
1913 reads or writes a structure.
1914 ********************************************************************/
1915 void samr_io_r_open_user(char *desc,  SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
1916 {
1917         if (r_u == NULL) return;
1918
1919         prs_debug(ps, depth, desc, "samr_io_r_open_user");
1920         depth++;
1921
1922         prs_align(ps);
1923
1924         smb_io_pol_hnd("user_pol", &(r_u->user_pol), ps, depth); 
1925         prs_align(ps);
1926
1927         prs_uint32("status", ps, depth, &(r_u->status));
1928 }
1929
1930
1931 /*******************************************************************
1932 makes a SAMR_Q_QUERY_USERGROUPS structure.
1933 ********************************************************************/
1934 void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1935                                 POLICY_HND *hnd)
1936 {
1937         if (q_u == NULL || hnd == NULL) return;
1938
1939         DEBUG(5,("make_samr_q_query_usergroups\n"));
1940
1941         memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
1942 }
1943
1944 /*******************************************************************
1945 reads or writes a structure.
1946 ********************************************************************/
1947 void samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
1948 {
1949         if (q_u == NULL) return;
1950
1951         prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
1952         depth++;
1953
1954         prs_align(ps);
1955
1956         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
1957         prs_align(ps);
1958 }
1959
1960 /*******************************************************************
1961 makes a SAMR_R_QUERY_USERGROUPS structure.
1962 ********************************************************************/
1963 void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
1964                 uint32 num_gids, DOM_GID *gid, uint32 status)
1965 {
1966         if (r_u == NULL) return;
1967
1968         DEBUG(5,("make_samr_r_query_usergroups\n"));
1969
1970         if (status == 0x0)
1971         {
1972                 r_u->ptr_0        = 1;
1973                 r_u->num_entries  = num_gids;
1974                 r_u->ptr_1        = 1;
1975                 r_u->num_entries2 = num_gids;
1976
1977                 r_u->gid = gid;
1978
1979 #if 0
1980                 int i;
1981                 for (i = 0; i < num_gids && i < LSA_MAX_GROUPS; i++)
1982                 {
1983                         r_u->gid[i].g_rid = gid[i].g_rid;
1984                         r_u->gid[i].attr  = gid[i].attr ;
1985                 }
1986 #endif
1987
1988         }
1989         else
1990         {
1991                 r_u->ptr_0       = 0;
1992                 r_u->num_entries = 0;
1993                 r_u->ptr_1       = 0;
1994         }
1995
1996         r_u->status = status;
1997 }
1998
1999 /*******************************************************************
2000 reads or writes a structure.
2001 ********************************************************************/
2002 void samr_io_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
2003 {
2004         int i;
2005         if (r_u == NULL) return;
2006
2007         prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
2008         depth++;
2009
2010         prs_align(ps);
2011
2012         prs_uint32("ptr_0       ", ps, depth, &(r_u->ptr_0      ));
2013
2014         if (r_u->ptr_0 != 0)
2015         {
2016                 prs_uint32("num_entries ", ps, depth, &(r_u->num_entries));
2017                 prs_uint32("ptr_1       ", ps, depth, &(r_u->ptr_1      ));
2018
2019                 if (r_u->num_entries != 0)
2020                 {
2021                         prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
2022
2023                         ASSERT_ARRAY(r_u->gid, r_u->num_entries2);
2024
2025                         for (i = 0; i < r_u->num_entries2; i++)
2026                         {
2027                                 smb_io_gid("", &(r_u->gid[i]), ps, depth);
2028                         }
2029                 }
2030         }
2031         prs_uint32("status", ps, depth, &(r_u->status));
2032 }
2033
2034 /*******************************************************************
2035 makes a SAMR_Q_QUERY_USERINFO structure.
2036 ********************************************************************/
2037 void make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
2038                                 POLICY_HND *hnd, uint16 switch_value)
2039 {
2040         if (q_u == NULL || hnd == NULL) return;
2041
2042         DEBUG(5,("make_samr_q_query_userinfo\n"));
2043
2044         memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
2045         q_u->switch_value = switch_value;
2046 }
2047
2048 /*******************************************************************
2049 reads or writes a structure.
2050 ********************************************************************/
2051 void samr_io_q_query_userinfo(char *desc,  SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth)
2052 {
2053         if (q_u == NULL) return;
2054
2055         prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
2056         depth++;
2057
2058         prs_align(ps);
2059
2060         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
2061         prs_align(ps);
2062
2063         prs_uint16("switch_value", ps, depth, &(q_u->switch_value)); /* 0x0015 or 0x0011 */
2064
2065         prs_align(ps);
2066 }
2067
2068 /*******************************************************************
2069 reads or writes a LOGON_HRS structure.
2070 ********************************************************************/
2071 void sam_io_logon_hrs(char *desc,  LOGON_HRS *hrs, prs_struct *ps, int depth)
2072 {
2073         if (hrs == NULL) return;
2074
2075         prs_debug(ps, depth, desc, "sam_io_logon_hrs");
2076         depth++;
2077
2078         prs_align(ps);
2079         
2080         prs_uint32 (       "len  ", ps, depth, &(hrs->len ));
2081
2082         if (hrs->len > 64)
2083         {
2084                 DEBUG(5,("sam_io_logon_hrs: truncating length\n"));
2085                 hrs->len = 64;
2086         }
2087
2088         prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len);
2089 }
2090
2091 /*******************************************************************
2092 makes a SAM_USER_INFO_11 structure.
2093 ********************************************************************/
2094 void make_sam_user_info11(SAM_USER_INFO_11 *usr,
2095                                 NTTIME *expiry,
2096                                 char *mach_acct,
2097                                 uint32 rid_user,
2098                                 uint32 rid_group,
2099                                 uint16 acct_ctrl)
2100                                 
2101 {
2102         int len_mach_acct;
2103         if (usr == NULL || expiry == NULL || mach_acct == NULL) return;
2104
2105         DEBUG(5,("make_samr_r_unknown_24\n"));
2106
2107         len_mach_acct = strlen(mach_acct);
2108
2109         memcpy(&(usr->expiry),expiry, sizeof(usr->expiry)); /* expiry time or something? */
2110         bzero(usr->padding_1, sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
2111
2112         make_uni_hdr(&(usr->hdr_mach_acct), len_mach_acct, len_mach_acct, 4);  /* unicode header for machine account */
2113         usr->padding_2 = 0;               /* 0 - padding 4 bytes */
2114
2115         usr->ptr_1        = 1;            /* pointer */
2116         bzero(usr->padding_3, sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
2117         usr->padding_4    = 0;            /* 0 - padding 4 bytes */
2118
2119         usr->ptr_2        = 1;            /* pointer */
2120         usr->padding_5    = 0;            /* 0 - padding 4 bytes */
2121
2122         usr->ptr_3        = 1;          /* pointer */
2123         bzero(usr->padding_6, sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
2124
2125         usr->rid_user     = rid_user; 
2126         usr->rid_group    = rid_group;
2127
2128         usr->acct_ctrl    = acct_ctrl;
2129         usr->unknown_3    = 0x0000;
2130
2131         usr->unknown_4    = 0x003f;       /* 0x003f      - 16 bit unknown */
2132         usr->unknown_5    = 0x003c;       /* 0x003c      - 16 bit unknown */
2133
2134         bzero(usr->padding_7, sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
2135         usr->padding_8    = 0;            /* 0 - padding 4 bytes */
2136         
2137         make_unistr2(&(usr->uni_mach_acct), mach_acct, len_mach_acct);  /* unicode string for machine account */
2138
2139         bzero(usr->padding_9, sizeof(usr->padding_9)); /* 0 - padding 48 bytes */
2140 }
2141
2142 /*******************************************************************
2143 reads or writes a structure.
2144 ********************************************************************/
2145 void sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps, int depth)
2146 {
2147         if (usr == NULL) return;
2148
2149         prs_debug(ps, depth, desc, "samr_io_r_unknown_24");
2150         depth++;
2151
2152         prs_align(ps);
2153
2154         prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0)); 
2155
2156         smb_io_time("time", &(usr->expiry), ps, depth); 
2157
2158         prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1));
2159
2160         smb_io_unihdr ("unihdr", &(usr->hdr_mach_acct), ps, depth); 
2161         prs_uint32(        "padding_2", ps, depth, &(usr->padding_2));
2162
2163         prs_uint32(        "ptr_1    ", ps, depth, &(usr->ptr_1    ));
2164         prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3));
2165         prs_uint32(        "padding_4", ps, depth, &(usr->padding_4));
2166
2167         prs_uint32(        "ptr_2    ", ps, depth, &(usr->ptr_2    ));
2168         prs_uint32(        "padding_5", ps, depth, &(usr->padding_5));
2169
2170         prs_uint32(        "ptr_3    ", ps, depth, &(usr->ptr_3    ));
2171         prs_uint8s (False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6));
2172
2173         prs_uint32(        "rid_user ", ps, depth, &(usr->rid_user ));
2174         prs_uint32(        "rid_group", ps, depth, &(usr->rid_group));
2175         prs_uint16(        "acct_ctrl", ps, depth, &(usr->acct_ctrl));
2176         prs_uint16(        "unknown_3", ps, depth, &(usr->unknown_3));
2177         prs_uint16(        "unknown_4", ps, depth, &(usr->unknown_4));
2178         prs_uint16(        "unknown_5", ps, depth, &(usr->unknown_5));
2179
2180         prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7));
2181         prs_uint32(        "padding_8", ps, depth, &(usr->padding_8));
2182         
2183         smb_io_unistr2("unistr2", &(usr->uni_mach_acct), True, ps, depth); 
2184         prs_align(ps);
2185
2186         prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9));
2187 }
2188
2189 /*************************************************************************
2190  make_sam_user_info21
2191
2192  unknown_3 = 0x00ff ffff
2193  unknown_5 = 0x0002 0000
2194  unknown_6 = 0x0000 04ec 
2195
2196  *************************************************************************/
2197 void make_sam_user_info21(SAM_USER_INFO_21 *usr,
2198
2199         NTTIME *logon_time,
2200         NTTIME *logoff_time,
2201         NTTIME *kickoff_time,
2202         NTTIME *pass_last_set_time,
2203         NTTIME *pass_can_change_time,
2204         NTTIME *pass_must_change_time,
2205
2206         char *user_name,
2207         char *full_name,
2208         char *home_dir,
2209         char *dir_drive,
2210         char *logon_script,
2211         char *profile_path,
2212         char *description,
2213         char *workstations,
2214         char *unknown_str,
2215         char *munged_dial,
2216
2217         uint32 user_rid,
2218         uint32 group_rid,
2219         uint16 acb_info, 
2220
2221         uint32 unknown_3,
2222         uint16 logon_divs,
2223         LOGON_HRS *hrs,
2224         uint32 unknown_5,
2225         uint32 unknown_6)
2226 {
2227         int len_user_name    = user_name    != NULL ? strlen(user_name   ) : 0;
2228         int len_full_name    = full_name    != NULL ? strlen(full_name   ) : 0;
2229         int len_home_dir     = home_dir     != NULL ? strlen(home_dir    ) : 0;
2230         int len_dir_drive    = dir_drive    != NULL ? strlen(dir_drive   ) : 0;
2231         int len_logon_script = logon_script != NULL ? strlen(logon_script) : 0;
2232         int len_profile_path = profile_path != NULL ? strlen(profile_path) : 0;
2233         int len_description  = description  != NULL ? strlen(description ) : 0;
2234         int len_workstations = workstations != NULL ? strlen(workstations) : 0;
2235         int len_unknown_str  = unknown_str  != NULL ? strlen(unknown_str ) : 0;
2236         int len_munged_dial  = munged_dial  != NULL ? strlen(munged_dial ) : 0;
2237
2238         usr->logon_time            = *logon_time;
2239         usr->logoff_time           = *logoff_time;
2240         usr->kickoff_time          = *kickoff_time;
2241         usr->pass_last_set_time    = *pass_last_set_time;
2242         usr->pass_can_change_time  = *pass_can_change_time;
2243         usr->pass_must_change_time = *pass_must_change_time;
2244
2245         make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   , len_user_name   , len_user_name    != 0);
2246         make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   , len_full_name   , len_full_name    != 0);
2247         make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    , len_home_dir    , len_home_dir     != 0);
2248         make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   , len_dir_drive   , len_dir_drive    != 0);
2249         make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, len_logon_script != 0);
2250         make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, len_profile_path != 0);
2251         make_uni_hdr(&(usr->hdr_acct_desc   ), len_description , len_description , len_description  != 0);
2252         make_uni_hdr(&(usr->hdr_workstations), len_workstations, len_workstations, len_workstations != 0);
2253         make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str , len_unknown_str , len_workstations != 0);
2254         make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial , len_munged_dial , len_workstations != 0);
2255
2256         bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
2257         bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
2258
2259         usr->user_rid  = user_rid;
2260         usr->group_rid = group_rid;
2261         usr->acb_info = acb_info;
2262         usr->unknown_3 = unknown_3; /* 0x00ff ffff */
2263
2264         usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
2265         usr->ptr_logon_hrs = hrs ? 1 : 0;
2266         usr->unknown_5 = unknown_5; /* 0x0002 0000 */
2267
2268         bzero(usr->padding1, sizeof(usr->padding1));
2269
2270         make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
2271         make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
2272         make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
2273         make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
2274         make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
2275         make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
2276         make_unistr2(&(usr->uni_acct_desc ), description , len_description );
2277         make_unistr2(&(usr->uni_workstations), workstations, len_workstations);
2278         make_unistr2(&(usr->uni_unknown_str ), unknown_str , len_unknown_str );
2279         make_unistr2(&(usr->uni_munged_dial ), munged_dial , len_munged_dial );
2280
2281         usr->unknown_6 = unknown_6; /* 0x0000 04ec */
2282         usr->padding4 = 0;
2283
2284         if (hrs)
2285         {
2286                 memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
2287         }
2288         else
2289         {
2290                 memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
2291         }
2292 }
2293
2294
2295 /*******************************************************************
2296 reads or writes a structure.
2297 ********************************************************************/
2298 void sam_io_user_info21(char *desc,  SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
2299 {
2300         if (usr == NULL) return;
2301
2302         prs_debug(ps, depth, desc, "lsa_io_user_info");
2303         depth++;
2304
2305         prs_align(ps);
2306         
2307         smb_io_time("logon_time           ", &(usr->logon_time)           , ps, depth);
2308         smb_io_time("logoff_time          ", &(usr->logoff_time)          , ps, depth); 
2309         smb_io_time("kickoff_time         ", &(usr->kickoff_time)         , ps, depth); 
2310         smb_io_time("pass_last_set_time   ", &(usr->pass_last_set_time)   , ps, depth); 
2311         smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth); 
2312         smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth); 
2313
2314         smb_io_unihdr("hdr_user_name   ", &(usr->hdr_user_name)   , ps, depth); /* username unicode string header */
2315         smb_io_unihdr("hdr_full_name   ", &(usr->hdr_full_name)   , ps, depth); /* user's full name unicode string header */
2316         smb_io_unihdr("hdr_home_dir    ", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
2317         smb_io_unihdr("hdr_dir_drive   ", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive */
2318         smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
2319         smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
2320         smb_io_unihdr("hdr_acct_desc   ", &(usr->hdr_acct_desc  ) , ps, depth); /* account description */
2321         smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* workstations user can log on from */
2322         smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
2323         smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* workstations user can log on from */
2324
2325         prs_uint8s (False, "lm_pwd        ", ps, depth, usr->lm_pwd   , sizeof(usr->lm_pwd   ));
2326         prs_uint8s (False, "nt_pwd        ", ps, depth, usr->nt_pwd   , sizeof(usr->nt_pwd   ));
2327
2328         prs_uint32("user_rid      ", ps, depth, &(usr->user_rid     ));       /* User ID */
2329         prs_uint32("group_rid     ", ps, depth, &(usr->group_rid    ));      /* Group ID */
2330         prs_uint16("acb_info      ", ps, depth, &(usr->acb_info     ));      /* Group ID */
2331         prs_align(ps);
2332
2333         prs_uint32("unknown_3     ", ps, depth, &(usr->unknown_3    ));
2334         prs_uint16("logon_divs    ", ps, depth, &(usr->logon_divs   ));     /* logon divisions per week */
2335         prs_align(ps);
2336         prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
2337         prs_uint32("unknown_5     ", ps, depth, &(usr->unknown_5    ));
2338
2339         prs_uint8s (False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1));
2340
2341         /* here begins pointed-to data */
2342
2343         smb_io_unistr2("uni_user_name   ", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
2344         smb_io_unistr2("uni_full_name   ", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
2345         smb_io_unistr2("uni_home_dir    ", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
2346         smb_io_unistr2("uni_dir_drive   ", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
2347         smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
2348         smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
2349         smb_io_unistr2("uni_acct_desc   ", &(usr->uni_acct_desc   ), usr->hdr_acct_desc   .buffer, ps, depth); /* user description unicode string */
2350         smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
2351         smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
2352         smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
2353
2354         prs_uint32("unknown_6     ", ps, depth, &(usr->unknown_6  ));
2355         prs_uint32("padding4      ", ps, depth, &(usr->padding4   ));
2356
2357         if (usr->ptr_logon_hrs)
2358         {
2359                 sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs)   , ps, depth);
2360         }
2361 }
2362
2363
2364 /*******************************************************************
2365 makes a SAMR_R_QUERY_USERINFO structure.
2366 ********************************************************************/
2367 void make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
2368                                 uint16 switch_value, void *info, uint32 status)
2369                                 
2370 {
2371         if (r_u == NULL || info == NULL) return;
2372
2373         DEBUG(5,("make_samr_r_query_userinfo\n"));
2374
2375         r_u->ptr = 0;
2376         r_u->switch_value = 0;
2377
2378         if (status == 0)
2379         {
2380                 r_u->switch_value = switch_value;
2381
2382                 switch (switch_value)
2383                 {
2384                         case 0x10:
2385                         {
2386                                 r_u->ptr = 1;
2387                                 r_u->info.id10 = (SAM_USER_INFO_10*)info;
2388
2389                                 break;
2390                         }
2391
2392                         case 0x11:
2393                         {
2394                                 r_u->ptr = 1;
2395                                 r_u->info.id11 = (SAM_USER_INFO_11*)info;
2396
2397                                 break;
2398                         }
2399
2400                         case 21:
2401                         {
2402                                 r_u->ptr = 1;
2403                                 r_u->info.id21 = (SAM_USER_INFO_21*)info;
2404
2405                                 break;
2406                         }
2407
2408                         default:
2409                         {
2410                                 DEBUG(4,("make_samr_r_query_aliasinfo: unsupported switch level\n"));
2411                                 break;
2412                         }
2413                 }
2414         }
2415
2416         r_u->status = status;         /* return status */
2417 }
2418
2419 /*******************************************************************
2420 reads or writes a structure.
2421 ********************************************************************/
2422 void samr_io_r_query_userinfo(char *desc,  SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
2423 {
2424         if (r_u == NULL) return;
2425
2426         prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
2427         depth++;
2428
2429         prs_align(ps);
2430
2431         prs_uint32("ptr         ", ps, depth, &(r_u->ptr         ));
2432         prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
2433         prs_align(ps);
2434
2435         if (r_u->ptr != 0 && r_u->switch_value != 0)
2436         {
2437                 switch (r_u->switch_value)
2438                 {
2439 /*
2440                         case 0x10:
2441                         {
2442                                 if (r_u->info.id10 != NULL)
2443                                 {
2444                                         sam_io_user_info10("", r_u->info.id10, ps, depth);
2445                                 }
2446                                 else
2447                                 {
2448                                         DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
2449                                         return NULL;
2450                                 }
2451                                 break;
2452                         }
2453                         case 0x11:
2454                         {
2455                                 if (r_u->info.id11 != NULL)
2456                                 {
2457                                         sam_io_user_info11("", r_u->info.id11, ps, depth);
2458                                 }
2459                                 else
2460                                 {
2461                                         DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
2462                                         return NULL;
2463                                 }
2464                                 break;
2465                         }
2466 */
2467                         case 21:
2468                         {
2469                                 if (r_u->info.id21 != NULL)
2470                                 {
2471                                         sam_io_user_info21("", r_u->info.id21, ps, depth);
2472                                 }
2473                                 else
2474                                 {
2475                                         DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
2476                                         return;
2477                                 }
2478                                 break;
2479                         }
2480                         default:
2481                         {
2482                                 DEBUG(2,("samr_io_r_query_userinfo: unknown switch level\n"));
2483                                 break;
2484                         }
2485                                 
2486                 }
2487         }
2488
2489         prs_uint32("status", ps, depth, &(r_u->status));
2490 }
2491
2492
2493 /*******************************************************************
2494 makes a SAMR_Q_UNKNOWN_21 structure.
2495 ********************************************************************/
2496 void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
2497                                 POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
2498 {
2499         if (q_c == NULL || hnd == NULL) return;
2500
2501         DEBUG(5,("make_samr_q_unknown_21\n"));
2502
2503         memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
2504         q_c->unknown_1 = unk_1;
2505         q_c->unknown_2 = unk_2;
2506 }
2507
2508 /*******************************************************************
2509 reads or writes a structure.
2510 ********************************************************************/
2511 void samr_io_q_unknown_21(char *desc,  SAMR_Q_UNKNOWN_21 *q_u, prs_struct *ps, int depth)
2512 {
2513         if (q_u == NULL) return;
2514
2515         prs_debug(ps, depth, desc, "samr_io_q_unknown_21");
2516         depth++;
2517
2518         prs_align(ps);
2519
2520         smb_io_pol_hnd("group_pol", &(q_u->group_pol), ps, depth); 
2521         prs_align(ps);
2522
2523         prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
2524         prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
2525 }
2526
2527 /*******************************************************************
2528 makes a SAMR_Q_UNKNOWN_13 structure.
2529 ********************************************************************/
2530 void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
2531                                 POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
2532 {
2533         if (q_c == NULL || hnd == NULL) return;
2534
2535         DEBUG(5,("make_samr_q_unknown_13\n"));
2536
2537         memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
2538         q_c->unknown_1 = unk_1;
2539         q_c->unknown_2 = unk_2;
2540 }
2541
2542 /*******************************************************************
2543 reads or writes a structure.
2544 ********************************************************************/
2545 void samr_io_q_unknown_13(char *desc,  SAMR_Q_UNKNOWN_13 *q_u, prs_struct *ps, int depth)
2546 {
2547         if (q_u == NULL) return;
2548
2549         prs_debug(ps, depth, desc, "samr_io_q_unknown_13");
2550         depth++;
2551
2552         prs_align(ps);
2553
2554         smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); 
2555         prs_align(ps);
2556
2557         prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
2558         prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
2559 }
2560
2561 /*******************************************************************
2562 reads or writes a structure.
2563 ********************************************************************/
2564 void samr_io_q_unknown_32(char *desc,  SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth)
2565 {
2566         if (q_u == NULL) return;
2567
2568         prs_debug(ps, depth, desc, "samr_io_q_unknown_32");
2569         depth++;
2570
2571         prs_align(ps);
2572
2573         smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
2574         prs_align(ps);
2575
2576         smb_io_unihdr ("", &(q_u->hdr_mach_acct), ps, depth); 
2577         smb_io_unistr2("", &(q_u->uni_mach_acct), q_u->hdr_mach_acct.buffer, ps, depth); 
2578
2579         prs_align(ps);
2580
2581         prs_uint32("acct_ctrl", ps, depth, &(q_u->acct_ctrl));
2582         prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
2583         prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
2584 }
2585
2586 /*******************************************************************
2587 reads or writes a structure.
2588 ********************************************************************/
2589 void samr_io_r_unknown_32(char *desc,  SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth)
2590 {
2591         if (r_u == NULL) return;
2592
2593         prs_debug(ps, depth, desc, "samr_io_r_unknown_32");
2594         depth++;
2595
2596         prs_align(ps);
2597
2598         smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
2599         prs_align(ps);
2600
2601         prs_uint32("status", ps, depth, &(r_u->status));
2602 }
2603
2604
2605 /*******************************************************************
2606 makes a SAMR_Q_CONNECT structure.
2607 ********************************************************************/
2608 void make_samr_q_connect(SAMR_Q_CONNECT *q_u,
2609                                 char *srv_name, uint32 unknown_0)
2610 {
2611         int len_srv_name = strlen(srv_name);
2612
2613         if (q_u == NULL) return;
2614
2615         DEBUG(5,("make_q_connect\n"));
2616
2617         /* make PDC server name \\server */
2618         make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name);  
2619
2620         /* example values: 0x0000 0002 */
2621         q_u->unknown_0 = unknown_0; 
2622 }
2623
2624 /*******************************************************************
2625 reads or writes a structure.
2626 ********************************************************************/
2627 void samr_io_q_connect(char *desc,  SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
2628 {
2629         if (q_u == NULL) return;
2630
2631         prs_debug(ps, depth, desc, "samr_io_q_connect");
2632         depth++;
2633
2634         prs_align(ps);
2635
2636         prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
2637         smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth); 
2638
2639         prs_align(ps);
2640
2641         prs_uint32("unknown_0   ", ps, depth, &(q_u->unknown_0   ));
2642 }
2643
2644 /*******************************************************************
2645 reads or writes a structure.
2646 ********************************************************************/
2647 void samr_io_r_connect(char *desc,  SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
2648 {
2649         if (r_u == NULL) return;
2650
2651         prs_debug(ps, depth, desc, "samr_io_r_connect");
2652         depth++;
2653
2654         prs_align(ps);
2655
2656         smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth); 
2657         prs_align(ps);
2658
2659         prs_uint32("status", ps, depth, &(r_u->status));
2660 }
2661
2662 /*******************************************************************
2663 makes a SAMR_Q_OPEN_ALIAS structure.
2664 ********************************************************************/
2665 void make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
2666                                 uint32 unknown_0, uint32 rid)
2667 {
2668         if (q_u == NULL) return;
2669
2670         DEBUG(5,("make_q_open_alias\n"));
2671
2672         /* example values: 0x0000 0008 */
2673         q_u->unknown_0 = unknown_0; 
2674
2675         q_u->rid_alias = rid; 
2676 }
2677
2678 /*******************************************************************
2679 reads or writes a structure.
2680 ********************************************************************/
2681 void samr_io_q_open_alias(char *desc,  SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
2682 {
2683         if (q_u == NULL) return;
2684
2685         prs_debug(ps, depth, desc, "samr_io_q_open_alias");
2686         depth++;
2687
2688         prs_align(ps);
2689
2690         prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
2691         prs_uint32("rid_alias", ps, depth, &(q_u->rid_alias));
2692 }
2693
2694 /*******************************************************************
2695 reads or writes a structure.
2696 ********************************************************************/
2697 void samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
2698 {
2699         if (r_u == NULL) return;
2700
2701         prs_debug(ps, depth, desc, "samr_io_r_open_alias");
2702         depth++;
2703
2704         prs_align(ps);
2705
2706         smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
2707         prs_align(ps);
2708
2709         prs_uint32("status", ps, depth, &(r_u->status));
2710 }
2711
2712 /*******************************************************************
2713 makes a SAMR_Q_UNKNOWN_38 structure.
2714 ********************************************************************/
2715 void make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name)
2716 {
2717         int len_srv_name = strlen(srv_name);
2718
2719         if (q_u == NULL) return;
2720
2721         DEBUG(5,("make_q_unknown_38\n"));
2722
2723         q_u->ptr = 1;
2724         make_uni_hdr(&(q_u->hdr_srv_name), len_srv_name, len_srv_name, len_srv_name != 0);
2725         make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name);  
2726
2727 }
2728
2729 /*******************************************************************
2730 reads or writes a structure.
2731 ********************************************************************/
2732 void samr_io_q_unknown_38(char *desc,  SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth)
2733 {
2734         if (q_u == NULL) return;
2735
2736         prs_debug(ps, depth, desc, "samr_io_q_unknown_38");
2737         depth++;
2738
2739         prs_align(ps);
2740
2741         prs_uint32("ptr", ps, depth, &(q_u->ptr));
2742         if (q_u->ptr != 0)
2743         {
2744                 smb_io_unihdr ("", &(q_u->hdr_srv_name), ps, depth); 
2745                 smb_io_unistr2("", &(q_u->uni_srv_name), q_u->hdr_srv_name.buffer, ps, depth); 
2746         }
2747 }
2748
2749 /*******************************************************************
2750 makes a SAMR_R_UNKNOWN_38 structure.
2751 ********************************************************************/
2752 void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u,
2753                                 uint16 level, uint32 status)
2754 {
2755         if (r_u == NULL) return;
2756
2757         DEBUG(5,("make_r_unknown_38\n"));
2758
2759         r_u->level.value = level;
2760         r_u->ptr_0       = 0;
2761         r_u->status      = status;
2762 }
2763
2764 /*******************************************************************
2765 reads or writes a structure.
2766 ********************************************************************/
2767 void samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth)
2768 {
2769         if (r_u == NULL) return;
2770
2771         prs_debug(ps, depth, desc, "samr_io_r_unknown_38");
2772         depth++;
2773
2774         prs_align(ps);
2775
2776         smb_io_lookup_level("level ", &(r_u->level), ps, depth); 
2777         prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 ));
2778         prs_uint32("status", ps, depth, &(r_u->status));
2779 }
2780
2781 /*******************************************************************
2782 reads or writes a SAMR_ENC_PASSWD structure.
2783 ********************************************************************/
2784 void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth)
2785 {
2786         if (pwd == NULL) return;
2787
2788         prs_debug(ps, depth, desc, "samr_io_enc_passwd");
2789         depth++;
2790
2791         prs_align(ps);
2792
2793         prs_uint32("ptr", ps, depth, &(pwd->ptr));
2794         prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)); 
2795 }
2796
2797 /*******************************************************************
2798 reads or writes a SAMR_ENC_HASH structure.
2799 ********************************************************************/
2800 void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth)
2801 {
2802         if (hsh == NULL) return;
2803
2804         prs_debug(ps, depth, desc, "samr_io_enc_hash");
2805         depth++;
2806
2807         prs_align(ps);
2808
2809         prs_uint32("ptr ", ps, depth, &(hsh->ptr));
2810         prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash)); 
2811 }
2812
2813 #if 0
2814 /* SAMR_Q_CHGPASSWD_USER */
2815 typedef struct q_samr_chgpasswd_user_info
2816 {
2817         uint32 ptr_0;
2818
2819         UNIHDR hdr_server; /* server name unicode header */
2820         UNISTR2 uni_server; /* server name unicode string */
2821
2822         UNIHDR hdr_user_name;    /* username unicode string header */
2823         UNISTR2 uni_user_name;    /* username unicode string */
2824
2825         SAMR_ENC_PASSWD nt_newpass;
2826         SAMR_ENC_HASH nt_oldhash;
2827
2828         uint32 unknown_1; /* seems to always contain 0001 */
2829
2830         SAMR_ENC_PASSWD lm_newpass;
2831         SAMR_ENC_HASH lm_oldhash;
2832
2833 } SAMR_Q_CHGPASSWD_USER;
2834
2835 /* SAMR_R_CHGPASSWD_USER */
2836 typedef struct r_samr_chgpasswd_user_info
2837 {
2838         uint32 result; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
2839
2840 } SAMR_R_CHGPASSWD_USER;
2841
2842 #endif /* 0 */
2843