mit_kdb: Add support for authentication logging
authorAndreas Schneider <asn@samba.org>
Wed, 25 Oct 2017 07:09:01 +0000 (09:09 +0200)
committerAndreas Schneider <asn@samba.org>
Wed, 3 May 2023 11:31:09 +0000 (13:31 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
source4/kdc/mit-kdb/kdb_samba_policies.c
source4/kdc/mit_samba.c
source4/kdc/mit_samba.h

index b5a2e25ec1705595a4c05c393cef848af43ac6ce..4671a0d17e684756336deeaea198c2de6f81e4b7 100644 (file)
@@ -32,6 +32,7 @@
 #include <profile.h>
 #include <kdb.h>
 
+#include "auth/common_auth.h"
 #include "kdc/mit_samba.h"
 #include "kdb_samba.h"
 
@@ -757,6 +758,8 @@ void kdb_samba_db_audit_as_req(krb5_context context,
                               krb5_timestamp authtime,
                               krb5_error_code error_code)
 {
+       struct mit_samba_context *mit_ctx = NULL;
+
        /*
         * FIXME: This segfaulted with a FAST test
         * FIND_FAST: <unknown client> for <unknown server>, Unknown FAST armor type 0
@@ -765,7 +768,18 @@ void kdb_samba_db_audit_as_req(krb5_context context,
                return;
        }
 
+       mit_ctx = ks_get_context(context);
+       if (mit_ctx == NULL) {
+               return;
+       }
+
        samba_bad_password_count(client, error_code);
 
-       /* TODO: perform proper audit logging for addresses */
+       mit_samba_log_auth_event(mit_ctx,
+                                authtime,
+                                request,
+                                client,
+                                local_addr,
+                                remote_addr,
+                                error_code);
 }
index 9a5d58b92479408e60572855b285035cb10e4e2f..8bdcc1ad9d39ffe827d3ac16f864691cec553018 100644 (file)
@@ -38,6 +38,7 @@
 #include "kdc/db-glue.h"
 #include "auth/auth.h"
 #include "kdc/kpasswd_glue.h"
+#include "lib/tsocket/tsocket.h"
 #include "auth/auth_sam.h"
 #include "messaging/messaging.h"
 
@@ -1172,3 +1173,158 @@ bool mit_samba_princ_needs_pac(krb5_db_entry *db_entry)
 
        return samba_princ_needs_pac(skdc_entry);
 }
+
+void mit_samba_log_auth_event(struct mit_samba_context *mit_ctx,
+                             krb5_timestamp authtime,
+                             krb5_kdc_req *request,
+                             krb5_db_entry *client,
+                             const krb5_address *local_addr,
+                             const krb5_address *remote_addr,
+                             krb5_error_code error_code)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       char *client_name = NULL;
+       char enctype[64] = "unknown enctype";
+       NTSTATUS status = NT_STATUS_OK;
+       krb5_error_code code;
+       /*
+        * Forcing this via the NTLM auth structure is not ideal, but
+        * it is the most practical option right now, and ensures the
+        * logs are consistent, even if some elements are always NULL.
+        */
+       struct auth_usersupplied_info ui = {
+               .was_mapped = true,
+               .client = {
+                       .domain_name = NULL,
+               },
+               .service_description = "Kerberos KDC",
+               .auth_description = "ENC-TS Pre-authentication",
+               .password_type = "unknown enctype",
+       };
+       struct timeval auth_time;
+       struct samba_kdc_entry *p;
+       struct tsocket_address *remote_host;
+       struct tsocket_address *local_host;
+       struct sockaddr_storage ss;
+       size_t sa_socklen = 0;
+       bool ok;
+       int rc;
+
+       p = (struct samba_kdc_entry *)client->e_data;
+
+       code = krb5_unparse_name(mit_ctx->context, client->princ, &client_name);
+       if (code != 0) {
+               return;
+       }
+       ui.client.account_name = client_name;
+
+       /* TODO: if PKINIT set it to "PKINIT" */
+       code = krb5_enctype_to_string(request->authorization_data.enctype,
+                                     enctype,
+                                     sizeof(enctype));
+       if (code == 0) {
+               ui.password_type = enctype;
+       }
+
+       switch (error_code) {
+       case 0: /* CORRECT PASSWORD */
+               status = NT_STATUS_OK;
+               break;
+       case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+               status = NT_STATUS_WRONG_PASSWORD;
+               break;
+       case KRB5KDC_ERR_PREAUTH_FAILED:
+               status = NT_STATUS_NO_SUCH_USER;
+               break;
+       case KRB5KDC_ERR_PREAUTH_REQUIRED:
+               /* Do not log PREAUTH */
+               SAFE_FREE(client_name);
+               TALLOC_FREE(frame);
+               return;
+       default:
+               DBG_ERR("Unhandled error code: %d\n", error_code);
+               SAFE_FREE(client_name);
+               TALLOC_FREE(frame);
+               return;
+       }
+
+       /* Set the local address */
+       ok = smb_krb5_kaddr_to_sockaddr(local_addr,
+                                       0,
+                                       &ss,
+                                       &sa_socklen);
+       if (!ok) {
+               SAFE_FREE(client_name);
+               TALLOC_FREE(frame);
+               return;
+       }
+
+       rc = tsocket_address_bsd_from_sockaddr(frame,
+                                              (const struct sockaddr *)&ss,
+                                              sa_socklen,
+                                              &local_host);
+       if (rc != 0) {
+               ui.local_host = NULL;
+       } else {
+               ui.local_host = local_host;
+       }
+
+       /* Set the remote address */
+       ok = smb_krb5_kaddr_to_sockaddr(remote_addr,
+                                       0,
+                                       &ss,
+                                       &sa_socklen);
+       if (!ok) {
+               SAFE_FREE(client_name);
+               TALLOC_FREE(frame);
+               return;
+       }
+
+       rc = tsocket_address_bsd_from_sockaddr(frame,
+                                              (const struct sockaddr *)&ss,
+                                              sa_socklen,
+                                              &remote_host);
+       if (rc != 0) {
+               ui.remote_host = NULL;
+       } else {
+               ui.remote_host = remote_host;
+       }
+
+       auth_time = timeval_set(authtime, 0);
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+               log_authentication_event(mit_ctx->db_ctx->msg_ctx,
+                                        mit_ctx->db_ctx->lp_ctx,
+                                        &auth_time,
+                                        &ui,
+                                        NT_STATUS_NO_SUCH_USER,
+                                        NULL,
+                                        NULL,
+                                        NULL);
+       } else {
+               struct dom_sid *sid = samdb_result_dom_sid(frame,
+                                                          p->msg,
+                                                          "objectSid");
+               const char *account_name =
+                       ldb_msg_find_attr_as_string(p->msg,
+                                                   "sAMAccountName",
+                                                   NULL);
+               const char *domain_name =
+                       lpcfg_sam_name(p->kdc_db_ctx->lp_ctx);
+
+               ui.mapped.account_name = account_name;
+               ui.mapped.domain_name = domain_name;
+
+               log_authentication_event(mit_ctx->db_ctx->msg_ctx,
+                                        mit_ctx->db_ctx->lp_ctx,
+                                        &auth_time,
+                                        &ui,
+                                        status,
+                                        domain_name,
+                                        account_name,
+                                        sid);
+       }
+
+       SAFE_FREE(client_name);
+       TALLOC_FREE(frame);
+}
index 03574084614461f32ae41595de7de5d27634f397..bcdffe67b72241488e2a1ddda3aa42252a075c84 100644 (file)
@@ -103,4 +103,12 @@ void mit_samba_update_bad_password_count(krb5_db_entry *db_entry);
 
 bool mit_samba_princ_needs_pac(krb5_db_entry *db_entry);
 
+void mit_samba_log_auth_event(struct mit_samba_context *mit_ctx,
+                             krb5_timestamp authtime,
+                             krb5_kdc_req *request,
+                             krb5_db_entry *client,
+                             const krb5_address *local_addr,
+                             const krb5_address *remote_addr,
+                             krb5_error_code error_code);
+
 #endif /* _MIT_SAMBA_H */