mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
netlogon_creds_cli: Protect netlogon_creds_cli_auth by _lck
This widens the lock range to cover the check for established credentials. Before this patch it could happen that more than one winbind finds no credentials and does the auth3. This can pile up. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
f6e39450f5
commit
4d19f8b4b9
@ -1084,10 +1084,8 @@ struct netlogon_creds_cli_auth_state {
|
||||
bool try_auth3;
|
||||
bool try_auth2;
|
||||
bool require_auth2;
|
||||
struct netlogon_creds_cli_locked_state *locked_state;
|
||||
};
|
||||
|
||||
static void netlogon_creds_cli_auth_locked(struct tevent_req *subreq);
|
||||
static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req);
|
||||
|
||||
struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx,
|
||||
@ -1099,7 +1097,6 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct netlogon_creds_cli_auth_state *state;
|
||||
struct netlogon_creds_cli_locked_state *locked_state;
|
||||
NTSTATUS status;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
@ -1124,22 +1121,11 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx,
|
||||
state->idx_nt_hashes = 0;
|
||||
state->nt_hashes = nt_hashes;
|
||||
|
||||
if (context->db.locked_state != NULL) {
|
||||
tevent_req_nterror(req, NT_STATUS_LOCK_NOT_GRANTED);
|
||||
if (context->db.lock != NETLOGON_CREDS_CLI_LCK_EXCLUSIVE) {
|
||||
tevent_req_nterror(req, NT_STATUS_NOT_LOCKED);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
locked_state = talloc_zero(state, struct netlogon_creds_cli_locked_state);
|
||||
if (tevent_req_nomem(locked_state, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
talloc_set_destructor(locked_state,
|
||||
netlogon_creds_cli_locked_state_destructor);
|
||||
locked_state->context = context;
|
||||
|
||||
context->db.locked_state = locked_state;
|
||||
state->locked_state = locked_state;
|
||||
|
||||
state->srv_name_slash = talloc_asprintf(state, "\\\\%s",
|
||||
context->server.computer);
|
||||
if (tevent_req_nomem(state->srv_name_slash, req)) {
|
||||
@ -1156,23 +1142,6 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx,
|
||||
state->used_nt_hash = state->nt_hashes[state->idx_nt_hashes];
|
||||
state->current_flags = context->client.proposed_flags;
|
||||
|
||||
if (context->db.g_ctx != NULL) {
|
||||
struct tevent_req *subreq;
|
||||
|
||||
subreq = g_lock_lock_send(state, ev,
|
||||
context->db.g_ctx,
|
||||
context->db.key_name,
|
||||
G_LOCK_WRITE);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(subreq,
|
||||
netlogon_creds_cli_auth_locked,
|
||||
req);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
status = dbwrap_purge(state->context->db.ctx,
|
||||
state->context->db.key_data);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
@ -1187,32 +1156,6 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx,
|
||||
return req;
|
||||
}
|
||||
|
||||
static void netlogon_creds_cli_auth_locked(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req =
|
||||
tevent_req_callback_data(subreq,
|
||||
struct tevent_req);
|
||||
struct netlogon_creds_cli_auth_state *state =
|
||||
tevent_req_data(req,
|
||||
struct netlogon_creds_cli_auth_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = g_lock_lock_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
state->locked_state->is_glocked = true;
|
||||
|
||||
status = dbwrap_purge(state->context->db.ctx,
|
||||
state->context->db.key_data);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
netlogon_creds_cli_auth_challenge_start(req);
|
||||
}
|
||||
|
||||
static void netlogon_creds_cli_auth_challenge_done(struct tevent_req *subreq);
|
||||
|
||||
static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req)
|
||||
@ -1456,7 +1399,6 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq)
|
||||
status = dbwrap_store(state->context->db.ctx,
|
||||
state->context->db.key_data,
|
||||
data, TDB_REPLACE);
|
||||
TALLOC_FREE(state->locked_state);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
@ -104,6 +104,36 @@ char *trust_pw_new_value(TALLOC_CTX *mem_ctx,
|
||||
return generate_random_machine_password(mem_ctx, min, max);
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporary function to wrap cli_auth in a lck
|
||||
*/
|
||||
|
||||
static NTSTATUS netlogon_creds_cli_lck_auth(
|
||||
struct netlogon_creds_cli_context *context,
|
||||
struct dcerpc_binding_handle *b,
|
||||
uint8_t num_nt_hashes,
|
||||
const struct samr_Password * const *nt_hashes,
|
||||
uint8_t *idx_nt_hashes)
|
||||
{
|
||||
struct netlogon_creds_cli_lck *lck;
|
||||
NTSTATUS status;
|
||||
|
||||
status = netlogon_creds_cli_lck(
|
||||
context, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
|
||||
talloc_tos(), &lck);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DBG_WARNING("netlogon_creds_cli_lck failed: %s\n",
|
||||
nt_errstr(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
status = netlogon_creds_cli_auth(context, b, num_nt_hashes, nt_hashes,
|
||||
idx_nt_hashes);
|
||||
TALLOC_FREE(lck);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
|
||||
struct messaging_context *msg_ctx,
|
||||
struct dcerpc_binding_handle *b,
|
||||
@ -358,10 +388,10 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
|
||||
* ServerTrustPasswordsGet() or netr_ServerGetTrustInfo() to fix our
|
||||
* local secrets before doing the change.
|
||||
*/
|
||||
status = netlogon_creds_cli_auth(context, b,
|
||||
num_nt_hashes,
|
||||
nt_hashes,
|
||||
&idx_nt_hashes);
|
||||
status = netlogon_creds_cli_lck_auth(context, b,
|
||||
num_nt_hashes,
|
||||
nt_hashes,
|
||||
&idx_nt_hashes);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("netlogon_creds_cli_auth(%s) failed for old passwords (%u) - %s!\n",
|
||||
context_name, num_nt_hashes, nt_errstr(status)));
|
||||
@ -571,10 +601,10 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
|
||||
idx_current = idx;
|
||||
nt_hashes[idx++] = current_nt_hash;
|
||||
num_nt_hashes = idx;
|
||||
status = netlogon_creds_cli_auth(context, b,
|
||||
num_nt_hashes,
|
||||
nt_hashes,
|
||||
&idx_nt_hashes);
|
||||
status = netlogon_creds_cli_lck_auth(context, b,
|
||||
num_nt_hashes,
|
||||
nt_hashes,
|
||||
&idx_nt_hashes);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("netlogon_creds_cli_auth(%s) failed for new password - %s!\n",
|
||||
context_name, nt_errstr(status)));
|
||||
|
@ -166,8 +166,19 @@ NTSTATUS rpccli_setup_netlogon_creds(
|
||||
uint8_t num_nt_hashes = 0;
|
||||
const struct samr_Password *nt_hashes[2] = { NULL, NULL };
|
||||
uint8_t idx_nt_hashes = 0;
|
||||
struct netlogon_creds_cli_lck *lck = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
status = netlogon_creds_cli_lck(
|
||||
creds_ctx, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
|
||||
frame, &lck);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DBG_WARNING("netlogon_creds_cli_lck failed: %s\n",
|
||||
nt_errstr(status));
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
const char *action = "using";
|
||||
@ -230,6 +241,8 @@ NTSTATUS rpccli_setup_netlogon_creds(
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
TALLOC_FREE(lck);
|
||||
|
||||
DEBUG(5,("%s: using new netlogon_creds cli[%s/%s] to %s\n",
|
||||
__FUNCTION__,
|
||||
creds->account_name, creds->computer_name,
|
||||
|
Loading…
Reference in New Issue
Block a user