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

s4:librpc/rpc: do LogonControl after LogonGetCapabilities downgrade

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>
This commit is contained in:
Stefan Metzmacher 2024-10-02 16:15:46 +02:00 committed by Douglas Bagnall
parent 25a2105ca7
commit 24de5d1cbd

View File

@ -409,6 +409,7 @@ struct auth_schannel_state {
struct netr_Authenticator return_auth; struct netr_Authenticator return_auth;
union netr_Capabilities capabilities; union netr_Capabilities capabilities;
struct netr_LogonGetCapabilities c; struct netr_LogonGetCapabilities c;
union netr_CONTROL_QUERY_INFORMATION ctrl_info;
}; };
@ -505,6 +506,8 @@ static void continue_bind_auth(struct composite_context *ctx)
composite_done(c); composite_done(c);
} }
static void continue_logon_control_do(struct composite_context *c);
/* /*
Stage 4 of auth_schannel: Get the Logon Capabilities and verify them. Stage 4 of auth_schannel: Get the Logon Capabilities and verify them.
*/ */
@ -521,13 +524,18 @@ static void continue_get_capabilities(struct tevent_req *subreq)
TALLOC_FREE(subreq); TALLOC_FREE(subreq);
if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} else { } else if (s->creds_state->negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
/* This is probably NT */ DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_done(c); composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
/* This is probably NT */
continue_logon_control_do(c);
return;
} else if (!composite_is_ok(c)) { } else if (!composite_is_ok(c)) {
return; return;
} }
@ -535,7 +543,8 @@ static void continue_get_capabilities(struct tevent_req *subreq)
if (NT_STATUS_EQUAL(s->c.out.result, NT_STATUS_NOT_IMPLEMENTED)) { if (NT_STATUS_EQUAL(s->c.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
/* This means AES isn't supported. */ /* This means AES isn't supported. */
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
@ -561,11 +570,11 @@ static void continue_get_capabilities(struct tevent_req *subreq)
/* compare capabilities */ /* compare capabilities */
if (s->creds_state->negotiate_flags != s->capabilities.server_capabilities) { if (s->creds_state->negotiate_flags != s->capabilities.server_capabilities) {
DEBUG(2, ("The client capabilities don't match the server " DBG_ERR("The client capabilities don't match the server "
"capabilities: local[0x%08X] remote[0x%08X]\n", "capabilities: local[0x%08X] remote[0x%08X]\n",
s->creds_state->negotiate_flags, s->creds_state->negotiate_flags,
s->capabilities.server_capabilities)); s->capabilities.server_capabilities);
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
@ -574,6 +583,53 @@ static void continue_get_capabilities(struct tevent_req *subreq)
composite_done(c); composite_done(c);
} }
static void continue_logon_control_done(struct tevent_req *subreq);
static void continue_logon_control_do(struct composite_context *c)
{
struct auth_schannel_state *s = NULL;
struct tevent_req *subreq = NULL;
s = talloc_get_type(c->private_data, struct auth_schannel_state);
subreq = dcerpc_netr_LogonControl_send(s,
c->event_ctx,
s->pipe->binding_handle,
s->c.in.server_name,
NETLOGON_CONTROL_QUERY,
2,
&s->ctrl_info);
if (composite_nomem(subreq, c)) return;
tevent_req_set_callback(subreq, continue_logon_control_done, c);
}
static void continue_logon_control_done(struct tevent_req *subreq)
{
struct composite_context *c = NULL;
struct auth_schannel_state *s = NULL;
WERROR werr;
c = tevent_req_callback_data(subreq, struct composite_context);
s = talloc_get_type(c->private_data, struct auth_schannel_state);
/* receive rpc request result */
c->status = dcerpc_netr_LogonControl_recv(subreq, s, &werr);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(c->status)) {
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
if (!W_ERROR_EQUAL(werr, WERR_NOT_SUPPORTED)) {
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
composite_done(c);
}
/* /*
Initiate schannel authentication request Initiate schannel authentication request