summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2017-03-01 12:18:49 +1300
committerAndrew Bartlett <abartlet@samba.org>2017-03-29 02:37:27 +0200
commita0ab86dedca2471ca2e4bb222f272d4bd35c85df (patch)
tree27ba831ad2af6e92a45e307eb2c85dc83ff1da24
parent3bc56854457191ab817bc9a4419b1dee74138b0f (diff)
downloadsamba-a0ab86dedca2471ca2e4bb222f272d4bd35c85df.tar.gz
auth: Add logging of service authorization
In ntlm_auth.c and authdata.c, the session info will be incomplete Signed-off-by: Andrew Bartlett <abartlet@samba.org> Pair-Programmed-by: Gary Lockyer <gary@catalyst.net.nz> Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
-rw-r--r--auth/auth_log.c54
-rw-r--r--auth/common_auth.h5
-rw-r--r--auth/gensec/gensec.c36
-rw-r--r--auth/gensec/gensec.h1
-rw-r--r--source3/libads/authdata.c3
-rw-r--r--source3/utils/ntlm_auth.c3
6 files changed, 100 insertions, 2 deletions
diff --git a/auth/auth_log.c b/auth/auth_log.c
index 64b6eaa102c..9bbc172e664 100644
--- a/auth/auth_log.c
+++ b/auth/auth_log.c
@@ -159,3 +159,57 @@ void log_authentication_event(const struct auth_usersupplied_info *ui,
talloc_free(frame);
}
+
+
+/*
+ * Log details of a successful authorization to a service.
+ *
+ * Only successful authorizations are logged. For clarity:
+ * - NTLM bad passwords will be recorded by the above
+ * - Kerberos decrypt failures need to be logged in gensec_gssapi et al
+ *
+ * The service may later refuse authorization due to an ACL.
+ *
+ */
+void log_successful_authz_event(const struct tsocket_address *remote,
+ const struct tsocket_address *local,
+ const char *service_description,
+ struct auth_session_info *session_info)
+{
+ TALLOC_CTX *frame = NULL;
+
+ char *ts = NULL; /* formatted current time */
+ char *remote_str = NULL; /* formatted remote host */
+ char *local_str = NULL; /* formatted local host */
+ char sid_buf[DOM_SID_STR_BUFLEN];
+
+ /* set the log level */
+ if (!CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT, AUTHZ_SUCCESS_LEVEL)) {
+ return;
+ }
+
+ frame = talloc_stackframe();
+
+ /* Get the current time */
+ ts = http_timestring(frame, time(NULL));
+
+ remote_str = tsocket_address_string(remote, frame);
+ local_str = tsocket_address_string(local, frame);
+
+ dom_sid_string_buf(&session_info->security_token->sids[0], sid_buf, sizeof(sid_buf));
+
+ DEBUGC( DBGC_AUTH_AUDIT, AUTHZ_SUCCESS_LEVEL, (
+ "Successful AuthZ: [%s] user [%s]\\[%s] [%s]"
+ " at [%s]"
+ " Remote host [%s]"
+ " local host [%s]\n",
+ service_description,
+ log_escape(frame, session_info->info->domain_name),
+ log_escape(frame, session_info->info->account_name),
+ sid_buf,
+ ts,
+ remote_str,
+ local_str));
+
+ talloc_free(frame);
+}
diff --git a/auth/common_auth.h b/auth/common_auth.h
index c2ba846de54..8950a0cdc91 100644
--- a/auth/common_auth.h
+++ b/auth/common_auth.h
@@ -152,4 +152,9 @@ void log_authentication_event(const struct auth_usersupplied_info *ui,
const char *domain_name,
const char *unix_username,
struct dom_sid *sid);
+
+void log_successful_authz_event(const struct tsocket_address *remote,
+ const struct tsocket_address *local,
+ const char *service_description,
+ struct auth_session_info *session_info);
#endif
diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c
index e413fbdfd6f..63cc35e9074 100644
--- a/auth/gensec/gensec.c
+++ b/auth/gensec/gensec.c
@@ -29,6 +29,7 @@
#include "auth/gensec/gensec.h"
#include "auth/gensec/gensec_internal.h"
#include "librpc/gen_ndr/dcerpc.h"
+#include "auth/common_auth.h"
_PRIVATE_ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security,
bool full_reset)
@@ -192,13 +193,36 @@ _PUBLIC_ NTSTATUS gensec_session_key(struct gensec_security *gensec_security,
return gensec_security->ops->session_key(gensec_security, mem_ctx, session_key);
}
+/*
+ * Log details of a successful GENSEC authorization to a service.
+ *
+ * Only successful authorizations are logged, as only these call gensec_session_info()
+ *
+ * The service may later refuse authorization due to an ACL.
+ *
+ */
+static void log_successful_gensec_authz_event(struct gensec_security *gensec_security,
+ struct auth_session_info *session_info)
+{
+ const struct tsocket_address *remote
+ = gensec_get_remote_address(gensec_security);
+ const struct tsocket_address *local
+ = gensec_get_local_address(gensec_security);
+ const char *service_description
+ = gensec_get_target_service_description(gensec_security);
+ log_successful_authz_event(remote, local, service_description, session_info);
+}
+
+
/**
* Return the credentials of a logged on user, including session keys
* etc.
*
* Only valid after a successful authentication
*
- * May only be called once per authentication.
+ * May only be called once per authentication. This will also make an
+ * authorization log entry, as it is already called by all the
+ * callers.
*
*/
@@ -206,10 +230,18 @@ _PUBLIC_ NTSTATUS gensec_session_info(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
struct auth_session_info **session_info)
{
+ NTSTATUS status;
if (!gensec_security->ops->session_info) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- return gensec_security->ops->session_info(gensec_security, mem_ctx, session_info);
+ status = gensec_security->ops->session_info(gensec_security, mem_ctx, session_info);
+
+ if (NT_STATUS_IS_OK(status) && !gensec_security->subcontext
+ && (gensec_security->want_features & GENSEC_FEATURE_NO_AUTHZ_LOG) == 0) {
+ log_successful_gensec_authz_event(gensec_security, *session_info);
+ }
+
+ return status;
}
_PUBLIC_ void gensec_set_max_update_size(struct gensec_security *gensec_security,
diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h
index 0c9fa2661a8..7bd893266b9 100644
--- a/auth/gensec/gensec.h
+++ b/auth/gensec/gensec.h
@@ -64,6 +64,7 @@ struct gensec_target {
#define GENSEC_FEATURE_UNIX_TOKEN 0x00000100
#define GENSEC_FEATURE_NTLM_CCACHE 0x00000200
#define GENSEC_FEATURE_LDAP_STYLE 0x00000400
+#define GENSEC_FEATURE_NO_AUTHZ_LOG 0x00000800
#define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
index f4f4b4f1898..d8a6487dc27 100644
--- a/source3/libads/authdata.c
+++ b/source3/libads/authdata.c
@@ -269,6 +269,9 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
talloc_unlink(tmp_ctx, gensec_settings);
talloc_unlink(tmp_ctx, auth_context);
+ /* Session info is not complete, do not pass to auth log */
+ gensec_want_feature(gensec_server_context, GENSEC_FEATURE_NO_AUTHZ_LOG);
+
status = gensec_start_mech_by_oid(gensec_server_context, GENSEC_OID_KERBEROS5);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, (__location__ "Failed to start server-side GENSEC krb5 to validate a Kerberos ticket: %s\n", nt_errstr(status)));
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index c0b55215300..6a7a269987c 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -1455,6 +1455,9 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
gensec_want_feature_list(state->gensec_state, want_feature_list);
+ /* Session info is not complete, do not pass to auth log */
+ gensec_want_feature(state->gensec_state, GENSEC_FEATURE_NO_AUTHZ_LOG);
+
switch (stdio_helper_mode) {
case GSS_SPNEGO_CLIENT:
case GSS_SPNEGO_SERVER: