177 lines
5.9 KiB
Diff
177 lines
5.9 KiB
Diff
From 5966f8c2d47ed0d6544d7ac242bcbe2c849b474e Mon Sep 17 00:00:00 2001
|
|
From: Stefan Metzmacher <metze@samba.org>
|
|
Date: Mon, 4 Oct 2021 17:29:34 +0200
|
|
Subject: [PATCH 103/266] CVE-2020-25717: s3:winbindd: make sure we default to
|
|
r->out.authoritative = true
|
|
|
|
We need to make sure that temporary failures don't trigger a fallback
|
|
to the local SAM that silently ignores the domain name part for users.
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
|
|
|
|
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
---
|
|
source3/winbindd/winbindd_dual_srv.c | 7 +++++++
|
|
source3/winbindd/winbindd_irpc.c | 7 +++++++
|
|
source3/winbindd/winbindd_pam.c | 15 +++++++++++----
|
|
source3/winbindd/winbindd_pam_auth_crap.c | 9 ++++++++-
|
|
source3/winbindd/winbindd_util.c | 7 +++++++
|
|
5 files changed, 40 insertions(+), 4 deletions(-)
|
|
|
|
Conflict:{ --> unsigned char local_nt_response[24];
|
|
delete a chunk from previos commit we don't introduce
|
|
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=5966f8c2d47ed0d6544d7ac242bcbe2c849b474e
|
|
|
|
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
|
|
index 4a4894c2658..078fa77aed6 100644
|
|
--- a/source3/winbindd/winbindd_dual_srv.c
|
|
+++ b/source3/winbindd/winbindd_dual_srv.c
|
|
@@ -940,6 +940,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
|
|
union netr_Validation *validation = NULL;
|
|
bool interactive = false;
|
|
|
|
+ /*
|
|
+ * Make sure we start with authoritative=true,
|
|
+ * it will only set to false if we don't know the
|
|
+ * domain.
|
|
+ */
|
|
+ r->out.authoritative = true;
|
|
+
|
|
domain = wb_child_domain();
|
|
if (domain == NULL) {
|
|
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
|
diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
|
|
index fda29c7e702..12f4554f9b6 100644
|
|
--- a/source3/winbindd/winbindd_irpc.c
|
|
+++ b/source3/winbindd/winbindd_irpc.c
|
|
@@ -141,6 +141,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
|
|
const char *target_domain_name = NULL;
|
|
const char *account_name = NULL;
|
|
|
|
+ /*
|
|
+ * Make sure we start with authoritative=true,
|
|
+ * it will only set to false if we don't know the
|
|
+ * domain.
|
|
+ */
|
|
+ req->out.authoritative = true;
|
|
+
|
|
switch (req->in.logon_level) {
|
|
case NetlogonInteractiveInformation:
|
|
case NetlogonServiceInformation:
|
|
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
|
|
index c49033b375d..59dd18e27b8 100644
|
|
--- a/source3/winbindd/winbindd_pam.c
|
|
+++ b/source3/winbindd/winbindd_pam.c
|
|
@@ -1797,7 +1797,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
|
|
unsigned char local_nt_response[24];
|
|
fstring name_namespace, name_domain, name_user;
|
|
NTSTATUS result;
|
|
- uint8_t authoritative = 0;
|
|
+ uint8_t authoritative = 1;
|
|
uint32_t flags = 0;
|
|
uint16_t validation_level = 0;
|
|
union netr_Validation *validation = NULL;
|
|
@@ -2451,6 +2451,13 @@ done:
|
|
result = NT_STATUS_NO_LOGON_SERVERS;
|
|
}
|
|
|
|
+ /*
|
|
+ * Here we don't alter
|
|
+ * state->response->data.auth.authoritative based
|
|
+ * on the servers response
|
|
+ * as we don't want a fallback to the local sam
|
|
+ * for interactive PAM logons
|
|
+ */
|
|
set_auth_errors(state->response, result);
|
|
|
|
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
|
|
@@ -2665,7 +2672,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
|
const char *name_domain = NULL;
|
|
const char *workstation;
|
|
uint64_t logon_id = 0;
|
|
- uint8_t authoritative = 0;
|
|
+ uint8_t authoritative = 1;
|
|
uint32_t flags = 0;
|
|
uint16_t validation_level;
|
|
union netr_Validation *validation = NULL;
|
|
@@ -2738,7 +2745,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
|
&validation_level,
|
|
&validation);
|
|
if (!NT_STATUS_IS_OK(result)) {
|
|
- state->response->data.auth.authoritative = authoritative;
|
|
goto done;
|
|
}
|
|
|
|
@@ -2792,6 +2797,8 @@ done:
|
|
}
|
|
|
|
set_auth_errors(state->response, result);
|
|
+ state->response->data.auth.authoritative = authoritative;
|
|
+
|
|
/*
|
|
* Log the winbind pam authentication, the logon_id will tie this to
|
|
* any of the logons invoked from this request.
|
|
diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c
|
|
index b7912db43df..40cab81b5ea 100644
|
|
--- a/source3/winbindd/winbindd_pam_auth_crap.c
|
|
+++ b/source3/winbindd/winbindd_pam_auth_crap.c
|
|
@@ -24,6 +24,7 @@
|
|
|
|
struct winbindd_pam_auth_crap_state {
|
|
struct winbindd_response *response;
|
|
+ bool authoritative;
|
|
uint32_t flags;
|
|
};
|
|
|
|
@@ -45,7 +46,7 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
|
if (req == NULL) {
|
|
return NULL;
|
|
}
|
|
-
|
|
+ state->authoritative = true;
|
|
state->flags = request->flags;
|
|
|
|
if (state->flags & WBFLAG_PAM_AUTH_PAC) {
|
|
@@ -124,6 +125,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
|
|
|
domain = find_auth_domain(request->flags, auth_domain);
|
|
if (domain == NULL) {
|
|
+ /*
|
|
+ * We don't know the domain so
|
|
+ * we're not authoritative
|
|
+ */
|
|
+ state->authoritative = false;
|
|
tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
|
|
return tevent_req_post(req, ev);
|
|
}
|
|
@@ -184,6 +190,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
|
|
|
|
if (tevent_req_is_nterror(req, &status)) {
|
|
set_auth_errors(response, status);
|
|
+ response->data.auth.authoritative = state->authoritative;
|
|
return status;
|
|
}
|
|
|
|
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
|
|
index bec706f87de..ef197310fa0 100644
|
|
--- a/source3/winbindd/winbindd_util.c
|
|
+++ b/source3/winbindd/winbindd_util.c
|
|
@@ -2092,6 +2092,13 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
|
|
|
|
void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
|
|
{
|
|
+ /*
|
|
+ * Make sure we start with authoritative=true,
|
|
+ * it will only set to false if we don't know the
|
|
+ * domain.
|
|
+ */
|
|
+ resp->data.auth.authoritative = true;
|
|
+
|
|
resp->data.auth.nt_status = NT_STATUS_V(result);
|
|
fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
|
|
|
|
--
|
|
2.23.0
|
|
|