[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