Fixed up SAM_USERINFO_CTR dynamic stuff in cmd_samr_query_user()
[samba.git] / source3 / rpcclient / cmd_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2
4    RPC pipe client
5
6    Copyright (C) Andrew Tridgell              1992-2000,
7    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8    Copyright (C) Elrond                            2000,
9    Copyright (C) Tim Potter                        2000
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 extern DOM_SID domain_sid;
29
30 /****************************************************************************
31  display sam_user_info_21 structure
32  ****************************************************************************/
33 static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
34 {
35         fstring temp;
36
37         unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
38         printf("\tUser Name   :\t%s\n", temp);
39         
40         unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
41         printf("\tFull Name   :\t%s\n", temp);
42         
43         unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
44         printf("\tHome Drive  :\t%s\n", temp);
45         
46         unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
47         printf("\tDir Drive   :\t%s\n", temp);
48         
49         unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
50         printf("\tProfile Path:\t%s\n", temp);
51         
52         unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
53         printf("\tLogon Script:\t%s\n", temp);
54         
55         unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
56         printf("\tDescription :\t%s\n", temp);
57         
58         unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
59         printf("\tWorkstations:\t%s\n", temp);
60         
61         unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
62         printf("\tUnknown Str :\t%s\n", temp);
63         
64         unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
65         printf("\tRemote Dial :\t%s\n", temp);
66         
67         printf("\tLogon Time               :\t%s\n", 
68                http_timestring(nt_time_to_unix(&usr->logon_time)));
69         printf("\tLogoff Time              :\t%s\n", 
70                http_timestring(nt_time_to_unix(&usr->logoff_time)));
71         printf("\tKickoff Time             :\t%s\n", 
72                http_timestring(nt_time_to_unix(&usr->kickoff_time)));
73         printf("\tPassword last set Time   :\t%s\n", 
74                http_timestring(nt_time_to_unix(&usr->pass_last_set_time)));
75         printf("\tPassword can change Time :\t%s\n", 
76                http_timestring(nt_time_to_unix(&usr->pass_can_change_time)));
77         printf("\tPassword must change Time:\t%s\n", 
78                http_timestring(nt_time_to_unix(&usr->pass_must_change_time)));
79         
80         printf("\tunknown_2[0..31]...\n"); /* user passwords? */
81         
82         printf("\tuser_rid :\t%x\n"  , usr->user_rid ); /* User ID */
83         printf("\tgroup_rid:\t%x\n"  , usr->group_rid); /* Group ID */
84         printf("\tacb_info :\t%04x\n", usr->acb_info ); /* Account Control Info */
85         
86         printf("\tunknown_3:\t%08x\n", usr->unknown_3); /* 0x00ff ffff */
87         printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
88         printf("\tunknown_5:\t%08x\n", usr->unknown_5); /* 0x0002 0000 */
89         
90         printf("\tpadding1[0..7]...\n");
91         
92         if (usr->ptr_logon_hrs) {
93                 printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
94         }
95 }
96
97 static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
98 {
99         fstring name;
100
101         unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1); 
102         printf("Domain:\t%s\n", name);
103
104         unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1); 
105         printf("Server:\t%s\n", name);
106
107         printf("Total Users:\t%d\n", info2->num_domain_usrs);
108         printf("Total Groups:\t%d\n", info2->num_domain_grps);
109         printf("Total Aliases:\t%d\n", info2->num_local_grps);
110         
111         printf("Sequence No:\t%d\n", info2->seq_num);
112         
113         printf("Unknown 0:\t0x%x\n", info2->unknown_0);
114         printf("Unknown 1:\t0x%x\n", info2->unknown_1);
115         printf("Unknown 2:\t0x%x\n", info2->unknown_2);
116         printf("Unknown 3:\t0x%x\n", info2->unknown_3);
117         printf("Unknown 4:\t0x%x\n", info2->unknown_4);
118         printf("Unknown 5:\t0x%x\n", info2->unknown_5);
119         printf("Unknown 6:\t0x%x\n", info2->unknown_6);
120 }
121
122 void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
123 {
124         fstring tmp;
125
126         printf("RID: 0x%x ", e1->rid_user);
127         
128         unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
129         printf("Account: %s\t", tmp);
130
131         unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
132         printf("Name: %s\t", tmp);
133
134         unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
135         printf("Desc: %s\n", tmp);
136 }
137
138 /**********************************************************************
139  * Query user information 
140  */
141 static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) 
142 {
143         POLICY_HND connect_pol, domain_pol, user_pol;
144         uint32  result = NT_STATUS_UNSUCCESSFUL, 
145                 info_level = 21;
146         BOOL    got_connect_pol = False, 
147                 got_domain_pol = False,
148                 got_user_pol = False;
149         SAM_USERINFO_CTR *user_ctr;
150         fstring                 server;
151         TALLOC_CTX              *mem_ctx;
152         uint32 user_rid;
153         
154         
155         if (argc != 2) {
156                 printf("Usage: %s rid\n", argv[0]);
157                 return 0;
158         }
159         
160         sscanf(argv[1], "%i", &user_rid);
161
162         if (!(mem_ctx=talloc_init()))
163         {
164                 DEBUG(0,("cmd_samr_query_user: talloc_init returned NULL!\n"));
165                 return NT_STATUS_UNSUCCESSFUL;
166         }
167
168         fetch_domain_sid(cli);
169
170         /* Initialise RPC connection */
171         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
172                 fprintf (stderr, "Could not initialize samr pipe!\n");
173                 return NT_STATUS_UNSUCCESSFUL;
174         }
175         
176         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
177         strupper (server);
178         
179         if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
180                                        &connect_pol)) !=
181             NT_STATUS_NOPROBLEMO) {
182                 goto done;
183         }
184
185         got_connect_pol = True;
186
187         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
188                                            MAXIMUM_ALLOWED_ACCESS,
189                                            &domain_sid, &domain_pol))
190              != NT_STATUS_NOPROBLEMO) {
191                 goto done;
192         }
193
194         got_domain_pol = True;
195
196         if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
197                                          MAXIMUM_ALLOWED_ACCESS,
198                                          user_rid, &user_pol))
199             != NT_STATUS_NOPROBLEMO) {
200                 goto done;
201         }
202
203         got_user_pol = True;
204
205         ZERO_STRUCT(user_ctr);
206
207         if ((result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, 
208                                               info_level, &user_ctr)) 
209             != NT_STATUS_NOPROBLEMO) {
210                 goto done;
211         }
212
213         display_sam_user_info_21(user_ctr->info.id21);
214
215 done:
216         if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
217         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
218         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
219
220         cli_nt_session_close(cli);
221         talloc_destroy(mem_ctx);
222
223         return result;
224 }
225
226 /****************************************************************************
227  display group info
228  ****************************************************************************/
229 static void display_group_info1(GROUP_INFO1 *info1)
230 {
231         fstring temp;
232
233         unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
234         printf("\tGroup Name:\t%s\n", temp);
235         unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
236         printf("\tDescription:\t%s\n", temp);
237         printf("\tunk1:%d\n", info1->unknown_1);
238         printf("\tNum Members:%d\n", info1->num_members);
239 }
240
241 /****************************************************************************
242  display group info
243  ****************************************************************************/
244 static void display_group_info4(GROUP_INFO4 *info4)
245 {
246         fstring desc;
247
248         unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
249         printf("\tGroup Description:%s\n", desc);
250 }
251
252 /****************************************************************************
253  display sam sync structure
254  ****************************************************************************/
255 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
256 {
257         switch (ctr->switch_value1) {
258             case 1: {
259                     display_group_info1(&ctr->group.info1);
260                     break;
261             }
262             case 4: {
263                     display_group_info4(&ctr->group.info4);
264                     break;
265             }
266         }
267 }
268
269 /***********************************************************************
270  * Query group information 
271  */
272 static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) 
273 {
274         POLICY_HND connect_pol, domain_pol, group_pol;
275         uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1;
276         BOOL got_connect_pol = False, got_domain_pol = False,
277                 got_group_pol = False;
278         GROUP_INFO_CTR group_ctr;
279         fstring                 server; 
280         TALLOC_CTX              *mem_ctx;
281         uint32 group_rid;
282         
283         if (argc != 2) {
284                 printf("Usage: %s rid\n", argv[0]);
285                 return 0;
286         }
287
288         group_rid = atoi(argv[1]);
289
290         if (!(mem_ctx=talloc_init())) {
291                 DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n"));
292                 return NT_STATUS_UNSUCCESSFUL;
293         }
294
295         fetch_domain_sid(cli);
296
297         /* Initialise RPC connection */
298         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
299                 fprintf (stderr, "Could not initialize samr pipe!\n");
300                 return NT_STATUS_UNSUCCESSFUL;
301         }
302         
303         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
304         strupper (server);
305
306         if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
307                                        &connect_pol)) !=
308             NT_STATUS_NOPROBLEMO) {
309                 goto done;
310         }
311
312         got_connect_pol = True;
313
314         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
315                                            MAXIMUM_ALLOWED_ACCESS,
316                                            &domain_sid, &domain_pol))
317              != NT_STATUS_NOPROBLEMO) {
318                 goto done;
319         }
320
321         got_domain_pol = True;
322
323         if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
324                                           MAXIMUM_ALLOWED_ACCESS,
325                                           group_rid, &group_pol))
326             != NT_STATUS_NOPROBLEMO) {
327                 goto done;
328         }
329
330         got_group_pol = True;
331
332         ZERO_STRUCT(group_ctr);
333
334         if ((result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol, 
335                                                info_level, &group_ctr)) 
336             != NT_STATUS_NOPROBLEMO) {
337                 goto done;
338         }
339
340         display_group_info_ctr(&group_ctr);
341
342 done:
343         if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
344         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
345         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
346
347         cli_nt_session_close(cli);
348         talloc_destroy(mem_ctx);
349
350         return result;
351 }
352
353 /* Query groups a user is a member of */
354
355 static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **argv) 
356 {
357         POLICY_HND              connect_pol, 
358                                 domain_pol, 
359                                 user_pol;
360         uint32                  result = NT_STATUS_UNSUCCESSFUL;
361         BOOL                    got_connect_pol = False, 
362                                 got_domain_pol = False,
363                                 got_user_pol = False;
364         uint32                  num_groups, 
365                                 user_rid;
366         DOM_GID                 *user_gids;
367         int                     i;
368         fstring                 server;
369         TALLOC_CTX              *mem_ctx;
370         
371         if (argc != 2) {
372                 printf("Usage: %s rid\n", argv[0]);
373                 return 0;
374         }
375
376         if (!(mem_ctx=talloc_init()))
377         {
378                 DEBUG(0,("cmd_samr_query_usergroups: talloc_init returned NULL!\n"));
379                 return NT_STATUS_UNSUCCESSFUL;
380         }
381
382         sscanf(argv[1], "%i", &user_rid);
383
384         fetch_domain_sid(cli);
385
386         /* Initialise RPC connection */
387         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
388                 fprintf (stderr, "Could not initialize samr pipe!\n");
389                 return NT_STATUS_UNSUCCESSFUL;
390         }
391
392         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
393         strupper (server);
394                 
395         if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
396                                        &connect_pol)) !=
397             NT_STATUS_NOPROBLEMO) {
398                 goto done;
399         }
400
401         got_connect_pol = True;
402
403         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
404                                            MAXIMUM_ALLOWED_ACCESS,
405                                            &domain_sid, &domain_pol))
406              != NT_STATUS_NOPROBLEMO) {
407                 goto done;
408         }
409
410         got_domain_pol = True;
411
412         if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
413                                          MAXIMUM_ALLOWED_ACCESS,
414                                          user_rid, &user_pol))
415             != NT_STATUS_NOPROBLEMO) {
416                 goto done;
417         }
418
419         got_user_pol = True;
420
421         if ((result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
422                                                 &num_groups, &user_gids))
423             != NT_STATUS_NOPROBLEMO) {
424                 goto done;
425         }
426
427         for (i = 0; i < num_groups; i++) {
428                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n", 
429                        user_gids[i].g_rid, user_gids[i].attr);
430         }
431
432  done:
433         if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
434         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
435         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
436
437         cli_nt_session_close(cli);
438         talloc_destroy(mem_ctx);
439
440         return result;
441 }
442
443 /* Query members of a group */
444
445 static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **argv) 
446 {
447         POLICY_HND connect_pol, domain_pol, group_pol;
448         uint32 result = NT_STATUS_UNSUCCESSFUL;
449         BOOL    got_connect_pol = False, 
450                 got_domain_pol = False,
451                 got_group_pol = False;
452         uint32 num_members, *group_rids, *group_attrs, group_rid;
453         int i;
454         fstring                 server;
455         TALLOC_CTX              *mem_ctx;
456         
457         if (argc != 2) {
458                 printf("Usage: %s rid\n", argv[0]);
459                 return 0;
460         }
461
462         if (!(mem_ctx=talloc_init()))
463         {
464                 DEBUG(0,("cmd_samr_query_groupmem: talloc_init returned NULL!\n"));
465                 return NT_STATUS_UNSUCCESSFUL;
466         }
467
468         sscanf(argv[1], "%i", &group_rid);
469
470         fetch_domain_sid(cli);
471
472         /* Initialise RPC connection */
473         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
474                 fprintf (stderr, "Could not initialize samr pipe!\n");
475                 return NT_STATUS_UNSUCCESSFUL;
476         }
477
478         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
479         strupper (server);
480
481         if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
482                                        &connect_pol)) !=
483             NT_STATUS_NOPROBLEMO) {
484                 goto done;
485         }
486
487         got_connect_pol = True;
488
489         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
490                                            MAXIMUM_ALLOWED_ACCESS,
491                                            &domain_sid, &domain_pol))
492              != NT_STATUS_NOPROBLEMO) {
493                 goto done;
494         }
495
496         got_domain_pol = True;
497
498         if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
499                                           MAXIMUM_ALLOWED_ACCESS,
500                                           group_rid, &group_pol))
501             != NT_STATUS_NOPROBLEMO) {
502                 goto done;
503         }
504
505         got_group_pol = True;
506
507         if ((result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
508                                               &num_members, &group_rids,
509                                               &group_attrs))
510             != NT_STATUS_NOPROBLEMO) {
511                 goto done;
512         }
513
514         for (i = 0; i < num_members; i++) {
515                 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
516                        group_attrs[i]);
517         }
518
519  done:
520         if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
521         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
522         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
523
524         cli_nt_session_close(cli);
525         talloc_destroy(mem_ctx);
526
527         return result;
528 }
529
530 /* Enumerate domain groups */
531
532 static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc, 
533                                        char **argv) 
534 {
535         POLICY_HND connect_pol, domain_pol;
536         uint32 result = NT_STATUS_UNSUCCESSFUL;
537         BOOL got_connect_pol = False, got_domain_pol = False;
538         TALLOC_CTX *mem_ctx;
539         fstring server;
540         uint32 start_idx, size, num_dom_groups, i;
541         struct acct_info *dom_groups;
542
543         if (argc != 1) {
544                 printf("Usage: %s\n", argv[0]);
545                 return 0;
546         }
547
548         if (!(mem_ctx = talloc_init())) {
549                 DEBUG(0, ("cmd_samr_enum_dom_groups: talloc_init returned "
550                           "NULL!\n"));
551                 return NT_STATUS_UNSUCCESSFUL;
552         }
553
554         fetch_domain_sid(cli);
555
556         /* Initialise RPC connection */
557
558         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
559                 fprintf (stderr, "Could not initialize samr pipe!\n");
560                 return NT_STATUS_UNSUCCESSFUL;
561         }
562
563         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
564         strupper(server);
565
566         /* Get sam policy handle */
567
568         if ((result = cli_samr_connect(cli, mem_ctx, server, 
569                                        MAXIMUM_ALLOWED_ACCESS, 
570                                        &connect_pol)) !=
571             NT_STATUS_NOPROBLEMO) {
572                 goto done;
573         }
574
575         got_connect_pol = True;
576
577         /* Get domain policy handle */
578
579         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
580                                            MAXIMUM_ALLOWED_ACCESS,
581                                            &domain_sid, &domain_pol))
582              != NT_STATUS_NOPROBLEMO) {
583                 goto done;
584         }
585
586         got_domain_pol = True;
587
588         /* Enumerate domain groups */
589
590         start_idx = 0;
591         size = 0xffff;
592
593         result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
594                                           &start_idx, size,
595                                           &dom_groups, &num_dom_groups);
596
597         for (i = 0; i < num_dom_groups; i++)
598                 printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name,
599                        dom_groups[i].rid);
600
601  done:
602         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
603         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
604
605         cli_nt_session_close(cli);
606         talloc_destroy(mem_ctx);
607
608         return result;
609 }
610
611 /* Query alias membership */
612
613 static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc, 
614                                       char **argv) 
615 {
616         POLICY_HND connect_pol, domain_pol, alias_pol;
617         BOOL got_connect_pol = False, got_domain_pol = False,
618                 got_alias_pol = False;
619         TALLOC_CTX *mem_ctx;
620         uint32 result = NT_STATUS_UNSUCCESSFUL, alias_rid, num_members, i;
621         DOM_SID *alias_sids;
622
623         fstring server;
624
625         if (argc != 2) {
626                 printf("Usage: %s rid\n", argv[0]);
627                 return 0;
628         }
629
630         if (!(mem_ctx=talloc_init())) {
631                 DEBUG(0,("cmd_samr_query_aliasmem: talloc_init() "
632                          "returned NULL!\n"));
633                 return NT_STATUS_UNSUCCESSFUL;
634         }
635
636         sscanf(argv[1], "%i", &alias_rid);
637
638         /* Initialise RPC connection */
639
640         fetch_domain_sid(cli);
641
642         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
643                 fprintf (stderr, "Could not initialize samr pipe!\n");
644                 return NT_STATUS_UNSUCCESSFUL;
645         }
646
647         /* Open SAMR handle */
648
649         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
650         strupper(server);
651
652         if ((result = cli_samr_connect(cli, mem_ctx, server, 
653                                        MAXIMUM_ALLOWED_ACCESS, 
654                                        &connect_pol)) != 
655             NT_STATUS_NOPROBLEMO) {
656                 goto done;
657         }
658
659         got_connect_pol = True;
660
661         /* Open handle on domain */
662
663         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
664                                            MAXIMUM_ALLOWED_ACCESS,
665                                            &domain_sid, &domain_pol))
666              != NT_STATUS_NOPROBLEMO) {
667                 goto done;
668         }
669
670         got_domain_pol = True;
671
672         /* Open handle on alias */
673
674         if ((result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
675                                           MAXIMUM_ALLOWED_ACCESS,
676                                           alias_rid, &alias_pol))
677             != NT_STATUS_NOPROBLEMO) {
678                 goto done;
679         }
680
681         got_alias_pol = True;
682
683         if ((result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
684                                               &num_members, &alias_sids))
685             != NT_STATUS_NOPROBLEMO) {
686                 goto done;
687         }
688
689         for (i = 0; i < num_members; i++) {
690                 fstring sid_str;
691
692                 sid_to_string(sid_str, &alias_sids[i]);
693                 printf("\tsid:[%s]\n", sid_str);
694         }
695
696  done:
697         if (got_alias_pol) cli_samr_close(cli, mem_ctx, &alias_pol);
698         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
699         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
700
701         cli_nt_session_close(cli);
702         talloc_destroy(mem_ctx);
703
704         return result;
705 }
706
707 /* Query display info */
708
709 static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc, 
710                                       char **argv) 
711 {
712         POLICY_HND connect_pol, domain_pol;
713         uint32 result = NT_STATUS_UNSUCCESSFUL;
714         BOOL got_connect_pol = False, got_domain_pol = False;
715         TALLOC_CTX *mem_ctx;
716         fstring server;
717         uint32 start_idx, max_entries, num_entries, i;
718         uint16 info_level = 1;
719         SAM_DISPINFO_CTR ctr;
720         SAM_DISPINFO_1 info1;
721
722         if (argc != 1) {
723                 printf("Usage: %s\n", argv[0]);
724                 return 0;
725         }
726
727         if (!(mem_ctx = talloc_init())) {
728                 DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
729                           "NULL!\n"));
730                 return NT_STATUS_UNSUCCESSFUL;
731         }
732
733         fetch_domain_sid(cli);
734
735         /* Initialise RPC connection */
736
737         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
738                 fprintf (stderr, "Could not initialize samr pipe!\n");
739                 return NT_STATUS_UNSUCCESSFUL;
740         }
741
742         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
743         strupper(server);
744
745         /* Get sam policy handle */
746
747         if ((result = cli_samr_connect(cli, mem_ctx, server, 
748                                        MAXIMUM_ALLOWED_ACCESS, 
749                                        &connect_pol)) 
750             != NT_STATUS_NOPROBLEMO) {
751                 goto done;
752         }
753
754         got_connect_pol = True;
755
756         /* Get domain policy handle */
757
758         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
759                                            MAXIMUM_ALLOWED_ACCESS, 
760                                            &domain_sid, &domain_pol))
761              != NT_STATUS_NOPROBLEMO) {
762                 goto done;
763         }
764
765         got_domain_pol = True;
766
767         /* Query display info */
768
769         start_idx = 0;
770         max_entries = 250;
771
772         ZERO_STRUCT(ctr);
773         ZERO_STRUCT(info1);
774
775         ctr.sam.info1 = &info1;
776
777         result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
778                                          &start_idx, info_level,
779                                          &num_entries, max_entries, &ctr);
780
781         for (i = 0; i < num_entries; i++) {
782                 display_sam_info_1(&ctr.sam.info1->sam[i],
783                                    &ctr.sam.info1->str[i]);
784         }
785
786  done:
787         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
788         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
789
790         cli_nt_session_close(cli);
791         talloc_destroy(mem_ctx);
792
793         return result;
794 }
795
796 /* Query domain info */
797
798 static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc, 
799                                      char **argv) 
800 {
801         POLICY_HND connect_pol, domain_pol;
802         uint32 result = NT_STATUS_UNSUCCESSFUL;
803         BOOL got_connect_pol = False, got_domain_pol = False;
804         TALLOC_CTX *mem_ctx;
805         fstring server;
806         uint16 switch_value = 2;
807         SAM_UNK_CTR ctr;
808
809         if (argc > 2) {
810                 printf("Usage: %s [infolevel\n", argv[0]);
811                 return 0;
812         }
813
814         if (argc == 2)
815                 switch_value = atoi(argv[1]);
816
817         if (!(mem_ctx = talloc_init())) {
818                 DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
819                           "NULL!\n"));
820                 return NT_STATUS_UNSUCCESSFUL;
821         }
822
823         fetch_domain_sid(cli);
824
825         /* Initialise RPC connection */
826
827         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
828                 fprintf (stderr, "Could not initialize samr pipe!\n");
829                 return NT_STATUS_UNSUCCESSFUL;
830         }
831
832         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
833         strupper(server);
834
835         /* Get sam policy handle */
836
837         if ((result = cli_samr_connect(cli, mem_ctx, server, 
838                                        MAXIMUM_ALLOWED_ACCESS, 
839                                        &connect_pol)) 
840             != NT_STATUS_NOPROBLEMO) {
841                 goto done;
842         }
843
844         got_connect_pol = True;
845
846         /* Get domain policy handle */
847
848         if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
849                                            MAXIMUM_ALLOWED_ACCESS,
850                                            &domain_sid, &domain_pol))
851             != NT_STATUS_NOPROBLEMO) {
852                 goto done;
853         }
854
855         got_domain_pol = True;
856
857         /* Query domain info */
858
859         if ((result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
860                                               switch_value, &ctr))
861             != NT_STATUS_NOPROBLEMO) {
862                 goto done;
863         }
864
865         /* Display domain info */
866
867         switch (switch_value) {
868         case 2:
869                 display_sam_unk_info_2(&ctr.info.inf2);
870                 break;
871         default:
872                 printf("cannot display domain info for switch value %d\n",
873                        switch_value);
874                 break;
875         }
876
877  done:
878         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
879         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
880
881         cli_nt_session_close(cli);
882         talloc_destroy(mem_ctx);
883
884         return result;
885 }
886
887 /* List of commands exported by this module */
888
889 struct cmd_set samr_commands[] = {
890         { "SAMR",               NULL,                           "" },
891
892         { "queryuser",          cmd_samr_query_user,            "Query user info" },
893         { "querygroup",         cmd_samr_query_group,           "Query group info" },
894         { "queryusergroups",    cmd_samr_query_usergroups,      "Query user groups" },
895         { "querygroupmem",      cmd_samr_query_groupmem,        "Query group membership" },
896         { "queryaliasmem",      cmd_samr_query_aliasmem,        "Query alias membership" },
897         { "querydispinfo",      cmd_samr_query_dispinfo,        "Query display info" },
898         { "querydominfo",       cmd_samr_query_dominfo,         "Query domain info" },
899         { "enumdomgroups",      cmd_samr_enum_dom_groups,       "Enumerate domain groups" },
900
901         { NULL, NULL, NULL }
902 };