mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
CVE-2021-20251 auth4: Reread the user record if a bad password is noticed.
As is, this is pointless, as we need a transaction to make this any less of a race, but this provides the steps towards that goal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
parent
408717242a
commit
7b8e32efc3
@ -827,6 +827,68 @@ static int authsam_get_user_pso(struct ldb_context *sam_ctx,
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-read the bad password and successful logon data for a user.
|
||||
*
|
||||
* The DN in the passed user record should contain the "objectGUID" in case the
|
||||
* object DN has changed.
|
||||
*/
|
||||
NTSTATUS authsam_reread_user_logon_data(
|
||||
struct ldb_context *sam_ctx,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct ldb_message *user_msg,
|
||||
struct ldb_message **current)
|
||||
{
|
||||
const struct ldb_val *v = NULL;
|
||||
struct ldb_result *res = NULL;
|
||||
uint16_t acct_flags = 0;
|
||||
const char *attr_name = "msDS-User-Account-Control-Computed";
|
||||
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Re-read the account details, using the GUID in case the DN
|
||||
* is being changed (this is automatic in LDB because the
|
||||
* original search also used DSDB_SEARCH_SHOW_EXTENDED_DN)
|
||||
*
|
||||
* We re read all the attributes in user_attrs, rather than using a
|
||||
* subset to ensure that we can reuse existing validation code.
|
||||
*/
|
||||
ret = dsdb_search_dn(sam_ctx,
|
||||
mem_ctx,
|
||||
&res,
|
||||
user_msg->dn,
|
||||
user_attrs,
|
||||
DSDB_SEARCH_SHOW_EXTENDED_DN);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DBG_ERR("Unable to re-read account control data for %s\n",
|
||||
ldb_dn_get_linearized(user_msg->dn));
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the account has not been locked out by another request
|
||||
*/
|
||||
v = ldb_msg_find_ldb_val(res->msgs[0], attr_name);
|
||||
if (v == NULL || v->data == NULL) {
|
||||
DBG_ERR("No %s attribute for %s\n",
|
||||
attr_name,
|
||||
ldb_dn_get_linearized(user_msg->dn));
|
||||
TALLOC_FREE(res);
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
acct_flags = samdb_result_acct_flags(res->msgs[0], attr_name);
|
||||
if (acct_flags & ACB_AUTOLOCK) {
|
||||
DBG_WARNING(
|
||||
"Account for user %s was locked out.\n",
|
||||
ldb_dn_get_linearized(user_msg->dn));
|
||||
TALLOC_FREE(res);
|
||||
return NT_STATUS_ACCOUNT_LOCKED_OUT;
|
||||
}
|
||||
*current = res->msgs[0];
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static struct db_context *authsam_get_bad_password_db(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ldb_context *sam_ctx)
|
||||
@ -1247,6 +1309,26 @@ NTSTATUS authsam_logon_success_accounting(struct ldb_context *sam_ctx,
|
||||
return status;
|
||||
}
|
||||
|
||||
if (need_db_reread) {
|
||||
struct ldb_message *current = NULL;
|
||||
|
||||
/*
|
||||
* Re-read the account details, using the GUID
|
||||
* embedded in DN so this is safe against a race where
|
||||
* it is being renamed.
|
||||
*/
|
||||
status = authsam_reread_user_logon_data(
|
||||
sam_ctx, mem_ctx, msg, ¤t);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
/*
|
||||
* The re-read can return account locked out, as well
|
||||
* as an internal error
|
||||
*/
|
||||
return status;
|
||||
}
|
||||
msg = current;
|
||||
}
|
||||
|
||||
lockoutTime = ldb_msg_find_attr_as_int64(msg, "lockoutTime", 0);
|
||||
dbBadPwdCount = ldb_msg_find_attr_as_int(msg, "badPwdCount", 0);
|
||||
if (interactive_or_kerberos) {
|
||||
|
Loading…
Reference in New Issue
Block a user