From ff16cb25c40607f5fb1923501e56b26e3dd19090 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Nov 2024 12:55:12 +0100 Subject: [PATCH] librpc/server: call dcesrv_netr_check_schannel() as schannel_check_creds_state() callback If schannel is not used we need to return ACCESS_DENIED and discard the effect of netlogon_creds_server_step_check(). Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- librpc/rpc/server/netlogon/schannel_util.c | 71 +++++++++++++++---- .../knownfail.d/samba.tests.krb5.netlogon | 2 - 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/librpc/rpc/server/netlogon/schannel_util.c b/librpc/rpc/server/netlogon/schannel_util.c index cc1355670d6..fd2c4a1ff38 100644 --- a/librpc/rpc/server/netlogon/schannel_util.c +++ b/librpc/rpc/server/netlogon/schannel_util.c @@ -579,6 +579,52 @@ NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call, return NT_STATUS_OK; } +struct dcesrv_netr_step_access_state { + struct dcesrv_call_state *dce_call; + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint16_t opnum; + NTSTATUS status; +}; + +static NTSTATUS dcesrv_netr_step_access_cb( + struct netlogon_creds_CredentialState *creds, + NTSTATUS step_status, + bool *store, + void *access_check_private) +{ + struct dcesrv_netr_step_access_state *s = + (struct dcesrv_netr_step_access_state *)access_check_private; + struct dcesrv_call_state *dce_call = + talloc_get_type_abort(s->dce_call, + struct dcesrv_call_state); + + if (NT_STATUS_EQUAL(step_status, NT_STATUS_ACCESS_DENIED)) { + s->status = step_status; + *store = true; + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(step_status)) { + *store = false; + return step_status; + } + + s->status = dcesrv_netr_check_schannel(dce_call, + creds, + s->auth_type, + s->auth_level, + s->opnum); + + if (!NT_STATUS_IS_OK(s->status)) { + *store = false; + } else { + *store = true; + } + + return NT_STATUS_OK; +} + NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, const char *computer_name, @@ -588,31 +634,32 @@ NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call, { NTSTATUS nt_status; struct netlogon_creds_CredentialState *creds = NULL; - enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; - enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; + struct dcesrv_netr_step_access_state state = { + .dce_call = dce_call, + .auth_type = DCERPC_AUTH_TYPE_NONE, + .auth_level = DCERPC_AUTH_LEVEL_NONE, + .opnum = dce_call->pkt.u.request.opnum, + .status = NT_STATUS_INTERNAL_ERROR, + }; - dcesrv_call_auth_info(dce_call, &auth_type, &auth_level); + dcesrv_call_auth_info(dce_call, &state.auth_type, &state.auth_level); nt_status = schannel_check_creds_state(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, computer_name, received_authenticator, return_authenticator, - auth_type, - auth_level, - NULL, /* access_check_cb */ - NULL, /* access_check_private */ + state.auth_type, + state.auth_level, + dcesrv_netr_step_access_cb, + &state, &creds); if (!NT_STATUS_IS_OK(nt_status)) { ZERO_STRUCTP(return_authenticator); return nt_status; } - nt_status = dcesrv_netr_check_schannel(dce_call, - creds, - auth_type, - auth_level, - dce_call->pkt.u.request.opnum); + nt_status = state.status; if (!NT_STATUS_IS_OK(nt_status)) { TALLOC_FREE(creds); ZERO_STRUCTP(return_authenticator); diff --git a/selftest/knownfail.d/samba.tests.krb5.netlogon b/selftest/knownfail.d/samba.tests.krb5.netlogon index 0f8d4c3fa3d..2f64171e5e2 100644 --- a/selftest/knownfail.d/samba.tests.krb5.netlogon +++ b/selftest/knownfail.d/samba.tests.krb5.netlogon @@ -1,5 +1,3 @@ -# This doesn't enforce that a krb5 connection can't be used by aes creds -^samba.tests.krb5.netlogon.*.test_wks1_authenticate_flags # This is not implemented yet ^samba.tests.krb5.netlogon.*.NetlogonSchannel.test_ticket_samlogon # These will be fixed in the next commits