summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2013-11-28 06:50:01 +1300
committerStefan Metzmacher <metze@samba.org>2014-03-13 15:06:35 +0100
commit48ffca0acac83bb31266390361ee77e1eaa2f2be (patch)
treed90a9042f9c1764db8e2372f14bb97b9b66d3b2f
parent9f53b61f0674f7855a42b8e0de66f343f4592589 (diff)
downloadsamba-48ffca0acac83bb31266390361ee77e1eaa2f2be.tar.gz
samba-48ffca0acac83bb31266390361ee77e1eaa2f2be.tar.xz
samba-48ffca0acac83bb31266390361ee77e1eaa2f2be.zip
CVE-2013-4496:Revert remainder of ce895609b04380bfc41e4f8fddc84bd2f9324340
Part of this was removed when ChangePasswordUser was unimplemented, but remove the remainder of this flawed commit. Fully check the password first, as extract_pw_from_buffer() already does a partial check of the password because it needs a correct old password to correctly decrypt the length. Andrew Bartlett Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245 Change-Id: Ibccc4ada400b5f89a942d79c1a269b493e0adda6 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Reviewed-on: https://gerrit.samba.org/38 Autobuild-User(master): Stefan Metzmacher <metze@samba.org> Autobuild-Date(master): Thu Mar 13 15:06:35 CET 2014 on sn-devel-104
-rw-r--r--source4/rpc_server/samr/samr_password.c69
1 files changed, 35 insertions, 34 deletions
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 9d6c9212f4..685a8e7864 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -142,6 +142,9 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
E_deshash(new_pass, new_lm_hash);
E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash);
+ if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
/* Connect to a SAMDB with user privileges for the password change */
sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
@@ -173,11 +176,6 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
return status;
}
- if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) {
- ldb_transaction_cancel(sam_ctx);
- return NT_STATUS_WRONG_PASSWORD;
- }
-
/* And this confirms it in a transaction commit */
ret = ldb_transaction_commit(sam_ctx);
if (ret != LDB_SUCCESS) {
@@ -267,33 +265,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
goto failed;
}
- /* Connect to a SAMDB with user privileges for the password change */
- sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx,
- dce_call->conn->auth_state.session_info, 0);
- if (sam_ctx == NULL) {
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
-
- ret = ldb_transaction_start(sam_ctx);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx)));
- return NT_STATUS_TRANSACTION_ABORTED;
- }
-
- /* Performs the password modification. We pass the old hashes read out
- * from the database since they were already checked against the user-
- * provided ones. */
- status = samdb_set_password(sam_ctx, mem_ctx,
- user_dn, NULL,
- &new_password,
- NULL, NULL,
- lm_pwd, nt_pwd, /* this is a user password change */
- &reason,
- &dominfo);
-
- if (!NT_STATUS_IS_OK(status)) {
- ldb_transaction_cancel(sam_ctx);
+ if (r->in.nt_verifier == NULL) {
+ status = NT_STATUS_WRONG_PASSWORD;
goto failed;
}
@@ -302,7 +275,6 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
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) {
- ldb_transaction_cancel(sam_ctx);
status = NT_STATUS_WRONG_PASSWORD;
goto failed;
}
@@ -322,13 +294,42 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
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) {
- ldb_transaction_cancel(sam_ctx);
status = NT_STATUS_WRONG_PASSWORD;
goto failed;
}
}
}
+ /* Connect to a SAMDB with user privileges for the password change */
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ dce_call->conn->auth_state.session_info, 0);
+ if (sam_ctx == NULL) {
+ return NT_STATUS_INVALID_SYSTEM_SERVICE;
+ }
+
+ ret = ldb_transaction_start(sam_ctx);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx)));
+ return NT_STATUS_TRANSACTION_ABORTED;
+ }
+
+ /* Performs the password modification. We pass the old hashes read out
+ * from the database since they were already checked against the user-
+ * provided ones. */
+ status = samdb_set_password(sam_ctx, mem_ctx,
+ user_dn, NULL,
+ &new_password,
+ NULL, NULL,
+ lm_pwd, nt_pwd, /* this is a user password change */
+ &reason,
+ &dominfo);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ ldb_transaction_cancel(sam_ctx);
+ goto failed;
+ }
+
/* And this confirms it in a transaction commit */
ret = ldb_transaction_commit(sam_ctx);
if (ret != LDB_SUCCESS) {