summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h21
-rw-r--r--source3/libsmb/passchange.c6
-rw-r--r--source3/rpc_client/cli_samr.c71
-rw-r--r--source3/rpcclient/cmd_samr.c107
-rw-r--r--source3/winbindd/winbindd_pam.c18
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. */