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_password_properties(uint32 password_properties)
154 printf("password_properties: 0x%08x\n", password_properties);
156 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
157 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
159 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
160 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
162 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
163 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
165 if (password_properties & DOMAIN_LOCKOUT_ADMINS)
166 printf("\tDOMAIN_LOCKOUT_ADMINS\n");
168 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
169 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
171 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
172 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
175 static void display_sam_unk_info_1(SAM_UNK_INFO_1 *info1)
178 printf("Minimum password length:\t\t\t%d\n", info1->min_length_password);
179 printf("Password uniqueness (remember x passwords):\t%d\n", info1->password_history);
180 display_password_properties(info1->password_properties);
181 printf("password expire in:\t\t\t\t%s\n", display_time(info1->expire));
182 printf("Min password age (allow changing in x days):\t%s\n", display_time(info1->min_passwordage));
185 static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
189 unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1);
190 printf("Domain:\t\t%s\n", name);
192 unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
193 printf("Server:\t\t%s\n", name);
195 unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1);
196 printf("Comment:\t%s\n", name);
198 printf("Total Users:\t%d\n", info2->num_domain_usrs);
199 printf("Total Groups:\t%d\n", info2->num_domain_grps);
200 printf("Total Aliases:\t%d\n", info2->num_local_grps);
202 printf("Sequence No:\t%d\n", info2->seq_num.low);
204 printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
206 printf("Unknown 4:\t0x%x\n", info2->unknown_4);
207 printf("Server Role:\t%s\n", server_role_str(info2->server_role));
208 printf("Unknown 6:\t0x%x\n", info2->unknown_6);
211 static void display_sam_unk_info_7(SAM_UNK_INFO_7 *info7)
213 printf("Server Role:\t%s\n", server_role_str(info7->server_role));
216 static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
218 printf("Sequence No:\t%d\n", info8->seq_num.low);
219 printf("Domain Create Time:\t%s\n",
220 http_timestring(nt_time_to_unix(&info8->domain_create_time)));
224 static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
226 printf("Bad password lockout duration: %s\n", display_time(info12->duration));
227 printf("Reset Lockout after: %s\n", display_time(info12->reset_count));
228 printf("Lockout after bad attempts: %d\n", info12->bad_attempt_lockout);
231 static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
235 printf("index: 0x%x ", e1->user_idx);
236 printf("RID: 0x%x ", e1->rid_user);
237 printf("acb: 0x%x ", e1->acb_info);
239 unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
240 printf("Account: %s\t", tmp);
242 unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
243 printf("Name: %s\t", tmp);
245 unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
246 printf("Desc: %s\n", tmp);
249 static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
253 printf("index: 0x%x ", e2->user_idx);
254 printf("RID: 0x%x ", e2->rid_user);
255 printf("acb: 0x%x ", e2->acb_info);
257 unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
258 printf("Account: %s\t", tmp);
260 unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
261 printf("Name: %s\n", tmp);
265 static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
269 printf("index: 0x%x ", e3->grp_idx);
270 printf("RID: 0x%x ", e3->rid_grp);
271 printf("attr: 0x%x ", e3->attr);
273 unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
274 printf("Account: %s\t", tmp);
276 unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
277 printf("Name: %s\n", tmp);
281 static void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4)
285 printf("index: %d ", e4->user_idx);
288 for (i=0; i<s4->acct_name.str_str_len; i++)
289 printf("%c", s4->acct_name.buffer[i]);
294 static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
298 printf("index: 0x%x ", e5->grp_idx);
301 for (i=0; i<s5->grp_name.str_str_len; i++)
302 printf("%c", s5->grp_name.buffer[i]);
307 /****************************************************************************
308 Try samr_connect4 first, then samr_conenct if it fails
309 ****************************************************************************/
310 static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
311 uint32 access_mask, POLICY_HND *connect_pol)
313 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
315 result = rpccli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
316 if (!NT_STATUS_IS_OK(result)) {
317 result = rpccli_samr_connect(cli, mem_ctx, access_mask,
323 /**********************************************************************
324 * Query user information
326 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
328 int argc, const char **argv)
330 POLICY_HND connect_pol, domain_pol, user_pol;
331 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
332 uint32 info_level = 21;
333 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
334 SAM_USERINFO_CTR *user_ctr;
338 if ((argc < 2) || (argc > 4)) {
339 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
343 user_rid = strtoul(argv[1], NULL, 10);
346 sscanf(argv[2], "%i", &info_level);
349 sscanf(argv[3], "%x", &access_mask);
352 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
355 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
358 if (!NT_STATUS_IS_OK(result))
361 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
362 MAXIMUM_ALLOWED_ACCESS,
363 &domain_sid, &domain_pol);
365 if (!NT_STATUS_IS_OK(result))
368 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
370 user_rid, &user_pol);
372 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
375 /* Probably this was a user name, try lookupnames */
377 uint32 *rids, *types;
379 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
384 if (NT_STATUS_IS_OK(result)) {
385 result = rpccli_samr_open_user(cli, mem_ctx,
393 if (!NT_STATUS_IS_OK(result))
396 ZERO_STRUCT(user_ctr);
398 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
399 info_level, &user_ctr);
401 if (!NT_STATUS_IS_OK(result))
404 switch (user_ctr->switch_value) {
406 display_sam_user_info_21(user_ctr->info.id21);
409 display_sam_user_info_7(user_ctr->info.id7);
412 display_sam_user_info_9(user_ctr->info.id9);
415 printf("Unsupported infolevel: %d\n", info_level);
419 rpccli_samr_close(cli, mem_ctx, &user_pol);
420 rpccli_samr_close(cli, mem_ctx, &domain_pol);
421 rpccli_samr_close(cli, mem_ctx, &connect_pol);
427 /****************************************************************************
429 ****************************************************************************/
430 static void display_group_info1(GROUP_INFO1 *info1)
434 unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
435 printf("\tGroup Name:\t%s\n", temp);
436 unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
437 printf("\tDescription:\t%s\n", temp);
438 printf("\tGroup Attribute:%d\n", info1->group_attr);
439 printf("\tNum Members:%d\n", info1->num_members);
442 /****************************************************************************
444 ****************************************************************************/
445 static void display_group_info3(GROUP_INFO3 *info3)
447 printf("\tGroup Attribute:%d\n", info3->group_attr);
451 /****************************************************************************
453 ****************************************************************************/
454 static void display_group_info4(GROUP_INFO4 *info4)
458 unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
459 printf("\tGroup Description:%s\n", desc);
462 /****************************************************************************
463 display sam sync structure
464 ****************************************************************************/
465 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
467 switch (ctr->switch_value1) {
469 display_group_info1(&ctr->group.info1);
473 display_group_info3(&ctr->group.info3);
477 display_group_info4(&ctr->group.info4);
483 /***********************************************************************
484 * Query group information
486 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
488 int argc, const char **argv)
490 POLICY_HND connect_pol, domain_pol, group_pol;
491 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
492 uint32 info_level = 1;
493 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
494 GROUP_INFO_CTR *group_ctr;
498 if ((argc < 2) || (argc > 4)) {
499 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
503 sscanf(argv[1], "%i", &group_rid);
506 sscanf(argv[2], "%i", &info_level);
509 sscanf(argv[3], "%x", &access_mask);
511 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
514 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
517 if (!NT_STATUS_IS_OK(result))
520 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
521 MAXIMUM_ALLOWED_ACCESS,
522 &domain_sid, &domain_pol);
524 if (!NT_STATUS_IS_OK(result))
527 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
529 group_rid, &group_pol);
531 if (!NT_STATUS_IS_OK(result))
534 result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
535 info_level, &group_ctr);
536 if (!NT_STATUS_IS_OK(result)) {
540 display_group_info_ctr(group_ctr);
542 rpccli_samr_close(cli, mem_ctx, &group_pol);
543 rpccli_samr_close(cli, mem_ctx, &domain_pol);
544 rpccli_samr_close(cli, mem_ctx, &connect_pol);
549 /* Query groups a user is a member of */
551 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
553 int argc, const char **argv)
555 POLICY_HND connect_pol,
558 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
561 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
566 if ((argc < 2) || (argc > 3)) {
567 printf("Usage: %s rid [access mask]\n", argv[0]);
571 sscanf(argv[1], "%i", &user_rid);
574 sscanf(argv[2], "%x", &access_mask);
576 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
579 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
582 if (!NT_STATUS_IS_OK(result))
585 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
586 MAXIMUM_ALLOWED_ACCESS,
587 &domain_sid, &domain_pol);
589 if (!NT_STATUS_IS_OK(result))
592 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
594 user_rid, &user_pol);
596 if (!NT_STATUS_IS_OK(result))
599 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
600 &num_groups, &user_gids);
602 if (!NT_STATUS_IS_OK(result))
605 for (i = 0; i < num_groups; i++) {
606 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
607 user_gids[i].g_rid, user_gids[i].attr);
610 rpccli_samr_close(cli, mem_ctx, &user_pol);
611 rpccli_samr_close(cli, mem_ctx, &domain_pol);
612 rpccli_samr_close(cli, mem_ctx, &connect_pol);
617 /* Query aliases a user is a member of */
619 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
621 int argc, const char **argv)
623 POLICY_HND connect_pol, domain_pol;
624 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
627 uint32 num_aliases, *alias_rids;
628 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
634 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
635 return NT_STATUS_INVALID_PARAMETER;
641 for (i=2; i<argc; i++) {
643 if (!string_to_sid(&tmp_sid, argv[i])) {
644 printf("%s is not a legal SID\n", argv[i]);
645 return NT_STATUS_INVALID_PARAMETER;
647 add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
650 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
652 return NT_STATUS_NO_MEMORY;
654 for (i=0; i<num_sids; i++) {
655 sid_copy(&sid2[i].sid, &sids[i]);
656 sid2[i].num_auths = sid2[i].sid.num_auths;
659 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
662 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
665 if (!NT_STATUS_IS_OK(result))
668 if (StrCaseCmp(argv[1], "domain")==0)
669 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
671 &domain_sid, &domain_pol);
672 else if (StrCaseCmp(argv[1], "builtin")==0)
673 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
678 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
679 return NT_STATUS_INVALID_PARAMETER;
682 if (!NT_STATUS_IS_OK(result))
685 result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
687 &num_aliases, &alias_rids);
689 if (!NT_STATUS_IS_OK(result))
692 for (i = 0; i < num_aliases; i++) {
693 printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
696 rpccli_samr_close(cli, mem_ctx, &domain_pol);
697 rpccli_samr_close(cli, mem_ctx, &connect_pol);
702 /* Query members of a group */
704 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
706 int argc, const char **argv)
708 POLICY_HND connect_pol, domain_pol, group_pol;
709 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
710 uint32 num_members, *group_rids, *group_attrs, group_rid;
711 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
715 if ((argc < 2) || (argc > 3)) {
716 printf("Usage: %s rid [access mask]\n", argv[0]);
720 sscanf(argv[1], "%i", &group_rid);
723 sscanf(argv[2], "%x", &access_mask);
725 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
728 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
731 if (!NT_STATUS_IS_OK(result))
734 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
735 MAXIMUM_ALLOWED_ACCESS,
736 &domain_sid, &domain_pol);
738 if (!NT_STATUS_IS_OK(result))
741 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
743 group_rid, &group_pol);
745 if (!NT_STATUS_IS_OK(result))
748 result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
749 &num_members, &group_rids,
752 if (!NT_STATUS_IS_OK(result))
755 for (i = 0; i < num_members; i++) {
756 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
760 rpccli_samr_close(cli, mem_ctx, &group_pol);
761 rpccli_samr_close(cli, mem_ctx, &domain_pol);
762 rpccli_samr_close(cli, mem_ctx, &connect_pol);
767 /* Enumerate domain users */
769 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
771 int argc, const char **argv)
773 POLICY_HND connect_pol, domain_pol;
774 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
775 uint32 start_idx, size, num_dom_users, i;
778 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
779 uint16 acb_mask = ACB_NORMAL;
780 BOOL got_connect_pol = False, got_domain_pol = False;
782 if ((argc < 1) || (argc > 3)) {
783 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
788 sscanf(argv[1], "%x", &access_mask);
791 sscanf(argv[2], "%hx", &acb_mask);
793 /* Get sam policy handle */
795 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
798 if (!NT_STATUS_IS_OK(result))
801 got_connect_pol = True;
803 /* Get domain policy handle */
805 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
807 &domain_sid, &domain_pol);
809 if (!NT_STATUS_IS_OK(result))
812 got_domain_pol = True;
814 /* Enumerate domain users */
820 result = rpccli_samr_enum_dom_users(
821 cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
822 size, &dom_users, &dom_rids, &num_dom_users);
824 if (NT_STATUS_IS_OK(result) ||
825 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
827 for (i = 0; i < num_dom_users; i++)
828 printf("user:[%s] rid:[0x%x]\n",
829 dom_users[i], dom_rids[i]);
832 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
836 rpccli_samr_close(cli, mem_ctx, &domain_pol);
839 rpccli_samr_close(cli, mem_ctx, &connect_pol);
844 /* Enumerate domain groups */
846 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
848 int argc, const char **argv)
850 POLICY_HND connect_pol, domain_pol;
851 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
852 uint32 start_idx, size, num_dom_groups, i;
853 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
854 struct acct_info *dom_groups;
855 BOOL got_connect_pol = False, got_domain_pol = False;
857 if ((argc < 1) || (argc > 2)) {
858 printf("Usage: %s [access_mask]\n", argv[0]);
863 sscanf(argv[1], "%x", &access_mask);
865 /* Get sam policy handle */
867 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
870 if (!NT_STATUS_IS_OK(result))
873 got_connect_pol = True;
875 /* Get domain policy handle */
877 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
879 &domain_sid, &domain_pol);
881 if (!NT_STATUS_IS_OK(result))
884 got_domain_pol = True;
886 /* Enumerate domain groups */
892 result = rpccli_samr_enum_dom_groups(
893 cli, mem_ctx, &domain_pol, &start_idx, size,
894 &dom_groups, &num_dom_groups);
896 if (NT_STATUS_IS_OK(result) ||
897 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
899 for (i = 0; i < num_dom_groups; i++)
900 printf("group:[%s] rid:[0x%x]\n",
901 dom_groups[i].acct_name,
905 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
909 rpccli_samr_close(cli, mem_ctx, &domain_pol);
912 rpccli_samr_close(cli, mem_ctx, &connect_pol);
917 /* Enumerate alias groups */
919 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
921 int argc, const char **argv)
923 POLICY_HND connect_pol, domain_pol;
924 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
925 uint32 start_idx, size, num_als_groups, i;
926 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
927 struct acct_info *als_groups;
928 BOOL got_connect_pol = False, got_domain_pol = False;
930 if ((argc < 2) || (argc > 3)) {
931 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
936 sscanf(argv[2], "%x", &access_mask);
938 /* Get sam policy handle */
940 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
943 if (!NT_STATUS_IS_OK(result))
946 got_connect_pol = True;
948 /* Get domain policy handle */
950 if (StrCaseCmp(argv[1], "domain")==0)
951 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
953 &domain_sid, &domain_pol);
954 else if (StrCaseCmp(argv[1], "builtin")==0)
955 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
957 &global_sid_Builtin, &domain_pol);
961 if (!NT_STATUS_IS_OK(result))
964 got_domain_pol = True;
966 /* Enumerate alias groups */
969 size = 0xffff; /* Number of groups to retrieve */
972 result = rpccli_samr_enum_als_groups(
973 cli, mem_ctx, &domain_pol, &start_idx, size,
974 &als_groups, &num_als_groups);
976 if (NT_STATUS_IS_OK(result) ||
977 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
979 for (i = 0; i < num_als_groups; i++)
980 printf("group:[%s] rid:[0x%x]\n",
981 als_groups[i].acct_name,
984 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
988 rpccli_samr_close(cli, mem_ctx, &domain_pol);
991 rpccli_samr_close(cli, mem_ctx, &connect_pol);
996 /* Query alias membership */
998 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1000 int argc, const char **argv)
1002 POLICY_HND connect_pol, domain_pol, alias_pol;
1003 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1004 uint32 alias_rid, num_members, i;
1005 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1006 DOM_SID *alias_sids;
1008 if ((argc < 3) || (argc > 4)) {
1009 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1010 return NT_STATUS_OK;
1013 sscanf(argv[2], "%i", &alias_rid);
1016 sscanf(argv[3], "%x", &access_mask);
1018 /* Open SAMR handle */
1020 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1023 if (!NT_STATUS_IS_OK(result))
1026 /* Open handle on domain */
1028 if (StrCaseCmp(argv[1], "domain")==0)
1029 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1030 MAXIMUM_ALLOWED_ACCESS,
1031 &domain_sid, &domain_pol);
1032 else if (StrCaseCmp(argv[1], "builtin")==0)
1033 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1034 MAXIMUM_ALLOWED_ACCESS,
1035 &global_sid_Builtin, &domain_pol);
1037 return NT_STATUS_OK;
1039 if (!NT_STATUS_IS_OK(result))
1042 /* Open handle on alias */
1044 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1046 alias_rid, &alias_pol);
1047 if (!NT_STATUS_IS_OK(result))
1050 result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
1051 &num_members, &alias_sids);
1053 if (!NT_STATUS_IS_OK(result))
1056 for (i = 0; i < num_members; i++) {
1059 sid_to_string(sid_str, &alias_sids[i]);
1060 printf("\tsid:[%s]\n", sid_str);
1063 rpccli_samr_close(cli, mem_ctx, &alias_pol);
1064 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1065 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1070 /* Query delete an alias membership */
1072 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1073 TALLOC_CTX *mem_ctx,
1074 int argc, const char **argv)
1076 POLICY_HND connect_pol, domain_pol, alias_pol;
1077 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1079 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1082 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1083 return NT_STATUS_OK;
1086 alias_rid = strtoul(argv[2], NULL, 10);
1088 /* Open SAMR handle */
1090 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1093 if (!NT_STATUS_IS_OK(result))
1096 /* Open handle on domain */
1098 if (StrCaseCmp(argv[1], "domain")==0)
1099 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1100 MAXIMUM_ALLOWED_ACCESS,
1101 &domain_sid, &domain_pol);
1102 else if (StrCaseCmp(argv[1], "builtin")==0)
1103 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1104 MAXIMUM_ALLOWED_ACCESS,
1105 &global_sid_Builtin, &domain_pol);
1107 return NT_STATUS_INVALID_PARAMETER;
1109 if (!NT_STATUS_IS_OK(result))
1112 /* Open handle on alias */
1114 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1116 alias_rid, &alias_pol);
1117 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1118 /* Probably this was a user name, try lookupnames */
1120 uint32 *rids, *types;
1122 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1127 if (NT_STATUS_IS_OK(result)) {
1128 result = rpccli_samr_open_alias(cli, mem_ctx,
1131 rids[0], &alias_pol);
1135 result = rpccli_samr_delete_dom_alias(cli, mem_ctx, &alias_pol);
1137 if (!NT_STATUS_IS_OK(result))
1140 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1141 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1146 /* Query display info */
1148 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1149 TALLOC_CTX *mem_ctx,
1150 int argc, const char **argv)
1152 POLICY_HND connect_pol, domain_pol;
1153 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1154 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
1155 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1156 uint32 info_level = 1;
1157 SAM_DISPINFO_CTR ctr;
1158 SAM_DISPINFO_1 info1;
1159 SAM_DISPINFO_2 info2;
1160 SAM_DISPINFO_3 info3;
1161 SAM_DISPINFO_4 info4;
1162 SAM_DISPINFO_5 info5;
1164 BOOL got_params = False; /* Use get_query_dispinfo_params() or not? */
1167 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1168 return NT_STATUS_OK;
1172 sscanf(argv[1], "%i", &info_level);
1175 sscanf(argv[2], "%i", &start_idx);
1178 sscanf(argv[3], "%i", &max_entries);
1183 sscanf(argv[4], "%i", &max_size);
1188 sscanf(argv[5], "%x", &access_mask);
1190 /* Get sam policy handle */
1192 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1195 if (!NT_STATUS_IS_OK(result))
1198 /* Get domain policy handle */
1200 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1202 &domain_sid, &domain_pol);
1204 if (!NT_STATUS_IS_OK(result))
1207 /* Query display info */
1212 switch (info_level) {
1215 ctr.sam.info1 = &info1;
1219 ctr.sam.info2 = &info2;
1223 ctr.sam.info3 = &info3;
1227 ctr.sam.info4 = &info4;
1231 ctr.sam.info5 = &info5;
1239 get_query_dispinfo_params(
1240 loop_count, &max_entries, &max_size);
1242 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1243 &start_idx, info_level,
1244 &num_entries, max_entries,
1249 if (NT_STATUS_IS_ERR(result))
1252 if (num_entries == 0)
1255 for (i = 0; i < num_entries; i++) {
1256 switch (info_level) {
1258 display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
1261 display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
1264 display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
1267 display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
1270 display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
1274 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1276 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1277 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1282 /* Query domain info */
1284 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1285 TALLOC_CTX *mem_ctx,
1286 int argc, const char **argv)
1288 POLICY_HND connect_pol, domain_pol;
1289 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1290 uint32 switch_level = 2;
1291 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1295 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1296 return NT_STATUS_OK;
1300 sscanf(argv[1], "%i", &switch_level);
1303 sscanf(argv[2], "%x", &access_mask);
1305 /* Get sam policy handle */
1307 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1310 if (!NT_STATUS_IS_OK(result))
1313 /* Get domain policy handle */
1315 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1317 &domain_sid, &domain_pol);
1319 if (!NT_STATUS_IS_OK(result))
1322 /* Query domain info */
1324 result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
1325 switch_level, &ctr);
1327 if (!NT_STATUS_IS_OK(result))
1330 /* Display domain info */
1332 switch (switch_level) {
1334 display_sam_unk_info_1(&ctr.info.inf1);
1337 display_sam_unk_info_2(&ctr.info.inf2);
1340 display_sam_unk_info_7(&ctr.info.inf7);
1343 display_sam_unk_info_8(&ctr.info.inf8);
1346 display_sam_unk_info_12(&ctr.info.inf12);
1349 printf("cannot display domain info for switch value %d\n",
1356 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1357 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1361 /* Create domain user */
1363 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1364 TALLOC_CTX *mem_ctx,
1365 int argc, const char **argv)
1367 POLICY_HND connect_pol, domain_pol, user_pol;
1368 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1369 const char *acct_name;
1371 uint32 unknown, user_rid;
1372 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1374 if ((argc < 2) || (argc > 3)) {
1375 printf("Usage: %s username [access mask]\n", argv[0]);
1376 return NT_STATUS_OK;
1379 acct_name = argv[1];
1382 sscanf(argv[2], "%x", &access_mask);
1384 /* Get sam policy handle */
1386 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1389 if (!NT_STATUS_IS_OK(result))
1392 /* Get domain policy handle */
1394 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1396 &domain_sid, &domain_pol);
1398 if (!NT_STATUS_IS_OK(result))
1401 /* Create domain user */
1403 acb_info = ACB_NORMAL;
1404 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
1406 result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1407 acct_name, acb_info, unknown,
1408 &user_pol, &user_rid);
1410 if (!NT_STATUS_IS_OK(result))
1413 result = rpccli_samr_close(cli, mem_ctx, &user_pol);
1414 if (!NT_STATUS_IS_OK(result)) goto done;
1416 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1417 if (!NT_STATUS_IS_OK(result)) goto done;
1419 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1420 if (!NT_STATUS_IS_OK(result)) goto done;
1426 /* Create domain group */
1428 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1429 TALLOC_CTX *mem_ctx,
1430 int argc, const char **argv)
1432 POLICY_HND connect_pol, domain_pol, group_pol;
1433 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1434 const char *grp_name;
1435 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1437 if ((argc < 2) || (argc > 3)) {
1438 printf("Usage: %s groupname [access mask]\n", argv[0]);
1439 return NT_STATUS_OK;
1445 sscanf(argv[2], "%x", &access_mask);
1447 /* Get sam policy handle */
1449 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1452 if (!NT_STATUS_IS_OK(result))
1455 /* Get domain policy handle */
1457 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1459 &domain_sid, &domain_pol);
1461 if (!NT_STATUS_IS_OK(result))
1464 /* Create domain user */
1466 result = rpccli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
1467 grp_name, MAXIMUM_ALLOWED_ACCESS,
1470 if (!NT_STATUS_IS_OK(result))
1473 result = rpccli_samr_close(cli, mem_ctx, &group_pol);
1474 if (!NT_STATUS_IS_OK(result)) goto done;
1476 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1477 if (!NT_STATUS_IS_OK(result)) goto done;
1479 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1480 if (!NT_STATUS_IS_OK(result)) goto done;
1486 /* Create domain alias */
1488 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1489 TALLOC_CTX *mem_ctx,
1490 int argc, const char **argv)
1492 POLICY_HND connect_pol, domain_pol, alias_pol;
1493 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1494 const char *alias_name;
1495 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1497 if ((argc < 2) || (argc > 3)) {
1498 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1499 return NT_STATUS_OK;
1502 alias_name = argv[1];
1505 sscanf(argv[2], "%x", &access_mask);
1507 /* Get sam policy handle */
1509 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1512 if (!NT_STATUS_IS_OK(result))
1515 /* Get domain policy handle */
1517 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1519 &domain_sid, &domain_pol);
1521 if (!NT_STATUS_IS_OK(result))
1524 /* Create domain user */
1526 result = rpccli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
1527 alias_name, &alias_pol);
1529 if (!NT_STATUS_IS_OK(result))
1532 result = rpccli_samr_close(cli, mem_ctx, &alias_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 /* Lookup sam names */
1547 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1548 TALLOC_CTX *mem_ctx,
1549 int argc, const char **argv)
1551 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1552 POLICY_HND connect_pol, domain_pol;
1553 uint32 flags = 0x000003e8; /* Unknown */
1554 uint32 num_rids, num_names, *name_types, *rids;
1559 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1560 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1561 printf("or check on the builtin SID: S-1-5-32\n");
1562 return NT_STATUS_OK;
1565 /* Get sam policy and domain handles */
1567 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1570 if (!NT_STATUS_IS_OK(result))
1573 if (StrCaseCmp(argv[1], "domain")==0)
1574 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1575 MAXIMUM_ALLOWED_ACCESS,
1576 &domain_sid, &domain_pol);
1577 else if (StrCaseCmp(argv[1], "builtin")==0)
1578 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1579 MAXIMUM_ALLOWED_ACCESS,
1580 &global_sid_Builtin, &domain_pol);
1582 return NT_STATUS_OK;
1584 if (!NT_STATUS_IS_OK(result))
1589 num_names = argc - 2;
1590 names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
1592 for (i = 0; i < argc - 2; i++)
1593 names[i] = argv[i + 2];
1595 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1596 flags, num_names, names,
1597 &num_rids, &rids, &name_types);
1599 if (!NT_STATUS_IS_OK(result))
1602 /* Display results */
1604 for (i = 0; i < num_names; i++)
1605 printf("name %s: 0x%x (%d)\n", names[i], rids[i],
1608 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1609 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1614 /* Lookup sam rids */
1616 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1617 TALLOC_CTX *mem_ctx,
1618 int argc, const char **argv)
1620 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1621 POLICY_HND connect_pol, domain_pol;
1622 uint32 num_rids, num_names, *rids, *name_types;
1627 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1628 return NT_STATUS_OK;
1631 /* Get sam policy and domain handles */
1633 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1636 if (!NT_STATUS_IS_OK(result))
1639 if (StrCaseCmp(argv[1], "domain")==0)
1640 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1641 MAXIMUM_ALLOWED_ACCESS,
1642 &domain_sid, &domain_pol);
1643 else if (StrCaseCmp(argv[1], "builtin")==0)
1644 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1645 MAXIMUM_ALLOWED_ACCESS,
1646 &global_sid_Builtin, &domain_pol);
1648 return NT_STATUS_OK;
1650 if (!NT_STATUS_IS_OK(result))
1655 num_rids = argc - 2;
1656 rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
1658 for (i = 0; i < argc - 2; i++)
1659 sscanf(argv[i + 2], "%i", &rids[i]);
1661 result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
1662 &num_names, &names, &name_types);
1664 if (!NT_STATUS_IS_OK(result) &&
1665 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1668 /* Display results */
1670 for (i = 0; i < num_names; i++)
1671 printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
1673 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1674 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1679 /* Delete domain user */
1681 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
1682 TALLOC_CTX *mem_ctx,
1683 int argc, const char **argv)
1685 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1686 POLICY_HND connect_pol, domain_pol, user_pol;
1687 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1689 if ((argc < 2) || (argc > 3)) {
1690 printf("Usage: %s username\n", argv[0]);
1691 return NT_STATUS_OK;
1695 sscanf(argv[2], "%x", &access_mask);
1697 /* Get sam policy and domain handles */
1699 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1702 if (!NT_STATUS_IS_OK(result))
1705 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1706 MAXIMUM_ALLOWED_ACCESS,
1707 &domain_sid, &domain_pol);
1709 if (!NT_STATUS_IS_OK(result))
1712 /* Get handle on user */
1715 uint32 *user_rids, num_rids, *name_types;
1716 uint32 flags = 0x000003e8; /* Unknown */
1718 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1719 flags, 1, (const char **)&argv[1],
1720 &num_rids, &user_rids,
1723 if (!NT_STATUS_IS_OK(result))
1726 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1728 user_rids[0], &user_pol);
1730 if (!NT_STATUS_IS_OK(result))
1736 result = rpccli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
1738 if (!NT_STATUS_IS_OK(result))
1741 /* Display results */
1743 rpccli_samr_close(cli, mem_ctx, &user_pol);
1744 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1745 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1751 /**********************************************************************
1752 * Query user security object
1754 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
1755 TALLOC_CTX *mem_ctx,
1756 int argc, const char **argv)
1758 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
1759 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1760 uint32 info_level = 4;
1762 uint32 user_rid = 0;
1763 TALLOC_CTX *ctx = NULL;
1764 SEC_DESC_BUF *sec_desc_buf=NULL;
1765 BOOL domain = False;
1767 ctx=talloc_init("cmd_samr_query_sec_obj");
1769 if ((argc < 1) || (argc > 2)) {
1770 printf("Usage: %s [rid|-d]\n", argv[0]);
1771 printf("\tSpecify rid for security on user, -d for security on domain\n");
1772 return NT_STATUS_OK;
1776 if (strcmp(argv[1], "-d") == 0)
1779 sscanf(argv[1], "%i", &user_rid);
1782 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
1784 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1787 if (!NT_STATUS_IS_OK(result))
1790 if (domain || user_rid)
1791 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1792 MAXIMUM_ALLOWED_ACCESS,
1793 &domain_sid, &domain_pol);
1795 if (!NT_STATUS_IS_OK(result))
1799 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1800 MAXIMUM_ALLOWED_ACCESS,
1801 user_rid, &user_pol);
1803 if (!NT_STATUS_IS_OK(result))
1806 /* Pick which query pol to use */
1816 /* Query SAM security object */
1818 result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, info_level, ctx,
1821 if (!NT_STATUS_IS_OK(result))
1824 display_sec_desc(sec_desc_buf->sec);
1826 rpccli_samr_close(cli, mem_ctx, &user_pol);
1827 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1828 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1830 talloc_destroy(ctx);
1834 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
1835 TALLOC_CTX *mem_ctx,
1836 int argc, const char **argv)
1838 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1839 POLICY_HND connect_pol, domain_pol, user_pol;
1840 uint16 min_pwd_length;
1841 uint32 password_properties, unknown1, rid;
1844 printf("Usage: %s rid\n", argv[0]);
1845 return NT_STATUS_OK;
1848 sscanf(argv[1], "%i", &rid);
1850 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1853 if (!NT_STATUS_IS_OK(result)) {
1857 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1858 MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol);
1860 if (!NT_STATUS_IS_OK(result)) {
1864 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1865 MAXIMUM_ALLOWED_ACCESS,
1868 if (!NT_STATUS_IS_OK(result)) {
1872 result = rpccli_samr_get_usrdom_pwinfo(cli, mem_ctx, &user_pol,
1873 &min_pwd_length, &password_properties,
1876 if (NT_STATUS_IS_OK(result)) {
1877 printf("min_pwd_length: %d\n", min_pwd_length);
1878 printf("unknown1: %d\n", unknown1);
1879 display_password_properties(password_properties);
1883 rpccli_samr_close(cli, mem_ctx, &user_pol);
1884 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1885 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1891 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
1892 TALLOC_CTX *mem_ctx,
1893 int argc, const char **argv)
1895 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1896 uint16 min_pwd_length;
1897 uint32 password_properties;
1900 printf("Usage: %s\n", argv[0]);
1901 return NT_STATUS_OK;
1904 result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &min_pwd_length, &password_properties) ;
1906 if (NT_STATUS_IS_OK(result)) {
1907 printf("min_pwd_length: %d\n", min_pwd_length);
1908 display_password_properties(password_properties);
1914 /* Look up domain name */
1916 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
1917 TALLOC_CTX *mem_ctx,
1918 int argc, const char **argv)
1920 POLICY_HND connect_pol, domain_pol;
1921 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1922 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1923 fstring domain_name,sid_string;
1927 printf("Usage: %s domain_name\n", argv[0]);
1928 return NT_STATUS_OK;
1931 sscanf(argv[1], "%s", domain_name);
1933 result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
1935 if (!NT_STATUS_IS_OK(result))
1938 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1939 access_mask, &domain_sid, &domain_pol);
1941 if (!NT_STATUS_IS_OK(result))
1944 result = rpccli_samr_lookup_domain(
1945 cli, mem_ctx, &connect_pol, domain_name, &sid);
1947 sid_to_string(sid_string,&sid);
1949 if (NT_STATUS_IS_OK(result))
1950 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
1951 domain_name,sid_string);
1953 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1954 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1959 /* Change user password */
1961 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
1962 TALLOC_CTX *mem_ctx,
1963 int argc, const char **argv)
1965 POLICY_HND connect_pol, domain_pol;
1966 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1967 const char *user, *oldpass, *newpass;
1968 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1969 SAM_UNK_INFO_1 info;
1970 SAMR_CHANGE_REJECT reject;
1973 printf("Usage: %s username oldpass newpass\n", argv[0]);
1974 return NT_STATUS_INVALID_PARAMETER;
1981 /* Get sam policy handle */
1983 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1986 if (!NT_STATUS_IS_OK(result))
1989 /* Get domain policy handle */
1991 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1993 &domain_sid, &domain_pol);
1995 if (!NT_STATUS_IS_OK(result))
1998 /* Change user password */
1999 result = rpccli_samr_chgpasswd3(cli, mem_ctx, user, newpass, oldpass, &info, &reject);
2001 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2003 display_sam_unk_info_1(&info);
2005 switch (reject.reject_reason) {
2006 case REJECT_REASON_TOO_SHORT:
2007 d_printf("REJECT_REASON_TOO_SHORT\n");
2009 case REJECT_REASON_IN_HISTORY:
2010 d_printf("REJECT_REASON_IN_HISTORY\n");
2012 case REJECT_REASON_NOT_COMPLEX:
2013 d_printf("REJECT_REASON_NOT_COMPLEX\n");
2018 d_printf("unknown reject reason: %d\n", reject.reject_reason);
2023 if (!NT_STATUS_IS_OK(result))
2026 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
2027 if (!NT_STATUS_IS_OK(result)) goto done;
2029 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
2030 if (!NT_STATUS_IS_OK(result)) goto done;
2036 /* List of commands exported by this module */
2038 struct cmd_set samr_commands[] = {
2042 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
2043 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
2044 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
2045 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
2046 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
2047 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
2048 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, PI_SAMR, NULL, "Delete an alias", "" },
2049 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
2050 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
2051 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
2052 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
2053 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
2055 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
2056 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
2057 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, PI_SAMR, NULL, "Create domain alias", "" },
2058 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
2059 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
2060 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
2061 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
2062 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2063 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2065 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2066 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, PI_SAMR, NULL, "Change user password", "" },