[LightDM] [PATCH] Add auditing capability
Steve Grubb
sgrubb at redhat.com
Thu Dec 3 12:39:35 PST 2015
Hello,
In order to correctly audit a user's session, the audit utilities need system
entry points to send an audit event that summarizes if an interactive session
will be allowed. For reference, the expectations are listed here:
http://people.redhat.com/sgrubb/audit/user-login-lifecycle.txt
The patch below adds the sending of this event to lightdm. I have tested it as
applied to lightdm 1.10.5 and seems to be working. In the process I found
something odd with pam and I'll describe that in a separate email thread.
Signed-off-by: "Steve Grubb" <sgrubb at redhat.com>
diff -urp lightdm-1.10.5.orig/configure.ac lightdm-1.10.5/configure.ac
--- lightdm-1.10.5.orig/configure.ac 2015-11-13 19:13:06.000000000 -0500
+++ lightdm-1.10.5/configure.ac 2015-11-21 11:19:19.355321264 -0500
@@ -190,6 +190,26 @@ AC_ARG_WITH(greeter-user,
AC_SUBST(GREETER_USER)
AC_DEFINE_UNQUOTED(GREETER_USER, "$GREETER_USER", User to run greeter as)
+AC_ARG_WITH([audit],
+ AS_HELP_STRING([--with-audit], [compile with audit support]),
+ [], [with_audit=no]
+)
+
+if test x$with_audit = xno ; then
+ have_audit=no;
+else
+ AC_CHECK_LIB(audit, audit_log_user_message,
+ have_audit=yes, have_audit=no)
+ AS_CASE([$with_audit:$have_audit],
+ [yes:no],
+ [AC_MSG_ERROR([Audit selected but libaudit not found (or does not support audit_log_user_message())])]
+ )
+ if test x$have_audit = xyes ; then
+ AC_DEFINE(WITH_AUDIT,1,[Define if you want to send login events to the audit system.])
+ fi
+fi
+AM_CONDITIONAL(HAVE_AUDIT, test x$have_audit = xyes)
+
dnl ###########################################################################
dnl Documentation
dnl ###########################################################################
diff -urp lightdm-1.10.5.orig/src/Makefile.am lightdm-1.10.5/src/Makefile.am
--- lightdm-1.10.5.orig/src/Makefile.am 2014-04-08 00:30:25.000000000 -0400
+++ lightdm-1.10.5/src/Makefile.am 2015-11-21 11:16:55.177313574 -0500
@@ -92,6 +92,10 @@ lightdm_LDADD = \
-lgcrypt \
-lpam
+if HAVE_AUDIT
+lightdm_LDADD += -laudit
+endif
+
dm_tool_SOURCES = \
dm-tool.c
diff -urp lightdm-1.10.5.orig/src/session-child.c lightdm-1.10.5/src/session-child.c
--- lightdm-1.10.5.orig/src/session-child.c 2015-11-13 19:50:26.000000000 -0500
+++ lightdm-1.10.5/src/session-child.c 2015-11-21 11:16:55.177313574 -0500
@@ -16,6 +16,9 @@
#include <utmp.h>
#include <utmpx.h>
#include <sys/mman.h>
+#ifdef WITH_AUDIT
+# include <libaudit.h>
+#endif
#include "configuration.h"
#include "session-child.h"
@@ -220,6 +223,33 @@ updwtmpx (const gchar *wtmp_file, struct
updwtmp (wtmp_file, &u);
}
+#ifdef WITH_AUDIT
+static void log_audit(const struct utmpx *ut, const char *tty, int status)
+{
+ int audit_fd;
+ struct passwd *pwd;
+
+ audit_fd = audit_open();
+ if (audit_fd == -1)
+ return;
+ pwd = getpwnam(ut->ut_user);
+ audit_log_acct_message(audit_fd,
+ AUDIT_USER_LOGIN,
+ NULL,
+ "login",
+ ut->ut_user ? ut->ut_user : "(unknown)",
+ pwd ? pwd->pw_uid : (unsigned int) -1,
+ ut->ut_host,
+ NULL,
+ tty,
+ status);
+
+ close(audit_fd);
+}
+#else /* !WITH_LIBAUDIT */
+# define log_audit(mut, mtty, mstatus)
+#endif
+
int
session_child_run (int argc, char **argv)
{
@@ -355,7 +385,7 @@ session_child_run (int argc, char **argv
if (pam_get_item (pam_handle, PAM_USER, (const void **) &new_username) != PAM_SUCCESS)
{
pam_end (pam_handle, 0);
- return EXIT_FAILURE;
+ goto err_out;
}
g_free (username);
username = g_strdup (new_username);
@@ -386,6 +416,7 @@ session_child_run (int argc, char **argv
ut.ut_tv.tv_usec = tv.tv_usec;
updwtmpx ("/var/log/btmp", &ut);
+ log_audit(&ut, tty, 0);
}
/* Check account is valid */
@@ -442,14 +473,14 @@ session_child_run (int argc, char **argv
{
g_printerr ("No user selected during authentication\n");
pam_end (pam_handle, 0);
- return EXIT_FAILURE;
+ goto err_out;
}
/* Stop if we didn't authenticated */
if (authentication_result != PAM_SUCCESS)
{
pam_end (pam_handle, 0);
- return EXIT_FAILURE;
+ goto err_out;
}
/* Get the command to run (blocks) */
@@ -482,7 +513,7 @@ session_child_run (int argc, char **argv
{
pam_setcred (pam_handle, PAM_REINITIALIZE_CRED);
pam_end (pam_handle, 0);
- return EXIT_SUCCESS;
+ goto err_out;
}
/* Redirect stderr to a log file */
@@ -522,7 +553,7 @@ session_child_run (int argc, char **argv
{
g_printerr ("Failed to establish PAM credentials: %s\n", pam_strerror (pam_handle, result));
pam_end (pam_handle, 0);
- return EXIT_FAILURE;
+ goto err_out;
}
/* Open the session */
@@ -531,7 +562,20 @@ session_child_run (int argc, char **argv
{
g_printerr ("Failed to open PAM session: %s\n", pam_strerror (pam_handle, result));
pam_end (pam_handle, 0);
- return EXIT_FAILURE;
+ goto err_out;
+ } else {
+ /* Write successful login to audit system */
+ struct utmpx ut;
+
+ memset (&ut, 0, sizeof (ut));
+ if (tty)
+ strncpy (ut.ut_line, tty + strlen ("/dev/"), sizeof (ut.ut_line));
+ strncpy (ut.ut_user, username, sizeof (ut.ut_user));
+ if (xdisplay)
+ strncpy (ut.ut_host, xdisplay, sizeof (ut.ut_host));
+ else if (remote_host_name)
+ strncpy (ut.ut_host, remote_host_name, sizeof (ut.ut_host));
+ log_audit(&ut, tty, 1);
}
/* Open a connection to the system bus for ConsoleKit - we must keep it open or CK will close the session */
@@ -775,4 +819,20 @@ session_child_run (int argc, char **argv
/* Return result of session process to the daemon */
return return_code;
+
+err_out:
+ {
+ struct utmpx ut;
+
+ memset (&ut, 0, sizeof (ut));
+ if (tty)
+ strncpy (ut.ut_line, tty + strlen ("/dev/"), sizeof (ut.ut_line));
+ strncpy (ut.ut_user, username, sizeof (ut.ut_user));
+ if (xdisplay)
+ strncpy (ut.ut_host, xdisplay, sizeof (ut.ut_host));
+ else if (remote_host_name)
+ strncpy (ut.ut_host, remote_host_name, sizeof (ut.ut_host));
+ log_audit(&ut, tty, 0);
+ }
+ return EXIT_FAILURE;
}
More information about the LightDM
mailing list