1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-11 16:58:40 +03:00

CVE-2021-20251 s4:dsdb: Make badPwdCount update atomic

We reread the account details inside the transaction in case the account
has been locked out in the meantime. If it has, we return the
appropriate error code.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit 96479747bdb5bc5f33d903085f5f69793f369e3a)
This commit is contained in:
Joseph Sutton 2022-07-09 15:54:12 +12:00 committed by Jule Anger
parent 254e94892c
commit 4d0cba69c8
2 changed files with 24 additions and 8 deletions

View File

@ -1,5 +0,0 @@
# This test currently depends on a race. The password_hash dsdb module
# relinquishes and immediately reacquires a transaction lock, and another
# process may be able to acquire it during the short period of time in which it
# is not held.
^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_race_ldap_pw_change.ad_dc:local

View File

@ -45,6 +45,7 @@
#include "lib/crypto/md4.h"
#include "param/param.h"
#include "lib/krb5_wrap/krb5_samba.h"
#include "auth/auth_sam.h"
#include "auth/common_auth.h"
#include "lib/messaging/messaging.h"
#include "lib/param/loadparm.h"
@ -2729,7 +2730,8 @@ static int make_error_and_update_badPwdCount(struct setup_password_fields_io *io
struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
struct ldb_message *mod_msg = NULL;
struct ldb_message *pso_msg = NULL;
NTSTATUS status;
struct ldb_message *current = NULL;
NTSTATUS status = NT_STATUS_OK;
int ret; /* The errors we will actually return */
int dbg_ret; /* The errors we can only complain about in logs */
@ -2775,13 +2777,28 @@ static int make_error_and_update_badPwdCount(struct setup_password_fields_io *io
goto done;
}
/*
* Re-read the account details, using the GUID in case the DN
* is being changed.
*/
status = authsam_reread_user_logon_data(
ldb, io->ac,
io->ac->search_res->message,
&current);
if (!NT_STATUS_IS_OK(status)) {
/* The re-read can return account locked out, as well
* as an internal error
*/
goto end_transaction;
}
/* PSO search result is optional (NULL if no PSO applies) */
if (io->ac->pso_res != NULL) {
pso_msg = io->ac->pso_res->message;
}
status = dsdb_update_bad_pwd_count(io->ac, ldb,
io->ac->search_res->message,
current,
io->ac->dom_res->message,
pso_msg,
&mod_msg);
@ -2831,7 +2848,11 @@ end_transaction:
done:
ret = LDB_ERR_CONSTRAINT_VIOLATION;
*werror = WERR_INVALID_PASSWORD;
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_LOCKED_OUT)) {
*werror = WERR_ACCOUNT_LOCKED_OUT;
} else {
*werror = WERR_INVALID_PASSWORD;
}
ldb_asprintf_errstring(ldb,
"%08X: %s - check_password_restrictions: "
"The old password specified doesn't match!",