auth: Generate a human readable Authentication log message.
[nivanova/samba-autobuild/.git] / source4 / auth / ntlm / auth.c
index 22602441d82dce9174d887baa143b6ac7fa76134..18ecf853fce01d23eb99b1ca5a03a207bd6ee78d 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;
@@ -187,6 +189,7 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
                                            TALLOC_CTX *mem_ctx,
                                            const struct auth_usersupplied_info *user_info,
+                                           uint8_t *pauthoritative,
                                            void **server_returned_info,
                                            DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
 {
@@ -194,7 +197,7 @@ static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
        NTSTATUS status;
 
        status = auth_check_password(auth_ctx, mem_ctx, user_info,
-                                    &user_info_dc);
+                                    &user_info_dc, pauthoritative);
        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;
 
@@ -353,11 +361,6 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 
        for (method=state->auth_ctx->methods; method; method = method->next) {
 
-               if (state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY
-                   && !(method->ops->flags & AUTH_METHOD_LOCAL_SAM)) {
-                       continue;
-               }
-
                /* we fill in state->method here so debug messages in
                   the callers know which method failed */
                state->method = method;
@@ -366,7 +369,7 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
                status = method->ops->want_check(method, req, state->user_info);
                if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
                        DEBUG(11,("auth_check_password_send: "
-                                 "%s had nothing to say\n",
+                                 "%s doesn't want to check\n",
                                  method->ops->name));
                        continue;
                }
@@ -379,20 +382,20 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
                                                     state,
                                                     state->user_info,
                                                     &state->user_info_dc);
-               if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-                       /* the backend has handled the request */
-                       break;
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
+                       DEBUG(11,("auth_check_password_send: "
+                                 "%s passes to the next method\n",
+                                 method->ops->name));
+                       continue;
                }
+
+               /* the backend has handled the request */
+               break;
        }
 
        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,30 @@ 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;
+       NTSTATUS status = NT_STATUS_OK;
+
+       *pauthoritative = state->authoritative;
 
        if (tevent_req_is_nterror(req, &status)) {
+               /*
+                * Please try not to change this string, it is probably in use
+                * in audit logging tools
+                */
                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));
+
+               log_authentication_event(state->user_info, status,
+                                        NULL, NULL, NULL, NULL);
                tevent_req_received(req);
                return status;
        }
@@ -448,6 +461,12 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
                 state->user_info_dc->info->domain_name,
                 state->user_info_dc->info->account_name));
 
+       log_authentication_event(state->user_info, status,
+                                state->user_info_dc->info->domain_name,
+                                state->user_info_dc->info->account_name,
+                                NULL,
+                                &state->user_info_dc->sids[0]);
+
        *user_info_dc = talloc_move(mem_ctx, &state->user_info_dc);
 
        tevent_req_received(req);
@@ -602,6 +621,20 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char *
 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
 {
        char **auth_methods = NULL;
+       const char **const_auth_methods = NULL;
+
+       /*
+        * As 'auth methods' is deprecated it will be removed
+        * in future releases again, but for now give
+        * admins the flexibility to configure, the behavior
+        * from Samba 4.6: "auth methods = anonymous sam_ignoredomain",
+        * for a while.
+        */
+       const_auth_methods = lpcfg_auth_methods(lp_ctx);
+       if (const_auth_methods != NULL) {
+               DBG_NOTICE("using deprecated 'auth methods' values.\n");
+               return const_auth_methods;
+       }
 
        switch (lpcfg_server_role(lp_ctx)) {
        case ROLE_STANDALONE:
@@ -613,7 +646,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *
        case ROLE_DOMAIN_BDC:
        case ROLE_DOMAIN_PDC:
        case ROLE_ACTIVE_DIRECTORY_DC:
-               auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL);
+               auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind_rodc", NULL);
                break;
        }
        return discard_const_p(const char *, auth_methods);
@@ -645,6 +678,15 @@ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
        return status;
 }
 
+_PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
+                                                  struct tevent_context *ev,
+                                                  struct imessaging_context *msg,
+                                                  struct loadparm_context *lp_ctx,
+                                                  struct auth4_context **auth_ctx)
+{
+       return auth_context_create(mem_ctx, ev, msg, lp_ctx, auth_ctx);
+}
+
 /* the list of currently registered AUTH backends */
 static struct auth_backend {
        const struct auth_operations *ops;