diff options
-rw-r--r-- | auth/auth_log.c | 8 | ||||
-rw-r--r-- | auth/common_auth.h | 7 | ||||
-rw-r--r-- | selftest/knownfail | 15 | ||||
-rw-r--r-- | source4/heimdal/kdc/kerberos5.c | 39 | ||||
-rw-r--r-- | source4/heimdal/lib/hdb/hdb.h | 11 | ||||
-rw-r--r-- | source4/kdc/db-glue.c | 1 | ||||
-rw-r--r-- | source4/kdc/hdb-samba4.c | 124 | ||||
-rw-r--r-- | source4/kdc/kdc-heimdal.c | 1 | ||||
-rw-r--r-- | source4/kdc/samba_kdc.h | 2 |
9 files changed, 180 insertions, 28 deletions
diff --git a/auth/auth_log.c b/auth/auth_log.c index 63b531ca1a0..cec135e45cf 100644 --- a/auth/auth_log.c +++ b/auth/auth_log.c @@ -637,9 +637,11 @@ static const char* get_password_type(const struct auth_usersupplied_info *ui) const char *password_type = NULL; - if (ui->password_state == AUTH_PASSWORD_RESPONSE && - (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) && - ui->password.response.nt.length == 24) { + if (ui->password_type != NULL) { + password_type = ui->password_type; + } else if (ui->password_state == AUTH_PASSWORD_RESPONSE && + (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) && + ui->password.response.nt.length == 24) { password_type = "MSCHAPv2"; } else if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED) || (ui->password_state == AUTH_PASSWORD_PLAIN)) { diff --git a/auth/common_auth.h b/auth/common_auth.h index db59cbb99f3..507971794f3 100644 --- a/auth/common_auth.h +++ b/auth/common_auth.h @@ -83,6 +83,13 @@ struct auth_usersupplied_info const char *service_description; const char *auth_description; + + /* + * for logging only, normally worked out from the password but + * for krb5 logging only (krb5 normally doesn't use this) we + * record the enc type here + */ + const char *password_type; }; struct auth_method_context; diff --git a/selftest/knownfail b/selftest/knownfail index e85a8a66907..b25038064c3 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -319,18 +319,3 @@ ^samba3.smb2.credits.skipped_mid.* ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_dbcheck ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_check_missing -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_ldap\( -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_ip_tcp_krb5_dns -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_ip_tcp_krb5_dns_connect -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_ip_tcp_krb5_dns_seal -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_ip_tcp_krb5_dns_sign -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_np_krb_dns -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_np_krb_dns_sign -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_np_krb_dns_smb2 -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_np_krb_srv -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_rpc_ncacn_np_krb_srv_sign -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_smb\( -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_smb_bad_password -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_smb_bad_user -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_smb_bad_user_and_password -^samba.tests.auth_log.samba.tests.auth_log.AuthLogTests.test_smb_default_connect diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index bd339b343a5..4baf90e41d8 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -1090,6 +1090,13 @@ _kdc_as_rep(krb5_context context, kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, msg); krb5_free_error_message(context, msg); ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + + if (config->db[0] && config->db[0]->hdb_auth_status) + (config->db[0]->hdb_auth_status)(context, config->db[0], NULL, + from_addr, + client_name, + NULL, + HDB_AUTH_CLIENT_UNKNOWN); goto out; } ret = _kdc_db_fetch(context, config, server_princ, @@ -1194,6 +1201,12 @@ _kdc_as_rep(krb5_context context, kdc_log(context, config, 0, "PKINIT pre-authentication succeeded -- %s using %s", client_name, client_cert); + if (clientdb->hdb_auth_status) + (clientdb->hdb_auth_status)(context, clientdb, client, + from_addr, + client_name, + "PKINIT", + HDB_AUTH_PKINIT_SUCCESS); free(client_cert); if (pkp) goto preauth_done; @@ -1291,22 +1304,30 @@ _kdc_as_rep(krb5_context context, pa_key->key.keytype, &str); if (ret2) str = NULL; + kdc_log(context, config, 5, "Failed to decrypt PA-DATA -- %s " "(enctype %s) error %s", client_name, str ? str : "unknown enctype", msg); krb5_free_error_message(context, msg); - free(str); if(hdb_next_enctype2key(context, &client->entry, - enc_data.etype, &pa_key) == 0) + enc_data.etype, &pa_key) == 0) { + free(str); goto try_next_key; + } e_text = "Failed to decrypt PA-DATA"; free_EncryptedData(&enc_data); if (clientdb->hdb_auth_status) - (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD); + (clientdb->hdb_auth_status)(context, clientdb, client, + from_addr, + client_name, + str ? str : "unknown enctype", + HDB_AUTH_WRONG_PASSWORD); + + free(str); ret = KRB5KDC_ERR_PREAUTH_FAILED; continue; @@ -1362,6 +1383,13 @@ _kdc_as_rep(krb5_context context, kdc_log(context, config, 2, "ENC-TS Pre-authentication succeeded -- %s using %s", client_name, str ? str : "unknown enctype"); + if (clientdb->hdb_auth_status) + (clientdb->hdb_auth_status)(context, clientdb, client, + from_addr, + client_name, + str ? str : "unknown enctype", + HDB_AUTH_CORRECT_PASSWORD); + free(str); break; } @@ -1414,7 +1442,10 @@ _kdc_as_rep(krb5_context context, if (clientdb->hdb_auth_status) (clientdb->hdb_auth_status)(context, clientdb, client, - HDB_AUTH_SUCCESS); + from_addr, + client_name, + NULL, + HDB_AUTHZ_SUCCESS); /* * Selelct the best encryption type for the KDC with out regard to diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index 75d18770f01..1af798d3512 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -70,9 +70,12 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4 /* auth status values */ -#define HDB_AUTH_SUCCESS 0 +#define HDB_AUTHZ_SUCCESS 0 #define HDB_AUTH_WRONG_PASSWORD 1 #define HDB_AUTH_INVALID_SIGNATURE 2 +#define HDB_AUTH_CORRECT_PASSWORD 3 +#define HDB_AUTH_PKINIT_SUCCESS 4 +#define HDB_AUTH_CLIENT_UNKNOWN 5 /* key usage for master key */ #define HDB_KU_MKEY 0x484442 @@ -244,7 +247,11 @@ typedef struct HDB{ * In case the entry is locked out, the backend should set the * hdb_entry.flags.locked-out flag. */ - krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int); + krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, + hdb_entry_ex *, struct sockaddr *from_addr, + const char *original_client_name, + const char *auth_type, + int); /** * Check if delegation is allowed. */ diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index bf55befddf8..ce6a707bb43 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -2677,6 +2677,7 @@ NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_conte } kdc_db_ctx->ev_ctx = base_ctx->ev_ctx; kdc_db_ctx->lp_ctx = base_ctx->lp_ctx; + kdc_db_ctx->msg_ctx = base_ctx->msg_ctx; /* get default kdc policy */ lpcfg_default_kdc_policy(base_ctx->lp_ctx, diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 85d166fda67..c0d0e24713f 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -36,9 +36,13 @@ #include "kdc/kdc-glue.h" #include "kdc/db-glue.h" #include "auth/auth_sam.h" +#include "auth/common_auth.h" #include <ldb.h> #include "sdb.h" #include "sdb_hdb.h" +#include "dsdb/samdb/samdb.h" +#include "param/param.h" +#include "../lib/tsocket/tsocket.h" static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode) { @@ -292,19 +296,131 @@ hdb_samba4_check_s4u2self(krb5_context context, HDB *db, static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, hdb_entry_ex *entry, + struct sockaddr *from_addr, + const char *original_client_name, + const char *auth_type, int hdb_auth_status) { struct samba_kdc_db_context *kdc_db_ctx = talloc_get_type_abort(db->hdb_db, struct samba_kdc_db_context); - struct samba_kdc_entry *p = talloc_get_type(entry->ctx, struct samba_kdc_entry); struct ldb_dn *domain_dn = ldb_get_default_basedn(kdc_db_ctx->samdb); - if (hdb_auth_status == HDB_AUTH_WRONG_PASSWORD) { - authsam_update_bad_pwd_count(kdc_db_ctx->samdb, p->msg, domain_dn); - } else if (hdb_auth_status == HDB_AUTH_SUCCESS) { + /* + * 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 = { + .mapped_state = true, + .was_mapped = true, + .client = { + .account_name = original_client_name, + .domain_name = NULL, + }, + .service_description = "Kerberos KDC", + .auth_description = "ENC-TS Pre-authentication", + .password_type = auth_type + }; + + size_t sa_socklen = 0; + + switch (from_addr->sa_family) { + case AF_INET: + sa_socklen = sizeof(struct sockaddr_in); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + sa_socklen = sizeof(struct sockaddr_in6); + break; +#endif + } + + switch (hdb_auth_status) { + case HDB_AUTHZ_SUCCESS: + { + struct samba_kdc_entry *p = talloc_get_type(entry->ctx, + struct samba_kdc_entry); + + /* + * TODO: We could log the AS-REQ authorization success here as + * well. However before we do that, we need to pass + * in the PAC here or re-calculate it. + */ authsam_logon_success_accounting(kdc_db_ctx->samdb, p->msg, domain_dn, true); + break; + } + case HDB_AUTH_INVALID_SIGNATURE: + break; + case HDB_AUTH_CORRECT_PASSWORD: + case HDB_AUTH_WRONG_PASSWORD: + { + TALLOC_CTX *frame = talloc_stackframe(); + struct samba_kdc_entry *p = talloc_get_type(entry->ctx, + struct samba_kdc_entry); + 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); + struct tsocket_address *remote_host; + NTSTATUS status; + int ret; + + if (hdb_auth_status == HDB_AUTH_WRONG_PASSWORD) { + authsam_update_bad_pwd_count(kdc_db_ctx->samdb, p->msg, domain_dn); + status = NT_STATUS_WRONG_PASSWORD; + } else { + status = NT_STATUS_OK; + } + + ret = tsocket_address_bsd_from_sockaddr(frame, from_addr, + sa_socklen, + &remote_host); + if (ret != 0) { + ui.remote_host = NULL; + } else { + ui.remote_host = remote_host; + } + + ui.mapped.account_name = account_name; + ui.mapped.domain_name = domain_name; + + log_authentication_event(kdc_db_ctx->msg_ctx, + kdc_db_ctx->lp_ctx, + &ui, + status, + domain_name, + account_name, + NULL, + sid); + TALLOC_FREE(frame); + break; + } + case HDB_AUTH_CLIENT_UNKNOWN: + { + struct tsocket_address *remote_host; + int ret; + TALLOC_CTX *frame = talloc_stackframe(); + ret = tsocket_address_bsd_from_sockaddr(frame, from_addr, + sa_socklen, + &remote_host); + if (ret != 0) { + ui.remote_host = NULL; + } else { + ui.remote_host = remote_host; + } + + log_authentication_event(kdc_db_ctx->msg_ctx, + kdc_db_ctx->lp_ctx, + &ui, + NT_STATUS_NO_SUCH_USER, + NULL, NULL, + NULL, NULL); + TALLOC_FREE(frame); + break; + } } return 0; } diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c index 061296a4f40..25bb3916038 100644 --- a/source4/kdc/kdc-heimdal.c +++ b/source4/kdc/kdc-heimdal.c @@ -391,6 +391,7 @@ static void kdc_task_init(struct task_server *task) kdc->base_ctx->ev_ctx = task->event_ctx; kdc->base_ctx->lp_ctx = task->lp_ctx; + kdc->base_ctx->msg_ctx = task->msg_ctx; status = hdb_samba4_create_kdc(kdc->base_ctx, kdc->smb_krb5_context->krb5_context, diff --git a/source4/kdc/samba_kdc.h b/source4/kdc/samba_kdc.h index 0827c193897..b76cc31ffda 100644 --- a/source4/kdc/samba_kdc.h +++ b/source4/kdc/samba_kdc.h @@ -33,6 +33,7 @@ struct samba_kdc_policy { struct samba_kdc_base_context { struct tevent_context *ev_ctx; struct loadparm_context *lp_ctx; + struct imessaging_context *msg_ctx; }; struct samba_kdc_seq; @@ -40,6 +41,7 @@ struct samba_kdc_seq; struct samba_kdc_db_context { struct tevent_context *ev_ctx; struct loadparm_context *lp_ctx; + struct imessaging_context *msg_ctx; struct ldb_context *samdb; struct samba_kdc_seq *seq_ctx; bool rodc; |