2 Unix SMB/CIFS implementation.
5 Copyright (C) Andrew Tridgell 1992-2000,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 Copyright (C) Elrond 2000,
8 Copyright (C) Tim Potter 2000
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "rpcclient.h"
28 extern DOM_SID domain_sid;
30 /****************************************************************************
31 display sam_user_info_7 structure
32 ****************************************************************************/
33 static void display_sam_user_info_7(SAM_USER_INFO_7 *usr)
37 unistr2_to_ascii(temp, &usr->uni_name, sizeof(temp)-1);
38 printf("\tUser Name :\t%s\n", temp);
41 /****************************************************************************
42 display sam_user_info_9 structure
43 ****************************************************************************/
44 static void display_sam_user_info_9(SAM_USER_INFO_9 *usr)
46 printf("\tPrimary group RID :\tox%x\n", usr->rid_group);
49 /****************************************************************************
50 display sam_user_info_21 structure
51 ****************************************************************************/
52 static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
56 unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
57 printf("\tUser Name :\t%s\n", temp);
59 unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
60 printf("\tFull Name :\t%s\n", temp);
62 unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
63 printf("\tHome Drive :\t%s\n", temp);
65 unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
66 printf("\tDir Drive :\t%s\n", temp);
68 unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
69 printf("\tProfile Path:\t%s\n", temp);
71 unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
72 printf("\tLogon Script:\t%s\n", temp);
74 unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
75 printf("\tDescription :\t%s\n", temp);
77 unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
78 printf("\tWorkstations:\t%s\n", temp);
80 unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
81 printf("\tUnknown Str :\t%s\n", temp);
83 unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
84 printf("\tRemote Dial :\t%s\n", temp);
86 printf("\tLogon Time :\t%s\n",
87 http_timestring(nt_time_to_unix(&usr->logon_time)));
88 printf("\tLogoff Time :\t%s\n",
89 http_timestring(nt_time_to_unix(&usr->logoff_time)));
90 printf("\tKickoff Time :\t%s\n",
91 http_timestring(nt_time_to_unix(&usr->kickoff_time)));
92 printf("\tPassword last set Time :\t%s\n",
93 http_timestring(nt_time_to_unix(&usr->pass_last_set_time)));
94 printf("\tPassword can change Time :\t%s\n",
95 http_timestring(nt_time_to_unix(&usr->pass_can_change_time)));
96 printf("\tPassword must change Time:\t%s\n",
97 http_timestring(nt_time_to_unix(&usr->pass_must_change_time)));
99 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
101 printf("\tuser_rid :\t0x%x\n" , usr->user_rid ); /* User ID */
102 printf("\tgroup_rid:\t0x%x\n" , usr->group_rid); /* Group ID */
103 printf("\tacb_info :\t0x%04x\n", usr->acb_info ); /* Account Control Info */
105 printf("\tfields_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */
106 printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
107 printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count);
108 printf("\tlogon_count:\t0x%08x\n", usr->logon_count);
110 printf("\tpadding1[0..7]...\n");
112 if (usr->ptr_logon_hrs) {
113 printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
117 static const char *display_time(NTTIME nttime)
119 static fstring string;
124 int days, hours, mins, secs;
126 if (nttime.high==0 && nttime.low==0)
129 if (nttime.high==0x80000000 && nttime.low==0)
136 high = high * (~nttime.high);
139 low = low/(1000*1000*10);
144 hours=(sec - (days*60*60*24)) / (60*60);
145 mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
146 secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
148 fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
152 static void display_sam_unk_info_1(SAM_UNK_INFO_1 *info1)
155 printf("Minimum password length:\t\t\t%d\n", info1->min_length_password);
156 printf("Password uniqueness (remember x passwords):\t%d\n", info1->password_history);
157 printf("Password Properties:\t\t\t\t0x%08x\n", info1->password_properties);
159 if (info1->password_properties & DOMAIN_PASSWORD_COMPLEX)
160 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
162 if (info1->password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE) {
163 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
164 printf("users must open a session to change password ");
167 if (info1->password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
168 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
170 if (info1->password_properties & DOMAIN_LOCKOUT_ADMINS)
171 printf("\tDOMAIN_LOCKOUT_ADMINS\n");
173 if (info1->password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
174 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
176 if (info1->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
177 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
179 printf("password expire in:\t\t\t\t%s\n", display_time(info1->expire));
180 printf("Min password age (allow changing in x days):\t%s\n", display_time(info1->min_passwordage));
183 static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
187 unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1);
188 printf("Domain:\t\t%s\n", name);
190 unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
191 printf("Server:\t\t%s\n", name);
193 unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1);
194 printf("Comment:\t%s\n", name);
196 printf("Total Users:\t%d\n", info2->num_domain_usrs);
197 printf("Total Groups:\t%d\n", info2->num_domain_grps);
198 printf("Total Aliases:\t%d\n", info2->num_local_grps);
200 printf("Sequence No:\t%d\n", info2->seq_num.low);
202 printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
204 printf("Unknown 4:\t0x%x\n", info2->unknown_4);
205 printf("Server Role:\t%s\n", server_role_str(info2->server_role));
206 printf("Unknown 6:\t0x%x\n", info2->unknown_6);
209 static void display_sam_unk_info_7(SAM_UNK_INFO_7 *info7)
211 printf("Server Role:\t%s\n", server_role_str(info7->server_role));
214 static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
216 printf("Sequence No:\t%d\n", info8->seq_num.low);
217 printf("Domain Create Time:\t%s\n",
218 http_timestring(nt_time_to_unix(&info8->domain_create_time)));
222 static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
224 printf("Bad password lockout duration: %s\n", display_time(info12->duration));
225 printf("Reset Lockout after: %s\n", display_time(info12->reset_count));
226 printf("Lockout after bad attempts: %d\n", info12->bad_attempt_lockout);
229 static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
233 printf("index: 0x%x ", e1->user_idx);
234 printf("RID: 0x%x ", e1->rid_user);
235 printf("acb: 0x%x ", e1->acb_info);
237 unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
238 printf("Account: %s\t", tmp);
240 unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
241 printf("Name: %s\t", tmp);
243 unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
244 printf("Desc: %s\n", tmp);
247 static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
251 printf("index: 0x%x ", e2->user_idx);
252 printf("RID: 0x%x ", e2->rid_user);
253 printf("acb: 0x%x ", e2->acb_info);
255 unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
256 printf("Account: %s\t", tmp);
258 unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
259 printf("Name: %s\n", tmp);
263 static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
267 printf("index: 0x%x ", e3->grp_idx);
268 printf("RID: 0x%x ", e3->rid_grp);
269 printf("attr: 0x%x ", e3->attr);
271 unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
272 printf("Account: %s\t", tmp);
274 unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
275 printf("Name: %s\n", tmp);
279 static void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4)
283 printf("index: %d ", e4->user_idx);
286 for (i=0; i<s4->acct_name.str_str_len; i++)
287 printf("%c", s4->acct_name.buffer[i]);
292 static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
296 printf("index: 0x%x ", e5->grp_idx);
299 for (i=0; i<s5->grp_name.str_str_len; i++)
300 printf("%c", s5->grp_name.buffer[i]);
305 /****************************************************************************
306 Try samr_connect4 first, then samr_conenct if it fails
307 ****************************************************************************/
308 static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
309 uint32 access_mask, POLICY_HND *connect_pol)
311 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
313 result = rpccli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
314 if (!NT_STATUS_IS_OK(result)) {
315 result = rpccli_samr_connect(cli, mem_ctx, access_mask,
321 /**********************************************************************
322 * Query user information
324 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
326 int argc, const char **argv)
328 POLICY_HND connect_pol, domain_pol, user_pol;
329 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
330 uint32 info_level = 21;
331 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
332 SAM_USERINFO_CTR *user_ctr;
336 if ((argc < 2) || (argc > 4)) {
337 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
341 user_rid = strtoul(argv[1], NULL, 10);
344 sscanf(argv[2], "%i", &info_level);
347 sscanf(argv[3], "%x", &access_mask);
350 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
353 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
356 if (!NT_STATUS_IS_OK(result))
359 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
360 MAXIMUM_ALLOWED_ACCESS,
361 &domain_sid, &domain_pol);
363 if (!NT_STATUS_IS_OK(result))
366 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
368 user_rid, &user_pol);
370 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
373 /* Probably this was a user name, try lookupnames */
375 uint32 *rids, *types;
377 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
382 if (NT_STATUS_IS_OK(result)) {
383 result = rpccli_samr_open_user(cli, mem_ctx,
391 if (!NT_STATUS_IS_OK(result))
394 ZERO_STRUCT(user_ctr);
396 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
397 info_level, &user_ctr);
399 if (!NT_STATUS_IS_OK(result))
402 switch (user_ctr->switch_value) {
404 display_sam_user_info_21(user_ctr->info.id21);
407 display_sam_user_info_7(user_ctr->info.id7);
410 display_sam_user_info_9(user_ctr->info.id9);
413 printf("Unsupported infolevel: %d\n", info_level);
417 rpccli_samr_close(cli, mem_ctx, &user_pol);
418 rpccli_samr_close(cli, mem_ctx, &domain_pol);
419 rpccli_samr_close(cli, mem_ctx, &connect_pol);
425 /****************************************************************************
427 ****************************************************************************/
428 static void display_group_info1(GROUP_INFO1 *info1)
432 unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
433 printf("\tGroup Name:\t%s\n", temp);
434 unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
435 printf("\tDescription:\t%s\n", temp);
436 printf("\tGroup Attribute:%d\n", info1->group_attr);
437 printf("\tNum Members:%d\n", info1->num_members);
440 /****************************************************************************
442 ****************************************************************************/
443 static void display_group_info3(GROUP_INFO3 *info3)
445 printf("\tGroup Attribute:%d\n", info3->group_attr);
449 /****************************************************************************
451 ****************************************************************************/
452 static void display_group_info4(GROUP_INFO4 *info4)
456 unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
457 printf("\tGroup Description:%s\n", desc);
460 /****************************************************************************
461 display sam sync structure
462 ****************************************************************************/
463 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
465 switch (ctr->switch_value1) {
467 display_group_info1(&ctr->group.info1);
471 display_group_info3(&ctr->group.info3);
475 display_group_info4(&ctr->group.info4);
481 /***********************************************************************
482 * Query group information
484 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
486 int argc, const char **argv)
488 POLICY_HND connect_pol, domain_pol, group_pol;
489 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
490 uint32 info_level = 1;
491 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
492 GROUP_INFO_CTR *group_ctr;
496 if ((argc < 2) || (argc > 4)) {
497 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
501 sscanf(argv[1], "%i", &group_rid);
504 sscanf(argv[2], "%i", &info_level);
507 sscanf(argv[3], "%x", &access_mask);
509 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
512 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
515 if (!NT_STATUS_IS_OK(result))
518 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
519 MAXIMUM_ALLOWED_ACCESS,
520 &domain_sid, &domain_pol);
522 if (!NT_STATUS_IS_OK(result))
525 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
527 group_rid, &group_pol);
529 if (!NT_STATUS_IS_OK(result))
532 result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
533 info_level, &group_ctr);
534 if (!NT_STATUS_IS_OK(result)) {
538 display_group_info_ctr(group_ctr);
540 rpccli_samr_close(cli, mem_ctx, &group_pol);
541 rpccli_samr_close(cli, mem_ctx, &domain_pol);
542 rpccli_samr_close(cli, mem_ctx, &connect_pol);
547 /* Query groups a user is a member of */
549 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
551 int argc, const char **argv)
553 POLICY_HND connect_pol,
556 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
559 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
564 if ((argc < 2) || (argc > 3)) {
565 printf("Usage: %s rid [access mask]\n", argv[0]);
569 sscanf(argv[1], "%i", &user_rid);
572 sscanf(argv[2], "%x", &access_mask);
574 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
577 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
580 if (!NT_STATUS_IS_OK(result))
583 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
584 MAXIMUM_ALLOWED_ACCESS,
585 &domain_sid, &domain_pol);
587 if (!NT_STATUS_IS_OK(result))
590 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
592 user_rid, &user_pol);
594 if (!NT_STATUS_IS_OK(result))
597 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
598 &num_groups, &user_gids);
600 if (!NT_STATUS_IS_OK(result))
603 for (i = 0; i < num_groups; i++) {
604 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
605 user_gids[i].g_rid, user_gids[i].attr);
608 rpccli_samr_close(cli, mem_ctx, &user_pol);
609 rpccli_samr_close(cli, mem_ctx, &domain_pol);
610 rpccli_samr_close(cli, mem_ctx, &connect_pol);
615 /* Query aliases a user is a member of */
617 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
619 int argc, const char **argv)
621 POLICY_HND connect_pol, domain_pol;
622 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
625 uint32 num_aliases, *alias_rids;
626 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
632 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
633 return NT_STATUS_INVALID_PARAMETER;
639 for (i=2; i<argc; i++) {
641 if (!string_to_sid(&tmp_sid, argv[i])) {
642 printf("%s is not a legal SID\n", argv[i]);
643 return NT_STATUS_INVALID_PARAMETER;
645 add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
648 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
650 return NT_STATUS_NO_MEMORY;
652 for (i=0; i<num_sids; i++) {
653 sid_copy(&sid2[i].sid, &sids[i]);
654 sid2[i].num_auths = sid2[i].sid.num_auths;
657 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
660 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
663 if (!NT_STATUS_IS_OK(result))
666 if (StrCaseCmp(argv[1], "domain")==0)
667 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
669 &domain_sid, &domain_pol);
670 else if (StrCaseCmp(argv[1], "builtin")==0)
671 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
676 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
677 return NT_STATUS_INVALID_PARAMETER;
680 if (!NT_STATUS_IS_OK(result))
683 result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
685 &num_aliases, &alias_rids);
687 if (!NT_STATUS_IS_OK(result))
690 for (i = 0; i < num_aliases; i++) {
691 printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
694 rpccli_samr_close(cli, mem_ctx, &domain_pol);
695 rpccli_samr_close(cli, mem_ctx, &connect_pol);
700 /* Query members of a group */
702 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
704 int argc, const char **argv)
706 POLICY_HND connect_pol, domain_pol, group_pol;
707 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
708 uint32 num_members, *group_rids, *group_attrs, group_rid;
709 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
713 if ((argc < 2) || (argc > 3)) {
714 printf("Usage: %s rid [access mask]\n", argv[0]);
718 sscanf(argv[1], "%i", &group_rid);
721 sscanf(argv[2], "%x", &access_mask);
723 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
726 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
729 if (!NT_STATUS_IS_OK(result))
732 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
733 MAXIMUM_ALLOWED_ACCESS,
734 &domain_sid, &domain_pol);
736 if (!NT_STATUS_IS_OK(result))
739 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
741 group_rid, &group_pol);
743 if (!NT_STATUS_IS_OK(result))
746 result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
747 &num_members, &group_rids,
750 if (!NT_STATUS_IS_OK(result))
753 for (i = 0; i < num_members; i++) {
754 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
758 rpccli_samr_close(cli, mem_ctx, &group_pol);
759 rpccli_samr_close(cli, mem_ctx, &domain_pol);
760 rpccli_samr_close(cli, mem_ctx, &connect_pol);
765 /* Enumerate domain users */
767 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
769 int argc, const char **argv)
771 POLICY_HND connect_pol, domain_pol;
772 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
773 uint32 start_idx, size, num_dom_users, i;
776 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
777 uint16 acb_mask = ACB_NORMAL;
778 BOOL got_connect_pol = False, got_domain_pol = False;
780 if ((argc < 1) || (argc > 3)) {
781 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
786 sscanf(argv[1], "%x", &access_mask);
789 sscanf(argv[2], "%hx", &acb_mask);
791 /* Get sam policy handle */
793 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
796 if (!NT_STATUS_IS_OK(result))
799 got_connect_pol = True;
801 /* Get domain policy handle */
803 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
805 &domain_sid, &domain_pol);
807 if (!NT_STATUS_IS_OK(result))
810 got_domain_pol = True;
812 /* Enumerate domain users */
818 result = rpccli_samr_enum_dom_users(
819 cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
820 size, &dom_users, &dom_rids, &num_dom_users);
822 if (NT_STATUS_IS_OK(result) ||
823 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
825 for (i = 0; i < num_dom_users; i++)
826 printf("user:[%s] rid:[0x%x]\n",
827 dom_users[i], dom_rids[i]);
830 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
834 rpccli_samr_close(cli, mem_ctx, &domain_pol);
837 rpccli_samr_close(cli, mem_ctx, &connect_pol);
842 /* Enumerate domain groups */
844 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
846 int argc, const char **argv)
848 POLICY_HND connect_pol, domain_pol;
849 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
850 uint32 start_idx, size, num_dom_groups, i;
851 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
852 struct acct_info *dom_groups;
853 BOOL got_connect_pol = False, got_domain_pol = False;
855 if ((argc < 1) || (argc > 2)) {
856 printf("Usage: %s [access_mask]\n", argv[0]);
861 sscanf(argv[1], "%x", &access_mask);
863 /* Get sam policy handle */
865 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
868 if (!NT_STATUS_IS_OK(result))
871 got_connect_pol = True;
873 /* Get domain policy handle */
875 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
877 &domain_sid, &domain_pol);
879 if (!NT_STATUS_IS_OK(result))
882 got_domain_pol = True;
884 /* Enumerate domain groups */
890 result = rpccli_samr_enum_dom_groups(
891 cli, mem_ctx, &domain_pol, &start_idx, size,
892 &dom_groups, &num_dom_groups);
894 if (NT_STATUS_IS_OK(result) ||
895 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
897 for (i = 0; i < num_dom_groups; i++)
898 printf("group:[%s] rid:[0x%x]\n",
899 dom_groups[i].acct_name,
903 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
907 rpccli_samr_close(cli, mem_ctx, &domain_pol);
910 rpccli_samr_close(cli, mem_ctx, &connect_pol);
915 /* Enumerate alias groups */
917 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
919 int argc, const char **argv)
921 POLICY_HND connect_pol, domain_pol;
922 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
923 uint32 start_idx, size, num_als_groups, i;
924 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
925 struct acct_info *als_groups;
926 BOOL got_connect_pol = False, got_domain_pol = False;
928 if ((argc < 2) || (argc > 3)) {
929 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
934 sscanf(argv[2], "%x", &access_mask);
936 /* Get sam policy handle */
938 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
941 if (!NT_STATUS_IS_OK(result))
944 got_connect_pol = True;
946 /* Get domain policy handle */
948 if (StrCaseCmp(argv[1], "domain")==0)
949 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
951 &domain_sid, &domain_pol);
952 else if (StrCaseCmp(argv[1], "builtin")==0)
953 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
955 &global_sid_Builtin, &domain_pol);
959 if (!NT_STATUS_IS_OK(result))
962 got_domain_pol = True;
964 /* Enumerate alias groups */
967 size = 0xffff; /* Number of groups to retrieve */
970 result = rpccli_samr_enum_als_groups(
971 cli, mem_ctx, &domain_pol, &start_idx, size,
972 &als_groups, &num_als_groups);
974 if (NT_STATUS_IS_OK(result) ||
975 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
977 for (i = 0; i < num_als_groups; i++)
978 printf("group:[%s] rid:[0x%x]\n",
979 als_groups[i].acct_name,
982 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
986 rpccli_samr_close(cli, mem_ctx, &domain_pol);
989 rpccli_samr_close(cli, mem_ctx, &connect_pol);
994 /* Query alias membership */
996 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
998 int argc, const char **argv)
1000 POLICY_HND connect_pol, domain_pol, alias_pol;
1001 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1002 uint32 alias_rid, num_members, i;
1003 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1004 DOM_SID *alias_sids;
1006 if ((argc < 3) || (argc > 4)) {
1007 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1008 return NT_STATUS_OK;
1011 sscanf(argv[2], "%i", &alias_rid);
1014 sscanf(argv[3], "%x", &access_mask);
1016 /* Open SAMR handle */
1018 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1021 if (!NT_STATUS_IS_OK(result))
1024 /* Open handle on domain */
1026 if (StrCaseCmp(argv[1], "domain")==0)
1027 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1028 MAXIMUM_ALLOWED_ACCESS,
1029 &domain_sid, &domain_pol);
1030 else if (StrCaseCmp(argv[1], "builtin")==0)
1031 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1032 MAXIMUM_ALLOWED_ACCESS,
1033 &global_sid_Builtin, &domain_pol);
1035 return NT_STATUS_OK;
1037 if (!NT_STATUS_IS_OK(result))
1040 /* Open handle on alias */
1042 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1044 alias_rid, &alias_pol);
1045 if (!NT_STATUS_IS_OK(result))
1048 result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
1049 &num_members, &alias_sids);
1051 if (!NT_STATUS_IS_OK(result))
1054 for (i = 0; i < num_members; i++) {
1057 sid_to_string(sid_str, &alias_sids[i]);
1058 printf("\tsid:[%s]\n", sid_str);
1061 rpccli_samr_close(cli, mem_ctx, &alias_pol);
1062 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1063 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1068 /* Query delete an alias membership */
1070 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1071 TALLOC_CTX *mem_ctx,
1072 int argc, const char **argv)
1074 POLICY_HND connect_pol, domain_pol, alias_pol;
1075 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1077 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1080 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1081 return NT_STATUS_OK;
1084 alias_rid = strtoul(argv[2], NULL, 10);
1086 /* Open SAMR handle */
1088 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1091 if (!NT_STATUS_IS_OK(result))
1094 /* Open handle on domain */
1096 if (StrCaseCmp(argv[1], "domain")==0)
1097 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1098 MAXIMUM_ALLOWED_ACCESS,
1099 &domain_sid, &domain_pol);
1100 else if (StrCaseCmp(argv[1], "builtin")==0)
1101 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1102 MAXIMUM_ALLOWED_ACCESS,
1103 &global_sid_Builtin, &domain_pol);
1105 return NT_STATUS_INVALID_PARAMETER;
1107 if (!NT_STATUS_IS_OK(result))
1110 /* Open handle on alias */
1112 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1114 alias_rid, &alias_pol);
1115 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1116 /* Probably this was a user name, try lookupnames */
1118 uint32 *rids, *types;
1120 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1125 if (NT_STATUS_IS_OK(result)) {
1126 result = rpccli_samr_open_alias(cli, mem_ctx,
1129 rids[0], &alias_pol);
1133 result = rpccli_samr_delete_dom_alias(cli, mem_ctx, &alias_pol);
1135 if (!NT_STATUS_IS_OK(result))
1138 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1139 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1144 /* Query display info */
1146 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1147 TALLOC_CTX *mem_ctx,
1148 int argc, const char **argv)
1150 POLICY_HND connect_pol, domain_pol;
1151 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1152 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
1153 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1154 uint32 info_level = 1;
1155 SAM_DISPINFO_CTR ctr;
1156 SAM_DISPINFO_1 info1;
1157 SAM_DISPINFO_2 info2;
1158 SAM_DISPINFO_3 info3;
1159 SAM_DISPINFO_4 info4;
1160 SAM_DISPINFO_5 info5;
1162 BOOL got_params = False; /* Use get_query_dispinfo_params() or not? */
1165 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1166 return NT_STATUS_OK;
1170 sscanf(argv[1], "%i", &info_level);
1173 sscanf(argv[2], "%i", &start_idx);
1176 sscanf(argv[3], "%i", &max_entries);
1181 sscanf(argv[4], "%i", &max_size);
1186 sscanf(argv[5], "%x", &access_mask);
1188 /* Get sam policy handle */
1190 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1193 if (!NT_STATUS_IS_OK(result))
1196 /* Get domain policy handle */
1198 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1200 &domain_sid, &domain_pol);
1202 if (!NT_STATUS_IS_OK(result))
1205 /* Query display info */
1210 switch (info_level) {
1213 ctr.sam.info1 = &info1;
1217 ctr.sam.info2 = &info2;
1221 ctr.sam.info3 = &info3;
1225 ctr.sam.info4 = &info4;
1229 ctr.sam.info5 = &info5;
1237 get_query_dispinfo_params(
1238 loop_count, &max_entries, &max_size);
1240 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1241 &start_idx, info_level,
1242 &num_entries, max_entries,
1247 if (NT_STATUS_IS_ERR(result))
1250 if (num_entries == 0)
1253 for (i = 0; i < num_entries; i++) {
1254 switch (info_level) {
1256 display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
1259 display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
1262 display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
1265 display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
1268 display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
1272 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1274 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1275 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1280 /* Query domain info */
1282 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1283 TALLOC_CTX *mem_ctx,
1284 int argc, const char **argv)
1286 POLICY_HND connect_pol, domain_pol;
1287 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1288 uint32 switch_level = 2;
1289 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1293 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1294 return NT_STATUS_OK;
1298 sscanf(argv[1], "%i", &switch_level);
1301 sscanf(argv[2], "%x", &access_mask);
1303 /* Get sam policy handle */
1305 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1308 if (!NT_STATUS_IS_OK(result))
1311 /* Get domain policy handle */
1313 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1315 &domain_sid, &domain_pol);
1317 if (!NT_STATUS_IS_OK(result))
1320 /* Query domain info */
1322 result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
1323 switch_level, &ctr);
1325 if (!NT_STATUS_IS_OK(result))
1328 /* Display domain info */
1330 switch (switch_level) {
1332 display_sam_unk_info_1(&ctr.info.inf1);
1335 display_sam_unk_info_2(&ctr.info.inf2);
1338 display_sam_unk_info_7(&ctr.info.inf7);
1341 display_sam_unk_info_8(&ctr.info.inf8);
1344 display_sam_unk_info_12(&ctr.info.inf12);
1347 printf("cannot display domain info for switch value %d\n",
1354 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1355 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1359 /* Create domain user */
1361 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1362 TALLOC_CTX *mem_ctx,
1363 int argc, const char **argv)
1365 POLICY_HND connect_pol, domain_pol, user_pol;
1366 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1367 const char *acct_name;
1369 uint32 unknown, user_rid;
1370 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1372 if ((argc < 2) || (argc > 3)) {
1373 printf("Usage: %s username [access mask]\n", argv[0]);
1374 return NT_STATUS_OK;
1377 acct_name = argv[1];
1380 sscanf(argv[2], "%x", &access_mask);
1382 /* Get sam policy handle */
1384 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1387 if (!NT_STATUS_IS_OK(result))
1390 /* Get domain policy handle */
1392 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1394 &domain_sid, &domain_pol);
1396 if (!NT_STATUS_IS_OK(result))
1399 /* Create domain user */
1401 acb_info = ACB_NORMAL;
1402 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
1404 result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1405 acct_name, acb_info, unknown,
1406 &user_pol, &user_rid);
1408 if (!NT_STATUS_IS_OK(result))
1411 result = rpccli_samr_close(cli, mem_ctx, &user_pol);
1412 if (!NT_STATUS_IS_OK(result)) goto done;
1414 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1415 if (!NT_STATUS_IS_OK(result)) goto done;
1417 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1418 if (!NT_STATUS_IS_OK(result)) goto done;
1424 /* Create domain group */
1426 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1427 TALLOC_CTX *mem_ctx,
1428 int argc, const char **argv)
1430 POLICY_HND connect_pol, domain_pol, group_pol;
1431 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1432 const char *grp_name;
1433 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1435 if ((argc < 2) || (argc > 3)) {
1436 printf("Usage: %s groupname [access mask]\n", argv[0]);
1437 return NT_STATUS_OK;
1443 sscanf(argv[2], "%x", &access_mask);
1445 /* Get sam policy handle */
1447 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1450 if (!NT_STATUS_IS_OK(result))
1453 /* Get domain policy handle */
1455 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1457 &domain_sid, &domain_pol);
1459 if (!NT_STATUS_IS_OK(result))
1462 /* Create domain user */
1464 result = rpccli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
1465 grp_name, MAXIMUM_ALLOWED_ACCESS,
1468 if (!NT_STATUS_IS_OK(result))
1471 result = rpccli_samr_close(cli, mem_ctx, &group_pol);
1472 if (!NT_STATUS_IS_OK(result)) goto done;
1474 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1475 if (!NT_STATUS_IS_OK(result)) goto done;
1477 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1478 if (!NT_STATUS_IS_OK(result)) goto done;
1484 /* Create domain alias */
1486 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1487 TALLOC_CTX *mem_ctx,
1488 int argc, const char **argv)
1490 POLICY_HND connect_pol, domain_pol, alias_pol;
1491 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1492 const char *alias_name;
1493 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1495 if ((argc < 2) || (argc > 3)) {
1496 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1497 return NT_STATUS_OK;
1500 alias_name = argv[1];
1503 sscanf(argv[2], "%x", &access_mask);
1505 /* Get sam policy handle */
1507 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1510 if (!NT_STATUS_IS_OK(result))
1513 /* Get domain policy handle */
1515 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1517 &domain_sid, &domain_pol);
1519 if (!NT_STATUS_IS_OK(result))
1522 /* Create domain user */
1524 result = rpccli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
1525 alias_name, &alias_pol);
1527 if (!NT_STATUS_IS_OK(result))
1530 result = rpccli_samr_close(cli, mem_ctx, &alias_pol);
1531 if (!NT_STATUS_IS_OK(result)) goto done;
1533 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1534 if (!NT_STATUS_IS_OK(result)) goto done;
1536 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1537 if (!NT_STATUS_IS_OK(result)) goto done;
1543 /* Lookup sam names */
1545 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1546 TALLOC_CTX *mem_ctx,
1547 int argc, const char **argv)
1549 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1550 POLICY_HND connect_pol, domain_pol;
1551 uint32 flags = 0x000003e8; /* Unknown */
1552 uint32 num_rids, num_names, *name_types, *rids;
1557 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1558 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1559 printf("or check on the builtin SID: S-1-5-32\n");
1560 return NT_STATUS_OK;
1563 /* Get sam policy and domain handles */
1565 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1568 if (!NT_STATUS_IS_OK(result))
1571 if (StrCaseCmp(argv[1], "domain")==0)
1572 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1573 MAXIMUM_ALLOWED_ACCESS,
1574 &domain_sid, &domain_pol);
1575 else if (StrCaseCmp(argv[1], "builtin")==0)
1576 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1577 MAXIMUM_ALLOWED_ACCESS,
1578 &global_sid_Builtin, &domain_pol);
1580 return NT_STATUS_OK;
1582 if (!NT_STATUS_IS_OK(result))
1587 num_names = argc - 2;
1588 names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
1590 for (i = 0; i < argc - 2; i++)
1591 names[i] = argv[i + 2];
1593 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1594 flags, num_names, names,
1595 &num_rids, &rids, &name_types);
1597 if (!NT_STATUS_IS_OK(result))
1600 /* Display results */
1602 for (i = 0; i < num_names; i++)
1603 printf("name %s: 0x%x (%d)\n", names[i], rids[i],
1606 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1607 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1612 /* Lookup sam rids */
1614 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1615 TALLOC_CTX *mem_ctx,
1616 int argc, const char **argv)
1618 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1619 POLICY_HND connect_pol, domain_pol;
1620 uint32 num_rids, num_names, *rids, *name_types;
1625 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1626 return NT_STATUS_OK;
1629 /* Get sam policy and domain handles */
1631 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1634 if (!NT_STATUS_IS_OK(result))
1637 if (StrCaseCmp(argv[1], "domain")==0)
1638 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1639 MAXIMUM_ALLOWED_ACCESS,
1640 &domain_sid, &domain_pol);
1641 else if (StrCaseCmp(argv[1], "builtin")==0)
1642 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1643 MAXIMUM_ALLOWED_ACCESS,
1644 &global_sid_Builtin, &domain_pol);
1646 return NT_STATUS_OK;
1648 if (!NT_STATUS_IS_OK(result))
1653 num_rids = argc - 2;
1654 rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
1656 for (i = 0; i < argc - 2; i++)
1657 sscanf(argv[i + 2], "%i", &rids[i]);
1659 result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
1660 &num_names, &names, &name_types);
1662 if (!NT_STATUS_IS_OK(result) &&
1663 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1666 /* Display results */
1668 for (i = 0; i < num_names; i++)
1669 printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
1671 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1672 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1677 /* Delete domain user */
1679 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
1680 TALLOC_CTX *mem_ctx,
1681 int argc, const char **argv)
1683 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1684 POLICY_HND connect_pol, domain_pol, user_pol;
1685 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1687 if ((argc < 2) || (argc > 3)) {
1688 printf("Usage: %s username\n", argv[0]);
1689 return NT_STATUS_OK;
1693 sscanf(argv[2], "%x", &access_mask);
1695 /* Get sam policy and domain handles */
1697 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1700 if (!NT_STATUS_IS_OK(result))
1703 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1704 MAXIMUM_ALLOWED_ACCESS,
1705 &domain_sid, &domain_pol);
1707 if (!NT_STATUS_IS_OK(result))
1710 /* Get handle on user */
1713 uint32 *user_rids, num_rids, *name_types;
1714 uint32 flags = 0x000003e8; /* Unknown */
1716 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1717 flags, 1, (const char **)&argv[1],
1718 &num_rids, &user_rids,
1721 if (!NT_STATUS_IS_OK(result))
1724 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1726 user_rids[0], &user_pol);
1728 if (!NT_STATUS_IS_OK(result))
1734 result = rpccli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
1736 if (!NT_STATUS_IS_OK(result))
1739 /* Display results */
1741 rpccli_samr_close(cli, mem_ctx, &user_pol);
1742 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1743 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1749 /**********************************************************************
1750 * Query user security object
1752 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
1753 TALLOC_CTX *mem_ctx,
1754 int argc, const char **argv)
1756 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
1757 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1758 uint32 info_level = 4;
1760 uint32 user_rid = 0;
1761 TALLOC_CTX *ctx = NULL;
1762 SEC_DESC_BUF *sec_desc_buf=NULL;
1763 BOOL domain = False;
1765 ctx=talloc_init("cmd_samr_query_sec_obj");
1767 if ((argc < 1) || (argc > 2)) {
1768 printf("Usage: %s [rid|-d]\n", argv[0]);
1769 printf("\tSpecify rid for security on user, -d for security on domain\n");
1770 return NT_STATUS_OK;
1774 if (strcmp(argv[1], "-d") == 0)
1777 sscanf(argv[1], "%i", &user_rid);
1780 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
1782 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1785 if (!NT_STATUS_IS_OK(result))
1788 if (domain || user_rid)
1789 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1790 MAXIMUM_ALLOWED_ACCESS,
1791 &domain_sid, &domain_pol);
1793 if (!NT_STATUS_IS_OK(result))
1797 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1798 MAXIMUM_ALLOWED_ACCESS,
1799 user_rid, &user_pol);
1801 if (!NT_STATUS_IS_OK(result))
1804 /* Pick which query pol to use */
1814 /* Query SAM security object */
1816 result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, info_level, ctx,
1819 if (!NT_STATUS_IS_OK(result))
1822 display_sec_desc(sec_desc_buf->sec);
1824 rpccli_samr_close(cli, mem_ctx, &user_pol);
1825 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1826 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1828 talloc_destroy(ctx);
1832 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
1833 TALLOC_CTX *mem_ctx,
1834 int argc, const char **argv)
1836 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1837 uint16 min_pwd_length;
1838 uint32 password_properties;
1841 printf("Usage: %s\n", argv[0]);
1842 return NT_STATUS_OK;
1845 result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &min_pwd_length, &password_properties) ;
1847 if (NT_STATUS_IS_OK(result)) {
1848 printf("min_pwd_length: %d\n", min_pwd_length);
1849 printf("password_properties: 0x%08x\n", password_properties);
1851 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
1852 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
1854 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
1855 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
1857 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
1858 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
1860 if (password_properties & DOMAIN_LOCKOUT_ADMINS)
1861 printf("\tDOMAIN_LOCKOUT_ADMINS\n");
1863 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
1864 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
1866 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
1867 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
1873 /* Look up domain name */
1875 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
1876 TALLOC_CTX *mem_ctx,
1877 int argc, const char **argv)
1879 POLICY_HND connect_pol, domain_pol;
1880 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1881 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1882 fstring domain_name,sid_string;
1886 printf("Usage: %s domain_name\n", argv[0]);
1887 return NT_STATUS_OK;
1890 sscanf(argv[1], "%s", domain_name);
1892 result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
1894 if (!NT_STATUS_IS_OK(result))
1897 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1898 access_mask, &domain_sid, &domain_pol);
1900 if (!NT_STATUS_IS_OK(result))
1903 result = rpccli_samr_lookup_domain(
1904 cli, mem_ctx, &connect_pol, domain_name, &sid);
1906 sid_to_string(sid_string,&sid);
1908 if (NT_STATUS_IS_OK(result))
1909 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
1910 domain_name,sid_string);
1912 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1913 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1919 /* List of commands exported by this module */
1921 struct cmd_set samr_commands[] = {
1925 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
1926 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
1927 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
1928 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
1929 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
1930 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
1931 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, PI_SAMR, NULL, "Delete an alias", "" },
1932 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
1933 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
1934 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
1935 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
1936 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
1938 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
1939 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
1940 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, PI_SAMR, NULL, "Create domain alias", "" },
1941 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
1942 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
1943 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
1944 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
1945 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
1947 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },