auth: Add hooks for notification of authentication events over the message bus
authorAndrew Bartlett <abartlet@samba.org>
Fri, 24 Mar 2017 02:18:46 +0000 (15:18 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 29 Mar 2017 00:37:28 +0000 (02:37 +0200)
This will allow tests to be written to confirm the correct events are triggered.

We pass in a messaging context from the callers

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
13 files changed:
auth/auth_log.c
auth/common_auth.h
auth/gensec/gensec.c
auth/wscript_build
docs-xml/smbdotconf/logon/autheventnotification.xml [new file with mode: 0644]
source3/auth/auth.c
source3/auth/auth_generic.c
source3/rpc_server/srv_pipe.c
source4/auth/ntlm/auth.c
source4/auth/ntlm/auth_simple.c
source4/ldap_server/ldap_backend.c
source4/rpc_server/dcesrv_auth.c
source4/smb_server/smb/sesssetup.c

index afe51d2122f0104e087891545cf59b1aab784ba1..63b531ca1a07dc3b4dd1e98b029fd091b99cfc7e 100644 (file)
@@ -200,7 +200,8 @@ static void auth_message_send(struct imessaging_context *msg_ctx,
  * Write the json object to the debug logs.
  *
  */
-static void log_json( struct json_context *context,
+static void log_json(struct imessaging_context *msg_ctx,
+                    struct json_context *context,
                     const char *type, int debug_class, int debug_level)
 {
        char* json = NULL;
@@ -217,6 +218,7 @@ static void log_json( struct json_context *context,
        }
 
        DEBUGC( debug_class, debug_level, ( "JSON %s: %s\n", type, json));
+       auth_message_send(msg_ctx, json);
 
        if (json) {
                free(json);
@@ -446,6 +448,8 @@ static void add_sid(struct json_context *context,
  *           \t\(.Authentication.localAddress)"'
  */
 static void log_authentication_event_json(
+                       struct imessaging_context *msg_ctx,
+                       struct loadparm_context *lp_ctx,
                        const struct auth_usersupplied_info *ui,
                        NTSTATUS status,
                        const char *domain_name,
@@ -498,7 +502,7 @@ static void log_authentication_event_json(
        add_string(&authentication, "passwordType", get_password_type( ui));
        add_object(&context,AUTH_JSON_TYPE, &authentication);
 
-       log_json(&context, AUTH_JSON_TYPE, DBGC_AUTH_AUDIT, debug_level);
+       log_json(msg_ctx, &context, AUTH_JSON_TYPE, DBGC_AUTH_AUDIT, debug_level);
        free_json_context(&context);
 }
 
@@ -523,6 +527,8 @@ static void log_authentication_event_json(
  *
  */
 static void log_successful_authz_event_json(
+                               struct imessaging_context *msg_ctx,
+                               struct loadparm_context *lp_ctx,
                                const struct tsocket_address *remote,
                                const struct tsocket_address *local,
                                const char *service_description,
@@ -559,7 +565,8 @@ static void log_successful_authz_event_json(
        add_string(&authorization, "accountFlags", account_flags);
        add_object(&context,AUTHZ_JSON_TYPE, &authorization);
 
-       log_json(&context,
+       log_json(msg_ctx,
+                &context,
                 AUTHZ_JSON_TYPE,
                 DBGC_AUTH_AUDIT,
                 debug_level);
@@ -568,7 +575,29 @@ static void log_successful_authz_event_json(
 
 #else
 
+static void log_no_json(struct imessaging_context *msg_ctx,
+                        struct loadparm_context *lp_ctx)
+{
+       if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
+               static bool auth_event_logged = false;
+               if (auth_event_logged == false) {
+                       auth_event_logged = true;
+                       DBG_ERR("auth event notification = true but Samba was not compiled with jansson\n");
+               }
+       } else {
+               static bool json_logged = false;
+               if (json_logged == false) {
+                       json_logged = true;
+                       DBG_NOTICE("JSON auth logs not available unless compiled with jansson\n");
+               }
+       }
+
+       return;
+}
+
 static void log_authentication_event_json(
+                       struct imessaging_context *msg_ctx,
+                       struct loadparm_context *lp_ctx,
                        const struct auth_usersupplied_info *ui,
                        NTSTATUS status,
                        const char *domain_name,
@@ -577,10 +606,13 @@ static void log_authentication_event_json(
                        struct dom_sid *sid,
                        int debug_level)
 {
+       log_no_json(msg_ctx, lp_ctx);
        return;
 }
 
 static void log_successful_authz_event_json(
+                               struct imessaging_context *msg_ctx,
+                               struct loadparm_context *lp_ctx,
                                const struct tsocket_address *remote,
                                const struct tsocket_address *local,
                                const char *service_description,
@@ -589,6 +621,7 @@ static void log_successful_authz_event_json(
                                struct auth_session_info *session_info,
                                int debug_level)
 {
+       log_no_json(msg_ctx, lp_ctx);
        return;
 }
 
@@ -722,7 +755,9 @@ static void log_authentication_event_human_readable(
  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
  * authentication events over the message bus.
  */
-void log_authentication_event( const struct auth_usersupplied_info *ui,
+void log_authentication_event(struct imessaging_context *msg_ctx,
+                             struct loadparm_context *lp_ctx,
+                             const struct auth_usersupplied_info *ui,
                              NTSTATUS status,
                              const char *domain_name,
                              const char *account_name,
@@ -748,8 +783,10 @@ void log_authentication_event( const struct auth_usersupplied_info *ui,
                                                        sid,
                                                        debug_level);
        }
-       if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level)) {
-               log_authentication_event_json(ui,
+       if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level) ||
+           (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
+               log_authentication_event_json(msg_ctx, lp_ctx,
+                                             ui,
                                              status,
                                              domain_name,
                                              account_name,
@@ -823,7 +860,9 @@ static void log_successful_authz_event_human_readable(
  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
  * authentication events over the message bus.
  */
-void log_successful_authz_event(const struct tsocket_address *remote,
+void log_successful_authz_event(struct imessaging_context *msg_ctx,
+                               struct loadparm_context *lp_ctx,
+                               const struct tsocket_address *remote,
                                const struct tsocket_address *local,
                                const char *service_description,
                                const char *auth_type,
@@ -846,8 +885,10 @@ void log_successful_authz_event(const struct tsocket_address *remote,
                                                          session_info,
                                                          debug_level);
        }
-       if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level)) {
-               log_successful_authz_event_json(remote,
+       if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level) ||
+           (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
+               log_successful_authz_event_json(msg_ctx, lp_ctx,
+                                               remote,
                                                local,
                                                service_description,
                                                auth_type,
index f94c5f15a79895717998befca518efae81354e2a..db59cbb99f3423dc71fef5a89681af0269f9cd26 100644 (file)
@@ -152,14 +152,38 @@ struct auth4_context {
 #define AUTHZ_TRANSPORT_PROTECTION_SEAL "SEAL"
 #define AUTHZ_TRANSPORT_PROTECTION_SIGN "SIGN"
 
-void log_authentication_event(const struct auth_usersupplied_info *ui,
+/*
+ * Log details of an authentication attempt.
+ * Successful and unsuccessful attempts are logged.
+ *
+ * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
+ * authentication events over the message bus.
+ */
+void log_authentication_event(struct imessaging_context *msg_ctx,
+                             struct loadparm_context *lp_ctx,
+                             const struct auth_usersupplied_info *ui,
                              NTSTATUS status,
                              const char *account_name,
                              const char *domain_name,
                              const char *unix_username,
                              struct dom_sid *sid);
 
-void log_successful_authz_event(const struct tsocket_address *remote,
+/*
+ * Log details of a successful authorization to a service.
+ *
+ * Only successful authorizations are logged.  For clarity:
+ * - NTLM bad passwords will be recorded by log_authentication_event
+ * - Kerberos decrypt failures need to be logged in gensec_gssapi et al
+ *
+ * The service may later refuse authorization due to an ACL.
+ *
+ *
+ * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
+ * authorization events over the message bus.
+ */
+void log_successful_authz_event(struct imessaging_context *msg_ctx,
+                               struct loadparm_context *lp_ctx,
+                               const struct tsocket_address *remote,
                                const struct tsocket_address *local,
                                const char *service_description,
                                const char *auth_type,
index 2cd5a22a9a9a84b8e0eed74bc41242f6b11dbf96..6cc82e611761cceee86a7106e773f0e3db48dcc1 100644 (file)
@@ -233,7 +233,9 @@ static void log_successful_gensec_authz_event(struct gensec_security *gensec_sec
        } else {
                transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
        }
-       log_successful_authz_event(remote, local,
+       log_successful_authz_event(gensec_security->auth_context->msg_ctx,
+                                  gensec_security->auth_context->lp_ctx,
+                                  remote, local,
                                   service_description,
                                   final_auth_type,
                                   transport_protection,
index 9e55e1000c77b82a28980cc30e18dc0fef519e63..88e9a0393141c74841af94a2b129265a46fcbd2e 100644 (file)
@@ -3,8 +3,7 @@
 bld.SAMBA_LIBRARY('common_auth',
                   source='auth_sam_reply.c wbc_auth_util.c auth_log.c',
                   deps='talloc samba-security samba-util util_str_escape LIBTSOCKET jansson MESSAGING_SEND server_id_db ',
-                  private_library=True,
-                  allow_warnings=True)
+                  private_library=True)
 
 bld.RECURSE('gensec')
 bld.RECURSE('ntlmssp')
diff --git a/docs-xml/smbdotconf/logon/autheventnotification.xml b/docs-xml/smbdotconf/logon/autheventnotification.xml
new file mode 100644 (file)
index 0000000..1ae2dbf
--- /dev/null
@@ -0,0 +1,26 @@
+<samba:parameter name="auth event notification"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+       <para>When enabled, this option causes Samba (acting as an
+       Active Directory Domain Controller) to stream authentication
+       events across the internal message bus.  Scripts built using
+       Samba's python bindings can listen to these events by
+       registering as the service
+       <filename moreinfo="none">auth_event</filename>.</para>
+
+       <para>This should be considered a developer option (it assists
+       in the Samba testsuite) rather than a facility for external
+       auditing, as message delivery is not guaranteed (a feature
+       that the testsuite works around).  Additionally Samba must be
+       compiled with the jansson support for this option to be
+       effective.</para>
+
+       <para>The authentication events are also logged via the normal
+       logging methods when the <smbconfoption name="log level"/> is
+       set appropriately.</para>
+</description>
+
+<value type="default">no</value>
+</samba:parameter>
index 45bcabd2721ddef74feac521d7c47d230c0dc86f..28d0955c327abe8d9f21be5532084e130d39c072 100644 (file)
@@ -299,7 +299,8 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
                sid = (struct dom_sid) {0};
        }
 
-       log_authentication_event(user_info, nt_status,
+       log_authentication_event(NULL, NULL,
+                                user_info, nt_status,
                                 server_info->info3->base.logon_domain.string,
                                 server_info->info3->base.account_name.string,
                                 unix_username, &sid);
@@ -330,7 +331,7 @@ fail:
                  user_info->client.account_name, user_info->mapped.account_name,
                  nt_errstr(nt_status), *pauthoritative));
 
-       log_authentication_event(user_info, nt_status, NULL, NULL, NULL, NULL);
+       log_authentication_event(NULL, NULL, user_info, nt_status, NULL, NULL, NULL, NULL);
 
        ZERO_STRUCTP(pserver_info);
 
index c18b5435ac49fb50bc70bbde62df6e98c4df91a1..6dedeedd30229661ce2c8188d816784be45b2ff6 100644 (file)
@@ -443,7 +443,9 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
         * log all authorizations consistently (be they NLTM, NTLMSSP
         * or krb5) we log this info again as an authorization.
         */
-       log_successful_authz_event(user_info->remote_host,
+       log_successful_authz_event(auth_context->msg_ctx,
+                                  auth_context->lp_ctx,
+                                  user_info->remote_host,
                                   user_info->local_host,
                                   user_info->service_description,
                                   user_info->auth_description,
index c8b0fdccf425031082e3b7ada76391d6c8bd4f66..95e2cebee8b232e7aaff0a0b5dff9d044a4c583f 100644 (file)
@@ -836,7 +836,8 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
                 * covered ncacn_np pass-through auth, and anonymous
                 * DCE/RPC (eg epmapper, netlogon etc)
                 */
-               log_successful_authz_event(p->remote_address,
+               log_successful_authz_event(NULL, NULL,
+                                          p->remote_address,
                                           p->local_address,
                                           table->name,
                                           derpc_transport_string_by_transport(p->transport),
index 18ecf853fce01d23eb99b1ca5a03a207bd6ee78d..ecb7d6b1cad7bb7e0b5712d3cec07d64b4200b89 100644 (file)
@@ -449,7 +449,9 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
                         state->user_info->mapped.account_name,
                         nt_errstr(status), state->authoritative));
 
-               log_authentication_event(state->user_info, status,
+               log_authentication_event(state->auth_ctx->msg_ctx,
+                                        state->auth_ctx->lp_ctx,
+                                        state->user_info, status,
                                         NULL, NULL, NULL, NULL);
                tevent_req_received(req);
                return status;
@@ -461,7 +463,9 @@ _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,
+       log_authentication_event(state->auth_ctx->msg_ctx,
+                                state->auth_ctx->lp_ctx,
+                                state->user_info, status,
                                 state->user_info_dc->info->domain_name,
                                 state->user_info_dc->info->account_name,
                                 NULL,
index a00d8d4dd2bc72752bc9a5c8ceea6f7fa3136ac8..7e434d7d3c21241ec8a039df349d74abcf5205ef 100644 (file)
@@ -130,7 +130,9 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
                talloc_steal(mem_ctx, *session_info);
        }
 
-       log_successful_authz_event(remote_address,
+       log_successful_authz_event(auth_context->msg_ctx,
+                                  auth_context->lp_ctx,
+                                  remote_address,
                                   local_address,
                                   "LDAP",
                                   "simple bind",
index 7aa51f293ed0f430fd24d666bf07e9e59d3f9b23..d20d586d237533c5e8cb8dfba8418726e9a5942b 100644 (file)
@@ -1285,7 +1285,9 @@ NTSTATUS ldapsrv_do_call(struct ldapsrv_call *call)
                                transport_protection = AUTHZ_TRANSPORT_PROTECTION_TLS;
                        }
 
-                       log_successful_authz_event(call->conn->connection->remote_address,
+                       log_successful_authz_event(call->conn->connection->msg_ctx,
+                                                  call->conn->connection->lp_ctx,
+                                                  call->conn->connection->remote_address,
                                                   call->conn->connection->local_address,
                                                   "LDAP",
                                                   "no bind",
index 1ebb5143b93e99787eb465d869b2293ad2eabbba..efcb586bfcfaaec2b659a6490be8b59af4bad37e 100644 (file)
@@ -62,7 +62,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
                 * covered ncacn_np pass-through auth, and anonymous
                 * DCE/RPC (eg epmapper, netlogon etc)
                 */
-               log_successful_authz_event(call->conn->remote_address,
+               log_successful_authz_event(call->conn->msg_ctx,
+                                          call->conn->dce_ctx->lp_ctx,
+                                          call->conn->remote_address,
                                           call->conn->local_address,
                                           "DCE/RPC",
                                           auth_type,
index cc02222973674a2628a9c51bd602dbc590c2dc1b..13f139344120e4bf602d6e313645e225ddcb51e7 100644 (file)
@@ -54,7 +54,9 @@ void smbsrv_not_spengo_sesssetup_authz_log(struct smbsrv_request *req,
        local_address = socket_get_local_addr(req->smb_conn->connection->socket,
                                              frame);
 
-       log_successful_authz_event(remote_address,
+       log_successful_authz_event(req->smb_conn->connection->msg_ctx,
+                                  req->smb_conn->lp_ctx,
+                                  remote_address,
                                   local_address,
                                   "SMB",
                                   "bare-NTLM",