mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
auth: Add hooks for notification of authentication events over the message bus
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>
This commit is contained in:
@ -200,7 +200,8 @@ static void auth_message_send(struct imessaging_context *msg_ctx,
|
|||||||
* Write the json object to the debug logs.
|
* 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)
|
const char *type, int debug_class, int debug_level)
|
||||||
{
|
{
|
||||||
char* json = NULL;
|
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));
|
DEBUGC( debug_class, debug_level, ( "JSON %s: %s\n", type, json));
|
||||||
|
auth_message_send(msg_ctx, json);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
free(json);
|
free(json);
|
||||||
@ -446,6 +448,8 @@ static void add_sid(struct json_context *context,
|
|||||||
* \t\(.Authentication.localAddress)"'
|
* \t\(.Authentication.localAddress)"'
|
||||||
*/
|
*/
|
||||||
static void log_authentication_event_json(
|
static void log_authentication_event_json(
|
||||||
|
struct imessaging_context *msg_ctx,
|
||||||
|
struct loadparm_context *lp_ctx,
|
||||||
const struct auth_usersupplied_info *ui,
|
const struct auth_usersupplied_info *ui,
|
||||||
NTSTATUS status,
|
NTSTATUS status,
|
||||||
const char *domain_name,
|
const char *domain_name,
|
||||||
@ -498,7 +502,7 @@ static void log_authentication_event_json(
|
|||||||
add_string(&authentication, "passwordType", get_password_type( ui));
|
add_string(&authentication, "passwordType", get_password_type( ui));
|
||||||
add_object(&context,AUTH_JSON_TYPE, &authentication);
|
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);
|
free_json_context(&context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,6 +527,8 @@ static void log_authentication_event_json(
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void log_successful_authz_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 *remote,
|
||||||
const struct tsocket_address *local,
|
const struct tsocket_address *local,
|
||||||
const char *service_description,
|
const char *service_description,
|
||||||
@ -559,7 +565,8 @@ static void log_successful_authz_event_json(
|
|||||||
add_string(&authorization, "accountFlags", account_flags);
|
add_string(&authorization, "accountFlags", account_flags);
|
||||||
add_object(&context,AUTHZ_JSON_TYPE, &authorization);
|
add_object(&context,AUTHZ_JSON_TYPE, &authorization);
|
||||||
|
|
||||||
log_json(&context,
|
log_json(msg_ctx,
|
||||||
|
&context,
|
||||||
AUTHZ_JSON_TYPE,
|
AUTHZ_JSON_TYPE,
|
||||||
DBGC_AUTH_AUDIT,
|
DBGC_AUTH_AUDIT,
|
||||||
debug_level);
|
debug_level);
|
||||||
@ -568,7 +575,29 @@ static void log_successful_authz_event_json(
|
|||||||
|
|
||||||
#else
|
#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(
|
static void log_authentication_event_json(
|
||||||
|
struct imessaging_context *msg_ctx,
|
||||||
|
struct loadparm_context *lp_ctx,
|
||||||
const struct auth_usersupplied_info *ui,
|
const struct auth_usersupplied_info *ui,
|
||||||
NTSTATUS status,
|
NTSTATUS status,
|
||||||
const char *domain_name,
|
const char *domain_name,
|
||||||
@ -577,10 +606,13 @@ static void log_authentication_event_json(
|
|||||||
struct dom_sid *sid,
|
struct dom_sid *sid,
|
||||||
int debug_level)
|
int debug_level)
|
||||||
{
|
{
|
||||||
|
log_no_json(msg_ctx, lp_ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_successful_authz_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 *remote,
|
||||||
const struct tsocket_address *local,
|
const struct tsocket_address *local,
|
||||||
const char *service_description,
|
const char *service_description,
|
||||||
@ -589,6 +621,7 @@ static void log_successful_authz_event_json(
|
|||||||
struct auth_session_info *session_info,
|
struct auth_session_info *session_info,
|
||||||
int debug_level)
|
int debug_level)
|
||||||
{
|
{
|
||||||
|
log_no_json(msg_ctx, lp_ctx);
|
||||||
return;
|
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
|
* NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
|
||||||
* authentication events over the message bus.
|
* 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,
|
NTSTATUS status,
|
||||||
const char *domain_name,
|
const char *domain_name,
|
||||||
const char *account_name,
|
const char *account_name,
|
||||||
@ -748,8 +783,10 @@ void log_authentication_event( const struct auth_usersupplied_info *ui,
|
|||||||
sid,
|
sid,
|
||||||
debug_level);
|
debug_level);
|
||||||
}
|
}
|
||||||
if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level)) {
|
if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level) ||
|
||||||
log_authentication_event_json(ui,
|
(msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
|
||||||
|
log_authentication_event_json(msg_ctx, lp_ctx,
|
||||||
|
ui,
|
||||||
status,
|
status,
|
||||||
domain_name,
|
domain_name,
|
||||||
account_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
|
* NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
|
||||||
* authentication events over the message bus.
|
* 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 struct tsocket_address *local,
|
||||||
const char *service_description,
|
const char *service_description,
|
||||||
const char *auth_type,
|
const char *auth_type,
|
||||||
@ -846,8 +885,10 @@ void log_successful_authz_event(const struct tsocket_address *remote,
|
|||||||
session_info,
|
session_info,
|
||||||
debug_level);
|
debug_level);
|
||||||
}
|
}
|
||||||
if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level)) {
|
if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level) ||
|
||||||
log_successful_authz_event_json(remote,
|
(msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
|
||||||
|
log_successful_authz_event_json(msg_ctx, lp_ctx,
|
||||||
|
remote,
|
||||||
local,
|
local,
|
||||||
service_description,
|
service_description,
|
||||||
auth_type,
|
auth_type,
|
||||||
|
@ -152,14 +152,38 @@ struct auth4_context {
|
|||||||
#define AUTHZ_TRANSPORT_PROTECTION_SEAL "SEAL"
|
#define AUTHZ_TRANSPORT_PROTECTION_SEAL "SEAL"
|
||||||
#define AUTHZ_TRANSPORT_PROTECTION_SIGN "SIGN"
|
#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,
|
NTSTATUS status,
|
||||||
const char *account_name,
|
const char *account_name,
|
||||||
const char *domain_name,
|
const char *domain_name,
|
||||||
const char *unix_username,
|
const char *unix_username,
|
||||||
struct dom_sid *sid);
|
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 struct tsocket_address *local,
|
||||||
const char *service_description,
|
const char *service_description,
|
||||||
const char *auth_type,
|
const char *auth_type,
|
||||||
|
@ -233,7 +233,9 @@ static void log_successful_gensec_authz_event(struct gensec_security *gensec_sec
|
|||||||
} else {
|
} else {
|
||||||
transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
|
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,
|
service_description,
|
||||||
final_auth_type,
|
final_auth_type,
|
||||||
transport_protection,
|
transport_protection,
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
bld.SAMBA_LIBRARY('common_auth',
|
bld.SAMBA_LIBRARY('common_auth',
|
||||||
source='auth_sam_reply.c wbc_auth_util.c auth_log.c',
|
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 ',
|
deps='talloc samba-security samba-util util_str_escape LIBTSOCKET jansson MESSAGING_SEND server_id_db ',
|
||||||
private_library=True,
|
private_library=True)
|
||||||
allow_warnings=True)
|
|
||||||
|
|
||||||
bld.RECURSE('gensec')
|
bld.RECURSE('gensec')
|
||||||
bld.RECURSE('ntlmssp')
|
bld.RECURSE('ntlmssp')
|
||||||
|
26
docs-xml/smbdotconf/logon/autheventnotification.xml
Normal file
26
docs-xml/smbdotconf/logon/autheventnotification.xml
Normal file
@ -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>
|
@ -299,7 +299,8 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
|
|||||||
sid = (struct dom_sid) {0};
|
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.logon_domain.string,
|
||||||
server_info->info3->base.account_name.string,
|
server_info->info3->base.account_name.string,
|
||||||
unix_username, &sid);
|
unix_username, &sid);
|
||||||
@ -330,7 +331,7 @@ fail:
|
|||||||
user_info->client.account_name, user_info->mapped.account_name,
|
user_info->client.account_name, user_info->mapped.account_name,
|
||||||
nt_errstr(nt_status), *pauthoritative));
|
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);
|
ZERO_STRUCTP(pserver_info);
|
||||||
|
|
||||||
|
@ -443,7 +443,9 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
|
|||||||
* log all authorizations consistently (be they NLTM, NTLMSSP
|
* log all authorizations consistently (be they NLTM, NTLMSSP
|
||||||
* or krb5) we log this info again as an authorization.
|
* 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->local_host,
|
||||||
user_info->service_description,
|
user_info->service_description,
|
||||||
user_info->auth_description,
|
user_info->auth_description,
|
||||||
|
@ -836,7 +836,8 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
|
|||||||
* covered ncacn_np pass-through auth, and anonymous
|
* covered ncacn_np pass-through auth, and anonymous
|
||||||
* DCE/RPC (eg epmapper, netlogon etc)
|
* 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,
|
p->local_address,
|
||||||
table->name,
|
table->name,
|
||||||
derpc_transport_string_by_transport(p->transport),
|
derpc_transport_string_by_transport(p->transport),
|
||||||
|
@ -449,7 +449,9 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
|
|||||||
state->user_info->mapped.account_name,
|
state->user_info->mapped.account_name,
|
||||||
nt_errstr(status), state->authoritative));
|
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);
|
NULL, NULL, NULL, NULL);
|
||||||
tevent_req_received(req);
|
tevent_req_received(req);
|
||||||
return status;
|
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->domain_name,
|
||||||
state->user_info_dc->info->account_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->domain_name,
|
||||||
state->user_info_dc->info->account_name,
|
state->user_info_dc->info->account_name,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -130,7 +130,9 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
|
|||||||
talloc_steal(mem_ctx, *session_info);
|
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,
|
local_address,
|
||||||
"LDAP",
|
"LDAP",
|
||||||
"simple bind",
|
"simple bind",
|
||||||
|
@ -1285,7 +1285,9 @@ NTSTATUS ldapsrv_do_call(struct ldapsrv_call *call)
|
|||||||
transport_protection = AUTHZ_TRANSPORT_PROTECTION_TLS;
|
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,
|
call->conn->connection->local_address,
|
||||||
"LDAP",
|
"LDAP",
|
||||||
"no bind",
|
"no bind",
|
||||||
|
@ -62,7 +62,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
|
|||||||
* covered ncacn_np pass-through auth, and anonymous
|
* covered ncacn_np pass-through auth, and anonymous
|
||||||
* DCE/RPC (eg epmapper, netlogon etc)
|
* 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,
|
call->conn->local_address,
|
||||||
"DCE/RPC",
|
"DCE/RPC",
|
||||||
auth_type,
|
auth_type,
|
||||||
|
@ -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,
|
local_address = socket_get_local_addr(req->smb_conn->connection->socket,
|
||||||
frame);
|
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,
|
local_address,
|
||||||
"SMB",
|
"SMB",
|
||||||
"bare-NTLM",
|
"bare-NTLM",
|
||||||
|
Reference in New Issue
Block a user