mirror of
https://github.com/samba-team/samba.git
synced 2025-03-11 16:58:40 +03:00
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>
This commit is contained in:
parent
b4ea50f8b2
commit
0558736149
@ -941,6 +941,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
|
|||||||
union netr_Validation *validation = NULL;
|
union netr_Validation *validation = NULL;
|
||||||
bool interactive = false;
|
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();
|
domain = wb_child_domain();
|
||||||
if (domain == NULL) {
|
if (domain == NULL) {
|
||||||
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||||
|
@ -142,6 +142,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
|
|||||||
const char *target_domain_name = NULL;
|
const char *target_domain_name = NULL;
|
||||||
const char *account_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) {
|
switch (req->in.logon_level) {
|
||||||
case NetlogonInteractiveInformation:
|
case NetlogonInteractiveInformation:
|
||||||
case NetlogonServiceInformation:
|
case NetlogonServiceInformation:
|
||||||
|
@ -1866,7 +1866,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
|
|||||||
{
|
{
|
||||||
fstring name_namespace, name_domain, name_user;
|
fstring name_namespace, name_domain, name_user;
|
||||||
NTSTATUS result;
|
NTSTATUS result;
|
||||||
uint8_t authoritative = 0;
|
uint8_t authoritative = 1;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
uint16_t validation_level = 0;
|
uint16_t validation_level = 0;
|
||||||
union netr_Validation *validation = NULL;
|
union netr_Validation *validation = NULL;
|
||||||
@ -2435,6 +2435,13 @@ done:
|
|||||||
result = NT_STATUS_NO_LOGON_SERVERS;
|
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);
|
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",
|
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
|
||||||
@ -2649,7 +2656,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
|||||||
const char *name_domain = NULL;
|
const char *name_domain = NULL;
|
||||||
const char *workstation;
|
const char *workstation;
|
||||||
uint64_t logon_id = 0;
|
uint64_t logon_id = 0;
|
||||||
uint8_t authoritative = 0;
|
uint8_t authoritative = 1;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
uint16_t validation_level;
|
uint16_t validation_level;
|
||||||
union netr_Validation *validation = NULL;
|
union netr_Validation *validation = NULL;
|
||||||
@ -2722,7 +2729,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
|||||||
&validation_level,
|
&validation_level,
|
||||||
&validation);
|
&validation);
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
state->response->data.auth.authoritative = authoritative;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2754,7 +2760,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
|||||||
"from firewalled domain [%s]\n",
|
"from firewalled domain [%s]\n",
|
||||||
info3->base.account_name.string,
|
info3->base.account_name.string,
|
||||||
info3->base.logon_domain.string);
|
info3->base.logon_domain.string);
|
||||||
state->response->data.auth.authoritative = true;
|
|
||||||
result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
|
result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -2776,6 +2781,8 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_auth_errors(state->response, result);
|
set_auth_errors(state->response, result);
|
||||||
|
state->response->data.auth.authoritative = authoritative;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Log the winbind pam authentication, the logon_id will tie this to
|
* Log the winbind pam authentication, the logon_id will tie this to
|
||||||
* any of the logons invoked from this request.
|
* any of the logons invoked from this request.
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
struct winbindd_pam_auth_crap_state {
|
struct winbindd_pam_auth_crap_state {
|
||||||
struct winbindd_response *response;
|
struct winbindd_response *response;
|
||||||
|
bool authoritative;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
|||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
state->authoritative = true;
|
||||||
state->flags = request->flags;
|
state->flags = request->flags;
|
||||||
|
|
||||||
if (state->flags & WBFLAG_PAM_AUTH_PAC) {
|
if (state->flags & WBFLAG_PAM_AUTH_PAC) {
|
||||||
@ -126,6 +127,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
|||||||
|
|
||||||
domain = find_auth_domain(request->flags, auth_domain);
|
domain = find_auth_domain(request->flags, auth_domain);
|
||||||
if (domain == NULL) {
|
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);
|
tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
|
||||||
return tevent_req_post(req, ev);
|
return tevent_req_post(req, ev);
|
||||||
}
|
}
|
||||||
@ -186,6 +192,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
|
|||||||
|
|
||||||
if (tevent_req_is_nterror(req, &status)) {
|
if (tevent_req_is_nterror(req, &status)) {
|
||||||
set_auth_errors(response, status);
|
set_auth_errors(response, status);
|
||||||
|
response->data.auth.authoritative = state->authoritative;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2155,6 +2155,13 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
|
|||||||
|
|
||||||
void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
|
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);
|
resp->data.auth.nt_status = NT_STATUS_V(result);
|
||||||
fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
|
fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user