From 25d6b0c5e4816c579ad7a502e0e5cbb7ecb0e95b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 15 Apr 2021 10:04:21 +0200 Subject: [PATCH] CVE-2020-25717 auth4: Make auth_sam pseudo-async Signed-off-by: Volker Lendecke Reviewed-by: Andrew Bartlett BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 (cherry picked from commit f852fb4cd4e2bcd676a9ea104c5bf00979771eed) --- source4/auth/ntlm/auth_sam.c | 69 ++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index 70eddc12c53..e4ebeae7523 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -36,6 +36,7 @@ #include "lib/messaging/irpc.h" #include "libcli/auth/libcli_auth.h" #include "libds/common/roles.h" +#include "lib/util/tevent_ntstatus.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -732,6 +733,68 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx return NT_STATUS_OK; } +struct authsam_check_password_state { + struct auth_user_info_dc *user_info_dc; + bool authoritative; +}; + +static struct tevent_req *authsam_check_password_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct auth_method_context *ctx, + const struct auth_usersupplied_info *user_info) +{ + struct tevent_req *req = NULL; + struct authsam_check_password_state *state = NULL; + NTSTATUS status; + + req = tevent_req_create( + mem_ctx, &state, struct authsam_check_password_state); + if (req == NULL) { + return NULL; + } + /* + * authsam_check_password_internals() sets this to false in + * the rodc case, otherwise it leaves it untouched. Default to + * "we're authoritative". + */ + state->authoritative = true; + + status = authsam_check_password_internals( + ctx, + state, + user_info, + &state->user_info_dc, + &state->authoritative); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + tevent_req_done(req); + return tevent_req_post(req, ev); +} + +static NTSTATUS authsam_check_password_recv( + struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct auth_user_info_dc **interim_info, + bool *authoritative) +{ + struct authsam_check_password_state *state = tevent_req_data( + req, struct authsam_check_password_state); + NTSTATUS status; + + *authoritative = state->authoritative; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + *interim_info = talloc_move(mem_ctx, &state->user_info_dc); + tevent_req_received(req); + return NT_STATUS_OK; +} + static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info) @@ -887,14 +950,16 @@ static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, static const struct auth_operations sam_ignoredomain_ops = { .name = "sam_ignoredomain", .want_check = authsam_ignoredomain_want_check, - .check_password = authsam_check_password_internals, + .check_password_send = authsam_check_password_send, + .check_password_recv = authsam_check_password_recv, .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, }; static const struct auth_operations sam_ops = { .name = "sam", .want_check = authsam_want_check, - .check_password = authsam_check_password_internals, + .check_password_send = authsam_check_password_send, + .check_password_recv = authsam_check_password_recv, .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, }; -- 2.47.2