it now all compiles - so try enabling it by default and see what explodes on the...
[nivanova/samba-autobuild/.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 NTSTATUS cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) 
142 {
143         POLICY_HND connect_pol, domain_pol, user_pol;
144         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
145         uint32 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 NT_STATUS_OK;
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                 talloc_destroy(mem_ctx);
174                 return NT_STATUS_UNSUCCESSFUL;
175         }
176         
177         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
178         strupper (server);
179         
180         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
181                                   &connect_pol);
182         if (!NT_STATUS_IS_OK(result)) {
183                 goto done;
184         }
185
186         got_connect_pol = True;
187
188         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
189                                       MAXIMUM_ALLOWED_ACCESS,
190                                       &domain_sid, &domain_pol);
191         if (!NT_STATUS_IS_OK(result)) {
192                 goto done;
193         }
194
195         got_domain_pol = True;
196
197         result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
198                                     MAXIMUM_ALLOWED_ACCESS,
199                                     user_rid, &user_pol);
200         if (!NT_STATUS_IS_OK(result)) {
201                 goto done;
202         }
203
204         got_user_pol = True;
205
206         ZERO_STRUCT(user_ctr);
207
208         result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, 
209                                          info_level, &user_ctr);
210         if (!NT_STATUS_IS_OK(result)) {
211                 goto done;
212         }
213
214         display_sam_user_info_21(user_ctr->info.id21);
215
216 done:
217         if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
218         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
219         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
220
221         cli_nt_session_close(cli);
222         talloc_destroy(mem_ctx);
223
224         return result;
225 }
226
227 /****************************************************************************
228  display group info
229  ****************************************************************************/
230 static void display_group_info1(GROUP_INFO1 *info1)
231 {
232         fstring temp;
233
234         unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
235         printf("\tGroup Name:\t%s\n", temp);
236         unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
237         printf("\tDescription:\t%s\n", temp);
238         printf("\tunk1:%d\n", info1->unknown_1);
239         printf("\tNum Members:%d\n", info1->num_members);
240 }
241
242 /****************************************************************************
243  display group info
244  ****************************************************************************/
245 static void display_group_info4(GROUP_INFO4 *info4)
246 {
247         fstring desc;
248
249         unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
250         printf("\tGroup Description:%s\n", desc);
251 }
252
253 /****************************************************************************
254  display sam sync structure
255  ****************************************************************************/
256 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
257 {
258         switch (ctr->switch_value1) {
259             case 1: {
260                     display_group_info1(&ctr->group.info1);
261                     break;
262             }
263             case 4: {
264                     display_group_info4(&ctr->group.info4);
265                     break;
266             }
267         }
268 }
269
270 /***********************************************************************
271  * Query group information 
272  */
273 static NTSTATUS cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) 
274 {
275         POLICY_HND connect_pol, domain_pol, group_pol;
276         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
277         uint32 info_level = 1;
278         BOOL got_connect_pol = False, got_domain_pol = False,
279                 got_group_pol = False;
280         GROUP_INFO_CTR group_ctr;
281         fstring                 server; 
282         TALLOC_CTX              *mem_ctx;
283         uint32 group_rid;
284         
285         if (argc != 2) {
286                 printf("Usage: %s rid\n", argv[0]);
287                 return NT_STATUS_OK;
288         }
289
290         group_rid = atoi(argv[1]);
291
292         if (!(mem_ctx=talloc_init())) {
293                 DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n"));
294                 return NT_STATUS_UNSUCCESSFUL;
295         }
296
297         fetch_domain_sid(cli);
298
299         /* Initialise RPC connection */
300         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
301                 fprintf (stderr, "Could not initialize samr pipe!\n");
302                 talloc_destroy(mem_ctx);
303                 return NT_STATUS_UNSUCCESSFUL;
304         }
305         
306         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
307         strupper (server);
308
309         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
310                                   &connect_pol);
311         if (!NT_STATUS_IS_OK(result)) {
312                 goto done;
313         }
314
315         got_connect_pol = True;
316
317         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
318                                       MAXIMUM_ALLOWED_ACCESS,
319                                       &domain_sid, &domain_pol);
320         if (!NT_STATUS_IS_OK(result)) {
321                 goto done;
322         }
323
324         got_domain_pol = True;
325
326         result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
327                                      MAXIMUM_ALLOWED_ACCESS,
328                                      group_rid, &group_pol);
329         if (!NT_STATUS_IS_OK(result)) {
330                 goto done;
331         }
332
333         got_group_pol = True;
334
335         ZERO_STRUCT(group_ctr);
336
337         result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol, 
338                                           info_level, &group_ctr);
339         if (!NT_STATUS_IS_OK(result)) {
340                 goto done;
341         }
342
343         display_group_info_ctr(&group_ctr);
344
345 done:
346         if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
347         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
348         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
349
350         cli_nt_session_close(cli);
351         talloc_destroy(mem_ctx);
352
353         return result;
354 }
355
356 /* Query groups a user is a member of */
357
358 static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **argv) 
359 {
360         POLICY_HND              connect_pol, 
361                                 domain_pol, 
362                                 user_pol;
363         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
364         BOOL                    got_connect_pol = False, 
365                                 got_domain_pol = False,
366                                 got_user_pol = False;
367         uint32                  num_groups, 
368                                 user_rid;
369         DOM_GID                 *user_gids;
370         int                     i;
371         fstring                 server;
372         TALLOC_CTX              *mem_ctx;
373         
374         if (argc != 2) {
375                 printf("Usage: %s rid\n", argv[0]);
376                 return NT_STATUS_OK;
377         }
378
379         if (!(mem_ctx=talloc_init()))
380         {
381                 DEBUG(0,("cmd_samr_query_usergroups: talloc_init returned NULL!\n"));
382                 return NT_STATUS_NO_MEMORY;
383         }
384
385         sscanf(argv[1], "%i", &user_rid);
386
387         fetch_domain_sid(cli);
388
389         /* Initialise RPC connection */
390         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
391                 fprintf (stderr, "Could not initialize samr pipe!\n");
392                 talloc_destroy(mem_ctx);
393                 return NT_STATUS_UNSUCCESSFUL;
394         }
395
396         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
397         strupper (server);
398                 
399         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
400                                   &connect_pol);
401         if (!NT_STATUS_IS_OK(result)) {
402                 goto done;
403         }
404
405         got_connect_pol = True;
406
407         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
408                                       MAXIMUM_ALLOWED_ACCESS,
409                                       &domain_sid, &domain_pol);
410         if (!NT_STATUS_IS_OK(result)) {
411                 goto done;
412         }
413
414         got_domain_pol = True;
415
416         result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
417                                     MAXIMUM_ALLOWED_ACCESS,
418                                     user_rid, &user_pol);
419         if (!NT_STATUS_IS_OK(result)) {
420                 goto done;
421         }
422
423         got_user_pol = True;
424
425         result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
426                                            &num_groups, &user_gids);
427         if (!NT_STATUS_IS_OK(result)) {
428                 goto done;
429         }
430
431         for (i = 0; i < num_groups; i++) {
432                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n", 
433                        user_gids[i].g_rid, user_gids[i].attr);
434         }
435
436  done:
437         if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
438         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
439         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
440
441         cli_nt_session_close(cli);
442         talloc_destroy(mem_ctx);
443
444         return result;
445 }
446
447 /* Query members of a group */
448
449 static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **argv) 
450 {
451         POLICY_HND connect_pol, domain_pol, group_pol;
452         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
453         BOOL    got_connect_pol = False, 
454                 got_domain_pol = False,
455                 got_group_pol = False;
456         uint32 num_members, *group_rids, *group_attrs, group_rid;
457         int i;
458         fstring                 server;
459         TALLOC_CTX              *mem_ctx;
460         
461         if (argc != 2) {
462                 printf("Usage: %s rid\n", argv[0]);
463                 return NT_STATUS_OK;
464         }
465
466         if (!(mem_ctx=talloc_init()))
467         {
468                 DEBUG(0,("cmd_samr_query_groupmem: talloc_init returned NULL!\n"));
469                 return NT_STATUS_NO_MEMORY;
470         }
471
472         sscanf(argv[1], "%i", &group_rid);
473
474         fetch_domain_sid(cli);
475
476         /* Initialise RPC connection */
477         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
478                 fprintf (stderr, "Could not initialize samr pipe!\n");
479                 talloc_destroy(mem_ctx);
480                 return NT_STATUS_UNSUCCESSFUL;
481         }
482
483         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
484         strupper (server);
485
486         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
487                                   &connect_pol);
488         if (!NT_STATUS_IS_OK(result)) {
489                 goto done;
490         }
491
492         got_connect_pol = True;
493
494         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
495                                       MAXIMUM_ALLOWED_ACCESS,
496                                       &domain_sid, &domain_pol);
497         if (!NT_STATUS_IS_OK(result)) {
498                 goto done;
499         }
500
501         got_domain_pol = True;
502
503         result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
504                                      MAXIMUM_ALLOWED_ACCESS,
505                                      group_rid, &group_pol);
506         if (!NT_STATUS_IS_OK(result)) {
507                 goto done;
508         }
509
510         got_group_pol = True;
511
512         result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
513                                          &num_members, &group_rids,
514                                          &group_attrs);
515         if (!NT_STATUS_IS_OK(result)) {
516                 goto done;
517         }
518
519         for (i = 0; i < num_members; i++) {
520                 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
521                        group_attrs[i]);
522         }
523
524  done:
525         if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
526         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
527         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
528
529         cli_nt_session_close(cli);
530         talloc_destroy(mem_ctx);
531
532         return result;
533 }
534
535 /* Enumerate domain groups */
536
537 static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli, int argc, 
538                                        char **argv) 
539 {
540         POLICY_HND connect_pol, domain_pol;
541         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
542         BOOL got_connect_pol = False, got_domain_pol = False;
543         TALLOC_CTX *mem_ctx;
544         uint32 start_idx, size, num_dom_groups, i;
545         struct acct_info *dom_groups;
546
547         if (argc != 1) {
548                 printf("Usage: %s\n", argv[0]);
549                 return NT_STATUS_OK;
550         }
551
552         if (!(mem_ctx = talloc_init())) {
553                 DEBUG(0, ("cmd_samr_enum_dom_groups: talloc_init returned "
554                           "NULL!\n"));
555                 return NT_STATUS_UNSUCCESSFUL;
556         }
557
558         fetch_domain_sid(cli);
559
560         /* Initialise RPC connection */
561
562         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
563                 fprintf (stderr, "Could not initialize samr pipe!\n");
564                 talloc_destroy(mem_ctx);
565                 return NT_STATUS_UNSUCCESSFUL;
566         }
567
568         /* Get sam policy handle */
569
570         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
571                                   &connect_pol);
572         if (!NT_STATUS_IS_OK(result)) {
573                 goto done;
574         }
575
576         got_connect_pol = True;
577
578         /* Get domain policy handle */
579
580         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
581                                       MAXIMUM_ALLOWED_ACCESS,
582                                       &domain_sid, &domain_pol);
583         if (!NT_STATUS_IS_OK(result)) {
584                 goto done;
585         }
586
587         got_domain_pol = True;
588
589         /* Enumerate domain groups */
590
591         start_idx = 0;
592         size = 0xffff;
593
594         result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
595                                           &start_idx, size,
596                                           &dom_groups, &num_dom_groups);
597
598         for (i = 0; i < num_dom_groups; i++)
599                 printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name,
600                        dom_groups[i].rid);
601
602  done:
603         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
604         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
605
606         cli_nt_session_close(cli);
607         talloc_destroy(mem_ctx);
608
609         return result;
610 }
611
612 /* Query alias membership */
613
614 static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli, int argc, 
615                                       char **argv) 
616 {
617         POLICY_HND connect_pol, domain_pol, alias_pol;
618         BOOL got_connect_pol = False, got_domain_pol = False,
619                 got_alias_pol = False;
620         TALLOC_CTX *mem_ctx;
621         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
622         uint32 alias_rid, num_members, i;
623         DOM_SID *alias_sids;
624
625         if (argc != 2) {
626                 printf("Usage: %s rid\n", argv[0]);
627                 return NT_STATUS_OK;
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                 talloc_destroy(mem_ctx);
645                 return NT_STATUS_UNSUCCESSFUL;
646         }
647
648         /* Open SAMR handle */
649
650         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
651                                   &connect_pol);
652         if (!NT_STATUS_IS_OK(result)) {
653                 goto done;
654         }
655
656         got_connect_pol = True;
657
658         /* Open handle on domain */
659
660         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
661                                       MAXIMUM_ALLOWED_ACCESS,
662                                       &domain_sid, &domain_pol);
663         if (!NT_STATUS_IS_OK(result)) {
664                 goto done;
665         }
666
667         got_domain_pol = True;
668
669         /* Open handle on alias */
670
671         result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
672                                      MAXIMUM_ALLOWED_ACCESS,
673                                      alias_rid, &alias_pol);
674         if (!NT_STATUS_IS_OK(result)) {
675                 goto done;
676         }
677
678         got_alias_pol = True;
679
680         result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
681                                          &num_members, &alias_sids);
682         if (!NT_STATUS_IS_OK(result)) {
683                 goto done;
684         }
685
686         for (i = 0; i < num_members; i++) {
687                 fstring sid_str;
688
689                 sid_to_string(sid_str, &alias_sids[i]);
690                 printf("\tsid:[%s]\n", sid_str);
691         }
692
693  done:
694         if (got_alias_pol) cli_samr_close(cli, mem_ctx, &alias_pol);
695         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
696         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
697
698         cli_nt_session_close(cli);
699         talloc_destroy(mem_ctx);
700
701         return result;
702 }
703
704 /* Query display info */
705
706 static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli, int argc, 
707                                         char **argv) 
708 {
709         POLICY_HND connect_pol, domain_pol;
710         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
711         BOOL got_connect_pol = False, got_domain_pol = False;
712         TALLOC_CTX *mem_ctx;
713         uint32 start_idx, max_entries, num_entries, i;
714         uint16 info_level = 1;
715         SAM_DISPINFO_CTR ctr;
716         SAM_DISPINFO_1 info1;
717
718         if (argc != 1) {
719                 printf("Usage: %s\n", argv[0]);
720                 return NT_STATUS_OK;
721         }
722
723         if (!(mem_ctx = talloc_init())) {
724                 DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
725                           "NULL!\n"));
726                 return NT_STATUS_NO_MEMORY;
727         }
728
729         fetch_domain_sid(cli);
730
731         /* Initialise RPC connection */
732
733         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
734                 fprintf (stderr, "Could not initialize samr pipe!\n");
735                 talloc_destroy(mem_ctx);
736                 return NT_STATUS_UNSUCCESSFUL;
737         }
738
739         /* Get sam policy handle */
740
741         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
742                                   &connect_pol);
743         if (!NT_STATUS_IS_OK(result)) {
744                 goto done;
745         }
746
747         got_connect_pol = True;
748
749         /* Get domain policy handle */
750
751         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
752                                       MAXIMUM_ALLOWED_ACCESS, 
753                                       &domain_sid, &domain_pol);
754         if (!NT_STATUS_IS_OK(result)) {
755                 goto done;
756         }
757
758         got_domain_pol = True;
759
760         /* Query display info */
761
762         start_idx = 0;
763         max_entries = 250;
764
765         ZERO_STRUCT(ctr);
766         ZERO_STRUCT(info1);
767
768         ctr.sam.info1 = &info1;
769
770         result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
771                                          &start_idx, info_level,
772                                          &num_entries, max_entries, &ctr);
773
774         for (i = 0; i < num_entries; i++) {
775                 display_sam_info_1(&ctr.sam.info1->sam[i],
776                                    &ctr.sam.info1->str[i]);
777         }
778
779  done:
780         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
781         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
782
783         cli_nt_session_close(cli);
784         talloc_destroy(mem_ctx);
785
786         return result;
787 }
788
789 /* Query domain info */
790
791 static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli, int argc, 
792                                        char **argv) 
793 {
794         POLICY_HND connect_pol, domain_pol;
795         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
796         BOOL got_connect_pol = False, got_domain_pol = False;
797         TALLOC_CTX *mem_ctx;
798         uint16 switch_value = 2;
799         SAM_UNK_CTR ctr;
800
801         if (argc > 2) {
802                 printf("Usage: %s [infolevel]\n", argv[0]);
803                 return NT_STATUS_OK;
804         }
805
806         if (argc == 2)
807                 switch_value = atoi(argv[1]);
808
809         if (!(mem_ctx = talloc_init())) {
810                 DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
811                           "NULL!\n"));
812                 return NT_STATUS_UNSUCCESSFUL;
813         }
814
815         fetch_domain_sid(cli);
816
817         /* Initialise RPC connection */
818
819         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
820                 fprintf (stderr, "Could not initialize samr pipe!\n");
821                 talloc_destroy(mem_ctx);
822                 return NT_STATUS_UNSUCCESSFUL;
823         }
824
825         /* Get sam policy handle */
826
827         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
828                                   &connect_pol);
829         if (!NT_STATUS_IS_OK(result)) {
830                 goto done;
831         }
832
833         got_connect_pol = True;
834
835         /* Get domain policy handle */
836
837         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
838                                       MAXIMUM_ALLOWED_ACCESS,
839                                       &domain_sid, &domain_pol);
840         if (!NT_STATUS_IS_OK(result)) {
841                 goto done;
842         }
843
844         got_domain_pol = True;
845
846         /* Query domain info */
847
848         result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
849                                          switch_value, &ctr);
850         if (!NT_STATUS_IS_OK(result)) {
851                 goto done;
852         }
853
854         /* Display domain info */
855
856         switch (switch_value) {
857         case 2:
858                 display_sam_unk_info_2(&ctr.info.inf2);
859                 break;
860         default:
861                 printf("cannot display domain info for switch value %d\n",
862                        switch_value);
863                 break;
864         }
865
866  done:
867         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
868         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
869
870         cli_nt_session_close(cli);
871         talloc_destroy(mem_ctx);
872
873         return result;
874 }
875
876 /* Create domain user */
877
878 static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli, int argc, 
879                                          char **argv) 
880 {
881         POLICY_HND connect_pol, domain_pol, user_pol;
882         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
883         BOOL got_connect_pol = False, got_domain_pol = False, 
884                 got_user_pol = False;
885         TALLOC_CTX *mem_ctx;
886         char *acct_name;
887         uint16 acb_info;
888         uint32 unknown, user_rid;
889
890         if (argc != 2) {
891                 printf("Usage: %s username\n", argv[0]);
892                 return NT_STATUS_OK;
893         }
894
895         acct_name = argv[1];
896
897         if (!(mem_ctx = talloc_init())) {
898                 DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
899                           "NULL!\n"));
900                 return NT_STATUS_UNSUCCESSFUL;
901         }
902
903         fetch_domain_sid(cli);
904
905         /* Initialise RPC connection */
906
907         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
908                 fprintf (stderr, "Could not initialize samr pipe!\n");
909                 talloc_destroy(mem_ctx);
910                 return NT_STATUS_UNSUCCESSFUL;
911         }
912
913         /* Get sam policy handle */
914
915         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
916                                   &connect_pol);
917         if (!NT_STATUS_IS_OK(result)) {
918                 goto done;
919         }
920
921         got_connect_pol = True;
922
923         /* Get domain policy handle */
924
925         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
926                                       MAXIMUM_ALLOWED_ACCESS,
927                                       &domain_sid, &domain_pol);
928         if (!NT_STATUS_IS_OK(result)) {
929                 goto done;
930         }
931
932         got_domain_pol = True;
933
934         /* Create domain user */
935
936         acb_info = ACB_NORMAL;
937         unknown = 0xe005000b; /* No idea what this is - a permission mask? */
938
939         result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
940                                           acct_name, acb_info, unknown,
941                                           &user_pol, &user_rid);
942         if (!NT_STATUS_IS_OK(result)) {
943                 goto done;
944         }
945
946         got_user_pol = True;
947
948  done:
949         if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
950         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
951         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
952
953         cli_nt_session_close(cli);
954         talloc_destroy(mem_ctx);
955
956         return result;
957 }
958
959 /* Lookup sam names */
960
961 static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli, int argc, 
962                                     char **argv) 
963 {
964         TALLOC_CTX *mem_ctx;
965         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
966         POLICY_HND connect_pol, domain_pol;
967         BOOL got_connect_pol = False, got_domain_pol = False;
968         uint32 flags = 0x000003e8;
969         uint32 num_rids, num_names, *name_types, *rids;
970         char **names;
971         int i;
972
973         if (argc < 2) {
974                 printf("Usage: %s name1 [name2 [name3] [...]]\n", argv[0]);
975                 return NT_STATUS_OK;
976         }
977
978         if (!(mem_ctx = talloc_init())) {
979                 DEBUG(0, ("cmd_samr_lookup_names: talloc_init failed\n"));
980                 return result;
981         }
982
983         fetch_domain_sid(cli);
984
985         /* Initialise RPC connection */
986
987         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
988                 fprintf (stderr, "Could not initialize samr pipe!\n");
989                 talloc_destroy(mem_ctx);
990                 return NT_STATUS_UNSUCCESSFUL;
991         }
992
993         /* Get sam policy and domain handles */
994
995         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
996                                   &connect_pol);
997         if (!NT_STATUS_IS_OK(result)) {
998                 goto done;
999         }
1000
1001         got_connect_pol = True;
1002
1003         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1004                                       MAXIMUM_ALLOWED_ACCESS,
1005                                       &domain_sid, &domain_pol);
1006         if (!NT_STATUS_IS_OK(result)) {
1007                 goto done;
1008         }
1009
1010         got_domain_pol = True;
1011
1012         /* Look up names */
1013
1014         num_names = argc - 1;
1015         names = (char **)talloc(mem_ctx, sizeof(char *) * num_names);
1016
1017         for (i = 0; i < argc - 1; i++)
1018                 names[i] = argv[i + 1];
1019
1020         result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1021                                        flags, num_names, names,
1022                                        &num_rids, &rids, &name_types);
1023         if (!NT_STATUS_IS_OK(result)) {
1024                 goto done;
1025         }
1026
1027         /* Display results */
1028
1029         for (i = 0; i < num_names; i++)
1030                 printf("name %s: 0x%x (%d)\n", names[i], rids[i], 
1031                        name_types[i]);
1032
1033  done:
1034         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
1035         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
1036
1037         cli_nt_session_close(cli);
1038         talloc_destroy(mem_ctx);
1039
1040         return result;
1041 }
1042
1043 /* Lookup sam rids */
1044
1045 static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli, int argc, 
1046                                    char **argv) 
1047 {
1048         TALLOC_CTX *mem_ctx;
1049         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1050         POLICY_HND connect_pol, domain_pol;
1051         BOOL got_connect_pol = False, got_domain_pol = False;
1052         uint32 flags = 0x000003e8;
1053         uint32 num_rids, num_names, *rids, *name_types;
1054         char **names;
1055         int i;
1056
1057         if (argc < 2) {
1058                 printf("Usage: %s rid1 [rid2 [rid3] [...]]\n", argv[0]);
1059                 return NT_STATUS_OK;
1060         }
1061
1062         if (!(mem_ctx = talloc_init())) {
1063                 DEBUG(0, ("cmd_samr_lookup_rids: talloc_init failed\n"));
1064                 return result;
1065         }
1066
1067         fetch_domain_sid(cli);
1068
1069         /* Initialise RPC connection */
1070
1071         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
1072                 fprintf (stderr, "Could not initialize samr pipe!\n");
1073                 talloc_destroy(mem_ctx);
1074                 return NT_STATUS_UNSUCCESSFUL;
1075         }
1076
1077         /* Get sam policy and domain handles */
1078
1079         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1080                                   &connect_pol);
1081         if (!NT_STATUS_IS_OK(result)) {
1082                 goto done;
1083         }
1084
1085         got_connect_pol = True;
1086
1087         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1088                                       MAXIMUM_ALLOWED_ACCESS,
1089                                       &domain_sid, &domain_pol);
1090         if (!NT_STATUS_IS_OK(result)) {
1091                 goto done;
1092         }
1093
1094         got_domain_pol = True;
1095
1096         /* Look up rids */
1097
1098         num_rids = argc - 1;
1099         rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
1100
1101         for (i = 0; i < argc - 1; i++)
1102                 rids[i] = atoi(argv[i + 1]);
1103
1104         result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
1105                                       flags, num_rids, rids,
1106                                       &num_names, &names, &name_types);
1107         if (!NT_STATUS_IS_OK(result)) {
1108                 goto done;
1109         }
1110
1111         /* Display results */
1112
1113         for (i = 0; i < num_names; i++)
1114                 printf("rid %x: %s (%d)\n", rids[i], names[i], name_types[i]);
1115
1116  done:
1117         if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
1118         if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
1119
1120         cli_nt_session_close(cli);
1121         talloc_destroy(mem_ctx);
1122
1123         return result;
1124 }
1125
1126 /* Delete domain user */
1127
1128 static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli, int argc, 
1129                                        char **argv) 
1130 {
1131         TALLOC_CTX *mem_ctx;
1132         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1133         POLICY_HND connect_pol, domain_pol, user_pol;
1134
1135         if (argc != 2) {
1136                 printf("Usage: %s username\n", argv[0]);
1137                 return NT_STATUS_OK;
1138         }
1139
1140         if (!(mem_ctx = talloc_init())) {
1141                 DEBUG(0, ("cmd_samr_delete_dom_user: talloc_init failed\n"));
1142                 return result;
1143         }
1144
1145         fetch_domain_sid(cli);
1146
1147         /* Initialise RPC connection */
1148
1149         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
1150                 DEBUG(0, ("cmd_samr_delete_dom_user: could not open samr pipe!\n"));
1151                 talloc_destroy(mem_ctx);
1152                 return NT_STATUS_UNSUCCESSFUL;
1153         }
1154
1155         /* Get sam policy and domain handles */
1156
1157         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1158                                   &connect_pol);
1159         if (!NT_STATUS_IS_OK(result)) {
1160                 goto done;
1161         }
1162
1163         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1164                                       MAXIMUM_ALLOWED_ACCESS,
1165                                       &domain_sid, &domain_pol);
1166         if (!NT_STATUS_IS_OK(result)) {
1167                 goto done;
1168         }
1169
1170         /* Get handle on user */
1171
1172         {
1173                 uint32 *user_rids, num_rids, *name_types;
1174                 uint32 flags = 0x000003e8;
1175
1176                 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1177                                                flags, 1, &argv[1],
1178                                                &num_rids, &user_rids,
1179                                                &name_types);
1180                 if (!NT_STATUS_IS_OK(result)) {
1181                         goto done;
1182                 }
1183
1184                 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
1185                                             MAXIMUM_ALLOWED_ACCESS,
1186                                             user_rids[0], &user_pol);
1187                 if (!NT_STATUS_IS_OK(result)) {
1188                         goto done;
1189                 }
1190         }
1191
1192         /* Delete user */
1193
1194         result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
1195         if (!NT_STATUS_IS_OK(result)) {
1196                 goto done;
1197         }
1198
1199         /* Display results */
1200
1201  done:
1202         cli_nt_session_close(cli);
1203         talloc_destroy(mem_ctx);
1204
1205         return result;
1206 }
1207
1208 /* List of commands exported by this module */
1209
1210 struct cmd_set samr_commands[] = {
1211
1212         { "SAMR" },
1213
1214         { "queryuser",          cmd_samr_query_user,            "Query user info",         "" },
1215         { "querygroup",         cmd_samr_query_group,           "Query group info",        "" },
1216         { "queryusergroups",    cmd_samr_query_usergroups,      "Query user groups",       "" },
1217         { "querygroupmem",      cmd_samr_query_groupmem,        "Query group membership",  "" },
1218         { "queryaliasmem",      cmd_samr_query_aliasmem,        "Query alias membership",  "" },
1219         { "querydispinfo",      cmd_samr_query_dispinfo,        "Query display info",      "" },
1220         { "querydominfo",       cmd_samr_query_dominfo,         "Query domain info",       "" },
1221         { "enumdomgroups",      cmd_samr_enum_dom_groups,       "Enumerate domain groups", "" },
1222
1223         { "createdomuser",      cmd_samr_create_dom_user,       "Create domain user",      "" },
1224         { "samlookupnames",     cmd_samr_lookup_names,          "Look up names",           "" },
1225         { "samlookuprids",      cmd_samr_lookup_rids,           "Look up names",           "" },
1226         { "deletedomuser",      cmd_samr_delete_dom_user,       "Delete domain user",      "" },
1227
1228         { NULL }
1229 };