merging Tim's changes form HEAD
[Samba.git] / source / rpcclient / cmd_samr.c
blobd199e65b95ad67b3f81eed6b1e2bb04ab19ff272
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.2
4 RPC pipe client
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
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.
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.
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.
26 #include "includes.h"
28 extern DOM_SID domain_sid;
30 /****************************************************************************
31 display sam_user_info_21 structure
32 ****************************************************************************/
33 static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
35 fstring temp;
37 unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
38 printf("\tUser Name :\t%s\n", temp);
40 unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
41 printf("\tFull Name :\t%s\n", temp);
43 unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
44 printf("\tHome Drive :\t%s\n", temp);
46 unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
47 printf("\tDir Drive :\t%s\n", temp);
49 unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
50 printf("\tProfile Path:\t%s\n", temp);
52 unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
53 printf("\tLogon Script:\t%s\n", temp);
55 unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
56 printf("\tDescription :\t%s\n", temp);
58 unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
59 printf("\tWorkstations:\t%s\n", temp);
61 unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
62 printf("\tUnknown Str :\t%s\n", temp);
64 unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
65 printf("\tRemote Dial :\t%s\n", temp);
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)));
80 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
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 */
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 */
90 printf("\tpadding1[0..7]...\n");
92 if (usr->ptr_logon_hrs) {
93 printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
97 /**********************************************************************
98 * Query user information
100 static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv)
102 POLICY_HND connect_pol, domain_pol, user_pol;
103 uint32 result = NT_STATUS_UNSUCCESSFUL,
104 info_level = 21;
105 BOOL got_connect_pol = False,
106 got_domain_pol = False,
107 got_user_pol = False;
108 SAM_USERINFO_CTR user_ctr;
109 SAM_USER_INFO_21 info_21;
110 fstring server;
111 TALLOC_CTX *mem_ctx;
114 if (argc != 1) {
115 printf("Usage: %s\n", argv[0]);
116 return 0;
119 if (!(mem_ctx=talloc_init()))
121 DEBUG(0,("cmd_samr_query_user: talloc_init returned NULL!\n"));
122 return NT_STATUS_UNSUCCESSFUL;
125 fetch_domain_sid(cli);
127 /* Initialise RPC connection */
128 if (!cli_nt_session_open (cli, PIPE_SAMR)) {
129 fprintf (stderr, "Could not initialize samr pipe!\n");
130 return NT_STATUS_UNSUCCESSFUL;
133 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
134 strupper (server);
136 if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
137 &connect_pol)) !=
138 NT_STATUS_NOPROBLEMO) {
139 goto done;
142 got_connect_pol = True;
144 if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
145 MAXIMUM_ALLOWED_ACCESS,
146 &domain_sid, &domain_pol))
147 != NT_STATUS_NOPROBLEMO) {
148 goto done;
151 got_domain_pol = True;
153 if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
154 MAXIMUM_ALLOWED_ACCESS,
155 0x1f4, &user_pol))
156 != NT_STATUS_NOPROBLEMO) {
157 goto done;
160 got_user_pol = True;
162 ZERO_STRUCT(user_ctr);
163 ZERO_STRUCT(info_21);
165 user_ctr.info.id21 = &info_21;
167 if ((result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, info_level,
168 &user_ctr))
169 != NT_STATUS_NOPROBLEMO) {
170 goto done;
173 display_sam_user_info_21(&info_21);
175 done:
176 if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
177 if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
178 if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
180 cli_nt_session_close(cli);
181 talloc_destroy(mem_ctx);
183 return result;
186 /****************************************************************************
187 display group info
188 ****************************************************************************/
189 static void display_group_info1(GROUP_INFO1 *info1)
191 fstring temp;
193 unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
194 printf("\tGroup Name:\t%s\n", temp);
195 unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
196 printf("\tDescription:\t%s\n", temp);
197 printf("\tunk1:%d\n", info1->unknown_1);
198 printf("\tNum Members:%d\n", info1->num_members);
201 /****************************************************************************
202 display group info
203 ****************************************************************************/
204 static void display_group_info4(GROUP_INFO4 *info4)
206 fstring desc;
208 unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
209 printf("\tGroup Description:%s\n", desc);
212 /****************************************************************************
213 display sam sync structure
214 ****************************************************************************/
215 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
217 switch (ctr->switch_value1) {
218 case 1: {
219 display_group_info1(&ctr->group.info1);
220 break;
222 case 4: {
223 display_group_info4(&ctr->group.info4);
224 break;
229 /***********************************************************************
230 * Query group information
232 static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
234 POLICY_HND connect_pol, domain_pol, group_pol;
235 uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1;
236 BOOL got_connect_pol = False, got_domain_pol = False,
237 got_group_pol = False;
238 GROUP_INFO_CTR group_ctr;
239 fstring server;
240 TALLOC_CTX *mem_ctx;
242 if (argc != 1) {
243 printf("Usage: %s\n", argv[0]);
244 return 0;
247 if (!(mem_ctx=talloc_init()))
249 DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n"));
250 return NT_STATUS_UNSUCCESSFUL;
253 fetch_domain_sid(cli);
255 /* Initialise RPC connection */
256 if (!cli_nt_session_open (cli, PIPE_SAMR)) {
257 fprintf (stderr, "Could not initialize samr pipe!\n");
258 return NT_STATUS_UNSUCCESSFUL;
261 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
262 strupper (server);
264 if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
265 &connect_pol)) !=
266 NT_STATUS_NOPROBLEMO) {
267 goto done;
270 got_connect_pol = True;
272 if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
273 MAXIMUM_ALLOWED_ACCESS,
274 &domain_sid, &domain_pol))
275 != NT_STATUS_NOPROBLEMO) {
276 goto done;
279 got_domain_pol = True;
281 if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
282 MAXIMUM_ALLOWED_ACCESS,
283 0x202, &group_pol))
284 != NT_STATUS_NOPROBLEMO) {
285 goto done;
288 got_group_pol = True;
290 ZERO_STRUCT(group_ctr);
292 if ((result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol, info_level,
293 &group_ctr))
294 != NT_STATUS_NOPROBLEMO) {
295 goto done;
298 display_group_info_ctr(&group_ctr);
300 done:
301 if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
302 if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
303 if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
305 cli_nt_session_close(cli);
306 talloc_destroy(mem_ctx);
308 return result;
311 /* Query groups a user is a member of */
313 static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **argv)
315 POLICY_HND connect_pol,
316 domain_pol,
317 user_pol;
318 uint32 result = NT_STATUS_UNSUCCESSFUL;
319 BOOL got_connect_pol = False,
320 got_domain_pol = False,
321 got_user_pol = False;
322 uint32 num_groups,
323 user_rid;
324 DOM_GID *user_gids;
325 int i;
326 fstring server;
327 TALLOC_CTX *mem_ctx;
329 if (argc != 2) {
330 printf("Usage: %s rid\n", argv[0]);
331 return 0;
334 if (!(mem_ctx=talloc_init()))
336 DEBUG(0,("cmd_samr_query_usergroups: talloc_init returned NULL!\n"));
337 return NT_STATUS_UNSUCCESSFUL;
340 sscanf(argv[1], "%i", &user_rid);
342 fetch_domain_sid(cli);
344 /* Initialise RPC connection */
345 if (!cli_nt_session_open (cli, PIPE_SAMR)) {
346 fprintf (stderr, "Could not initialize samr pipe!\n");
347 return NT_STATUS_UNSUCCESSFUL;
350 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
351 strupper (server);
353 if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
354 &connect_pol)) !=
355 NT_STATUS_NOPROBLEMO) {
356 goto done;
359 got_connect_pol = True;
361 if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
362 MAXIMUM_ALLOWED_ACCESS,
363 &domain_sid, &domain_pol))
364 != NT_STATUS_NOPROBLEMO) {
365 goto done;
368 got_domain_pol = True;
370 if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
371 MAXIMUM_ALLOWED_ACCESS,
372 user_rid, &user_pol))
373 != NT_STATUS_NOPROBLEMO) {
374 goto done;
377 got_user_pol = True;
379 if ((result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
380 &num_groups, &user_gids))
381 != NT_STATUS_NOPROBLEMO) {
382 goto done;
385 for (i = 0; i < num_groups; i++) {
386 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
387 user_gids[i].g_rid, user_gids[i].attr);
390 done:
391 if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
392 if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
393 if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
395 cli_nt_session_close(cli);
396 talloc_destroy(mem_ctx);
398 return result;
401 /* Query members of a group */
403 static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **argv)
405 POLICY_HND connect_pol, domain_pol, group_pol;
406 uint32 result = NT_STATUS_UNSUCCESSFUL;
407 BOOL got_connect_pol = False,
408 got_domain_pol = False,
409 got_group_pol = False;
410 uint32 num_members, *group_rids, *group_attrs, group_rid;
411 int i;
412 fstring server;
413 TALLOC_CTX *mem_ctx;
415 if (argc != 2) {
416 printf("Usage: %s rid\n", argv[0]);
417 return 0;
420 if (!(mem_ctx=talloc_init()))
422 DEBUG(0,("cmd_samr_query_groupmem: talloc_init returned NULL!\n"));
423 return NT_STATUS_UNSUCCESSFUL;
426 sscanf(argv[1], "%i", &group_rid);
428 fetch_domain_sid(cli);
430 /* Initialise RPC connection */
431 if (!cli_nt_session_open (cli, PIPE_SAMR)) {
432 fprintf (stderr, "Could not initialize samr pipe!\n");
433 return NT_STATUS_UNSUCCESSFUL;
436 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
437 strupper (server);
439 if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
440 &connect_pol)) !=
441 NT_STATUS_NOPROBLEMO) {
442 goto done;
445 got_connect_pol = True;
447 if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
448 MAXIMUM_ALLOWED_ACCESS,
449 &domain_sid, &domain_pol))
450 != NT_STATUS_NOPROBLEMO) {
451 goto done;
454 got_domain_pol = True;
456 if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
457 MAXIMUM_ALLOWED_ACCESS,
458 group_rid, &group_pol))
459 != NT_STATUS_NOPROBLEMO) {
460 goto done;
463 got_group_pol = True;
465 if ((result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
466 &num_members, &group_rids,
467 &group_attrs))
468 != NT_STATUS_NOPROBLEMO) {
469 goto done;
472 for (i = 0; i < num_members; i++) {
473 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
474 group_attrs[i]);
477 done:
478 if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
479 if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
480 if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
482 cli_nt_session_close(cli);
483 talloc_destroy(mem_ctx);
485 return result;
488 /* Enumerate domain groups */
490 static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc,
491 char **argv)
493 POLICY_HND connect_pol, domain_pol;
494 uint32 result = NT_STATUS_UNSUCCESSFUL;
495 BOOL got_connect_pol = False, got_domain_pol = False;
496 TALLOC_CTX *mem_ctx;
497 fstring server;
498 uint32 start_idx, size, num_dom_groups, i;
499 struct acct_info *dom_groups;
501 if (argc != 1) {
502 printf("Usage: %s\n", argv[0]);
503 return 0;
506 if (!(mem_ctx = talloc_init())) {
507 DEBUG(0, ("cmd_samr_enum_dom_groups: talloc_init returned "
508 "NULL!\n"));
509 return NT_STATUS_UNSUCCESSFUL;
512 fetch_domain_sid(cli);
514 /* Initialise RPC connection */
516 if (!cli_nt_session_open (cli, PIPE_SAMR)) {
517 fprintf (stderr, "Could not initialize samr pipe!\n");
518 return NT_STATUS_UNSUCCESSFUL;
521 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
522 strupper(server);
524 /* Get sam policy handle */
526 if ((result = cli_samr_connect(cli, mem_ctx, server,
527 MAXIMUM_ALLOWED_ACCESS,
528 &connect_pol)) !=
529 NT_STATUS_NOPROBLEMO) {
530 goto done;
533 got_connect_pol = True;
535 /* Get domain policy handle */
537 if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
538 MAXIMUM_ALLOWED_ACCESS,
539 &domain_sid, &domain_pol))
540 != NT_STATUS_NOPROBLEMO) {
541 goto done;
544 got_domain_pol = True;
546 /* Enumerate domain groups */
548 start_idx = 0;
549 size = 0xffff;
551 result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
552 &start_idx, size,
553 &dom_groups, &num_dom_groups);
555 for (i = 0; i < num_dom_groups; i++)
556 printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name,
557 dom_groups[i].rid);
559 done:
560 if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
561 if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
563 cli_nt_session_close(cli);
564 talloc_destroy(mem_ctx);
566 return result;
569 /* Query alias membership */
571 static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
572 char **argv)
574 POLICY_HND connect_pol, domain_pol, alias_pol;
575 BOOL got_connect_pol = False, got_domain_pol = False,
576 got_alias_pol = False;
577 TALLOC_CTX *mem_ctx;
578 uint32 result = NT_STATUS_UNSUCCESSFUL, alias_rid, num_members, i;
579 DOM_SID *alias_sids;
581 fstring server;
583 if (argc != 2) {
584 printf("Usage: %s rid\n", argv[0]);
585 return 0;
588 if (!(mem_ctx=talloc_init())) {
589 DEBUG(0,("cmd_samr_query_aliasmem: talloc_init() "
590 "returned NULL!\n"));
591 return NT_STATUS_UNSUCCESSFUL;
594 sscanf(argv[1], "%i", &alias_rid);
596 /* Initialise RPC connection */
598 fetch_domain_sid(cli);
600 if (!cli_nt_session_open (cli, PIPE_SAMR)) {
601 fprintf (stderr, "Could not initialize samr pipe!\n");
602 return NT_STATUS_UNSUCCESSFUL;
605 /* Open SAMR handle */
607 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
608 strupper(server);
610 if ((result = cli_samr_connect(cli, mem_ctx, server,
611 MAXIMUM_ALLOWED_ACCESS,
612 &connect_pol)) !=
613 NT_STATUS_NOPROBLEMO) {
614 goto done;
617 got_connect_pol = True;
619 /* Open handle on domain */
621 if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
622 MAXIMUM_ALLOWED_ACCESS,
623 &domain_sid, &domain_pol))
624 != NT_STATUS_NOPROBLEMO) {
625 goto done;
628 got_domain_pol = True;
630 /* Open handle on alias */
632 if ((result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
633 MAXIMUM_ALLOWED_ACCESS,
634 alias_rid, &alias_pol))
635 != NT_STATUS_NOPROBLEMO) {
636 goto done;
639 got_alias_pol = True;
641 if ((result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
642 &num_members, &alias_sids))
643 != NT_STATUS_NOPROBLEMO) {
644 goto done;
647 for (i = 0; i < num_members; i++) {
648 fstring sid_str;
650 sid_to_string(sid_str, &alias_sids[i]);
651 printf("\tsid:[%s]\n", sid_str);
654 done:
655 if (got_alias_pol) cli_samr_close(cli, mem_ctx, &alias_pol);
656 if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
657 if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
659 cli_nt_session_close(cli);
660 talloc_destroy(mem_ctx);
662 return result;
665 /* List of commands exported by this module */
667 struct cmd_set samr_commands[] = {
668 { "SAMR", NULL, "" },
670 { "queryuser", cmd_samr_query_user, "Query user info" },
671 { "querygroup", cmd_samr_query_group, "Query group info" },
672 { "queryusergroups", cmd_samr_query_usergroups, "Query user groups" },
673 { "querygroupmem", cmd_samr_query_groupmem, "Query group membership" },
674 { "queryaliasmem", cmd_samr_query_aliasmem, "Query alias membership" },
675 { "enumdomgroups", cmd_samr_enum_dom_groups, "Enumerate domain groups" },
677 { NULL, NULL, NULL }