From 19a8acda6400e17707b32e3cba721d83e5cbf987 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 15 Jan 2001 23:35:59 +0000 Subject: rpcclient functions for remaining samr and lsa functions. All functions now pass through insure except for some of the dodgy spoolss prs weirdness. (This used to be commit 76f08426a08881793b0ef32ccc4e13c54f26417f) --- source3/rpcclient/cmd_lsarpc.c | 2 +- source3/rpcclient/cmd_samr.c | 417 ++++++++++++++++++++++++++++++++++++++--- source3/rpcclient/rpcclient.c | 64 +++++++ 3 files changed, 458 insertions(+), 25 deletions(-) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index d9e5ac397f..694dd4d81a 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -64,7 +64,7 @@ static uint32 cmd_lsa_query_info_policy(int argc, char **argv) got_policy_hnd = True; - /* Lookup the names */ + /* Lookup info policy */ if ((result = cli_lsa_query_info_policy(&cli, &pol, info_class, domain_name, &dom_sid)) diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index d38aec3994..23e2fab0e7 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -1,8 +1,12 @@ +#define NEW_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 2.2 RPC pipe client + Copyright (C) Andrew Tridgell 1992-2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + Copyright (C) Elrond 2000 Copyright (C) Tim Potter 2000 This program is free software; you can redistribute it and/or modify @@ -22,61 +26,421 @@ #include "includes.h" -extern int DEBUGLEVEL; extern pstring server; +extern DOM_SID domain_sid; -static uint32 cmd_samr_connect(int argc, char **argv) +/**************************************************************************** + display sam_user_info_21 structure + ****************************************************************************/ +static void display_sam_user_info_21(SAM_USER_INFO_21 *usr) +{ + fstring temp; + + unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1); + printf("\tUser Name :\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1); + printf("\tFull Name :\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1); + printf("\tHome Drive :\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1); + printf("\tDir Drive :\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1); + printf("\tProfile Path:\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1); + printf("\tLogon Script:\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1); + printf("\tDescription :\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1); + printf("\tWorkstations:\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1); + printf("\tUnknown Str :\t%s\n", temp); + + unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1); + printf("\tRemote Dial :\t%s\n", temp); + + printf("\tLogon Time :\t%s\n", + http_timestring(nt_time_to_unix(&usr->logon_time))); + printf("\tLogoff Time :\t%s\n", + http_timestring(nt_time_to_unix(&usr->logoff_time))); + printf("\tKickoff Time :\t%s\n", + http_timestring(nt_time_to_unix(&usr->kickoff_time))); + printf("\tPassword last set Time :\t%s\n", + http_timestring(nt_time_to_unix(&usr->pass_last_set_time))); + printf("\tPassword can change Time :\t%s\n", + http_timestring(nt_time_to_unix(&usr->pass_can_change_time))); + printf("\tPassword must change Time:\t%s\n", + http_timestring(nt_time_to_unix(&usr->pass_must_change_time))); + + printf("\tunknown_2[0..31]...\n"); /* user passwords? */ + + printf("\tuser_rid :\t%x\n" , usr->user_rid ); /* User ID */ + printf("\tgroup_rid:\t%x\n" , usr->group_rid); /* Group ID */ + printf("\tacb_info :\t%04x\n", usr->acb_info ); /* Account Control Info */ + + printf("\tunknown_3:\t%08x\n", usr->unknown_3); /* 0x00ff ffff */ + printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */ + printf("\tunknown_5:\t%08x\n", usr->unknown_5); /* 0x0002 0000 */ + + printf("\tpadding1[0..7]...\n"); + + if (usr->ptr_logon_hrs) { + printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len); + } +} + +/* Query user information */ + +static uint32 cmd_samr_query_user(int argc, char **argv) { struct cli_state cli; - POLICY_HND pol, domain_pol, user_pol; - uint32 result = NT_STATUS_UNSUCCESSFUL; + POLICY_HND connect_pol, domain_pol, user_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 21; struct ntuser_creds creds; - BOOL got_policy_hnd = False, got_domain_hnd = False; - DOM_SID sid; + BOOL got_connect_pol = False, got_domain_pol = False, + got_user_pol = False; + SAM_USERINFO_CTR user_ctr; + SAM_USER_INFO_21 info_21; + + if (argc != 1) { + printf("Usage: %s\n", argv[0]); + return 0; + } + + /* Open a lsa handle */ + + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); + + if (!cli_samr_initialise(&cli, server, &creds)) { + goto done; + } + + if ((result = cli_samr_connect(&cli, server, MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + fetch_domain_sid(); + + if ((result = cli_samr_open_domain(&cli, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + if ((result = cli_samr_open_user(&cli, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + 0x1f4, &user_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_user_pol = True; + + ZERO_STRUCT(user_ctr); + ZERO_STRUCT(info_21); + + user_ctr.info.id21 = &info_21; + + if ((result = cli_samr_query_userinfo(&cli, &user_pol, info_level, + &user_ctr)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } - if (argc > 1) { + display_sam_user_info_21(&info_21); + + done: + if (got_user_pol) cli_samr_close(&cli, &user_pol); + if (got_domain_pol) cli_samr_close(&cli, &domain_pol); + if (got_connect_pol) cli_samr_close(&cli, &connect_pol); + + cli_samr_shutdown(&cli); + + return result; +} + +/**************************************************************************** + display group info + ****************************************************************************/ +static void display_group_info1(GROUP_INFO1 *info1) +{ + fstring temp; + + unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1); + printf("\tGroup Name:\t%s\n", temp); + unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1); + printf("\tDescription:\t%s\n", temp); + printf("\tunk1:%d\n", info1->unknown_1); + printf("\tNum Members:%d\n", info1->num_members); +} + +/**************************************************************************** + display group info + ****************************************************************************/ +static void display_group_info4(GROUP_INFO4 *info4) +{ + fstring desc; + + unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1); + printf("\tGroup Description:%s\n", desc); +} + +/**************************************************************************** + display sam sync structure + ****************************************************************************/ +static void display_group_info_ctr(GROUP_INFO_CTR *ctr) +{ + switch (ctr->switch_value1) { + case 1: { + display_group_info1(&ctr->group.info1); + break; + } + case 4: { + display_group_info4(&ctr->group.info4); + break; + } + } +} + +/* Query group information */ + +static uint32 cmd_samr_query_group(int argc, char **argv) +{ + struct cli_state cli; + POLICY_HND connect_pol, domain_pol, group_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1; + struct ntuser_creds creds; + BOOL got_connect_pol = False, got_domain_pol = False, + got_group_pol = False; + GROUP_INFO_CTR group_ctr; + + if (argc != 1) { printf("Usage: %s\n", argv[0]); return 0; } - /* Open a sam handle */ + /* Open a lsa handle */ ZERO_STRUCT(cli); init_rpcclient_creds(&creds); - if (cli_samr_initialise(&cli, server, &creds) == NULL) { + if (!cli_samr_initialise(&cli, server, &creds)) { goto done; } + + if ((result = cli_samr_connect(&cli, server, MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + fetch_domain_sid(); - if ((result = cli_samr_connect(&cli, server, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &pol)) != NT_STATUS_NOPROBLEMO) { + if ((result = cli_samr_open_domain(&cli, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { goto done; } - got_policy_hnd = True; + got_domain_pol = True; - string_to_sid(&sid, "S-1-5-21-1067277791-1719175008-3000797951"); + if ((result = cli_samr_open_group(&cli, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + 0x202, &group_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_group_pol = True; - if ((result = cli_samr_open_domain(&cli, &pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &sid, &domain_pol)) + ZERO_STRUCT(group_ctr); + + if ((result = cli_samr_query_groupinfo(&cli, &group_pol, info_level, + &group_ctr)) != NT_STATUS_NOPROBLEMO) { goto done; } - got_domain_hnd = True; + display_group_info_ctr(&group_ctr); + + done: + if (got_group_pol) cli_samr_close(&cli, &group_pol); + if (got_domain_pol) cli_samr_close(&cli, &domain_pol); + if (got_connect_pol) cli_samr_close(&cli, &connect_pol); + + cli_samr_shutdown(&cli); + + return result; +} + +/* Query groups a user is a member of */ + +static uint32 cmd_samr_query_usergroups(int argc, char **argv) +{ + struct cli_state cli; + POLICY_HND connect_pol, domain_pol, user_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + struct ntuser_creds creds; + BOOL got_connect_pol = False, got_domain_pol = False, + got_user_pol = False; + uint32 num_groups, user_rid; + DOM_GID *user_gids; + int i; + + if (argc != 2) { + printf("Usage: %s rid/name\n", argv[0]); + return 0; + } + + sscanf(argv[1], "%i", &user_rid); + + /* Open a lsa handle */ + + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); + + if (!cli_samr_initialise(&cli, server, &creds)) { + goto done; + } + + if ((result = cli_samr_connect(&cli, server, MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + fetch_domain_sid(); + + if ((result = cli_samr_open_domain(&cli, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; if ((result = cli_samr_open_user(&cli, &domain_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, 500, - &user_pol)) + MAXIMUM_ALLOWED_ACCESS, + user_rid, &user_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_user_pol = True; + + if ((result = cli_samr_query_usergroups(&cli, &user_pol, + &num_groups, &user_gids)) != NT_STATUS_NOPROBLEMO) { goto done; } -done: - if (got_domain_hnd) cli_samr_close(&cli, &domain_pol); - if (got_policy_hnd) cli_samr_close(&cli, &pol); + for (i = 0; i < num_groups; i++) { + printf("\tgroup rid:[0x%x] attr:[0x%x]\n", + user_gids[i].g_rid, user_gids[i].attr); + } + + done: + if (got_user_pol) cli_samr_close(&cli, &user_pol); + if (got_domain_pol) cli_samr_close(&cli, &domain_pol); + if (got_connect_pol) cli_samr_close(&cli, &connect_pol); + + cli_samr_shutdown(&cli); + + return result; +} + +/* Query members of a group */ + +static uint32 cmd_samr_query_groupmem(int argc, char **argv) +{ + struct cli_state cli; + POLICY_HND connect_pol, domain_pol, group_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + struct ntuser_creds creds; + BOOL got_connect_pol = False, got_domain_pol = False, + got_group_pol = False; + uint32 num_members, *group_rids, *group_attrs, group_rid; + int i; + + if (argc != 2) { + printf("Usage: %s rid/name\n", argv[0]); + return 0; + } + + sscanf(argv[1], "%i", &group_rid); + + /* Open a lsa handle */ + + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); + + if (!cli_samr_initialise(&cli, server, &creds)) { + goto done; + } + + if ((result = cli_samr_connect(&cli, server, MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + fetch_domain_sid(); + + if ((result = cli_samr_open_domain(&cli, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + if ((result = cli_samr_open_group(&cli, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rid, &group_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_group_pol = True; + + if ((result = cli_samr_query_groupmem(&cli, &group_pol, + &num_members, &group_rids, + &group_attrs)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + for (i = 0; i < num_members; i++) { + printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i], + group_attrs[i]); + } + + done: + if (got_group_pol) cli_samr_close(&cli, &group_pol); + if (got_domain_pol) cli_samr_close(&cli, &domain_pol); + if (got_connect_pol) cli_samr_close(&cli, &connect_pol); + + cli_samr_shutdown(&cli); return result; } @@ -84,6 +448,11 @@ done: /* List of commands exported by this module */ struct cmd_set samr_commands[] = { - { "samconnect", cmd_samr_connect, "Test" }, + { "queryuser", cmd_samr_query_user, "Query user info" }, + { "querygroup", cmd_samr_query_group, "Query group info" }, + { "queryusergroups", cmd_samr_query_usergroups, "Query user groups" }, + { "querygroupmem", cmd_samr_query_groupmem, "Query group membership" }, { NULL, NULL, NULL } }; + +#undef NEW_NTDOMAIN diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 91cf722120..7f2779fc6a 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -24,6 +24,8 @@ extern int DEBUGLEVEL; +/* Connect info */ + pstring password; pstring username; pstring workgroup; @@ -35,6 +37,58 @@ extern struct cmd_set lsarpc_commands[]; extern struct cmd_set samr_commands[]; extern struct cmd_set spoolss_commands[]; +DOM_SID domain_sid; + +/* Fetch the SID for this domain */ + +void fetch_domain_sid(void) +{ + struct cli_state cli; + POLICY_HND pol; + uint32 result = 0, info_class = 5; + struct ntuser_creds creds; + fstring domain_name; + static BOOL got_domain_sid; + + if (got_domain_sid) return; + + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); + + if (cli_lsa_initialise(&cli, server, &creds) == NULL) { + fprintf(stderr, "could not initialise lsa pipe\n"); + goto error; + } + + if ((result = cli_lsa_open_policy(&cli, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol) != NT_STATUS_NOPROBLEMO)) { + goto error; + } + + if ((result = cli_lsa_query_info_policy(&cli, &pol, info_class, + domain_name, &domain_sid)) + != NT_STATUS_NOPROBLEMO) { + goto error; + } + + got_domain_sid = True; + + cli_lsa_close(&cli, &pol); + cli_lsa_shutdown(&cli); + + return; + + error: + fprintf(stderr, "could not obtain sid for domain %s\n", workgroup); + + if (result != NT_STATUS_NOPROBLEMO) { + fprintf(stderr, "error: %s\n", get_nt_error_msg(result)); + } + + exit(1); +} + /* Initialise client credentials for authenticated pipe access */ void init_rpcclient_creds(struct ntuser_creds *creds) @@ -91,11 +145,17 @@ static uint32 cmd_debuglevel(int argc, char **argv) return NT_STATUS_NOPROBLEMO; } +static uint32 cmd_quit(int argc, char **argv) +{ + exit(0); +} + /* Build in rpcclient commands */ static struct cmd_set rpcclient_commands[] = { { "help", cmd_help, "Print list of commands" }, { "debuglevel", cmd_debuglevel, "Set debug level" }, + { "quit", cmd_quit, "Exit program" }, { "?", cmd_help, "Print list of commands" }, { NULL, NULL, NULL } @@ -235,6 +295,7 @@ static void usage(char *pname) extern char *optarg; extern int optind; struct in_addr dest_ip; + extern pstring global_myname; BOOL got_pass = False; BOOL have_ip = False; int opt; @@ -265,6 +326,9 @@ static void usage(char *pname) TimeInit(); + get_myname((*global_myname)?NULL:global_myname); + strupper(global_myname); + /* Parse options */ if (argc < 2) { -- cgit