1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-03 01:18:10 +03:00

libcli/auth: use a LogonControl after a LogonGetCapabilities downgrade

If LogonGetCapabilities was downgraded by an DCERPC Fault, we
rely on the schannel message ordering to detect failures.

Instead of letting any real winbindd request trigger this,
we do it directly in netlogon_creds_cli_check() with
a LogonControl that is also used for 'wbinfo --ping-dc'.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 276137e950)
This commit is contained in:
Stefan Metzmacher 2024-10-02 14:25:19 +02:00 committed by Jule Anger
parent d73e6c7ab0
commit ea1bb19585

View File

@ -1591,6 +1591,8 @@ struct netlogon_creds_cli_check_state {
struct netlogon_creds_CredentialState *creds;
struct netr_Authenticator req_auth;
struct netr_Authenticator rep_auth;
union netr_CONTROL_QUERY_INFORMATION ctrl_info;
};
static void netlogon_creds_cli_check_cleanup(struct tevent_req *req,
@ -1709,6 +1711,8 @@ static void netlogon_creds_cli_check_cleanup(struct tevent_req *req,
TALLOC_FREE(state->creds);
}
static void netlogon_creds_cli_check_control_do(struct tevent_req *req);
static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
{
struct tevent_req *req =
@ -1769,9 +1773,10 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
* we should detect a faked NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
* with the next request as the sequence number processing
* gets out of sync.
*
* So we'll do a LogonControl message to check that...
*/
netlogon_creds_cli_check_cleanup(req, status);
tevent_req_done(req);
netlogon_creds_cli_check_control_do(req);
return;
}
if (tevent_req_nterror(req, status)) {
@ -1854,6 +1859,73 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
tevent_req_done(req);
}
static void netlogon_creds_cli_check_control_done(struct tevent_req *subreq);
static void netlogon_creds_cli_check_control_do(struct tevent_req *req)
{
struct netlogon_creds_cli_check_state *state =
tevent_req_data(req,
struct netlogon_creds_cli_check_state);
struct tevent_req *subreq = NULL;
/*
* In case we got a downgrade based on a FAULT
* we use a LogonControl that is supposed to
* return WERR_NOT_SUPPORTED (without a DCERPC FAULT)
* to verify that the connection is still ok and didn't
* get out of sync.
*/
subreq = dcerpc_netr_LogonControl_send(state,
state->ev,
state->binding_handle,
state->srv_name_slash,
NETLOGON_CONTROL_QUERY,
2,
&state->ctrl_info);
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq,
netlogon_creds_cli_check_control_done,
req);
return;
}
static void netlogon_creds_cli_check_control_done(struct tevent_req *subreq)
{
struct tevent_req *req =
tevent_req_callback_data(subreq,
struct tevent_req);
struct netlogon_creds_cli_check_state *state =
tevent_req_data(req,
struct netlogon_creds_cli_check_state);
NTSTATUS status;
WERROR result;
status = dcerpc_netr_LogonControl_recv(subreq, state, &result);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
/*
* We want to delete the creds,
* so we pass NT_STATUS_DOWNGRADE_DETECTED
* to netlogon_creds_cli_check_cleanup()
*/
status = NT_STATUS_DOWNGRADE_DETECTED;
netlogon_creds_cli_check_cleanup(req, status);
return;
}
if (!W_ERROR_EQUAL(result, WERR_NOT_SUPPORTED)) {
status = NT_STATUS_DOWNGRADE_DETECTED;
tevent_req_nterror(req, status);
netlogon_creds_cli_check_cleanup(req, status);
return;
}
tevent_req_done(req);
}
NTSTATUS netlogon_creds_cli_check_recv(struct tevent_req *req,
union netr_Capabilities *capabilities)
{