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_comment, 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%08x\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);
118 static void display_password_properties(uint32 password_properties)
120 printf("password_properties: 0x%08x\n", password_properties);
122 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
123 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
125 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
126 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
128 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
129 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
131 if (password_properties & DOMAIN_LOCKOUT_ADMINS)
132 printf("\tDOMAIN_LOCKOUT_ADMINS\n");
134 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
135 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
137 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
138 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
141 static void display_sam_unk_info_1(SAM_UNK_INFO_1 *info1)
144 printf("Minimum password length:\t\t\t%d\n", info1->min_length_password);
145 printf("Password uniqueness (remember x passwords):\t%d\n", info1->password_history);
146 display_password_properties(info1->password_properties);
147 printf("password expire in:\t\t\t\t%s\n", display_time(info1->expire));
148 printf("Min password age (allow changing in x days):\t%s\n", display_time(info1->min_passwordage));
151 static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
155 unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1);
156 printf("Domain:\t\t%s\n", name);
158 unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
159 printf("Server:\t\t%s\n", name);
161 unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1);
162 printf("Comment:\t%s\n", name);
164 printf("Total Users:\t%d\n", info2->num_domain_usrs);
165 printf("Total Groups:\t%d\n", info2->num_domain_grps);
166 printf("Total Aliases:\t%d\n", info2->num_local_grps);
168 printf("Sequence No:\t%lld\n", info2->seq_num);
170 printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
172 printf("Unknown 4:\t0x%x\n", info2->unknown_4);
173 printf("Server Role:\t%s\n", server_role_str(info2->server_role));
174 printf("Unknown 6:\t0x%x\n", info2->unknown_6);
177 static void display_sam_unk_info_3(SAM_UNK_INFO_3 *info3)
179 printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info3->logout));
182 static void display_sam_unk_info_4(SAM_UNK_INFO_4 *info4)
186 unistr2_to_ascii(name, &info4->uni_comment, sizeof(name) - 1);
187 printf("Comment:\t%s\n", name);
190 static void display_sam_unk_info_5(SAM_UNK_INFO_5 *info5)
194 unistr2_to_ascii(name, &info5->uni_domain, sizeof(name) - 1);
195 printf("Domain:\t\t%s\n", name);
198 static void display_sam_unk_info_6(SAM_UNK_INFO_6 *info6)
202 unistr2_to_ascii(name, &info6->uni_server, sizeof(name) - 1);
203 printf("Server:\t\t%s\n", name);
206 static void display_sam_unk_info_7(SAM_UNK_INFO_7 *info7)
208 printf("Server Role:\t%s\n", server_role_str(info7->server_role));
211 static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
213 printf("Sequence No:\t%lld\n", info8->seq_num);
214 printf("Domain Create Time:\t%s\n",
215 http_timestring(nt_time_to_unix(info8->domain_create_time)));
218 static void display_sam_unk_info_9(SAM_UNK_INFO_9 *info9)
220 printf("unknown:\t%d (0x%08x)\n", info9->unknown, info9->unknown);
223 static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
225 printf("Bad password lockout duration: %s\n", display_time(info12->duration));
226 printf("Reset Lockout after: %s\n", display_time(info12->reset_count));
227 printf("Lockout after bad attempts: %d\n", info12->bad_attempt_lockout);
230 static void display_sam_unk_info_13(SAM_UNK_INFO_13 *info13)
232 printf("Sequence No:\t%lld\n", info13->seq_num);
233 printf("Domain Create Time:\t%s\n",
234 http_timestring(nt_time_to_unix(info13->domain_create_time)));
235 printf("Unknown1:\t%d\n", info13->unknown1);
236 printf("Unknown2:\t%d\n", info13->unknown2);
240 static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
244 printf("index: 0x%x ", e1->user_idx);
245 printf("RID: 0x%x ", e1->rid_user);
246 printf("acb: 0x%x ", e1->acb_info);
248 unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
249 printf("Account: %s\t", tmp);
251 unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
252 printf("Name: %s\t", tmp);
254 unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
255 printf("Desc: %s\n", tmp);
258 static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
262 printf("index: 0x%x ", e2->user_idx);
263 printf("RID: 0x%x ", e2->rid_user);
264 printf("acb: 0x%x ", e2->acb_info);
266 unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
267 printf("Account: %s\t", tmp);
269 unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
270 printf("Name: %s\n", tmp);
274 static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
278 printf("index: 0x%x ", e3->grp_idx);
279 printf("RID: 0x%x ", e3->rid_grp);
280 printf("attr: 0x%x ", e3->attr);
282 unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
283 printf("Account: %s\t", tmp);
285 unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
286 printf("Name: %s\n", tmp);
290 static void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4)
294 printf("index: %d ", e4->user_idx);
297 for (i=0; i<s4->acct_name.str_str_len; i++)
298 printf("%c", s4->acct_name.buffer[i]);
303 static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
307 printf("index: 0x%x ", e5->grp_idx);
310 for (i=0; i<s5->grp_name.str_str_len; i++)
311 printf("%c", s5->grp_name.buffer[i]);
316 /****************************************************************************
317 Try samr_connect4 first, then samr_conenct if it fails
318 ****************************************************************************/
319 static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
320 uint32 access_mask, POLICY_HND *connect_pol)
322 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
324 result = rpccli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
325 if (!NT_STATUS_IS_OK(result)) {
326 result = rpccli_samr_connect(cli, mem_ctx, access_mask,
332 /**********************************************************************
333 * Query user information
335 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
337 int argc, const char **argv)
339 POLICY_HND connect_pol, domain_pol, user_pol;
340 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
341 uint32 info_level = 21;
342 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
343 SAM_USERINFO_CTR *user_ctr;
347 if ((argc < 2) || (argc > 4)) {
348 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
352 user_rid = strtoul(argv[1], NULL, 10);
355 sscanf(argv[2], "%i", &info_level);
358 sscanf(argv[3], "%x", &access_mask);
361 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
364 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
367 if (!NT_STATUS_IS_OK(result))
370 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
371 MAXIMUM_ALLOWED_ACCESS,
372 &domain_sid, &domain_pol);
374 if (!NT_STATUS_IS_OK(result))
377 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
379 user_rid, &user_pol);
381 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
384 /* Probably this was a user name, try lookupnames */
386 uint32 *rids, *types;
388 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
393 if (NT_STATUS_IS_OK(result)) {
394 result = rpccli_samr_open_user(cli, mem_ctx,
402 if (!NT_STATUS_IS_OK(result))
405 ZERO_STRUCT(user_ctr);
407 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
408 info_level, &user_ctr);
410 if (!NT_STATUS_IS_OK(result))
413 switch (user_ctr->switch_value) {
415 display_sam_user_info_21(user_ctr->info.id21);
418 display_sam_user_info_7(user_ctr->info.id7);
421 display_sam_user_info_9(user_ctr->info.id9);
424 printf("Unsupported infolevel: %d\n", info_level);
428 rpccli_samr_close(cli, mem_ctx, &user_pol);
429 rpccli_samr_close(cli, mem_ctx, &domain_pol);
430 rpccli_samr_close(cli, mem_ctx, &connect_pol);
436 /****************************************************************************
438 ****************************************************************************/
439 static void display_group_info1(GROUP_INFO1 *info1)
443 unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
444 printf("\tGroup Name:\t%s\n", temp);
445 unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
446 printf("\tDescription:\t%s\n", temp);
447 printf("\tGroup Attribute:%d\n", info1->group_attr);
448 printf("\tNum Members:%d\n", info1->num_members);
451 /****************************************************************************
453 ****************************************************************************/
454 static void display_group_info2(GROUP_INFO2 *info2)
458 unistr2_to_ascii(name, &info2->uni_acct_name, sizeof(name)-1);
459 printf("\tGroup Description:%s\n", name);
463 /****************************************************************************
465 ****************************************************************************/
466 static void display_group_info3(GROUP_INFO3 *info3)
468 printf("\tGroup Attribute:%d\n", info3->group_attr);
472 /****************************************************************************
474 ****************************************************************************/
475 static void display_group_info4(GROUP_INFO4 *info4)
479 unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
480 printf("\tGroup Description:%s\n", desc);
483 /****************************************************************************
485 ****************************************************************************/
486 static void display_group_info5(GROUP_INFO5 *info5)
490 unistr2_to_ascii(temp, &info5->uni_acct_name, sizeof(temp)-1);
491 printf("\tGroup Name:\t%s\n", temp);
492 unistr2_to_ascii(temp, &info5->uni_acct_desc, sizeof(temp)-1);
493 printf("\tDescription:\t%s\n", temp);
494 printf("\tGroup Attribute:%d\n", info5->group_attr);
495 printf("\tNum Members:%d\n", info5->num_members);
498 /****************************************************************************
499 display sam sync structure
500 ****************************************************************************/
501 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
503 switch (ctr->switch_value1) {
505 display_group_info1(&ctr->group.info1);
508 display_group_info2(&ctr->group.info2);
511 display_group_info3(&ctr->group.info3);
514 display_group_info4(&ctr->group.info4);
517 display_group_info5(&ctr->group.info5);
523 /***********************************************************************
524 * Query group information
526 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
528 int argc, const char **argv)
530 POLICY_HND connect_pol, domain_pol, group_pol;
531 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
532 uint32 info_level = 1;
533 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
534 GROUP_INFO_CTR *group_ctr;
538 if ((argc < 2) || (argc > 4)) {
539 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
543 sscanf(argv[1], "%i", &group_rid);
546 sscanf(argv[2], "%i", &info_level);
549 sscanf(argv[3], "%x", &access_mask);
551 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
554 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
557 if (!NT_STATUS_IS_OK(result))
560 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
561 MAXIMUM_ALLOWED_ACCESS,
562 &domain_sid, &domain_pol);
564 if (!NT_STATUS_IS_OK(result))
567 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
569 group_rid, &group_pol);
571 if (!NT_STATUS_IS_OK(result))
574 result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
575 info_level, &group_ctr);
576 if (!NT_STATUS_IS_OK(result)) {
580 display_group_info_ctr(group_ctr);
582 rpccli_samr_close(cli, mem_ctx, &group_pol);
583 rpccli_samr_close(cli, mem_ctx, &domain_pol);
584 rpccli_samr_close(cli, mem_ctx, &connect_pol);
589 /* Query groups a user is a member of */
591 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
593 int argc, const char **argv)
595 POLICY_HND connect_pol,
598 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
601 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
606 if ((argc < 2) || (argc > 3)) {
607 printf("Usage: %s rid [access mask]\n", argv[0]);
611 sscanf(argv[1], "%i", &user_rid);
614 sscanf(argv[2], "%x", &access_mask);
616 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
619 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
622 if (!NT_STATUS_IS_OK(result))
625 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
626 MAXIMUM_ALLOWED_ACCESS,
627 &domain_sid, &domain_pol);
629 if (!NT_STATUS_IS_OK(result))
632 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
634 user_rid, &user_pol);
636 if (!NT_STATUS_IS_OK(result))
639 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
640 &num_groups, &user_gids);
642 if (!NT_STATUS_IS_OK(result))
645 for (i = 0; i < num_groups; i++) {
646 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
647 user_gids[i].g_rid, user_gids[i].attr);
650 rpccli_samr_close(cli, mem_ctx, &user_pol);
651 rpccli_samr_close(cli, mem_ctx, &domain_pol);
652 rpccli_samr_close(cli, mem_ctx, &connect_pol);
657 /* Query aliases a user is a member of */
659 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
661 int argc, const char **argv)
663 POLICY_HND connect_pol, domain_pol;
664 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
667 uint32 num_aliases, *alias_rids;
668 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
674 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
675 return NT_STATUS_INVALID_PARAMETER;
681 for (i=2; i<argc; i++) {
683 if (!string_to_sid(&tmp_sid, argv[i])) {
684 printf("%s is not a legal SID\n", argv[i]);
685 return NT_STATUS_INVALID_PARAMETER;
687 add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
690 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
692 return NT_STATUS_NO_MEMORY;
694 for (i=0; i<num_sids; i++) {
695 sid_copy(&sid2[i].sid, &sids[i]);
696 sid2[i].num_auths = sid2[i].sid.num_auths;
699 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
702 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
705 if (!NT_STATUS_IS_OK(result))
708 if (StrCaseCmp(argv[1], "domain")==0)
709 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
711 &domain_sid, &domain_pol);
712 else if (StrCaseCmp(argv[1], "builtin")==0)
713 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
718 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
719 return NT_STATUS_INVALID_PARAMETER;
722 if (!NT_STATUS_IS_OK(result))
725 result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
727 &num_aliases, &alias_rids);
729 if (!NT_STATUS_IS_OK(result))
732 for (i = 0; i < num_aliases; i++) {
733 printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
736 rpccli_samr_close(cli, mem_ctx, &domain_pol);
737 rpccli_samr_close(cli, mem_ctx, &connect_pol);
742 /* Query members of a group */
744 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
746 int argc, const char **argv)
748 POLICY_HND connect_pol, domain_pol, group_pol;
749 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
750 uint32 num_members, *group_rids, *group_attrs, group_rid;
751 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
755 if ((argc < 2) || (argc > 3)) {
756 printf("Usage: %s rid [access mask]\n", argv[0]);
760 sscanf(argv[1], "%i", &group_rid);
763 sscanf(argv[2], "%x", &access_mask);
765 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
768 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
771 if (!NT_STATUS_IS_OK(result))
774 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
775 MAXIMUM_ALLOWED_ACCESS,
776 &domain_sid, &domain_pol);
778 if (!NT_STATUS_IS_OK(result))
781 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
783 group_rid, &group_pol);
785 if (!NT_STATUS_IS_OK(result))
788 result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
789 &num_members, &group_rids,
792 if (!NT_STATUS_IS_OK(result))
795 for (i = 0; i < num_members; i++) {
796 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
800 rpccli_samr_close(cli, mem_ctx, &group_pol);
801 rpccli_samr_close(cli, mem_ctx, &domain_pol);
802 rpccli_samr_close(cli, mem_ctx, &connect_pol);
807 /* Enumerate domain users */
809 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
811 int argc, const char **argv)
813 POLICY_HND connect_pol, domain_pol;
814 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
815 uint32 start_idx, size, num_dom_users, i;
818 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
819 uint32 acb_mask = ACB_NORMAL;
820 BOOL got_connect_pol = False, got_domain_pol = False;
822 if ((argc < 1) || (argc > 3)) {
823 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
828 sscanf(argv[1], "%x", &access_mask);
831 sscanf(argv[2], "%x", &acb_mask);
833 /* Get sam policy handle */
835 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
838 if (!NT_STATUS_IS_OK(result))
841 got_connect_pol = True;
843 /* Get domain policy handle */
845 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
847 &domain_sid, &domain_pol);
849 if (!NT_STATUS_IS_OK(result))
852 got_domain_pol = True;
854 /* Enumerate domain users */
860 result = rpccli_samr_enum_dom_users(
861 cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
862 size, &dom_users, &dom_rids, &num_dom_users);
864 if (NT_STATUS_IS_OK(result) ||
865 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
867 for (i = 0; i < num_dom_users; i++)
868 printf("user:[%s] rid:[0x%x]\n",
869 dom_users[i], dom_rids[i]);
872 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
876 rpccli_samr_close(cli, mem_ctx, &domain_pol);
879 rpccli_samr_close(cli, mem_ctx, &connect_pol);
884 /* Enumerate domain groups */
886 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
888 int argc, const char **argv)
890 POLICY_HND connect_pol, domain_pol;
891 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
892 uint32 start_idx, size, num_dom_groups, i;
893 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
894 struct acct_info *dom_groups;
895 BOOL got_connect_pol = False, got_domain_pol = False;
897 if ((argc < 1) || (argc > 2)) {
898 printf("Usage: %s [access_mask]\n", argv[0]);
903 sscanf(argv[1], "%x", &access_mask);
905 /* Get sam policy handle */
907 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
910 if (!NT_STATUS_IS_OK(result))
913 got_connect_pol = True;
915 /* Get domain policy handle */
917 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
919 &domain_sid, &domain_pol);
921 if (!NT_STATUS_IS_OK(result))
924 got_domain_pol = True;
926 /* Enumerate domain groups */
932 result = rpccli_samr_enum_dom_groups(
933 cli, mem_ctx, &domain_pol, &start_idx, size,
934 &dom_groups, &num_dom_groups);
936 if (NT_STATUS_IS_OK(result) ||
937 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
939 for (i = 0; i < num_dom_groups; i++)
940 printf("group:[%s] rid:[0x%x]\n",
941 dom_groups[i].acct_name,
945 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
949 rpccli_samr_close(cli, mem_ctx, &domain_pol);
952 rpccli_samr_close(cli, mem_ctx, &connect_pol);
957 /* Enumerate alias groups */
959 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
961 int argc, const char **argv)
963 POLICY_HND connect_pol, domain_pol;
964 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
965 uint32 start_idx, size, num_als_groups, i;
966 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
967 struct acct_info *als_groups;
968 BOOL got_connect_pol = False, got_domain_pol = False;
970 if ((argc < 2) || (argc > 3)) {
971 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
976 sscanf(argv[2], "%x", &access_mask);
978 /* Get sam policy handle */
980 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
983 if (!NT_STATUS_IS_OK(result))
986 got_connect_pol = True;
988 /* Get domain policy handle */
990 if (StrCaseCmp(argv[1], "domain")==0)
991 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
993 &domain_sid, &domain_pol);
994 else if (StrCaseCmp(argv[1], "builtin")==0)
995 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
997 &global_sid_Builtin, &domain_pol);
1001 if (!NT_STATUS_IS_OK(result))
1004 got_domain_pol = True;
1006 /* Enumerate alias groups */
1009 size = 0xffff; /* Number of groups to retrieve */
1012 result = rpccli_samr_enum_als_groups(
1013 cli, mem_ctx, &domain_pol, &start_idx, size,
1014 &als_groups, &num_als_groups);
1016 if (NT_STATUS_IS_OK(result) ||
1017 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1019 for (i = 0; i < num_als_groups; i++)
1020 printf("group:[%s] rid:[0x%x]\n",
1021 als_groups[i].acct_name,
1024 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1028 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1030 if (got_connect_pol)
1031 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1036 /* Query alias membership */
1038 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1039 TALLOC_CTX *mem_ctx,
1040 int argc, const char **argv)
1042 POLICY_HND connect_pol, domain_pol, alias_pol;
1043 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1044 uint32 alias_rid, num_members, i;
1045 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1046 DOM_SID *alias_sids;
1048 if ((argc < 3) || (argc > 4)) {
1049 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1050 return NT_STATUS_OK;
1053 sscanf(argv[2], "%i", &alias_rid);
1056 sscanf(argv[3], "%x", &access_mask);
1058 /* Open SAMR handle */
1060 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1063 if (!NT_STATUS_IS_OK(result))
1066 /* Open handle on domain */
1068 if (StrCaseCmp(argv[1], "domain")==0)
1069 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1070 MAXIMUM_ALLOWED_ACCESS,
1071 &domain_sid, &domain_pol);
1072 else if (StrCaseCmp(argv[1], "builtin")==0)
1073 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1074 MAXIMUM_ALLOWED_ACCESS,
1075 &global_sid_Builtin, &domain_pol);
1077 return NT_STATUS_OK;
1079 if (!NT_STATUS_IS_OK(result))
1082 /* Open handle on alias */
1084 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1086 alias_rid, &alias_pol);
1087 if (!NT_STATUS_IS_OK(result))
1090 result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
1091 &num_members, &alias_sids);
1093 if (!NT_STATUS_IS_OK(result))
1096 for (i = 0; i < num_members; i++) {
1099 sid_to_string(sid_str, &alias_sids[i]);
1100 printf("\tsid:[%s]\n", sid_str);
1103 rpccli_samr_close(cli, mem_ctx, &alias_pol);
1104 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1105 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1110 /* Query delete an alias membership */
1112 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1113 TALLOC_CTX *mem_ctx,
1114 int argc, const char **argv)
1116 POLICY_HND connect_pol, domain_pol, alias_pol;
1117 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1119 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1122 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1123 return NT_STATUS_OK;
1126 alias_rid = strtoul(argv[2], NULL, 10);
1128 /* Open SAMR handle */
1130 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1133 if (!NT_STATUS_IS_OK(result))
1136 /* Open handle on domain */
1138 if (StrCaseCmp(argv[1], "domain")==0)
1139 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1140 MAXIMUM_ALLOWED_ACCESS,
1141 &domain_sid, &domain_pol);
1142 else if (StrCaseCmp(argv[1], "builtin")==0)
1143 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1144 MAXIMUM_ALLOWED_ACCESS,
1145 &global_sid_Builtin, &domain_pol);
1147 return NT_STATUS_INVALID_PARAMETER;
1149 if (!NT_STATUS_IS_OK(result))
1152 /* Open handle on alias */
1154 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1156 alias_rid, &alias_pol);
1157 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1158 /* Probably this was a user name, try lookupnames */
1160 uint32 *rids, *types;
1162 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1167 if (NT_STATUS_IS_OK(result)) {
1168 result = rpccli_samr_open_alias(cli, mem_ctx,
1171 rids[0], &alias_pol);
1175 result = rpccli_samr_delete_dom_alias(cli, mem_ctx, &alias_pol);
1177 if (!NT_STATUS_IS_OK(result))
1180 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1181 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1186 /* Query display info */
1188 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1189 TALLOC_CTX *mem_ctx,
1190 int argc, const char **argv)
1192 POLICY_HND connect_pol, domain_pol;
1193 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1194 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
1195 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1196 uint32 info_level = 1;
1197 SAM_DISPINFO_CTR ctr;
1198 SAM_DISPINFO_1 info1;
1199 SAM_DISPINFO_2 info2;
1200 SAM_DISPINFO_3 info3;
1201 SAM_DISPINFO_4 info4;
1202 SAM_DISPINFO_5 info5;
1204 BOOL got_params = False; /* Use get_query_dispinfo_params() or not? */
1207 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1208 return NT_STATUS_OK;
1212 sscanf(argv[1], "%i", &info_level);
1215 sscanf(argv[2], "%i", &start_idx);
1218 sscanf(argv[3], "%i", &max_entries);
1223 sscanf(argv[4], "%i", &max_size);
1228 sscanf(argv[5], "%x", &access_mask);
1230 /* Get sam policy handle */
1232 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1235 if (!NT_STATUS_IS_OK(result))
1238 /* Get domain policy handle */
1240 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1242 &domain_sid, &domain_pol);
1244 if (!NT_STATUS_IS_OK(result))
1247 /* Query display info */
1252 switch (info_level) {
1255 ctr.sam.info1 = &info1;
1259 ctr.sam.info2 = &info2;
1263 ctr.sam.info3 = &info3;
1267 ctr.sam.info4 = &info4;
1271 ctr.sam.info5 = &info5;
1279 get_query_dispinfo_params(
1280 loop_count, &max_entries, &max_size);
1282 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1283 &start_idx, info_level,
1284 &num_entries, max_entries,
1289 if (NT_STATUS_IS_ERR(result))
1292 if (num_entries == 0)
1295 for (i = 0; i < num_entries; i++) {
1296 switch (info_level) {
1298 display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
1301 display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
1304 display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
1307 display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
1310 display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
1314 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1316 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1317 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1322 /* Query domain info */
1324 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1325 TALLOC_CTX *mem_ctx,
1326 int argc, const char **argv)
1328 POLICY_HND connect_pol, domain_pol;
1329 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1330 uint32 switch_level = 2;
1331 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1335 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1336 return NT_STATUS_OK;
1340 sscanf(argv[1], "%i", &switch_level);
1343 sscanf(argv[2], "%x", &access_mask);
1345 /* Get sam policy handle */
1347 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1350 if (!NT_STATUS_IS_OK(result))
1353 /* Get domain policy handle */
1355 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1357 &domain_sid, &domain_pol);
1359 if (!NT_STATUS_IS_OK(result))
1362 /* Query domain info */
1364 result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
1365 switch_level, &ctr);
1367 if (!NT_STATUS_IS_OK(result))
1370 /* Display domain info */
1372 switch (switch_level) {
1374 display_sam_unk_info_1(&ctr.info.inf1);
1377 display_sam_unk_info_2(&ctr.info.inf2);
1380 display_sam_unk_info_3(&ctr.info.inf3);
1383 display_sam_unk_info_4(&ctr.info.inf4);
1386 display_sam_unk_info_5(&ctr.info.inf5);
1389 display_sam_unk_info_6(&ctr.info.inf6);
1392 display_sam_unk_info_7(&ctr.info.inf7);
1395 display_sam_unk_info_8(&ctr.info.inf8);
1398 display_sam_unk_info_9(&ctr.info.inf9);
1401 display_sam_unk_info_12(&ctr.info.inf12);
1404 display_sam_unk_info_13(&ctr.info.inf13);
1408 printf("cannot display domain info for switch value %d\n",
1415 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1416 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1420 /* Create domain user */
1422 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1423 TALLOC_CTX *mem_ctx,
1424 int argc, const char **argv)
1426 POLICY_HND connect_pol, domain_pol, user_pol;
1427 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1428 const char *acct_name;
1430 uint32 unknown, user_rid;
1431 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1433 if ((argc < 2) || (argc > 3)) {
1434 printf("Usage: %s username [access mask]\n", argv[0]);
1435 return NT_STATUS_OK;
1438 acct_name = argv[1];
1441 sscanf(argv[2], "%x", &access_mask);
1443 /* Get sam policy handle */
1445 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1448 if (!NT_STATUS_IS_OK(result))
1451 /* Get domain policy handle */
1453 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1455 &domain_sid, &domain_pol);
1457 if (!NT_STATUS_IS_OK(result))
1460 /* Create domain user */
1462 acb_info = ACB_NORMAL;
1463 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
1465 result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1466 acct_name, acb_info, unknown,
1467 &user_pol, &user_rid);
1469 if (!NT_STATUS_IS_OK(result))
1472 result = rpccli_samr_close(cli, mem_ctx, &user_pol);
1473 if (!NT_STATUS_IS_OK(result)) goto done;
1475 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1476 if (!NT_STATUS_IS_OK(result)) goto done;
1478 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1479 if (!NT_STATUS_IS_OK(result)) goto done;
1485 /* Create domain group */
1487 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1488 TALLOC_CTX *mem_ctx,
1489 int argc, const char **argv)
1491 POLICY_HND connect_pol, domain_pol, group_pol;
1492 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1493 const char *grp_name;
1494 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1496 if ((argc < 2) || (argc > 3)) {
1497 printf("Usage: %s groupname [access mask]\n", argv[0]);
1498 return NT_STATUS_OK;
1504 sscanf(argv[2], "%x", &access_mask);
1506 /* Get sam policy handle */
1508 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1511 if (!NT_STATUS_IS_OK(result))
1514 /* Get domain policy handle */
1516 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1518 &domain_sid, &domain_pol);
1520 if (!NT_STATUS_IS_OK(result))
1523 /* Create domain user */
1525 result = rpccli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
1526 grp_name, MAXIMUM_ALLOWED_ACCESS,
1529 if (!NT_STATUS_IS_OK(result))
1532 result = rpccli_samr_close(cli, mem_ctx, &group_pol);
1533 if (!NT_STATUS_IS_OK(result)) goto done;
1535 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1536 if (!NT_STATUS_IS_OK(result)) goto done;
1538 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1539 if (!NT_STATUS_IS_OK(result)) goto done;
1545 /* Create domain alias */
1547 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1548 TALLOC_CTX *mem_ctx,
1549 int argc, const char **argv)
1551 POLICY_HND connect_pol, domain_pol, alias_pol;
1552 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1553 const char *alias_name;
1554 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1556 if ((argc < 2) || (argc > 3)) {
1557 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1558 return NT_STATUS_OK;
1561 alias_name = argv[1];
1564 sscanf(argv[2], "%x", &access_mask);
1566 /* Get sam policy handle */
1568 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1571 if (!NT_STATUS_IS_OK(result))
1574 /* Get domain policy handle */
1576 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1578 &domain_sid, &domain_pol);
1580 if (!NT_STATUS_IS_OK(result))
1583 /* Create domain user */
1585 result = rpccli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
1586 alias_name, &alias_pol);
1588 if (!NT_STATUS_IS_OK(result))
1591 result = rpccli_samr_close(cli, mem_ctx, &alias_pol);
1592 if (!NT_STATUS_IS_OK(result)) goto done;
1594 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1595 if (!NT_STATUS_IS_OK(result)) goto done;
1597 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1598 if (!NT_STATUS_IS_OK(result)) goto done;
1604 /* Lookup sam names */
1606 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1607 TALLOC_CTX *mem_ctx,
1608 int argc, const char **argv)
1610 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1611 POLICY_HND connect_pol, domain_pol;
1612 uint32 flags = 0x000003e8; /* Unknown */
1613 uint32 num_rids, num_names, *name_types, *rids;
1618 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1619 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1620 printf("or check on the builtin SID: S-1-5-32\n");
1621 return NT_STATUS_OK;
1624 /* Get sam policy and domain handles */
1626 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1629 if (!NT_STATUS_IS_OK(result))
1632 if (StrCaseCmp(argv[1], "domain")==0)
1633 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1634 MAXIMUM_ALLOWED_ACCESS,
1635 &domain_sid, &domain_pol);
1636 else if (StrCaseCmp(argv[1], "builtin")==0)
1637 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1638 MAXIMUM_ALLOWED_ACCESS,
1639 &global_sid_Builtin, &domain_pol);
1641 return NT_STATUS_OK;
1643 if (!NT_STATUS_IS_OK(result))
1648 num_names = argc - 2;
1649 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
1650 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1651 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1652 result = NT_STATUS_NO_MEMORY;
1656 for (i = 0; i < argc - 2; i++)
1657 names[i] = argv[i + 2];
1659 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1660 flags, num_names, names,
1661 &num_rids, &rids, &name_types);
1663 if (!NT_STATUS_IS_OK(result))
1666 /* Display results */
1668 for (i = 0; i < num_names; i++)
1669 printf("name %s: 0x%x (%d)\n", names[i], rids[i],
1672 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1673 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1678 /* Lookup sam rids */
1680 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1681 TALLOC_CTX *mem_ctx,
1682 int argc, const char **argv)
1684 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1685 POLICY_HND connect_pol, domain_pol;
1686 uint32 num_rids, num_names, *rids, *name_types;
1691 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1692 return NT_STATUS_OK;
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 if (StrCaseCmp(argv[1], "domain")==0)
1704 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1705 MAXIMUM_ALLOWED_ACCESS,
1706 &domain_sid, &domain_pol);
1707 else if (StrCaseCmp(argv[1], "builtin")==0)
1708 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1709 MAXIMUM_ALLOWED_ACCESS,
1710 &global_sid_Builtin, &domain_pol);
1712 return NT_STATUS_OK;
1714 if (!NT_STATUS_IS_OK(result))
1719 num_rids = argc - 2;
1720 rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
1721 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1722 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1723 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1724 result = NT_STATUS_NO_MEMORY;
1728 for (i = 0; i < argc - 2; i++)
1729 sscanf(argv[i + 2], "%i", &rids[i]);
1731 result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
1732 &num_names, &names, &name_types);
1734 if (!NT_STATUS_IS_OK(result) &&
1735 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1738 /* Display results */
1740 for (i = 0; i < num_names; i++)
1741 printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
1743 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1744 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1749 /* Delete domain user */
1751 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
1752 TALLOC_CTX *mem_ctx,
1753 int argc, const char **argv)
1755 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1756 POLICY_HND connect_pol, domain_pol, user_pol;
1757 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1759 if ((argc < 2) || (argc > 3)) {
1760 printf("Usage: %s username\n", argv[0]);
1761 return NT_STATUS_OK;
1765 sscanf(argv[2], "%x", &access_mask);
1767 /* Get sam policy and domain handles */
1769 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1772 if (!NT_STATUS_IS_OK(result))
1775 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1776 MAXIMUM_ALLOWED_ACCESS,
1777 &domain_sid, &domain_pol);
1779 if (!NT_STATUS_IS_OK(result))
1782 /* Get handle on user */
1785 uint32 *user_rids, num_rids, *name_types;
1786 uint32 flags = 0x000003e8; /* Unknown */
1788 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1789 flags, 1, (const char **)&argv[1],
1790 &num_rids, &user_rids,
1793 if (!NT_STATUS_IS_OK(result))
1796 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1798 user_rids[0], &user_pol);
1800 if (!NT_STATUS_IS_OK(result))
1806 result = rpccli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
1808 if (!NT_STATUS_IS_OK(result))
1811 /* Display results */
1813 rpccli_samr_close(cli, mem_ctx, &user_pol);
1814 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1815 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1821 /**********************************************************************
1822 * Query user security object
1824 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
1825 TALLOC_CTX *mem_ctx,
1826 int argc, const char **argv)
1828 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
1829 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1830 uint32 sec_info = DACL_SECURITY_INFORMATION;
1832 uint32 user_rid = 0;
1833 TALLOC_CTX *ctx = NULL;
1834 SEC_DESC_BUF *sec_desc_buf=NULL;
1835 BOOL domain = False;
1837 ctx=talloc_init("cmd_samr_query_sec_obj");
1839 if ((argc < 1) || (argc > 3)) {
1840 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
1841 printf("\tSpecify rid for security on user, -d for security on domain\n");
1842 return NT_STATUS_OK;
1846 if (strcmp(argv[1], "-d") == 0)
1849 sscanf(argv[1], "%i", &user_rid);
1853 sec_info = atoi(argv[2]);
1856 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
1858 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1861 if (!NT_STATUS_IS_OK(result))
1864 if (domain || user_rid)
1865 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1866 MAXIMUM_ALLOWED_ACCESS,
1867 &domain_sid, &domain_pol);
1869 if (!NT_STATUS_IS_OK(result))
1873 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1874 MAXIMUM_ALLOWED_ACCESS,
1875 user_rid, &user_pol);
1877 if (!NT_STATUS_IS_OK(result))
1880 /* Pick which query pol to use */
1890 /* Query SAM security object */
1892 result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, sec_info, ctx,
1895 if (!NT_STATUS_IS_OK(result))
1898 display_sec_desc(sec_desc_buf->sec);
1900 rpccli_samr_close(cli, mem_ctx, &user_pol);
1901 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1902 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1904 talloc_destroy(ctx);
1908 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
1909 TALLOC_CTX *mem_ctx,
1910 int argc, const char **argv)
1912 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1913 POLICY_HND connect_pol, domain_pol, user_pol;
1914 uint16 min_pwd_length;
1915 uint32 password_properties, unknown1, rid;
1918 printf("Usage: %s rid\n", argv[0]);
1919 return NT_STATUS_OK;
1922 sscanf(argv[1], "%i", &rid);
1924 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1927 if (!NT_STATUS_IS_OK(result)) {
1931 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1932 MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol);
1934 if (!NT_STATUS_IS_OK(result)) {
1938 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1939 MAXIMUM_ALLOWED_ACCESS,
1942 if (!NT_STATUS_IS_OK(result)) {
1946 result = rpccli_samr_get_usrdom_pwinfo(cli, mem_ctx, &user_pol,
1947 &min_pwd_length, &password_properties,
1950 if (NT_STATUS_IS_OK(result)) {
1951 printf("min_pwd_length: %d\n", min_pwd_length);
1952 printf("unknown1: %d\n", unknown1);
1953 display_password_properties(password_properties);
1957 rpccli_samr_close(cli, mem_ctx, &user_pol);
1958 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1959 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1965 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
1966 TALLOC_CTX *mem_ctx,
1967 int argc, const char **argv)
1969 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1970 uint16 min_pwd_length;
1971 uint32 password_properties;
1974 printf("Usage: %s\n", argv[0]);
1975 return NT_STATUS_OK;
1978 result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &min_pwd_length, &password_properties) ;
1980 if (NT_STATUS_IS_OK(result)) {
1981 printf("min_pwd_length: %d\n", min_pwd_length);
1982 display_password_properties(password_properties);
1988 /* Look up domain name */
1990 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
1991 TALLOC_CTX *mem_ctx,
1992 int argc, const char **argv)
1994 POLICY_HND connect_pol, domain_pol;
1995 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1996 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1997 fstring domain_name,sid_string;
2001 printf("Usage: %s domain_name\n", argv[0]);
2002 return NT_STATUS_OK;
2005 sscanf(argv[1], "%s", domain_name);
2007 result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
2009 if (!NT_STATUS_IS_OK(result))
2012 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
2013 access_mask, &domain_sid, &domain_pol);
2015 if (!NT_STATUS_IS_OK(result))
2018 result = rpccli_samr_lookup_domain(
2019 cli, mem_ctx, &connect_pol, domain_name, &sid);
2021 sid_to_string(sid_string,&sid);
2023 if (NT_STATUS_IS_OK(result))
2024 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2025 domain_name,sid_string);
2027 rpccli_samr_close(cli, mem_ctx, &domain_pol);
2028 rpccli_samr_close(cli, mem_ctx, &connect_pol);
2033 /* Change user password */
2035 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2036 TALLOC_CTX *mem_ctx,
2037 int argc, const char **argv)
2039 POLICY_HND connect_pol, domain_pol;
2040 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2041 const char *user, *oldpass, *newpass;
2042 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2043 SAM_UNK_INFO_1 info;
2044 SAMR_CHANGE_REJECT reject;
2047 printf("Usage: %s username oldpass newpass\n", argv[0]);
2048 return NT_STATUS_INVALID_PARAMETER;
2055 /* Get sam policy handle */
2057 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2060 if (!NT_STATUS_IS_OK(result))
2063 /* Get domain policy handle */
2065 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
2067 &domain_sid, &domain_pol);
2069 if (!NT_STATUS_IS_OK(result))
2072 /* Change user password */
2073 result = rpccli_samr_chgpasswd3(cli, mem_ctx, user, newpass, oldpass, &info, &reject);
2075 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2077 display_sam_unk_info_1(&info);
2079 switch (reject.reject_reason) {
2080 case REJECT_REASON_TOO_SHORT:
2081 d_printf("REJECT_REASON_TOO_SHORT\n");
2083 case REJECT_REASON_IN_HISTORY:
2084 d_printf("REJECT_REASON_IN_HISTORY\n");
2086 case REJECT_REASON_NOT_COMPLEX:
2087 d_printf("REJECT_REASON_NOT_COMPLEX\n");
2089 case REJECT_REASON_OTHER:
2090 d_printf("REJECT_REASON_OTHER\n");
2093 d_printf("unknown reject reason: %d\n", reject.reject_reason);
2098 if (!NT_STATUS_IS_OK(result))
2101 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
2102 if (!NT_STATUS_IS_OK(result)) goto done;
2104 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
2105 if (!NT_STATUS_IS_OK(result)) goto done;
2111 /* List of commands exported by this module */
2113 struct cmd_set samr_commands[] = {
2117 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
2118 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
2119 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
2120 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
2121 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
2122 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
2123 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, PI_SAMR, NULL, "Delete an alias", "" },
2124 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
2125 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
2126 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
2127 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
2128 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
2130 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
2131 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
2132 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, PI_SAMR, NULL, "Create domain alias", "" },
2133 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
2134 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
2135 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
2136 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
2137 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2138 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2140 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2141 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, PI_SAMR, NULL, "Change user password", "" },