summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c21
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c27
-rw-r--r--source4/rpc_server/samr/samr_password.c88
3 files changed, 70 insertions, 66 deletions
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 9cda7d0d89..4c596f1f03 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -968,19 +968,14 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc
mem_ctx, msg_user, "unicodePwd",
&auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
} else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
- struct samr_Password hash;
-/*
- . We cannot do this, as windows chooses to send in random passwords here, that won't convert to UTF8
- samdb_msg_add_string(trusted_domain_state->policy->sam_ldb,
- mem_ctx, msg_user, "userPassword",
- auth_struct.incoming.current->array[i].AuthInfo.clear.password);
-*/
- mdfour(hash.hash, auth_struct.incoming.current[i]->AuthInfo.clear.password,
- auth_struct.incoming.current[i]->AuthInfo.clear.size);
- samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
- mem_ctx, msg_user, "unicodePwd",
- &hash);
- }
+ DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
+ auth_struct.incoming.current[i]->AuthInfo.clear.size);
+ ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
+ if (ret != LDB_SUCCESS) {
+ ldb_transaction_cancel(policy_state->sam_ldb);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
}
}
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 470c27a075..9d4c897892 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -107,7 +107,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
- char *flatname;
+ const char *flatname;
if (!encoded_account) {
return NT_STATUS_NO_MEMORY;
}
@@ -370,7 +370,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
creds->sid,
NULL, /* Don't have plaintext */
NULL, &r->in.new_password,
- false, /* This is not considered a password change */
+ true, /* Password change */
NULL, NULL);
return nt_status;
}
@@ -385,15 +385,14 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
struct creds_CredentialState *creds;
struct ldb_context *sam_ctx;
NTSTATUS nt_status;
- char new_pass[512];
- bool ret;
+ DATA_BLOB new_password;
struct samr_CryptPassword password_buf;
nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
r->in.computer_name, mem_ctx,
- &r->in.credential, &r->out.return_authenticator,
- &creds);
+ &r->in.credential, &r->out.return_authenticator,
+ &creds);
NT_STATUS_NOT_OK_RETURN(nt_status);
sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
@@ -402,22 +401,20 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
}
memcpy(password_buf.data, r->in.new_password.data, 512);
- SIVAL(password_buf.data,512,r->in.new_password.length);
+ SIVAL(password_buf.data, 512, r->in.new_password.length);
creds_arcfour_crypt(creds, password_buf.data, 516);
- ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
- STR_UNICODE);
- if (!ret) {
- DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
- return NT_STATUS_ACCESS_DENIED;
+ if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
+ DEBUG(3,("samr: failed to decode password buffer\n"));
+ return NT_STATUS_WRONG_PASSWORD;
}
-
+
/* Using the sid for the account as the key, set the password */
nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
creds->sid,
- new_pass, /* we have plaintext */
+ &new_password, /* we have plaintext */
NULL, NULL,
- false, /* This is not considered a password change */
+ true, /* Password change */
NULL, NULL);
return nt_status;
}
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 8a855a7bdb..336720ecc7 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -86,7 +86,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call,
}
msg = res[0];
- status = samdb_result_passwords(mem_ctx, msg, &lm_pwd, &nt_pwd);
+ status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
+ msg, &lm_pwd, &nt_pwd);
if (!NT_STATUS_IS_OK(status) || !lm_pwd || !nt_pwd) {
ldb_transaction_cancel(sam_ctx);
return NT_STATUS_WRONG_PASSWORD;
@@ -183,8 +184,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
struct samr_OemChangePasswordUser2 *r)
{
NTSTATUS status;
- char new_pass[512];
- uint32_t new_pass_len;
+ DATA_BLOB new_password;
+ char *new_pass;
struct samr_CryptPassword *pwbuf = r->in.password;
struct ldb_context *sam_ctx;
struct ldb_dn *user_dn;
@@ -231,7 +232,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
user_dn = res[0]->dn;
- status = samdb_result_passwords(mem_ctx, res[0], &lm_pwd, NULL);
+ status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
+ res[0], &lm_pwd, NULL);
if (!NT_STATUS_IS_OK(status) || !lm_pwd) {
ldb_transaction_cancel(sam_ctx);
return NT_STATUS_WRONG_PASSWORD;
@@ -242,15 +244,18 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
arcfour_crypt_blob(pwbuf->data, 516, &lm_pwd_blob);
data_blob_free(&lm_pwd_blob);
- if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass),
- STR_ASCII)) {
+ if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) {
ldb_transaction_cancel(sam_ctx);
DEBUG(3,("samr: failed to decode password buffer\n"));
return NT_STATUS_WRONG_PASSWORD;
}
-
- /* check LM verifier */
- if (lm_pwd == NULL) {
+
+ if (convert_string_talloc(mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
+ CH_DOS, CH_UNIX,
+ (const char *)new_password.data,
+ new_password.length,
+ (void **)&new_pass) == -1) {
+ DEBUG(3,("samr: failed to convert incoming password buffer to unix charset\n"));
ldb_transaction_cancel(sam_ctx);
return NT_STATUS_WRONG_PASSWORD;
}
@@ -278,7 +283,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
* due to password policies */
status = samdb_set_password(sam_ctx, mem_ctx,
user_dn, NULL,
- mod, new_pass,
+ mod, &new_password,
NULL, NULL,
true, /* this is a user password change */
NULL,
@@ -320,7 +325,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
struct samr_ChangePasswordUser3 *r)
{
NTSTATUS status;
- char new_pass[512];
+ DATA_BLOB new_password;
struct ldb_context *sam_ctx = NULL;
struct ldb_dn *user_dn;
int ret;
@@ -369,7 +374,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
user_dn = res[0]->dn;
- status = samdb_result_passwords(mem_ctx, res[0], &lm_pwd, &nt_pwd);
+ status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
+ res[0], &lm_pwd, &nt_pwd);
if (!NT_STATUS_IS_OK(status) ) {
goto failed;
}
@@ -384,40 +390,49 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
arcfour_crypt_blob(r->in.nt_password->data, 516, &nt_pwd_blob);
data_blob_free(&nt_pwd_blob);
- if (!decode_pw_buffer(r->in.nt_password->data, new_pass, sizeof(new_pass),
- STR_UNICODE)) {
+ if (!extract_pw_from_buffer(mem_ctx, r->in.nt_password->data, &new_password)) {
+ ldb_transaction_cancel(sam_ctx);
DEBUG(3,("samr: failed to decode password buffer\n"));
- status = NT_STATUS_WRONG_PASSWORD;
- goto failed;
+ return NT_STATUS_WRONG_PASSWORD;
}
-
+
if (r->in.nt_verifier == NULL) {
status = NT_STATUS_WRONG_PASSWORD;
goto failed;
}
/* check NT verifier */
- E_md4hash(new_pass, new_nt_hash);
+ mdfour(new_nt_hash, new_password.data, new_password.length);
+
E_old_pw_hash(new_nt_hash, nt_pwd->hash, nt_verifier.hash);
if (memcmp(nt_verifier.hash, r->in.nt_verifier->hash, 16) != 0) {
status = NT_STATUS_WRONG_PASSWORD;
goto failed;
}
- /* check LM verifier */
+ /* check LM verifier (really not needed as we just checked the
+ * much stronger NT hash, but the RPC-SAMR test checks for
+ * this) */
if (lm_pwd && r->in.lm_verifier != NULL) {
- E_deshash(new_pass, new_lm_hash);
- E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash);
- if (memcmp(lm_verifier.hash, r->in.lm_verifier->hash, 16) != 0) {
- status = NT_STATUS_WRONG_PASSWORD;
- goto failed;
+ char *new_pass;
+ if (convert_string_talloc(mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
+ CH_UTF16, CH_UNIX,
+ (const char *)new_password.data,
+ new_password.length,
+ (void **)&new_pass) != -1) {
+ E_deshash(new_pass, new_lm_hash);
+ E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash);
+ if (memcmp(lm_verifier.hash, r->in.lm_verifier->hash, 16) != 0) {
+ status = NT_STATUS_WRONG_PASSWORD;
+ goto failed;
+ }
}
}
-
mod = ldb_msg_new(mem_ctx);
if (mod == NULL) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto failed;
}
mod->dn = ldb_dn_copy(mod, user_dn);
@@ -430,7 +445,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
* due to password policies */
status = samdb_set_password(sam_ctx, mem_ctx,
user_dn, NULL,
- mod, new_pass,
+ mod, &new_password,
NULL, NULL,
true, /* this is a user password change */
&reason,
@@ -517,7 +532,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
struct samr_CryptPassword *pwbuf)
{
NTSTATUS nt_status;
- char new_pass[512];
+ DATA_BLOB new_password;
DATA_BLOB session_key = data_blob(NULL, 0);
nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
@@ -527,17 +542,16 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
arcfour_crypt_blob(pwbuf->data, 516, &session_key);
- if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass),
- STR_UNICODE)) {
+ if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) {
DEBUG(3,("samr: failed to decode password buffer\n"));
return NT_STATUS_WRONG_PASSWORD;
}
-
+
/* set the password - samdb needs to know both the domain and user DNs,
so the domain password policy can be used */
return samdb_set_password(sam_ctx, mem_ctx,
account_dn, domain_dn,
- msg, new_pass,
+ msg, &new_password,
NULL, NULL,
false, /* This is a password set, not change */
NULL, NULL);
@@ -557,8 +571,7 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
struct samr_CryptPasswordEx *pwbuf)
{
NTSTATUS nt_status;
- char new_pass[512];
- uint32_t new_pass_len;
+ DATA_BLOB new_password;
DATA_BLOB co_session_key;
DATA_BLOB session_key = data_blob(NULL, 0);
struct MD5Context ctx;
@@ -580,17 +593,16 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
arcfour_crypt_blob(pwbuf->data, 516, &co_session_key);
- if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass),
- STR_UNICODE)) {
+ if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) {
DEBUG(3,("samr: failed to decode password buffer\n"));
return NT_STATUS_WRONG_PASSWORD;
}
-
+
/* set the password - samdb needs to know both the domain and user DNs,
so the domain password policy can be used */
return samdb_set_password(sam_ctx, mem_ctx,
account_dn, domain_dn,
- msg, new_pass,
+ msg, &new_password,
NULL, NULL,
false, /* This is a password set, not change */
NULL, NULL);