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_21 structure
32 ****************************************************************************/
33 static void display_sam_user_info_21(SAM_USER_INFO_21
*usr
)
37 unistr2_to_ascii(temp
, &usr
->uni_user_name
, sizeof(temp
)-1);
38 printf("\tUser Name :\t%s\n", temp
);
40 unistr2_to_ascii(temp
, &usr
->uni_full_name
, sizeof(temp
)-1);
41 printf("\tFull Name :\t%s\n", temp
);
43 unistr2_to_ascii(temp
, &usr
->uni_home_dir
, sizeof(temp
)-1);
44 printf("\tHome Drive :\t%s\n", temp
);
46 unistr2_to_ascii(temp
, &usr
->uni_dir_drive
, sizeof(temp
)-1);
47 printf("\tDir Drive :\t%s\n", temp
);
49 unistr2_to_ascii(temp
, &usr
->uni_profile_path
, sizeof(temp
)-1);
50 printf("\tProfile Path:\t%s\n", temp
);
52 unistr2_to_ascii(temp
, &usr
->uni_logon_script
, sizeof(temp
)-1);
53 printf("\tLogon Script:\t%s\n", temp
);
55 unistr2_to_ascii(temp
, &usr
->uni_acct_desc
, sizeof(temp
)-1);
56 printf("\tDescription :\t%s\n", temp
);
58 unistr2_to_ascii(temp
, &usr
->uni_workstations
, sizeof(temp
)-1);
59 printf("\tWorkstations:\t%s\n", temp
);
61 unistr2_to_ascii(temp
, &usr
->uni_unknown_str
, sizeof(temp
)-1);
62 printf("\tUnknown Str :\t%s\n", temp
);
64 unistr2_to_ascii(temp
, &usr
->uni_munged_dial
, sizeof(temp
)-1);
65 printf("\tRemote Dial :\t%s\n", temp
);
67 printf("\tLogon Time :\t%s\n",
68 http_timestring(nt_time_to_unix(&usr
->logon_time
)));
69 printf("\tLogoff Time :\t%s\n",
70 http_timestring(nt_time_to_unix(&usr
->logoff_time
)));
71 printf("\tKickoff Time :\t%s\n",
72 http_timestring(nt_time_to_unix(&usr
->kickoff_time
)));
73 printf("\tPassword last set Time :\t%s\n",
74 http_timestring(nt_time_to_unix(&usr
->pass_last_set_time
)));
75 printf("\tPassword can change Time :\t%s\n",
76 http_timestring(nt_time_to_unix(&usr
->pass_can_change_time
)));
77 printf("\tPassword must change Time:\t%s\n",
78 http_timestring(nt_time_to_unix(&usr
->pass_must_change_time
)));
80 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
82 printf("\tuser_rid :\t%x\n" , usr
->user_rid
); /* User ID */
83 printf("\tgroup_rid:\t%x\n" , usr
->group_rid
); /* Group ID */
84 printf("\tacb_info :\t%04x\n", usr
->acb_info
); /* Account Control Info */
86 printf("\tunknown_3:\t%08x\n", usr
->unknown_3
); /* 0x00ff ffff */
87 printf("\tlogon_divs:\t%d\n", usr
->logon_divs
); /* 0x0000 00a8 which is 168 which is num hrs in a week */
88 printf("\tunknown_5:\t%08x\n", usr
->unknown_5
); /* 0x0002 0000 */
90 printf("\tpadding1[0..7]...\n");
92 if (usr
->ptr_logon_hrs
) {
93 printf("\tlogon_hrs[0..%d]...\n", usr
->logon_hrs
.len
);
97 static char *display_time(NTTIME nttime
)
99 static fstring string
;
104 int days
, hours
, mins
, secs
;
106 if (nttime
.high
==0 && nttime
.low
==0)
109 if (nttime
.high
==0x80000000 && nttime
.low
==0)
116 high
= high
* (~nttime
.high
);
119 low
= low
/(1000*1000*10);
124 hours
=(sec
- (days
*60*60*24)) / (60*60);
125 mins
=(sec
- (days
*60*60*24) - (hours
*60*60) ) / 60;
126 secs
=sec
- (days
*60*60*24) - (hours
*60*60) - (mins
*60);
128 snprintf(string
, sizeof(string
)-1, "%u days, %u hours, %u minutes, %u seconds", days
, hours
, mins
, secs
);
132 static void display_sam_unk_info_1(SAM_UNK_INFO_1
*info1
)
135 printf("Minimum password length: %d\n", info1
->min_length_password
);
136 printf("Password uniqueness (remember x passwords): %d\n", info1
->password_history
);
138 if(info1
->flag
&&2==2) printf("users must open a session to change password ");
141 printf("password expire in: %s\n", display_time(info1
->expire
));
142 printf("Min password age (allow changing in x days): %s\n", display_time(info1
->min_passwordage
));
145 static void display_sam_unk_info_2(SAM_UNK_INFO_2
*info2
)
149 unistr2_to_ascii(name
, &info2
->uni_domain
, sizeof(name
) - 1);
150 printf("Domain:\t%s\n", name
);
152 unistr2_to_ascii(name
, &info2
->uni_server
, sizeof(name
) - 1);
153 printf("Server:\t%s\n", name
);
155 printf("Total Users:\t%d\n", info2
->num_domain_usrs
);
156 printf("Total Groups:\t%d\n", info2
->num_domain_grps
);
157 printf("Total Aliases:\t%d\n", info2
->num_local_grps
);
159 printf("Sequence No:\t%d\n", info2
->seq_num
);
161 printf("Unknown 0:\t0x%x\n", info2
->unknown_0
);
162 printf("Unknown 1:\t0x%x\n", info2
->unknown_1
);
163 printf("Unknown 2:\t0x%x\n", info2
->unknown_2
);
164 printf("Unknown 3:\t0x%x\n", info2
->unknown_3
);
165 printf("Unknown 4:\t0x%x\n", info2
->unknown_4
);
166 printf("Unknown 5:\t0x%x\n", info2
->unknown_5
);
167 printf("Unknown 6:\t0x%x\n", info2
->unknown_6
);
170 static void display_sam_info_1(SAM_ENTRY1
*e1
, SAM_STR1
*s1
)
174 printf("index: 0x%x ", e1
->user_idx
);
175 printf("RID: 0x%x ", e1
->rid_user
);
176 printf("acb: 0x%x ", e1
->acb_info
);
178 unistr2_to_ascii(tmp
, &s1
->uni_acct_name
, sizeof(tmp
)-1);
179 printf("Account: %s\t", tmp
);
181 unistr2_to_ascii(tmp
, &s1
->uni_full_name
, sizeof(tmp
)-1);
182 printf("Name: %s\t", tmp
);
184 unistr2_to_ascii(tmp
, &s1
->uni_acct_desc
, sizeof(tmp
)-1);
185 printf("Desc: %s\n", tmp
);
188 static void display_sam_info_2(SAM_ENTRY2
*e2
, SAM_STR2
*s2
)
192 printf("index: 0x%x ", e2
->user_idx
);
193 printf("RID: 0x%x ", e2
->rid_user
);
194 printf("acb: 0x%x ", e2
->acb_info
);
196 unistr2_to_ascii(tmp
, &s2
->uni_srv_name
, sizeof(tmp
)-1);
197 printf("Account: %s\t", tmp
);
199 unistr2_to_ascii(tmp
, &s2
->uni_srv_desc
, sizeof(tmp
)-1);
200 printf("Name: %s\n", tmp
);
204 static void display_sam_info_3(SAM_ENTRY3
*e3
, SAM_STR3
*s3
)
208 printf("index: 0x%x ", e3
->grp_idx
);
209 printf("RID: 0x%x ", e3
->rid_grp
);
210 printf("attr: 0x%x ", e3
->attr
);
212 unistr2_to_ascii(tmp
, &s3
->uni_grp_name
, sizeof(tmp
)-1);
213 printf("Account: %s\t", tmp
);
215 unistr2_to_ascii(tmp
, &s3
->uni_grp_desc
, sizeof(tmp
)-1);
216 printf("Name: %s\n", tmp
);
220 static void display_sam_info_4(SAM_ENTRY4
*e4
, SAM_STR4
*s4
)
224 printf("index: %d ", e4
->user_idx
);
227 for (i
=0; i
<s4
->acct_name
.str_str_len
; i
++)
228 printf("%c", s4
->acct_name
.buffer
[i
]);
233 static void display_sam_info_5(SAM_ENTRY5
*e5
, SAM_STR5
*s5
)
237 printf("index: 0x%x ", e5
->grp_idx
);
240 for (i
=0; i
<s5
->grp_name
.str_str_len
; i
++)
241 printf("%c", s5
->grp_name
.buffer
[i
]);
246 /**********************************************************************
247 * Query user information
249 static NTSTATUS
cmd_samr_query_user(struct cli_state
*cli
,
251 int argc
, char **argv
)
253 POLICY_HND connect_pol
, domain_pol
, user_pol
;
254 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
255 uint32 info_level
= 21;
256 SAM_USERINFO_CTR
*user_ctr
;
261 printf("Usage: %s rid\n", argv
[0]);
265 sscanf(argv
[1], "%i", &user_rid
);
267 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
270 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
273 if (!NT_STATUS_IS_OK(result
))
276 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
277 MAXIMUM_ALLOWED_ACCESS
,
278 &domain_sid
, &domain_pol
);
280 if (!NT_STATUS_IS_OK(result
))
283 result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
284 MAXIMUM_ALLOWED_ACCESS
,
285 user_rid
, &user_pol
);
287 if (!NT_STATUS_IS_OK(result
))
290 ZERO_STRUCT(user_ctr
);
292 result
= cli_samr_query_userinfo(cli
, mem_ctx
, &user_pol
,
293 info_level
, &user_ctr
);
295 if (!NT_STATUS_IS_OK(result
))
298 display_sam_user_info_21(user_ctr
->info
.id21
);
304 /****************************************************************************
306 ****************************************************************************/
307 static void display_group_info1(GROUP_INFO1
*info1
)
311 unistr2_to_ascii(temp
, &info1
->uni_acct_name
, sizeof(temp
)-1);
312 printf("\tGroup Name:\t%s\n", temp
);
313 unistr2_to_ascii(temp
, &info1
->uni_acct_desc
, sizeof(temp
)-1);
314 printf("\tDescription:\t%s\n", temp
);
315 printf("\tunk1:%d\n", info1
->unknown_1
);
316 printf("\tNum Members:%d\n", info1
->num_members
);
319 /****************************************************************************
321 ****************************************************************************/
322 static void display_group_info4(GROUP_INFO4
*info4
)
326 unistr2_to_ascii(desc
, &info4
->uni_acct_desc
, sizeof(desc
)-1);
327 printf("\tGroup Description:%s\n", desc
);
330 /****************************************************************************
331 display sam sync structure
332 ****************************************************************************/
333 static void display_group_info_ctr(GROUP_INFO_CTR
*ctr
)
335 switch (ctr
->switch_value1
) {
337 display_group_info1(&ctr
->group
.info1
);
341 display_group_info4(&ctr
->group
.info4
);
347 /***********************************************************************
348 * Query group information
350 static NTSTATUS
cmd_samr_query_group(struct cli_state
*cli
,
352 int argc
, char **argv
)
354 POLICY_HND connect_pol
, domain_pol
, group_pol
;
355 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
356 uint32 info_level
= 1;
357 GROUP_INFO_CTR group_ctr
;
362 printf("Usage: %s rid\n", argv
[0]);
366 sscanf(argv
[1], "%i", &group_rid
);
368 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
371 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
374 if (!NT_STATUS_IS_OK(result
))
377 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
378 MAXIMUM_ALLOWED_ACCESS
,
379 &domain_sid
, &domain_pol
);
381 if (!NT_STATUS_IS_OK(result
))
384 result
= cli_samr_open_group(cli
, mem_ctx
, &domain_pol
,
385 MAXIMUM_ALLOWED_ACCESS
,
386 group_rid
, &group_pol
);
388 if (!NT_STATUS_IS_OK(result
))
391 ZERO_STRUCT(group_ctr
);
393 result
= cli_samr_query_groupinfo(cli
, mem_ctx
, &group_pol
,
394 info_level
, &group_ctr
);
395 if (!NT_STATUS_IS_OK(result
)) {
399 display_group_info_ctr(&group_ctr
);
405 /* Query groups a user is a member of */
407 static NTSTATUS
cmd_samr_query_usergroups(struct cli_state
*cli
,
409 int argc
, char **argv
)
411 POLICY_HND connect_pol
,
414 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
422 printf("Usage: %s rid\n", argv
[0]);
426 sscanf(argv
[1], "%i", &user_rid
);
428 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
431 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
433 if (!NT_STATUS_IS_OK(result
)) {
437 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
438 MAXIMUM_ALLOWED_ACCESS
,
439 &domain_sid
, &domain_pol
);
440 if (!NT_STATUS_IS_OK(result
)) {
444 result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
445 MAXIMUM_ALLOWED_ACCESS
,
446 user_rid
, &user_pol
);
447 if (!NT_STATUS_IS_OK(result
)) {
451 result
= cli_samr_query_usergroups(cli
, mem_ctx
, &user_pol
,
452 &num_groups
, &user_gids
);
453 if (!NT_STATUS_IS_OK(result
)) {
457 for (i
= 0; i
< num_groups
; i
++) {
458 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
459 user_gids
[i
].g_rid
, user_gids
[i
].attr
);
466 /* Query aliases a user is a member of */
468 static NTSTATUS
cmd_samr_query_useraliases(struct cli_state
*cli
,
470 int argc
, char **argv
)
472 POLICY_HND connect_pol
, domain_pol
;
473 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
474 uint32 user_rid
, num_aliases
, *alias_rids
;
479 DOM_SID global_sid_Builtin
;
481 string_to_sid(&global_sid_Builtin
, "S-1-5-32");
484 printf("Usage: %s builtin|domain rid\n", argv
[0]);
488 sscanf(argv
[2], "%i", &user_rid
);
490 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
493 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
495 if (!NT_STATUS_IS_OK(result
)) {
499 if (StrCaseCmp(argv
[1], "domain")==0)
500 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
501 MAXIMUM_ALLOWED_ACCESS
,
502 &domain_sid
, &domain_pol
);
503 else if (StrCaseCmp(argv
[1], "builtin")==0)
504 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
505 MAXIMUM_ALLOWED_ACCESS
,
506 &global_sid_Builtin
, &domain_pol
);
510 if (!NT_STATUS_IS_OK(result
)) {
514 sid_copy(&tmp_sid
, &domain_sid
);
515 sid_append_rid(&tmp_sid
, user_rid
);
516 init_dom_sid2(&sid
, &tmp_sid
);
518 result
= cli_samr_query_useraliases(cli
, mem_ctx
, &domain_pol
, 1, &sid
, &num_aliases
, &alias_rids
);
519 if (!NT_STATUS_IS_OK(result
)) {
523 for (i
= 0; i
< num_aliases
; i
++) {
524 printf("\tgroup rid:[0x%x]\n", alias_rids
[i
]);
531 /* Query members of a group */
533 static NTSTATUS
cmd_samr_query_groupmem(struct cli_state
*cli
,
535 int argc
, char **argv
)
537 POLICY_HND connect_pol
, domain_pol
, group_pol
;
538 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
539 uint32 num_members
, *group_rids
, *group_attrs
, group_rid
;
544 printf("Usage: %s rid\n", argv
[0]);
548 sscanf(argv
[1], "%i", &group_rid
);
550 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
553 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
555 if (!NT_STATUS_IS_OK(result
)) {
559 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
560 MAXIMUM_ALLOWED_ACCESS
,
561 &domain_sid
, &domain_pol
);
562 if (!NT_STATUS_IS_OK(result
)) {
566 result
= cli_samr_open_group(cli
, mem_ctx
, &domain_pol
,
567 MAXIMUM_ALLOWED_ACCESS
,
568 group_rid
, &group_pol
);
569 if (!NT_STATUS_IS_OK(result
)) {
573 result
= cli_samr_query_groupmem(cli
, mem_ctx
, &group_pol
,
574 &num_members
, &group_rids
,
576 if (!NT_STATUS_IS_OK(result
)) {
580 for (i
= 0; i
< num_members
; i
++) {
581 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids
[i
],
589 /* Enumerate domain groups */
591 static NTSTATUS
cmd_samr_enum_dom_groups(struct cli_state
*cli
,
593 int argc
, char **argv
)
595 POLICY_HND connect_pol
, domain_pol
;
596 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
597 uint32 start_idx
, size
, num_dom_groups
, i
;
598 struct acct_info
*dom_groups
;
601 printf("Usage: %s\n", argv
[0]);
605 /* Get sam policy handle */
607 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
609 if (!NT_STATUS_IS_OK(result
)) {
613 /* Get domain policy handle */
615 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
616 MAXIMUM_ALLOWED_ACCESS
,
617 &domain_sid
, &domain_pol
);
618 if (!NT_STATUS_IS_OK(result
)) {
622 /* Enumerate domain groups */
627 result
= cli_samr_enum_dom_groups(cli
, mem_ctx
, &domain_pol
,
629 &dom_groups
, &num_dom_groups
);
631 for (i
= 0; i
< num_dom_groups
; i
++)
632 printf("group:[%s] rid:[0x%x]\n", dom_groups
[i
].acct_name
,
639 /* Enumerate domain groups */
641 static NTSTATUS
cmd_samr_enum_als_groups(struct cli_state
*cli
,
643 int argc
, char **argv
)
645 POLICY_HND connect_pol
, domain_pol
;
646 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
647 uint32 start_idx
, size
, num_dom_groups
, i
;
648 struct acct_info
*dom_groups
;
649 DOM_SID global_sid_Builtin
;
651 string_to_sid(&global_sid_Builtin
, "S-1-5-32");
654 printf("Usage: %s builtin|domain\n", argv
[0]);
658 /* Get sam policy handle */
660 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
662 if (!NT_STATUS_IS_OK(result
)) {
666 /* Get domain policy handle */
668 if (StrCaseCmp(argv
[1], "domain")==0)
669 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
670 MAXIMUM_ALLOWED_ACCESS
,
671 &domain_sid
, &domain_pol
);
672 else if (StrCaseCmp(argv
[1], "builtin")==0)
673 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
674 MAXIMUM_ALLOWED_ACCESS
,
675 &global_sid_Builtin
, &domain_pol
);
678 if (!NT_STATUS_IS_OK(result
)) {
682 /* Enumerate domain groups */
687 result
= cli_samr_enum_als_groups(cli
, mem_ctx
, &domain_pol
,
689 &dom_groups
, &num_dom_groups
);
691 for (i
= 0; i
< num_dom_groups
; i
++)
692 printf("group:[%s] rid:[0x%x]\n", dom_groups
[i
].acct_name
,
699 /* Query alias membership */
701 static NTSTATUS
cmd_samr_query_aliasmem(struct cli_state
*cli
,
703 int argc
, char **argv
)
705 POLICY_HND connect_pol
, domain_pol
, alias_pol
;
706 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
707 uint32 alias_rid
, num_members
, i
;
711 printf("Usage: %s rid\n", argv
[0]);
715 sscanf(argv
[1], "%i", &alias_rid
);
717 /* Open SAMR handle */
719 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
721 if (!NT_STATUS_IS_OK(result
)) {
725 /* Open handle on domain */
727 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
728 MAXIMUM_ALLOWED_ACCESS
,
729 &domain_sid
, &domain_pol
);
730 if (!NT_STATUS_IS_OK(result
)) {
734 /* Open handle on alias */
736 result
= cli_samr_open_alias(cli
, mem_ctx
, &domain_pol
,
737 MAXIMUM_ALLOWED_ACCESS
,
738 alias_rid
, &alias_pol
);
739 if (!NT_STATUS_IS_OK(result
)) {
743 result
= cli_samr_query_aliasmem(cli
, mem_ctx
, &alias_pol
,
744 &num_members
, &alias_sids
);
745 if (!NT_STATUS_IS_OK(result
)) {
749 for (i
= 0; i
< num_members
; i
++) {
752 sid_to_string(sid_str
, &alias_sids
[i
]);
753 printf("\tsid:[%s]\n", sid_str
);
760 /* Query display info */
762 static NTSTATUS
cmd_samr_query_dispinfo(struct cli_state
*cli
,
764 int argc
, char **argv
)
766 POLICY_HND connect_pol
, domain_pol
;
767 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
768 uint32 start_idx
=0, max_entries
=250, num_entries
, i
;
770 SAM_DISPINFO_CTR ctr
;
771 SAM_DISPINFO_1 info1
;
772 SAM_DISPINFO_2 info2
;
773 SAM_DISPINFO_3 info3
;
774 SAM_DISPINFO_4 info4
;
775 SAM_DISPINFO_5 info5
;
778 printf("Usage: %s [info level] [start index] [max entries]\n", argv
[0]);
783 sscanf(argv
[1], "%i", &info_level
);
786 sscanf(argv
[2], "%i", &start_idx
);
789 sscanf(argv
[3], "%i", &max_entries
);
791 /* Get sam policy handle */
793 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
, &connect_pol
);
794 if (!NT_STATUS_IS_OK(result
)) {
798 /* Get domain policy handle */
800 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
801 MAXIMUM_ALLOWED_ACCESS
,
802 &domain_sid
, &domain_pol
);
803 if (!NT_STATUS_IS_OK(result
)) {
807 /* Query display info */
812 switch (info_level
) {
815 ctr
.sam
.info1
= &info1
;
819 ctr
.sam
.info2
= &info2
;
823 ctr
.sam
.info3
= &info3
;
827 ctr
.sam
.info4
= &info4
;
831 ctr
.sam
.info5
= &info5
;
837 result
= cli_samr_query_dispinfo(cli
, mem_ctx
, &domain_pol
,
838 &start_idx
, info_level
,
839 &num_entries
, max_entries
, &ctr
);
841 for (i
= 0; i
< num_entries
; i
++) {
842 switch (info_level
) {
844 display_sam_info_1(&ctr
.sam
.info1
->sam
[i
], &ctr
.sam
.info1
->str
[i
]);
847 display_sam_info_2(&ctr
.sam
.info2
->sam
[i
], &ctr
.sam
.info2
->str
[i
]);
850 display_sam_info_3(&ctr
.sam
.info3
->sam
[i
], &ctr
.sam
.info3
->str
[i
]);
853 display_sam_info_4(&ctr
.sam
.info4
->sam
[i
], &ctr
.sam
.info4
->str
[i
]);
856 display_sam_info_5(&ctr
.sam
.info5
->sam
[i
], &ctr
.sam
.info5
->str
[i
]);
860 } while (!NT_STATUS_IS_OK(result
));
865 /* Query domain info */
867 static NTSTATUS
cmd_samr_query_dominfo(struct cli_state
*cli
,
869 int argc
, char **argv
)
871 POLICY_HND connect_pol
, domain_pol
;
872 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
873 int switch_value
= 2;
877 printf("Usage: %s [infolevel]\n", argv
[0]);
882 sscanf(argv
[1], "%i", &switch_value
);
884 /* Get sam policy handle */
886 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
888 if (!NT_STATUS_IS_OK(result
)) {
892 /* Get domain policy handle */
894 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
895 MAXIMUM_ALLOWED_ACCESS
,
896 &domain_sid
, &domain_pol
);
897 if (!NT_STATUS_IS_OK(result
)) {
901 /* Query domain info */
903 result
= cli_samr_query_dom_info(cli
, mem_ctx
, &domain_pol
,
905 if (!NT_STATUS_IS_OK(result
)) {
909 /* Display domain info */
911 switch (switch_value
) {
913 display_sam_unk_info_1(&ctr
.info
.inf1
);
916 display_sam_unk_info_2(&ctr
.info
.inf2
);
919 printf("cannot display domain info for switch value %d\n",
926 cli_samr_close(cli
, mem_ctx
, &domain_pol
);
927 cli_samr_close(cli
, mem_ctx
, &connect_pol
);
931 /* Create domain user */
933 static NTSTATUS
cmd_samr_create_dom_user(struct cli_state
*cli
,
935 int argc
, char **argv
)
937 POLICY_HND connect_pol
, domain_pol
, user_pol
;
938 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
941 uint32 unknown
, user_rid
;
944 printf("Usage: %s username\n", argv
[0]);
950 /* Get sam policy handle */
952 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
954 if (!NT_STATUS_IS_OK(result
)) {
958 /* Get domain policy handle */
960 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
961 MAXIMUM_ALLOWED_ACCESS
,
962 &domain_sid
, &domain_pol
);
963 if (!NT_STATUS_IS_OK(result
)) {
967 /* Create domain user */
969 acb_info
= ACB_NORMAL
;
970 unknown
= 0xe005000b; /* No idea what this is - a permission mask? */
972 result
= cli_samr_create_dom_user(cli
, mem_ctx
, &domain_pol
,
973 acct_name
, acb_info
, unknown
,
974 &user_pol
, &user_rid
);
975 if (!NT_STATUS_IS_OK(result
)) {
983 /* Lookup sam names */
985 static NTSTATUS
cmd_samr_lookup_names(struct cli_state
*cli
,
987 int argc
, char **argv
)
989 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
990 POLICY_HND connect_pol
, domain_pol
;
991 uint32 flags
= 0x000003e8; /* Unknown */
992 uint32 num_rids
, num_names
, *name_types
, *rids
;
995 DOM_SID global_sid_Builtin
;
997 string_to_sid(&global_sid_Builtin
, "S-1-5-32");
1000 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv
[0]);
1001 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1002 printf("or check on the builtin SID: S-1-5-32\n");
1003 return NT_STATUS_OK
;
1006 /* Get sam policy and domain handles */
1008 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
1011 if (!NT_STATUS_IS_OK(result
)) {
1015 if (StrCaseCmp(argv
[1], "domain")==0)
1016 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
1017 MAXIMUM_ALLOWED_ACCESS
,
1018 &domain_sid
, &domain_pol
);
1019 else if (StrCaseCmp(argv
[1], "builtin")==0)
1020 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
1021 MAXIMUM_ALLOWED_ACCESS
,
1022 &global_sid_Builtin
, &domain_pol
);
1024 return NT_STATUS_OK
;
1026 if (!NT_STATUS_IS_OK(result
)) {
1032 num_names
= argc
- 2;
1033 names
= (char **)talloc(mem_ctx
, sizeof(char *) * num_names
);
1035 for (i
= 0; i
< argc
- 2; i
++)
1036 names
[i
] = argv
[i
+ 2];
1038 result
= cli_samr_lookup_names(cli
, mem_ctx
, &domain_pol
,
1039 flags
, num_names
, names
,
1040 &num_rids
, &rids
, &name_types
);
1042 if (!NT_STATUS_IS_OK(result
)) {
1046 /* Display results */
1048 for (i
= 0; i
< num_names
; i
++)
1049 printf("name %s: 0x%x (%d)\n", names
[i
], rids
[i
],
1056 /* Lookup sam rids */
1058 static NTSTATUS
cmd_samr_lookup_rids(struct cli_state
*cli
,
1059 TALLOC_CTX
*mem_ctx
,
1060 int argc
, char **argv
)
1062 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1063 POLICY_HND connect_pol
, domain_pol
;
1064 uint32 flags
= 0x000003e8; /* Unknown */
1065 uint32 num_rids
, num_names
, *rids
, *name_types
;
1070 printf("Usage: %s rid1 [rid2 [rid3] [...]]\n", argv
[0]);
1071 return NT_STATUS_OK
;
1074 /* Get sam policy and domain handles */
1076 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
1079 if (!NT_STATUS_IS_OK(result
)) {
1083 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
1084 MAXIMUM_ALLOWED_ACCESS
,
1085 &domain_sid
, &domain_pol
);
1087 if (!NT_STATUS_IS_OK(result
)) {
1093 num_rids
= argc
- 1;
1094 rids
= (uint32
*)talloc(mem_ctx
, sizeof(uint32
) * num_rids
);
1096 for (i
= 0; i
< argc
- 1; i
++)
1097 sscanf(argv
[i
+ 1], "%i", &rids
[i
]);
1099 result
= cli_samr_lookup_rids(cli
, mem_ctx
, &domain_pol
,
1100 flags
, num_rids
, rids
,
1101 &num_names
, &names
, &name_types
);
1103 if (!NT_STATUS_IS_OK(result
)) {
1107 /* Display results */
1109 for (i
= 0; i
< num_names
; i
++)
1110 printf("rid 0x%x: %s (%d)\n", rids
[i
], names
[i
], name_types
[i
]);
1116 /* Delete domain user */
1118 static NTSTATUS
cmd_samr_delete_dom_user(struct cli_state
*cli
,
1119 TALLOC_CTX
*mem_ctx
,
1120 int argc
, char **argv
)
1122 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1123 POLICY_HND connect_pol
, domain_pol
, user_pol
;
1126 printf("Usage: %s username\n", argv
[0]);
1127 return NT_STATUS_OK
;
1130 /* Get sam policy and domain handles */
1132 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
1135 if (!NT_STATUS_IS_OK(result
)) {
1139 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
1140 MAXIMUM_ALLOWED_ACCESS
,
1141 &domain_sid
, &domain_pol
);
1143 if (!NT_STATUS_IS_OK(result
)) {
1147 /* Get handle on user */
1150 uint32
*user_rids
, num_rids
, *name_types
;
1151 uint32 flags
= 0x000003e8; /* Unknown */
1153 result
= cli_samr_lookup_names(cli
, mem_ctx
, &domain_pol
,
1155 &num_rids
, &user_rids
,
1158 if (!NT_STATUS_IS_OK(result
)) {
1162 result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
1163 MAXIMUM_ALLOWED_ACCESS
,
1164 user_rids
[0], &user_pol
);
1166 if (!NT_STATUS_IS_OK(result
)) {
1173 result
= cli_samr_delete_dom_user(cli
, mem_ctx
, &user_pol
);
1175 if (!NT_STATUS_IS_OK(result
)) {
1179 /* Display results */
1185 /**********************************************************************
1186 * Query user security object
1188 static NTSTATUS
cmd_samr_query_sec_obj(struct cli_state
*cli
,
1189 TALLOC_CTX
*mem_ctx
,
1190 int argc
, char **argv
)
1192 POLICY_HND connect_pol
, domain_pol
, user_pol
, *pol
;
1193 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1194 uint32 info_level
= 4;
1196 uint32 user_rid
= 0;
1197 TALLOC_CTX
*ctx
= NULL
;
1198 SEC_DESC_BUF
*sec_desc_buf
=NULL
;
1199 BOOL domain
= False
;
1204 printf("Usage: %s [rid|-d]\n", argv
[0]);
1205 printf("\tSpecify rid for security on user, -d for security on domain\n");
1206 return NT_STATUS_OK
;
1210 if (strcmp(argv
[1], "-d") == 0)
1213 sscanf(argv
[1], "%i", &user_rid
);
1216 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
1218 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
1221 if (!NT_STATUS_IS_OK(result
))
1224 if (domain
|| user_rid
)
1225 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
1226 MAXIMUM_ALLOWED_ACCESS
,
1227 &domain_sid
, &domain_pol
);
1229 if (!NT_STATUS_IS_OK(result
))
1233 result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
1234 MAXIMUM_ALLOWED_ACCESS
,
1235 user_rid
, &user_pol
);
1237 if (!NT_STATUS_IS_OK(result
))
1240 /* Pick which query pol to use */
1250 /* Query SAM security object */
1252 result
= cli_samr_query_sec_obj(cli
, mem_ctx
, pol
, info_level
, ctx
,
1255 if (!NT_STATUS_IS_OK(result
))
1258 display_sec_desc(sec_desc_buf
->sec
);
1261 talloc_destroy(ctx
);
1265 /* List of commands exported by this module */
1267 struct cmd_set samr_commands
[] = {
1271 { "queryuser", cmd_samr_query_user
, PIPE_SAMR
, "Query user info", "" },
1272 { "querygroup", cmd_samr_query_group
, PIPE_SAMR
, "Query group info", "" },
1273 { "queryusergroups", cmd_samr_query_usergroups
, PIPE_SAMR
, "Query user groups", "" },
1274 { "queryuseraliases", cmd_samr_query_useraliases
, PIPE_SAMR
, "Query user aliases", "" },
1275 { "querygroupmem", cmd_samr_query_groupmem
, PIPE_SAMR
, "Query group membership", "" },
1276 { "queryaliasmem", cmd_samr_query_aliasmem
, PIPE_SAMR
, "Query alias membership", "" },
1277 { "querydispinfo", cmd_samr_query_dispinfo
, PIPE_SAMR
, "Query display info", "" },
1278 { "querydominfo", cmd_samr_query_dominfo
, PIPE_SAMR
, "Query domain info", "" },
1279 { "enumdomgroups", cmd_samr_enum_dom_groups
, PIPE_SAMR
, "Enumerate domain groups", "" },
1280 { "enumalsgroups", cmd_samr_enum_als_groups
, PIPE_SAMR
, "Enumerate alias groups", "" },
1282 { "createdomuser", cmd_samr_create_dom_user
, PIPE_SAMR
, "Create domain user", "" },
1283 { "samlookupnames", cmd_samr_lookup_names
, PIPE_SAMR
, "Look up names", "" },
1284 { "samlookuprids", cmd_samr_lookup_rids
, PIPE_SAMR
, "Look up names", "" },
1285 { "deletedomuser", cmd_samr_delete_dom_user
, PIPE_SAMR
, "Delete domain user", "" },
1286 { "samquerysecobj", cmd_samr_query_sec_obj
, PIPE_SAMR
, "Query SAMR security object", "" },