6941265
--- gdm-2.19.1/daemon/verify-pam.c.audit-login	2007-05-13 22:08:24.000000000 -0400
6941265
+++ gdm-2.19.1/daemon/verify-pam.c	2007-05-21 11:59:00.000000000 -0400
6941265
@@ -55,6 +55,14 @@
5c37e63
 #include <bsm/adt_event.h>
5c37e63
 #endif	/* HAVE_ADT */
5c37e63
 
5c37e63
+#define  AU_FAILED 0
5c37e63
+#define  AU_SUCCESS 1
5c37e63
+#ifdef HAVE_LIBAUDIT
5c37e63
+#include <libaudit.h>
5c37e63
+#else
5c37e63
+#define log_to_audit_system(l,h,d,s)	do { ; } while (0)
5c37e63
+#endif
5c37e63
+
5c37e63
 /* Evil, but this way these things are passed to the child session */
5c37e63
 static pam_handle_t *pamh = NULL;
5c37e63
 
6941265
@@ -789,6 +797,54 @@ create_pamh (GdmDisplay *d,
5c37e63
 }
5c37e63
 
6941265
 /**
5c37e63
+ * log_to_audit_system:
5c37e63
+ * @login: Name of user
5c37e63
+ * @hostname: Name of host machine
5c37e63
+ * @tty: Name of display 
5c37e63
+ * @success: 1 for success, 0 for failure
5c37e63
+ *
5c37e63
+ * Logs the success or failure of the login attempt with the linux kernel
5c37e63
+ * audit system. The intent is to capture failed events where the user
5c37e63
+ * fails authentication or otherwise is not permitted to login. There are
5c37e63
+ * many other places where pam could potentially fail and cause login to 
5c37e63
+ * fail, but these are system failures rather than the signs of an account
5c37e63
+ * being hacked.
5c37e63
+ *
5c37e63
+ * Returns nothing.
5c37e63
+ */
5c37e63
+
5c37e63
+#ifdef HAVE_LIBAUDIT
5c37e63
+static void 
5c37e63
+log_to_audit_system(const char *login,
6941265
+		    const char *hostname,
6941265
+		    const char *tty,
6941265
+		    gboolean success)
5c37e63
+{
5c37e63
+	struct passwd *pw;
5c37e63
+	char buf[64];
5c37e63
+	int audit_fd;
5c37e63
+
5c37e63
+	audit_fd = audit_open();
5c37e63
+	if (login)
5c37e63
+		pw = getpwnam(login);
5c37e63
+	else {
5c37e63
+		login = "unknown";
5c37e63
+		pw = NULL;
5c37e63
+	}
5c37e63
+	if (pw) {
5c37e63
+		snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
5c37e63
+		audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
6941265
+				       buf, hostname, NULL, tty, (int)success);
5c37e63
+	} else {
5c37e63
+		snprintf(buf, sizeof(buf), "acct=%s", login);
5c37e63
+		audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
6941265
+				       buf, hostname, NULL, tty, (int)success);
5c37e63
+	}
5c37e63
+	close(audit_fd);
5c37e63
+}
5c37e63
+#endif
5c37e63
+
6941265
+/**
6941265
  * gdm_verify_user:
6941265
  * @username: Name of user or NULL if we should ask
6941265
  * @display: Name of display to register with the authentication system
6941265
@@ -910,6 +966,8 @@ gdm_verify_user (GdmDisplay *d,
6941265
 	/* Start authentication session */
6941265
 	did_we_ask_for_password = FALSE;
6941265
 	if ((pamerr = pam_authenticate (pamh, null_tok)) != PAM_SUCCESS) {
6941265
+		/* Log the failed login attempt */
6941265
+		log_to_audit_system(login, d->hostname, display, AU_FAILED);
6941265
 		if ( ! ve_string_empty (selected_user)) {
6941265
 			pam_handle_t *tmp_pamh;
5c37e63
 
6941265
@@ -1030,6 +1088,8 @@ gdm_verify_user (GdmDisplay *d,
6941265
 	       ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT) && ! local) ) &&
6941265
 	     pwent != NULL &&
6941265
 	     pwent->pw_uid == 0) {
6941265
+		/* Log the failed login attempt */
6941265
+		log_to_audit_system(login, d->hostname, display, AU_FAILED);
6941265
 		gdm_error (_("Root login disallowed on display '%s'"),
6941265
 			   display);
6941265
 		gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
6941265
@@ -1063,6 +1123,8 @@ gdm_verify_user (GdmDisplay *d,
6941265
 		break;
6941265
 	case PAM_NEW_AUTHTOK_REQD :
6941265
 		if ((pamerr = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK)) != PAM_SUCCESS) {
6941265
+			/* Log the failed login attempt */
6941265
+			log_to_audit_system(login, d->hostname, display, AU_FAILED);
6941265
 			gdm_error (_("Authentication token change failed for user %s"), login);
6941265
 			gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
6941265
 						      _("\nThe change of the authentication token failed. "
6941265
@@ -1080,18 +1142,24 @@ gdm_verify_user (GdmDisplay *d,
5c37e63
 #endif	/* HAVE_ADT */
6941265
 		break;
6941265
 	case PAM_ACCT_EXPIRED :
6941265
+		/* Log the failed login attempt */
6941265
+		log_to_audit_system(login, d->hostname, display, AU_FAILED);
6941265
 		gdm_error (_("User %s no longer permitted to access the system"), login);
6941265
 		gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
6941265
 					      _("\nThe system administrator has disabled your account."));
6941265
 		error_msg_given = TRUE;
6941265
 		goto pamerr;
6941265
 	case PAM_PERM_DENIED :
6941265
+		/* Log the failed login attempt */
6941265
+		log_to_audit_system(login, d->hostname, display, AU_FAILED);
6941265
 		gdm_error (_("User %s not permitted to gain access at this time"), login);
6941265
 		gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
6941265
 					      _("\nThe system administrator has disabled access to the system temporarily."));
6941265
 		error_msg_given = TRUE;
6941265
 		goto pamerr;
6941265
 	default :
6941265
+		/* Log the failed login attempt */
6941265
+		log_to_audit_system(login, d->hostname, display, AU_FAILED);
6941265
 		if (gdm_slave_action_pending ())
6941265
 			gdm_error (_("Couldn't set acct. mgmt for %s"), login);
6941265
 		goto pamerr;
6941265
@@ -1143,6 +1211,8 @@ gdm_verify_user (GdmDisplay *d,
6941265
 			gdm_error (_("Couldn't open session for %s"), login);
6941265
 		goto pamerr;
6941265
 	}
6941265
+	/* Login succeeded */
6941265
+	log_to_audit_system(login, d->hostname, display, AU_SUCCESS);
6941265
 
6941265
 	/* Workaround to avoid gdm messages being logged as PAM_pwdb */
6941265
 	gdm_log_shutdown ();
6941265
--- gdm-2.19.1/configure.ac.audit-login	2007-05-13 22:08:48.000000000 -0400
6941265
+++ gdm-2.19.1/configure.ac	2007-05-21 11:37:59.000000000 -0400
6941265
@@ -837,6 +837,10 @@ else
6941265
 fi
6941265
 AC_SUBST(logdir, $GDM_LOG_DIR)
6941265
 
6941265
+AC_ARG_WITH(libaudit,
6941265
+  [  --with-libaudit=[auto/yes/no]  Add Linux audit support [default=auto]],,
6941265
+  with_libaudit=auto)
6941265
+
6941265
 withval=""
6941265
 AC_ARG_WITH(at-bindir,
6941265
 [  --with-at-bindir=<PATH>   PATH to Accessible Technology programs [default=BINDIR]],)
6941265
@@ -948,6 +952,24 @@ else
6941265
    AC_MSG_RESULT(no)
6941265
 fi
5c37e63
 
6941265
+# Check for Linux auditing API
6941265
+#
6941265
+# libaudit detection
6941265
+if test x$with_libaudit = xno ; then
6941265
+    have_libaudit=no;
6941265
+else
6941265
+    # See if we have audit daemon library
6941265
+    AC_CHECK_LIB(audit, audit_log_user_message,
6941265
+                 have_libaudit=yes, have_libaudit=no)
6941265
+fi
6941265
+
6941265
+AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes)
6941265
+
6941265
+if test x$have_libaudit = xyes ; then
6941265
+    EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit"
6941265
+    AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support])
6941265
+fi
6941265
+
6941265
 # Check for Solaris auditing API
6941265
 # Note, Solaris auditing not supported for Solaris 9 or earlier and
6941265
 # should not be used on these versions of Solaris if auditing is