diff options
-rw-r--r-- | source3/include/proto.h | 21 | ||||
-rw-r--r-- | source3/libsmb/passchange.c | 6 | ||||
-rw-r--r-- | source3/rpc_client/cli_samr.c | 71 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 107 | ||||
-rw-r--r-- | source3/winbindd/winbindd_pam.c | 18 |
5 files changed, 187 insertions, 36 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 1aca7f436d..1eb5fbda03 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7146,9 +7146,14 @@ uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val ); NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - const char *username, + struct policy_handle *user_handle, const char *newpassword, const char *oldpassword); +NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *username, + const char *newpassword, + const char *oldpassword); NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *username, @@ -7156,13 +7161,13 @@ NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli, DATA_BLOB old_nt_hash_enc_blob, DATA_BLOB new_lm_password_blob, DATA_BLOB old_lm_hash_enc_blob); -NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *username, - const char *newpassword, - const char *oldpassword, - struct samr_DomInfo1 **dominfo1, - struct samr_ChangeReject **reject); +NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *username, + const char *newpassword, + const char *oldpassword, + struct samr_DomInfo1 **dominfo1, + struct samr_ChangeReject **reject); void get_query_dispinfo_params(int loop_count, uint32 *max_entries, uint32 *max_size); NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli, diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 8f7cbf265e..3b82e5767f 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -177,8 +177,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } } - result = rpccli_samr_chgpasswd_user(pipe_hnd, talloc_tos(), - user_name, new_passwd, old_passwd); + result = rpccli_samr_chgpasswd_user2(pipe_hnd, talloc_tos(), + user_name, new_passwd, old_passwd); if (NT_STATUS_IS_OK(result)) { /* Great - it all worked! */ cli_shutdown(cli); @@ -207,7 +207,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && - (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user( + (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user2( pipe_hnd, talloc_tos(), user_name, new_passwd, old_passwd)))) { /* Great - it all worked! */ diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 21fecc4196..ed42d56a02 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -27,11 +27,64 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - const char *username, + struct policy_handle *user_handle, const char *newpassword, const char *oldpassword) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6; + + uchar old_nt_hash[16]; + uchar old_lm_hash[16]; + uchar new_nt_hash[16]; + uchar new_lm_hash[16]; + + ZERO_STRUCT(old_nt_hash); + ZERO_STRUCT(old_lm_hash); + ZERO_STRUCT(new_nt_hash); + ZERO_STRUCT(new_lm_hash); + + DEBUG(10,("rpccli_samr_chgpasswd_user\n")); + + E_md4hash(oldpassword, old_nt_hash); + E_md4hash(newpassword, new_nt_hash); + + E_deshash(oldpassword, old_lm_hash); + E_deshash(newpassword, new_lm_hash); + + E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash); + E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash); + E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash); + E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash); + E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash); + E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash); + + result = rpccli_samr_ChangePasswordUser(cli, mem_ctx, + user_handle, + true, + &hash1, + &hash2, + true, + &hash3, + &hash4, + true, + &hash5, + true, + &hash6); + + return result; +} + + +/* User change password */ + +NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *username, + const char *newpassword, + const char *oldpassword) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; struct samr_Password old_nt_hash_enc; @@ -43,7 +96,7 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli, uchar new_lanman_hash[16]; struct lsa_String server, account; - DEBUG(10,("rpccli_samr_chgpasswd_user\n")); + DEBUG(10,("rpccli_samr_chgpasswd_user2\n")); init_lsa_String(&server, cli->srv_name_slash); init_lsa_String(&account, username); @@ -127,13 +180,13 @@ NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli, /* change password 3 */ -NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *username, - const char *newpassword, - const char *oldpassword, - struct samr_DomInfo1 **dominfo1, - struct samr_ChangeReject **reject) +NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *username, + const char *newpassword, + const char *oldpassword, + struct samr_DomInfo1 **dominfo1, + struct samr_ChangeReject **reject) { NTSTATUS status; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index cc92fef7e5..e25a358cd3 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -2424,6 +2424,98 @@ done: /* Change user password */ +static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + POLICY_HND connect_pol, domain_pol, user_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + const char *user, *oldpass, *newpass; + uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; + struct samr_Ids rids, types; + struct lsa_String lsa_acct_name; + + if (argc < 3) { + printf("Usage: %s username oldpass newpass\n", argv[0]); + return NT_STATUS_INVALID_PARAMETER; + } + + user = argv[1]; + oldpass = argv[2]; + newpass = argv[3]; + + /* Get sam policy handle */ + + result = rpccli_try_samr_connects(cli, mem_ctx, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + + result = rpccli_samr_OpenDomain(cli, mem_ctx, + &connect_pol, + access_mask, + &domain_sid, + &domain_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + init_lsa_String(&lsa_acct_name, user); + + result = rpccli_samr_LookupNames(cli, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &types); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_samr_OpenUser(cli, mem_ctx, + &domain_pol, + access_mask, + rids.ids[0], + &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Change user password */ + result = rpccli_samr_chgpasswd_user(cli, mem_ctx, + &user_pol, + newpass, + oldpass); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&user_pol)) { + rpccli_samr_Close(cli, mem_ctx, &user_pol); + } + if (is_valid_policy_hnd(&domain_pol)) { + rpccli_samr_Close(cli, mem_ctx, &domain_pol); + } + if (is_valid_policy_hnd(&connect_pol)) { + rpccli_samr_Close(cli, mem_ctx, &connect_pol); + } + + return result; +} + + +/* Change user password */ + static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -2463,7 +2555,7 @@ static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli, goto done; /* Change user password */ - result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass); + result = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass); if (!NT_STATUS_IS_OK(result)) goto done; @@ -2522,12 +2614,12 @@ static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli, goto done; /* Change user password */ - result = rpccli_samr_chgpasswd3(cli, mem_ctx, - user, - newpass, - oldpass, - &info, - &reject); + result = rpccli_samr_chgpasswd_user3(cli, mem_ctx, + user, + newpass, + oldpass, + &info, + &reject); if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) { @@ -2663,6 +2755,7 @@ struct cmd_set samr_commands[] = { { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" }, { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" }, + { "chgpasswd", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd, NULL, PI_SAMR, NULL, "Change user password", "" }, { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, PI_SAMR, NULL, "Change user password", "" }, { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, PI_SAMR, NULL, "Change user password", "" }, { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, PI_SAMR, NULL, "Get Display Information Index", "" }, diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index f548a04d35..f7001f7716 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -2066,12 +2066,12 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact goto done; } - result = rpccli_samr_chgpasswd3(cli, state->mem_ctx, - user, - newpass, - oldpass, - &info, - &reject); + result = rpccli_samr_chgpasswd_user3(cli, state->mem_ctx, + user, + newpass, + oldpass, + &info, + &reject); /* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */ @@ -2093,15 +2093,15 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact got_info = True; } - /* only fallback when the chgpasswd3 call is not supported */ + /* only fallback when the chgpasswd_user3 call is not supported */ if ((NT_STATUS_EQUAL(result, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR))) || (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) || (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED))) { - DEBUG(10,("Password change with chgpasswd3 failed with: %s, retrying chgpasswd_user\n", + DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n", nt_errstr(result))); - result = rpccli_samr_chgpasswd_user(cli, state->mem_ctx, user, newpass, oldpass); + result = rpccli_samr_chgpasswd_user2(cli, state->mem_ctx, user, newpass, oldpass); /* Windows 2000 returns NT_STATUS_ACCOUNT_RESTRICTION. Map to the same status code as Windows 2003. */ |