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)) {
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;
^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
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,
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;
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;
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;
}
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
#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
* 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.
*/
}
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,
#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)
{
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;
}
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,
struct samba_kdc_base_context {
struct tevent_context *ev_ctx;
struct loadparm_context *lp_ctx;
+ struct imessaging_context *msg_ctx;
};
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;