]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25717: s3:winbindd: make sure we default to r->out.authoritative = true
authorStefan Metzmacher <metze@samba.org>
Mon, 4 Oct 2021 15:29:34 +0000 (17:29 +0200)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:10 +0000 (10:52 +0100)
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
source3/winbindd/winbindd_irpc.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_pam_auth_crap.c
source3/winbindd/winbindd_util.c

index 4a4894c2658aa69085461f3bbf5acf06dc5c8079..078fa77aed622f84677943d2f6623d99db582f2c 100644 (file)
@@ -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;
index fda29c7e7022a9e1da6da750b0b5f65806cb46c4..12f4554f9b6b85b2164572e20d425ec8461422ea 100644 (file)
@@ -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:
index c49033b375dfc43ef14fe11968ddca1c333c8f20..59dd18e27b8676ce22c1dfd8fbc0b753cbb4a4e0 100644 (file)
@@ -1797,7 +1797,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
 {
        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;
        }
 
@@ -2770,7 +2776,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                                   "from firewalled domain [%s]\n",
                                   info3->base.account_name.string,
                                   info3->base.logon_domain.string);
-                       state->response->data.auth.authoritative = true;
                        result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
                        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.
index b7912db43df2ec47405ced20375c0e88c04c1673..40cab81b5ea93d421475270f587f38bde48d2e47 100644 (file)
@@ -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;
        }
 
index bec706f87deaef04f7ee8dcebfc1bac8d0c053c2..ef197310fa0ce71596881cf35443837c13dea299 100644 (file)
@@ -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));