mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
heimdal: Pass extra information to hdb_auth_status() to log success and failures
We now pass on the original client name and the client address to allow consistent audit logging in Samba across multiple protocols. We use config->db[0] to find the first database to record incorrect users. Signed-off-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
7cbe1c844e
commit
f498ba77df
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user