2 Unix SMB/Netbios implementation.
6 Copyright (C) Andrew Tridgell 1992-2000,
7 Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8 Copyright (C) Elrond 2000,
9 Copyright (C) Tim Potter 2000
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 /**********************************************************************
98 * Query user information
100 static uint32
cmd_samr_query_user(struct cli_state
*cli
, int argc
, char **argv
)
102 POLICY_HND connect_pol
, domain_pol
, user_pol
;
103 uint32 result
= NT_STATUS_UNSUCCESSFUL
,
105 BOOL got_connect_pol
= False
,
106 got_domain_pol
= False
,
107 got_user_pol
= False
;
108 SAM_USERINFO_CTR user_ctr
;
109 SAM_USER_INFO_21 info_21
;
115 printf("Usage: %s\n", argv
[0]);
119 if (!(mem_ctx
=talloc_init()))
121 DEBUG(0,("cmd_samr_query_user: talloc_init returned NULL!\n"));
122 return NT_STATUS_UNSUCCESSFUL
;
125 fetch_domain_sid(cli
);
127 /* Initialise RPC connection */
128 if (!cli_nt_session_open (cli
, PIPE_SAMR
)) {
129 fprintf (stderr
, "Could not initialize samr pipe!\n");
130 return NT_STATUS_UNSUCCESSFUL
;
133 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
136 if ((result
= cli_samr_connect(cli
, mem_ctx
, server
, MAXIMUM_ALLOWED_ACCESS
,
138 NT_STATUS_NOPROBLEMO
) {
142 got_connect_pol
= True
;
144 if ((result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
145 MAXIMUM_ALLOWED_ACCESS
,
146 &domain_sid
, &domain_pol
))
147 != NT_STATUS_NOPROBLEMO
) {
151 got_domain_pol
= True
;
153 if ((result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
154 MAXIMUM_ALLOWED_ACCESS
,
156 != NT_STATUS_NOPROBLEMO
) {
162 ZERO_STRUCT(user_ctr
);
163 ZERO_STRUCT(info_21
);
165 user_ctr
.info
.id21
= &info_21
;
167 if ((result
= cli_samr_query_userinfo(cli
, mem_ctx
, &user_pol
, info_level
,
169 != NT_STATUS_NOPROBLEMO
) {
173 display_sam_user_info_21(&info_21
);
176 if (got_user_pol
) cli_samr_close(cli
, mem_ctx
, &user_pol
);
177 if (got_domain_pol
) cli_samr_close(cli
, mem_ctx
, &domain_pol
);
178 if (got_connect_pol
) cli_samr_close(cli
, mem_ctx
, &connect_pol
);
180 cli_nt_session_close(cli
);
181 talloc_destroy(mem_ctx
);
186 /****************************************************************************
188 ****************************************************************************/
189 static void display_group_info1(GROUP_INFO1
*info1
)
193 unistr2_to_ascii(temp
, &info1
->uni_acct_name
, sizeof(temp
)-1);
194 printf("\tGroup Name:\t%s\n", temp
);
195 unistr2_to_ascii(temp
, &info1
->uni_acct_desc
, sizeof(temp
)-1);
196 printf("\tDescription:\t%s\n", temp
);
197 printf("\tunk1:%d\n", info1
->unknown_1
);
198 printf("\tNum Members:%d\n", info1
->num_members
);
201 /****************************************************************************
203 ****************************************************************************/
204 static void display_group_info4(GROUP_INFO4
*info4
)
208 unistr2_to_ascii(desc
, &info4
->uni_acct_desc
, sizeof(desc
)-1);
209 printf("\tGroup Description:%s\n", desc
);
212 /****************************************************************************
213 display sam sync structure
214 ****************************************************************************/
215 static void display_group_info_ctr(GROUP_INFO_CTR
*ctr
)
217 switch (ctr
->switch_value1
) {
219 display_group_info1(&ctr
->group
.info1
);
223 display_group_info4(&ctr
->group
.info4
);
229 /***********************************************************************
230 * Query group information
232 static uint32
cmd_samr_query_group(struct cli_state
*cli
, int argc
, char **argv
)
234 POLICY_HND connect_pol
, domain_pol
, group_pol
;
235 uint32 result
= NT_STATUS_UNSUCCESSFUL
, info_level
= 1;
236 BOOL got_connect_pol
= False
, got_domain_pol
= False
,
237 got_group_pol
= False
;
238 GROUP_INFO_CTR group_ctr
;
243 printf("Usage: %s\n", argv
[0]);
247 if (!(mem_ctx
=talloc_init()))
249 DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n"));
250 return NT_STATUS_UNSUCCESSFUL
;
253 fetch_domain_sid(cli
);
255 /* Initialise RPC connection */
256 if (!cli_nt_session_open (cli
, PIPE_SAMR
)) {
257 fprintf (stderr
, "Could not initialize samr pipe!\n");
258 return NT_STATUS_UNSUCCESSFUL
;
261 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
264 if ((result
= cli_samr_connect(cli
, mem_ctx
, server
, MAXIMUM_ALLOWED_ACCESS
,
266 NT_STATUS_NOPROBLEMO
) {
270 got_connect_pol
= True
;
272 if ((result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
273 MAXIMUM_ALLOWED_ACCESS
,
274 &domain_sid
, &domain_pol
))
275 != NT_STATUS_NOPROBLEMO
) {
279 got_domain_pol
= True
;
281 if ((result
= cli_samr_open_group(cli
, mem_ctx
, &domain_pol
,
282 MAXIMUM_ALLOWED_ACCESS
,
284 != NT_STATUS_NOPROBLEMO
) {
288 got_group_pol
= True
;
290 ZERO_STRUCT(group_ctr
);
292 if ((result
= cli_samr_query_groupinfo(cli
, mem_ctx
, &group_pol
, info_level
,
294 != NT_STATUS_NOPROBLEMO
) {
298 display_group_info_ctr(&group_ctr
);
301 if (got_group_pol
) cli_samr_close(cli
, mem_ctx
, &group_pol
);
302 if (got_domain_pol
) cli_samr_close(cli
, mem_ctx
, &domain_pol
);
303 if (got_connect_pol
) cli_samr_close(cli
, mem_ctx
, &connect_pol
);
305 cli_nt_session_close(cli
);
306 talloc_destroy(mem_ctx
);
311 /* Query groups a user is a member of */
313 static uint32
cmd_samr_query_usergroups(struct cli_state
*cli
, int argc
, char **argv
)
315 POLICY_HND connect_pol
,
318 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
319 BOOL got_connect_pol
= False
,
320 got_domain_pol
= False
,
321 got_user_pol
= False
;
330 printf("Usage: %s rid\n", argv
[0]);
334 if (!(mem_ctx
=talloc_init()))
336 DEBUG(0,("cmd_samr_query_usergroups: talloc_init returned NULL!\n"));
337 return NT_STATUS_UNSUCCESSFUL
;
340 sscanf(argv
[1], "%i", &user_rid
);
342 fetch_domain_sid(cli
);
344 /* Initialise RPC connection */
345 if (!cli_nt_session_open (cli
, PIPE_SAMR
)) {
346 fprintf (stderr
, "Could not initialize samr pipe!\n");
347 return NT_STATUS_UNSUCCESSFUL
;
350 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
353 if ((result
= cli_samr_connect(cli
, mem_ctx
, server
, MAXIMUM_ALLOWED_ACCESS
,
355 NT_STATUS_NOPROBLEMO
) {
359 got_connect_pol
= True
;
361 if ((result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
362 MAXIMUM_ALLOWED_ACCESS
,
363 &domain_sid
, &domain_pol
))
364 != NT_STATUS_NOPROBLEMO
) {
368 got_domain_pol
= True
;
370 if ((result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
371 MAXIMUM_ALLOWED_ACCESS
,
372 user_rid
, &user_pol
))
373 != NT_STATUS_NOPROBLEMO
) {
379 if ((result
= cli_samr_query_usergroups(cli
, mem_ctx
, &user_pol
,
380 &num_groups
, &user_gids
))
381 != NT_STATUS_NOPROBLEMO
) {
385 for (i
= 0; i
< num_groups
; i
++) {
386 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
387 user_gids
[i
].g_rid
, user_gids
[i
].attr
);
391 if (got_user_pol
) cli_samr_close(cli
, mem_ctx
, &user_pol
);
392 if (got_domain_pol
) cli_samr_close(cli
, mem_ctx
, &domain_pol
);
393 if (got_connect_pol
) cli_samr_close(cli
, mem_ctx
, &connect_pol
);
395 cli_nt_session_close(cli
);
396 talloc_destroy(mem_ctx
);
401 /* Query members of a group */
403 static uint32
cmd_samr_query_groupmem(struct cli_state
*cli
, int argc
, char **argv
)
405 POLICY_HND connect_pol
, domain_pol
, group_pol
;
406 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
407 BOOL got_connect_pol
= False
,
408 got_domain_pol
= False
,
409 got_group_pol
= False
;
410 uint32 num_members
, *group_rids
, *group_attrs
, group_rid
;
416 printf("Usage: %s rid\n", argv
[0]);
420 if (!(mem_ctx
=talloc_init()))
422 DEBUG(0,("cmd_samr_query_groupmem: talloc_init returned NULL!\n"));
423 return NT_STATUS_UNSUCCESSFUL
;
426 sscanf(argv
[1], "%i", &group_rid
);
428 fetch_domain_sid(cli
);
430 /* Initialise RPC connection */
431 if (!cli_nt_session_open (cli
, PIPE_SAMR
)) {
432 fprintf (stderr
, "Could not initialize samr pipe!\n");
433 return NT_STATUS_UNSUCCESSFUL
;
436 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
439 if ((result
= cli_samr_connect(cli
, mem_ctx
, server
, MAXIMUM_ALLOWED_ACCESS
,
441 NT_STATUS_NOPROBLEMO
) {
445 got_connect_pol
= True
;
447 if ((result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
448 MAXIMUM_ALLOWED_ACCESS
,
449 &domain_sid
, &domain_pol
))
450 != NT_STATUS_NOPROBLEMO
) {
454 got_domain_pol
= True
;
456 if ((result
= cli_samr_open_group(cli
, mem_ctx
, &domain_pol
,
457 MAXIMUM_ALLOWED_ACCESS
,
458 group_rid
, &group_pol
))
459 != NT_STATUS_NOPROBLEMO
) {
463 got_group_pol
= True
;
465 if ((result
= cli_samr_query_groupmem(cli
, mem_ctx
, &group_pol
,
466 &num_members
, &group_rids
,
468 != NT_STATUS_NOPROBLEMO
) {
472 for (i
= 0; i
< num_members
; i
++) {
473 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids
[i
],
478 if (got_group_pol
) cli_samr_close(cli
, mem_ctx
, &group_pol
);
479 if (got_domain_pol
) cli_samr_close(cli
, mem_ctx
, &domain_pol
);
480 if (got_connect_pol
) cli_samr_close(cli
, mem_ctx
, &connect_pol
);
482 cli_nt_session_close(cli
);
483 talloc_destroy(mem_ctx
);
488 /* Enumerate domain groups */
490 static uint32
cmd_samr_enum_dom_groups(struct cli_state
*cli
, int argc
,
493 POLICY_HND connect_pol
, domain_pol
;
494 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
495 BOOL got_connect_pol
= False
, got_domain_pol
= False
;
498 uint32 start_idx
, size
, num_dom_groups
, i
;
499 struct acct_info
*dom_groups
;
502 printf("Usage: %s\n", argv
[0]);
506 if (!(mem_ctx
= talloc_init())) {
507 DEBUG(0, ("cmd_samr_enum_dom_groups: talloc_init returned "
509 return NT_STATUS_UNSUCCESSFUL
;
512 fetch_domain_sid(cli
);
514 /* Initialise RPC connection */
516 if (!cli_nt_session_open (cli
, PIPE_SAMR
)) {
517 fprintf (stderr
, "Could not initialize samr pipe!\n");
518 return NT_STATUS_UNSUCCESSFUL
;
521 slprintf(server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
524 /* Get sam policy handle */
526 if ((result
= cli_samr_connect(cli
, mem_ctx
, server
,
527 MAXIMUM_ALLOWED_ACCESS
,
529 NT_STATUS_NOPROBLEMO
) {
533 got_connect_pol
= True
;
535 /* Get domain policy handle */
537 if ((result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
538 MAXIMUM_ALLOWED_ACCESS
,
539 &domain_sid
, &domain_pol
))
540 != NT_STATUS_NOPROBLEMO
) {
544 got_domain_pol
= True
;
546 /* Enumerate domain groups */
551 result
= cli_samr_enum_dom_groups(cli
, mem_ctx
, &domain_pol
,
553 &dom_groups
, &num_dom_groups
);
555 for (i
= 0; i
< num_dom_groups
; i
++)
556 printf("group:[%s] rid:[0x%x]\n", dom_groups
[i
].acct_name
,
560 if (got_domain_pol
) cli_samr_close(cli
, mem_ctx
, &domain_pol
);
561 if (got_connect_pol
) cli_samr_close(cli
, mem_ctx
, &connect_pol
);
563 cli_nt_session_close(cli
);
564 talloc_destroy(mem_ctx
);
569 /* Query alias membership */
571 static uint32
cmd_samr_query_aliasmem(struct cli_state
*cli
, int argc
,
574 POLICY_HND connect_pol
, domain_pol
, alias_pol
;
575 BOOL got_connect_pol
= False
, got_domain_pol
= False
,
576 got_alias_pol
= False
;
578 uint32 result
= NT_STATUS_UNSUCCESSFUL
, alias_rid
, num_members
, i
;
584 printf("Usage: %s rid\n", argv
[0]);
588 if (!(mem_ctx
=talloc_init())) {
589 DEBUG(0,("cmd_samr_query_aliasmem: talloc_init() "
590 "returned NULL!\n"));
591 return NT_STATUS_UNSUCCESSFUL
;
594 sscanf(argv
[1], "%i", &alias_rid
);
596 /* Initialise RPC connection */
598 fetch_domain_sid(cli
);
600 if (!cli_nt_session_open (cli
, PIPE_SAMR
)) {
601 fprintf (stderr
, "Could not initialize samr pipe!\n");
602 return NT_STATUS_UNSUCCESSFUL
;
605 /* Open SAMR handle */
607 slprintf(server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
610 if ((result
= cli_samr_connect(cli
, mem_ctx
, server
,
611 MAXIMUM_ALLOWED_ACCESS
,
613 NT_STATUS_NOPROBLEMO
) {
617 got_connect_pol
= True
;
619 /* Open handle on domain */
621 if ((result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
622 MAXIMUM_ALLOWED_ACCESS
,
623 &domain_sid
, &domain_pol
))
624 != NT_STATUS_NOPROBLEMO
) {
628 got_domain_pol
= True
;
630 /* Open handle on alias */
632 if ((result
= cli_samr_open_alias(cli
, mem_ctx
, &domain_pol
,
633 MAXIMUM_ALLOWED_ACCESS
,
634 alias_rid
, &alias_pol
))
635 != NT_STATUS_NOPROBLEMO
) {
639 got_alias_pol
= True
;
641 if ((result
= cli_samr_query_aliasmem(cli
, mem_ctx
, &alias_pol
,
642 &num_members
, &alias_sids
))
643 != NT_STATUS_NOPROBLEMO
) {
647 for (i
= 0; i
< num_members
; i
++) {
650 sid_to_string(sid_str
, &alias_sids
[i
]);
651 printf("\tsid:[%s]\n", sid_str
);
655 if (got_alias_pol
) cli_samr_close(cli
, mem_ctx
, &alias_pol
);
656 if (got_domain_pol
) cli_samr_close(cli
, mem_ctx
, &domain_pol
);
657 if (got_connect_pol
) cli_samr_close(cli
, mem_ctx
, &connect_pol
);
659 cli_nt_session_close(cli
);
660 talloc_destroy(mem_ctx
);
665 /* List of commands exported by this module */
667 struct cmd_set samr_commands
[] = {
668 { "SAMR", NULL
, "" },
670 { "queryuser", cmd_samr_query_user
, "Query user info" },
671 { "querygroup", cmd_samr_query_group
, "Query group info" },
672 { "queryusergroups", cmd_samr_query_usergroups
, "Query user groups" },
673 { "querygroupmem", cmd_samr_query_groupmem
, "Query group membership" },
674 { "queryaliasmem", cmd_samr_query_aliasmem
, "Query alias membership" },
675 { "enumdomgroups", cmd_samr_enum_dom_groups
, "Enumerate domain groups" },