auth4: let auth_check_password* return pauthoritative
authorStefan Metzmacher <metze@samba.org>
Fri, 17 Mar 2017 10:16:36 +0000 (11:16 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 24 Mar 2017 10:57:09 +0000 (11:57 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/auth/auth_samba4.c
source4/auth/auth.h
source4/auth/ntlm/auth.c
source4/auth/ntlm/auth_simple.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/smb_server/smb/sesssetup.c

index a0d6afd32d4f9f9aa324fb350f6e81d706dd2e4e..138c6cd4f0960674bd40c874f2c664c7c3025fed 100644 (file)
@@ -118,6 +118,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
        NTSTATUS nt_status;
        struct auth_user_info_dc *user_info_dc;
        struct auth4_context *auth4_context;
+       uint8_t authoritative = 0;
 
        nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -132,13 +133,19 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
                return nt_status;
        }
 
-       nt_status = auth_check_password(auth4_context, auth4_context, user_info, &user_info_dc);
+       nt_status = auth_check_password(auth4_context, auth4_context, user_info,
+                                       &user_info_dc, &authoritative);
        if (!NT_STATUS_IS_OK(nt_status)) {
+               if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
+                                   authoritative == 0)
+               {
+                       nt_status = NT_STATUS_NOT_IMPLEMENTED;
+               }
                TALLOC_FREE(auth4_context);
                TALLOC_FREE(frame);
                return nt_status;
        }
-       
+
        nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
                                                       user_info_dc,
                                                       &info3);
index 95aacfe8eefa8461352afa11817701b96b7d2db5..7358f40b70df04553b53a8a80b1622dda65b31da 100644 (file)
@@ -153,7 +153,8 @@ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
 NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
                             TALLOC_CTX *mem_ctx,
                             const struct auth_usersupplied_info *user_info, 
-                            struct auth_user_info_dc **user_info_dc);
+                            struct auth_user_info_dc **user_info_dc,
+                            uint8_t *pauthoritative);
 NTSTATUS auth4_init(void);
 NTSTATUS auth_register(const struct auth_operations *ops);
 NTSTATUS server_service_auth_init(void);
@@ -173,7 +174,8 @@ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
                                            const struct auth_usersupplied_info *user_info);
 NTSTATUS auth_check_password_recv(struct tevent_req *req,
                                  TALLOC_CTX *mem_ctx,
-                                 struct auth_user_info_dc **user_info_dc);
+                                 struct auth_user_info_dc **user_info_dc,
+                                 uint8_t *pauthoritative);
 
 bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx);
 NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by);
index 926bf48e19262b1b99b3c64db7f42318453cc382..12e26f4c1fa37024af91393b7a5dd3571fcd56ea 100644 (file)
@@ -155,7 +155,8 @@ static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_
 _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
                             TALLOC_CTX *mem_ctx,
                             const struct auth_usersupplied_info *user_info, 
-                            struct auth_user_info_dc **user_info_dc)
+                            struct auth_user_info_dc **user_info_dc,
+                            uint8_t *pauthoritative)
 {
        struct tevent_req *subreq;
        struct tevent_context *ev;
@@ -178,7 +179,8 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
                return NT_STATUS_INTERNAL_ERROR;
        }
 
-       status = auth_check_password_recv(subreq, mem_ctx, user_info_dc);
+       status = auth_check_password_recv(subreq, mem_ctx,
+                                         user_info_dc, pauthoritative);
        TALLOC_FREE(subreq);
 
        return status;
@@ -192,9 +194,10 @@ static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
 {
        struct auth_user_info_dc *user_info_dc;
        NTSTATUS status;
+       uint8_t authoritative = 0;
 
        status = auth_check_password(auth_ctx, mem_ctx, user_info,
-                                    &user_info_dc);
+                                    &user_info_dc, &authoritative);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -225,6 +228,7 @@ struct auth_check_password_state {
        const struct auth_usersupplied_info *user_info;
        struct auth_user_info_dc *user_info_dc;
        struct auth_method_context *method;
+       uint8_t authoritative;
 };
 
 static void auth_check_password_async_trigger(struct tevent_context *ev,
@@ -279,6 +283,10 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
+       /*
+        * We are authoritative by default.
+        */
+       state->authoritative    = 1;
        state->auth_ctx         = auth_ctx;
        state->user_info        = user_info;
 
@@ -386,13 +394,8 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
        }
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-               if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) {
-                       /* don't expose the NT_STATUS_NOT_IMPLEMENTED
-                        * internals, except when the caller is only probing
-                        * one method, as they may do the fallback 
-                        */
-                       status = NT_STATUS_NO_SUCH_USER;
-               }
+               state->authoritative = 0;
+               status = NT_STATUS_NO_SUCH_USER;
        }
 
        if (tevent_req_nterror(req, status)) {
@@ -424,20 +427,23 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 
 _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
                                  TALLOC_CTX *mem_ctx,
-                                 struct auth_user_info_dc **user_info_dc)
+                                 struct auth_user_info_dc **user_info_dc,
+                                 uint8_t *pauthoritative)
 {
        struct auth_check_password_state *state =
                tevent_req_data(req, struct auth_check_password_state);
        NTSTATUS status;
 
+       *pauthoritative = state->authoritative;
+
        if (tevent_req_is_nterror(req, &status)) {
                DEBUG(2,("auth_check_password_recv: "
                         "%s authentication for user [%s\\%s] "
-                        "FAILED with error %s\n",
+                        "FAILED with error %s, authoritative=%u\n",
                         (state->method ? state->method->ops->name : "NO_METHOD"),
                         state->user_info->mapped.domain_name,
                         state->user_info->mapped.account_name,
-                        nt_errstr(status)));
+                        nt_errstr(status), state->authoritative));
                tevent_req_received(req);
                return status;
        }
index f6dd9d0e6be73f7b5b4e1d7437630af0cf46db75..be2ff5e1690389e23b1d3ac99539049c773a2068 100644 (file)
@@ -42,6 +42,7 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
        struct auth_usersupplied_info *user_info;
        struct auth_user_info_dc *user_info_dc;
        NTSTATUS nt_status;
+       uint8_t authoritative = 0;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 
        if (!tmp_ctx) {
@@ -83,7 +84,8 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
                MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
                MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
 
-       nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc);
+       nt_status = auth_check_password(auth_context, tmp_ctx, user_info,
+                                       &user_info_dc, &authoritative);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
                return nt_status;
index 332afd3b4630731e8aebcb125f584c475fddc042..0f59a96cef6d817395f6a5737d381256dd7c06a2 100644 (file)
@@ -982,8 +982,8 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc);
-       /* TODO: set *r->out.authoritative = 0 on specific errors */
+       nt_status = auth_check_password(auth_context, mem_ctx, user_info,
+                                       &user_info_dc, r->out.authoritative);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
        switch (r->in.validation_level) {
index e06853afcd4fb67826c08b3fa57bf9620b3aab9b..e3bfcb3083d07ea61c89afa182dfcf8e71cc2ff6 100644 (file)
@@ -72,9 +72,11 @@ static void sesssetup_old_send(struct tevent_req *subreq)
        struct auth_session_info *session_info;
        struct smbsrv_session *smb_sess;
        NTSTATUS status;
+       uint8_t authoritative = 0;
        uint32_t flags;
 
-       status = auth_check_password_recv(subreq, req, &user_info_dc);
+       status = auth_check_password_recv(subreq, req, &user_info_dc,
+                                         &authoritative);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
@@ -202,11 +204,12 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
        struct auth_user_info_dc *user_info_dc = NULL;
        struct auth_session_info *session_info;
        struct smbsrv_session *smb_sess;
-
+       uint8_t authoritative = 0;
        uint32_t flags;
        NTSTATUS status;
 
-       status = auth_check_password_recv(subreq, req, &user_info_dc);
+       status = auth_check_password_recv(subreq, req, &user_info_dc,
+                                         &authoritative);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) goto failed;