diff options
-rw-r--r-- | source/libsmb/cli_samr.c | 230 | ||||
-rw-r--r-- | source/rpcclient/cmd_samr.c | 208 |
2 files changed, 342 insertions, 96 deletions
diff --git a/source/libsmb/cli_samr.c b/source/libsmb/cli_samr.c index 985a0a1ecb1..9fb7e078f67 100644 --- a/source/libsmb/cli_samr.c +++ b/source/libsmb/cli_samr.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 2.2 RPC pipe client - Copyright (C) Tim Potter 2000, + Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, @@ -84,18 +84,14 @@ void cli_samr_shutdown(struct cli_state *cli) /* Connect to SAMR database */ -uint32 cli_samr_connect( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *srv_name, - uint32 access_mask, - POLICY_HND *connect_pol -) +uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *srv_name, uint32 access_mask, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CONNECT q; SAMR_R_CONNECT r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -111,14 +107,12 @@ uint32 cli_samr_connect( if (!samr_io_q_connect("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_connect("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -137,16 +131,13 @@ uint32 cli_samr_connect( /* Close SAMR handle */ -uint32 cli_samr_close( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol -) +uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CLOSE_HND q; SAMR_R_CLOSE_HND r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -162,14 +153,12 @@ uint32 cli_samr_close( if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -188,19 +177,14 @@ uint32 cli_samr_close( /* Open handle on a domain */ -uint32 cli_samr_open_domain( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, - uint32 access_mask, - DOM_SID *domain_sid, - POLICY_HND *domain_pol -) +uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol, uint32 access_mask, + DOM_SID *domain_sid, POLICY_HND *domain_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_DOMAIN q; SAMR_R_OPEN_DOMAIN r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -216,14 +200,12 @@ uint32 cli_samr_open_domain( if (!samr_io_q_open_domain("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -242,19 +224,14 @@ uint32 cli_samr_open_domain( /* Open handle on a user */ -uint32 cli_samr_open_user( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, - uint32 access_mask, - uint32 user_rid, - POLICY_HND *user_pol -) +uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 user_rid, POLICY_HND *user_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_USER q; SAMR_R_OPEN_USER r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -270,14 +247,12 @@ uint32 cli_samr_open_user( if (!samr_io_q_open_user("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_user("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -296,19 +271,14 @@ uint32 cli_samr_open_user( /* Open handle on a group */ -uint32 cli_samr_open_group( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, - uint32 access_mask, - uint32 group_rid, - POLICY_HND *group_pol -) +uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 group_rid, POLICY_HND *group_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_GROUP q; SAMR_R_OPEN_GROUP r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -324,14 +294,12 @@ uint32 cli_samr_open_group( if (!samr_io_q_open_group("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_group("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -350,18 +318,14 @@ uint32 cli_samr_open_group( /* Query user info */ -uint32 cli_samr_query_userinfo( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, - uint16 switch_value, - SAM_USERINFO_CTR *ctr -) +uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERINFO q; SAMR_R_QUERY_USERINFO r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -377,7 +341,6 @@ uint32 cli_samr_query_userinfo( if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -386,7 +349,6 @@ uint32 cli_samr_query_userinfo( r.ctr = ctr; if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -403,18 +365,14 @@ uint32 cli_samr_query_userinfo( /* Query group info */ -uint32 cli_samr_query_groupinfo( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, - uint32 info_level, - GROUP_INFO_CTR *ctr -) +uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 info_level, + GROUP_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPINFO q; SAMR_R_QUERY_GROUPINFO r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -430,7 +388,6 @@ uint32 cli_samr_query_groupinfo( if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -439,7 +396,6 @@ uint32 cli_samr_query_groupinfo( r.ctr = ctr; if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -456,18 +412,14 @@ uint32 cli_samr_query_groupinfo( /* Query user groups */ -uint32 cli_samr_query_usergroups( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, - uint32 *num_groups, - DOM_GID **gid -) +uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint32 *num_groups, + DOM_GID **gid) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERGROUPS q; SAMR_R_QUERY_USERGROUPS r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -483,14 +435,12 @@ uint32 cli_samr_query_usergroups( if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -510,19 +460,14 @@ uint32 cli_samr_query_usergroups( /* Query user groups */ -uint32 cli_samr_query_groupmem( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, - uint32 *num_mem, - uint32 **rid, - uint32 **attr -) +uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 *num_mem, + uint32 **rid, uint32 **attr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPMEM q; SAMR_R_QUERY_GROUPMEM r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -538,14 +483,12 @@ uint32 cli_samr_query_groupmem( if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -747,3 +690,104 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Query domain info */ + +uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint16 switch_value, + SAM_UNK_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_DOMAIN_INFO q; + SAMR_R_QUERY_DOMAIN_INFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_dom_info(&q, domain_pol, switch_value); + + if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query display info */ + +uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 *start_idx, + uint16 switch_value, uint32 *num_entries, + uint32 max_entries, SAM_DISPINFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_DISPINFO q; + SAMR_R_QUERY_DISPINFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_dispinfo(&q, domain_pol, switch_value, + *start_idx, max_entries); + + if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + *num_entries = r.num_entries; + *start_idx += r.num_entries; /* No next_idx in this structure! */ + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c index d199e65b95a..931d44eb3b1 100644 --- a/source/rpcclient/cmd_samr.c +++ b/source/rpcclient/cmd_samr.c @@ -94,6 +94,31 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr) } } +static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2) +{ + fstring name; + + unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1); + printf("Domain:\t%s\n", name); + + unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1); + printf("Server:\t%s\n", name); + + printf("Total Users:\t%d\n", info2->num_domain_usrs); + printf("Total Groups:\t%d\n", info2->num_domain_grps); + printf("Total Aliases:\t%d\n", info2->num_local_grps); + + printf("Sequence No:\t%d\n", info2->seq_num); + + printf("Unknown 0:\t0x%x\n", info2->unknown_0); + printf("Unknown 1:\t0x%x\n", info2->unknown_1); + printf("Unknown 2:\t0x%x\n", info2->unknown_2); + printf("Unknown 3:\t0x%x\n", info2->unknown_3); + printf("Unknown 4:\t0x%x\n", info2->unknown_4); + printf("Unknown 5:\t0x%x\n", info2->unknown_5); + printf("Unknown 6:\t0x%x\n", info2->unknown_6); +} + /********************************************************************** * Query user information */ @@ -109,13 +134,16 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) SAM_USER_INFO_21 info_21; fstring server; TALLOC_CTX *mem_ctx; + uint32 user_rid; - if (argc != 1) { - printf("Usage: %s\n", argv[0]); + if (argc != 2) { + printf("Usage: %s rid\n", argv[0]); return 0; } + sscanf(argv[1], "%i", &user_rid); + if (!(mem_ctx=talloc_init())) { DEBUG(0,("cmd_samr_query_user: talloc_init returned NULL!\n")); @@ -152,7 +180,7 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol, MAXIMUM_ALLOWED_ACCESS, - 0x1f4, &user_pol)) + user_rid, &user_pol)) != NT_STATUS_NOPROBLEMO) { goto done; } @@ -662,6 +690,178 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc, return result; } +/* Query display info */ + +static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc, + char **argv) +{ + POLICY_HND connect_pol, domain_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_connect_pol = False, got_domain_pol = False; + TALLOC_CTX *mem_ctx; + fstring server; + uint32 start_idx, size, num_dom_groups, i; + struct acct_info *dom_groups; + + if (argc != 1) { + printf("Usage: %s\n", argv[0]); + return 0; + } + + if (!(mem_ctx = talloc_init())) { + DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned " + "NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_SAMR)) { + fprintf (stderr, "Could not initialize samr pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper(server); + + /* Get sam policy handle */ + + if ((result = cli_samr_connect(cli, mem_ctx, server, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + + /* Get domain policy handle */ + + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + /* Query display info */ + + start_idx = 0; + size = 0xffff; + + result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol, + &start_idx, size, + &dom_groups, &num_dom_groups); + + for (i = 0; i < num_dom_groups; i++) + printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name, + dom_groups[i].rid); + + done: + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + +/* Query domain info */ + +static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc, + char **argv) +{ + POLICY_HND connect_pol, domain_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_connect_pol = False, got_domain_pol = False; + TALLOC_CTX *mem_ctx; + fstring server; + uint16 switch_value = 2; + SAM_UNK_CTR ctr; + + if (argc > 2) { + printf("Usage: %s [infolevel\n", argv[0]); + return 0; + } + + if (argc == 2) + switch_value = atoi(argv[1]); + + if (!(mem_ctx = talloc_init())) { + DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned " + "NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_SAMR)) { + fprintf (stderr, "Could not initialize samr pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper(server); + + /* Get sam policy handle */ + + if ((result = cli_samr_connect(cli, mem_ctx, server, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + + /* Get domain policy handle */ + + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + /* Query domain info */ + + if ((result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol, + switch_value, &ctr)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + /* Display domain info */ + + switch (switch_value) { + case 2: + display_sam_unk_info_2(&ctr.info.inf2); + break; + default: + printf("cannot display domain info for switch value %d\n", + switch_value); + break; + } + + done: + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + /* List of commands exported by this module */ struct cmd_set samr_commands[] = { @@ -672,6 +872,8 @@ struct cmd_set samr_commands[] = { { "queryusergroups", cmd_samr_query_usergroups, "Query user groups" }, { "querygroupmem", cmd_samr_query_groupmem, "Query group membership" }, { "queryaliasmem", cmd_samr_query_aliasmem, "Query alias membership" }, + { "querydispinfo", cmd_samr_query_dispinfo, "Query display info" }, + { "querydominfo", cmd_samr_query_dominfo, "Query domain info" }, { "enumdomgroups", cmd_samr_enum_dom_groups, "Enumerate domain groups" }, { NULL, NULL, NULL } |