diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/rpc_samr.h | 8 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 53 | ||||
-rw-r--r-- | source3/utils/net_help.c | 3 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 128 |
4 files changed, 190 insertions, 2 deletions
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 9945f674c8..a007bcd2e5 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -412,6 +412,13 @@ typedef struct sam_user_info_10 } SAM_USER_INFO_10; +/* SAM_USER_INFO_7 */ +typedef struct sam_user_info_7 +{ + UNIHDR hdr_name; /* unicode header for name */ + UNISTR2 uni_name; /* unicode string for name */ + +} SAM_USER_INFO_7; /* SAMR_Q_CLOSE_HND - probably a policy handle close */ @@ -1273,6 +1280,7 @@ typedef struct sam_userinfo_ctr_info union { + SAM_USER_INFO_7 *id7; /* auth-level 0x07 */ SAM_USER_INFO_10 *id10; /* auth-level 0x10 */ SAM_USER_INFO_11 *id11; /* auth-level 0x11 */ SAM_USER_INFO_12 *id12; /* auth-level 0x12 */ diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 8d5fee68e0..748ee1fb7c 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5207,6 +5207,44 @@ static BOOL sam_io_user_info12(const char *desc, SAM_USER_INFO_12 * u, } /******************************************************************* +inits a SAM_USER_INFO_7 structure. +********************************************************************/ + +void init_sam_user_info7(SAM_USER_INFO_7 * usr, const char *name) +{ + DEBUG(5, ("init_sam_user_info7\n")); + + init_unistr2(&usr->uni_name, name, UNI_FLAGS_NONE); /* unicode string for name */ + init_uni_hdr(&usr->hdr_name, &usr->uni_name); /* unicode header for name */ + +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +static BOOL sam_io_user_info7(const char *desc, SAM_USER_INFO_7 * usr, + prs_struct *ps, int depth) +{ + if (usr == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_r_user_info7"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_unihdr("unihdr", &usr->hdr_name, ps, depth)) + return False; + + if(!smb_io_unistr2("unistr2", &usr->uni_name, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* inits a SAM_USER_INFO_10 structure. ********************************************************************/ @@ -6277,7 +6315,7 @@ NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr, uint16 switch_value, SAM_USER_INFO_21 * usr) { - DEBUG(5, ("init_samr_userinfo_ctr\n")); + DEBUG(5, ("make_samr_userinfo_ctr_usr21\n")); ctr->switch_value = switch_value; ctr->info.id = NULL; @@ -6360,8 +6398,10 @@ static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key, dump_data(100, (char *)sess_key->data, sess_key->length); dump_data(100, (char *)ctr->info.id23->pass, 516); break; + case 0x07: + break; default: - DEBUG(4,("init_samr_userinfo_ctr: unsupported switch level\n")); + DEBUG(4,("init_samr_userinfo_ctr: unsupported switch level: %d\n", switch_value)); } } @@ -6397,6 +6437,15 @@ static BOOL samr_io_userinfo_ctr(const char *desc, SAM_USERINFO_CTR **ppctr, ret = False; switch (ctr->switch_value) { + case 0x07: + if (UNMARSHALLING(ps)) + ctr->info.id7 = PRS_ALLOC_MEM(ps,SAM_USER_INFO_7,1); + if (ctr->info.id7 == NULL) { + DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n")); + return False; + } + ret = sam_io_user_info7("", ctr->info.id7, ps, depth); + break; case 0x10: if (UNMARSHALLING(ps)) ctr->info.id10 = PRS_ALLOC_MEM(ps,SAM_USER_INFO_10,1); diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 8286e85321..328e134459 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -76,6 +76,9 @@ int net_help_user(int argc, const char **argv) d_printf("\nnet [<method>] user ADD <name> [password] [-c container] "\ "[-F user flags] [misc. options]"\ " [targets]\n\tAdd specified user\n"); + d_printf("\nnet [<method>] user RENAME <oldusername> <newusername>"\ + " [targets]\n\tRename specified user\n\n"); + net_common_methods_usage(argc, argv); net_common_flags_usage(argc, argv); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 5374d48de6..430649d81b 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -670,6 +670,133 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, } /** + * Rename a user on a remote RPC server + * + * All parameters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { + + POLICY_HND connect_pol, domain_pol, user_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 info_level = 7; + const char *old_name, *new_name; + uint32 *user_rid; + uint32 flags = 0x000003e8; /* Unknown */ + uint32 num_rids, *name_types; + uint32 num_names = 1; + const char **names; + SAM_USERINFO_CTR *user_ctr; + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_7 info7; + + if (argc != 2) { + d_printf("New and old username must be specified\n"); + rpc_user_usage(argc, argv); + return NT_STATUS_OK; + } + + old_name = argv[0]; + new_name = argv[1]; + + ZERO_STRUCT(ctr); + ZERO_STRUCT(user_ctr); + + /* Get sam policy handle */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + names = TALLOC_ARRAY(mem_ctx, const char *, num_names); + names[0] = old_name; + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, + flags, num_names, names, + &num_rids, &user_rid, &name_types); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Open domain user */ + result = cli_samr_open_user(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Query user info */ + result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, + info_level, &user_ctr); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + ctr.switch_value = info_level; + ctr.info.id7 = &info7; + + init_sam_user_info7(&info7, new_name); + + /* Set new name */ + result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, + info_level, &cli->user_session_key, &ctr); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + done: + if (!NT_STATUS_IS_OK(result)) { + d_printf("Failed to rename user from %s to %s - %s\n", old_name, new_name, + nt_errstr(result)); + } else { + d_printf("Renamed user from %s to %s\n", old_name, new_name); + } + return result; +} + + +/** + * Rename a user on a remote RPC server + * + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + +static int rpc_user_rename(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals, + argc, argv); +} + +/** * Delete a user from a remote RPC server * * @param argc Standard main() style argc @@ -1011,6 +1138,7 @@ int net_rpc_user(int argc, const char **argv) {"info", rpc_user_info}, {"delete", rpc_user_delete}, {"password", rpc_user_password}, + {"rename", rpc_user_rename}, {NULL, NULL} }; |