File kdm-audit-log.diff of Package kdebase4-workspace
Index: cmake/modules/FindAudit.cmake
===================================================================
--- /dev/null
+++ cmake/modules/FindAudit.cmake
@@ -0,0 +1,12 @@
+FIND_LIBRARY(AUDIT_LIBRARIES NAMES audit)
+FIND_PATH(AUDIT_INCLUDE_DIR libaudit.h)
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Audit DEFAULT_MSG AUDIT_INCLUDE_DIR AUDIT_LIBRARIES )
+MACRO_LOG_FEATURE(AUDIT_FOUND "audit" "Audit Logging for kdm" "http://people.redhat.com/sgrubb/audit/" FALSE)
+
+MARK_AS_ADVANCED(AUDIT_INCLUDE_DIR AUDIT_LIBRARIES)
+
+if ( AUDIT_LIBRARIES AND AUDIT_INCLUDE_DIR )
+ set(HAVE_LIBAUDIT 1)
+endif ( AUDIT_LIBRARIES AND AUDIT_INCLUDE_DIR )
Index: kdm/backend/client.c
===================================================================
--- kdm/backend/client.c.orig
+++ kdm/backend/client.c
@@ -88,6 +88,14 @@ extern int loginsuccess( const char *Use
#endif
#include <signal.h>
+#define AU_FAILED 0
+#define AU_SUCCESS 1
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#else
+#define log_to_audit_system(l,h,d,s) do { ; } while (0)
+#endif
+
/*
* Session data, mostly what struct verify_info was for
*/
@@ -337,6 +345,56 @@ getPAMXauthData( const char *xauth_file
}
# endif
+ /**
+ * log_to_audit_system:
+ * @login: Name of user
+ * @hostname: Name of host machine
+ * @tty: Name of display
+ * @success: 1 for success, 0 for failure
+ *
+ * Logs the success or failure of the login attempt with the linux kernel
+ * audit system. The intent is to capture failed events where the user
+ * fails authentication or otherwise is not permitted to login. There are
+ * many other places where pam could potentially fail and cause login to
+ * fail, but these are system failures rather than the signs of an account
+ * being hacked.
+ *
+ * Returns nothing.
+ */
+
+#ifdef HAVE_LIBAUDIT
+static void
+log_to_audit_system (const char *loginname,
+ const char *hostname,
+ const char *tty,
+ int success)
+{
+ struct passwd *pw;
+ char buf[64];
+ int audit_fd;
+
+ audit_fd = audit_open();
+ if (loginname)
+ pw = getpwnam(loginname);
+ else {
+ loginname = "unknown";
+ pw = NULL;
+ }
+ Debug("log_to_audit %p %s\n", pw, loginname);
+
+ if (pw) {
+ snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
+ audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
+ buf, hostname, NULL, tty, (int)success);
+ } else {
+ snprintf(buf, sizeof(buf), "acct=%s", loginname);
+ audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
+ buf, hostname, NULL, tty, (int)success);
+ }
+ close(audit_fd);
+}
+#endif
+
static int
doPAMAuth( const char *psrv, struct pam_data *pdata )
{
@@ -422,6 +480,8 @@ doPAMAuth( const char *psrv, struct pam_
gSendStr( curuser );
}
if (pretc != PAM_SUCCESS) {
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
switch (pretc) {
case PAM_USER_UNKNOWN:
case PAM_AUTH_ERR:
@@ -765,6 +825,8 @@ verify( GConvFunc gconv, int rootok )
if (!p->pw_uid) {
if (!rootok && !td->allowRootLogin)
V_RET_FAIL( "Root logins are not allowed" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
wipeStr( curpass );
curpass = 0;
return True; /* don't deny root to log in */
@@ -805,6 +867,8 @@ verify( GConvFunc gconv, int rootok )
}
if (pretc == PAM_SUCCESS)
break;
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
/* effectively there is only PAM_AUTHTOK_ERR */
gSendInt( V_FAIL );
}
@@ -891,6 +955,8 @@ verify( GConvFunc gconv, int rootok )
displayStr( V_MSG_ERR,
"Your account has expired;"
" please contact your system administrator" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
gSendInt( V_FAIL );
LC_RET0;
} else if (tim > (expir - warntime) && !quietlog) {
@@ -917,6 +983,8 @@ verify( GConvFunc gconv, int rootok )
displayStr( V_MSG_ERR,
"Your account has expired;"
" please contact your system administrator" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
gSendInt( V_FAIL );
LC_RET0;
}
@@ -968,6 +1036,8 @@ verify( GConvFunc gconv, int rootok )
}
displayStr( V_MSG_ERR,
"Logins are not allowed at the moment.\nTry again later" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
gSendInt( V_FAIL );
LC_RET0;
}
@@ -977,6 +1047,8 @@ verify( GConvFunc gconv, int rootok )
if (!auth_timeok( lc, time( 0 ) )) {
displayStr( V_MSG_ERR,
"You are not allowed to login at the moment" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
gSendInt( V_FAIL );
LC_RET0;
}
@@ -988,6 +1060,8 @@ verify( GConvFunc gconv, int rootok )
debug( "shell not in /etc/shells\n" );
endusershell();
V_RET_FAIL( "Your login shell is not listed in /etc/shells" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
}
if (!strcmp( s, p->pw_shell )) {
endusershell();
@@ -1514,6 +1588,9 @@ startClient( volatile int *pid )
# define D_LOGIN_SETGROUP 0
#endif /* USE_PAM */
+ /* Login succeeded */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS);
+
removeAuth = True;
chownCtrl( &td->ctrl, curuid );
ctltalk.pipe = &ctlpipe;
Index: kdm/ConfigureChecks.cmake
===================================================================
--- kdm/ConfigureChecks.cmake.orig
+++ kdm/ConfigureChecks.cmake
@@ -231,4 +231,6 @@ if (NOT LIBEXEC_INSTALL_DIR STREQUAL "${
endif (NOT inip)
endif (NOT LIBEXEC_INSTALL_DIR STREQUAL "${BIN_INSTALL_DIR}")
+find_package(Audit)
+
configure_file(config-kdm.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kdm.h)