43fc079
--- gdm-2.16.0/config/PostSession.in.wtmp	2006-10-15 20:09:47.000000000 -0400
43fc079
+++ gdm-2.16.0/config/PostSession.in	2006-10-15 20:10:00.000000000 -0400
43fc079
@@ -19,8 +19,4 @@ gdmwhich () {
43fc079
   echo "$OUTPUT"
43fc079
 }
43fc079
 
43fc079
-SESSREG=`gdmwhich sessreg`
43fc079
-if [ "x$SESSREG" != "x" ] ; then
43fc079
-	"$SESSREG" -d -w /var/log/wtmp -u /var/run/utmp -x "$X_SERVERS" -h "$REMOTE_HOST" -l "$DISPLAY" "$USER"
43fc079
-fi
43fc079
 exit 0
43fc079
--- gdm-2.16.0/config/PreSession.in.wtmp	2006-04-26 21:06:05.000000000 -0400
43fc079
+++ gdm-2.16.0/config/PreSession.in	2006-10-15 20:05:45.000000000 -0400
43fc079
@@ -68,17 +68,4 @@ if [ "x$XSETROOT" != "x" ] ; then
43fc079
 	"$XSETROOT" -cursor_name left_ptr -solid "$BACKCOLOR"
43fc079
 fi
43fc079
 
43fc079
-
43fc079
-SESSREG=`gdmwhich sessreg`
43fc079
-if [ "x$SESSREG" != "x" ] ; then
43fc079
-	# some output for easy debugging
43fc079
-	echo "$0: Registering your session with wtmp and utmp"
43fc079
-	echo "$0: running: $SESSREG -a -w /var/log/wtmp -u /var/run/utmp -x \"$X_SERVERS\" -h \"$REMOTE_HOST\" -l \"$DISPLAY\" \"$USER\""
43fc079
-
43fc079
-	exec "$SESSREG" -a -w /var/log/wtmp -u /var/run/utmp -x "$X_SERVERS" -h "$REMOTE_HOST" -l "$DISPLAY" "$USER"
43fc079
-	# this is not reached
43fc079
-fi
43fc079
-
43fc079
-# some output for easy debugging
43fc079
-echo "$0: could not find the sessreg utility, cannot update wtmp and utmp"
43fc079
 exit 0
43fc079
--- gdm-2.16.0/daemon/slave.c.wtmp	2006-10-15 20:05:45.000000000 -0400
43fc079
+++ gdm-2.16.0/daemon/slave.c	2006-10-15 20:05:45.000000000 -0400
43fc079
@@ -4315,6 +4315,14 @@ gdm_slave_session_start (void)
43fc079
     g_free (language);
43fc079
     g_free (gnome_session);
43fc079
 
43fc079
+    gdm_verify_write_record (d,
43fc079
+			     GDM_VERIFY_RECORD_TYPE_LOGIN,
43fc079
+			     pwent->pw_name,
43fc079
+			     d->name, 
43fc079
+			     !d->attached? d->hostname : NULL,
43fc079
+			     pid);
43fc079
+
43fc079
+
43fc079
     gdm_slave_send_num (GDM_SOP_SESSPID, pid);
43fc079
 
43fc079
     gdm_sigchld_block_push ();
43fc079
@@ -4363,6 +4371,17 @@ gdm_slave_session_start (void)
43fc079
 				uid, gid);
43fc079
     }
43fc079
 
43fc079
+    if ((pid != 0) && (d->last_sess_status != -1)) {
43fc079
+	    gdm_debug ("session '%d' exited with status '%d', recording logout",
43fc079
+		       pid, d->last_sess_status);
43fc079
+	    gdm_verify_write_record (d,
43fc079
+				     GDM_VERIFY_RECORD_TYPE_LOGOUT,
43fc079
+				     pwent->pw_name,
43fc079
+				     d->name, 
43fc079
+				     !d->attached? d->hostname : NULL,
43fc079
+				     pid);
43fc079
+    }
43fc079
+
43fc079
     gdm_slave_session_stop (pid != 0 /* run_post_session */,
43fc079
 			    FALSE /* no_shutdown_check */);
43fc079
 
43fc079
@@ -4721,7 +4740,7 @@ gdm_slave_child_handler (int sig)
43fc079
 		}
43fc079
 	} else if (pid != 0 && pid == d->sesspid) {
43fc079
 		d->sesspid = 0;
43fc079
-		if (WIFEXITED (status))
43fc079
+		if (WIFEXITED (status)) 
43fc079
 			d->last_sess_status = WEXITSTATUS (status);
43fc079
 		else
43fc079
 			d->last_sess_status = -1;
43fc079
--- gdm-2.16.0/daemon/verify.h.wtmp	2005-11-03 19:51:21.000000000 -0500
43fc079
+++ gdm-2.16.0/daemon/verify.h	2006-10-15 20:05:45.000000000 -0400
43fc079
@@ -21,6 +21,12 @@
43fc079
 
43fc079
 #include "gdm.h"
43fc079
 
43fc079
+typedef enum {
43fc079
+	GDM_VERIFY_RECORD_TYPE_LOGIN,
43fc079
+	GDM_VERIFY_RECORD_TYPE_LOGOUT,
43fc079
+	GDM_VERIFY_RECORD_TYPE_FAILED_ATTEMPT
43fc079
+} GdmVerifyRecordType;
43fc079
+
43fc079
 /* If username is NULL, we ask, if local is FALSE, don't start
43fc079
  * the timed login timer */
43fc079
 gchar *gdm_verify_user    (GdmDisplay *d,
43fc079
@@ -30,6 +36,13 @@ gchar *gdm_verify_user    (GdmDisplay *d
43fc079
 void   gdm_verify_cleanup (GdmDisplay *d);
43fc079
 void   gdm_verify_check   (void);
43fc079
 void   gdm_verify_select_user (const char *user);
43fc079
+void   gdm_verify_write_record (GdmDisplay *d,
43fc079
+				GdmVerifyRecordType record_type,
43fc079
+				const gchar *username,
43fc079
+				const gchar *console_name,
43fc079
+				const gchar *host_name,
43fc079
+				GPid  pid);
43fc079
+
43fc079
 /* used in pam */
43fc079
 gboolean gdm_verify_setup_env (GdmDisplay *d);
43fc079
 gboolean gdm_verify_setup_user (GdmDisplay *d,
43fc079
--- gdm-2.16.0/daemon/verify-pam.c.wtmp	2006-10-15 20:05:45.000000000 -0400
43fc079
+++ gdm-2.16.0/daemon/verify-pam.c	2006-10-15 20:08:48.000000000 -0400
43fc079
@@ -29,6 +29,7 @@
43fc079
 #ifdef sun
43fc079
 #include <fcntl.h>
43fc079
 #endif
43fc079
+#include <utmp.h>
43fc079
 
43fc079
 #include <glib/gi18n.h>
43fc079
 
43fc079
@@ -55,6 +56,14 @@
43fc079
 #define log_to_audit_system(l,h,d,s)	do { ; } while (0)
43fc079
 #endif
43fc079
 
43fc079
+#ifndef GDM_BAD_RECORDS_FILE
43fc079
+#define GDM_BAD_RECORDS_FILE "/var/log/btmp"
43fc079
+#endif
43fc079
+
43fc079
+#ifndef GDM_NEW_RECORDS_FILE
43fc079
+#define GDM_NEW_RECORDS_FILE "/var/log/wtmp"
43fc079
+#endif
43fc079
+
43fc079
 /* Evil, but this way these things are passed to the child session */
43fc079
 static pam_handle_t *pamh = NULL;
43fc079
 
43fc079
@@ -417,6 +426,125 @@ gdm_verify_select_user (const char *user
43fc079
 		selected_user = g_strdup (user);
43fc079
 }
43fc079
 
43fc079
+void   
43fc079
+gdm_verify_write_record (GdmDisplay *d,
43fc079
+			 GdmVerifyRecordType record_type,
43fc079
+			 const gchar *username,
43fc079
+			 const gchar *console_name,
43fc079
+			 const gchar *host_name,
43fc079
+			 GPid  pid)
43fc079
+{
43fc079
+    struct utmp record = { 0 };
43fc079
+    GTimeVal now = { 0 };
43fc079
+    gchar *host;
43fc079
+
43fc079
+    gdm_debug ("writing %s record",
43fc079
+	       record_type == GDM_VERIFY_RECORD_TYPE_LOGIN? "session" :
43fc079
+	       record_type == GDM_VERIFY_RECORD_TYPE_LOGOUT?  "logout" :
43fc079
+	       "failed session attempt");
43fc079
+
43fc079
+    if (record_type != GDM_VERIFY_RECORD_TYPE_LOGOUT)
43fc079
+    {
43fc079
+	    /* it's possible that PAM failed before
43fc079
+	     * it mapped the user input into a valid username
43fc079
+	     * so we fallback to try using "(unknown)"
43fc079
+	     */
43fc079
+	    if (username != NULL)
43fc079
+		    strncpy (record.ut_user,
43fc079
+			     username, 
43fc079
+			     sizeof (record.ut_user));
43fc079
+	    else
43fc079
+		    strncpy (record.ut_user,
43fc079
+			     "(unknown)",
43fc079
+			     sizeof (record.ut_user));
43fc079
+    }
43fc079
+
43fc079
+    gdm_debug ("using username %.*s",
43fc079
+	       sizeof (record.ut_user),
43fc079
+	       record.ut_user);
43fc079
+
43fc079
+    strncpy (record.ut_id, 
43fc079
+	     console_name + 
43fc079
+	     strlen (console_name) - 
43fc079
+	     sizeof (record.ut_id),
43fc079
+	     sizeof (record.ut_id));
43fc079
+
43fc079
+    gdm_debug ("using id %.*s",
43fc079
+	       sizeof (record.ut_id),
43fc079
+	       record.ut_id);
43fc079
+
43fc079
+    if (g_str_has_prefix (console_name, "/dev/")) {
43fc079
+	    strncpy (record.ut_line, 
43fc079
+		     console_name + strlen ("/dev/"),
43fc079
+		     sizeof (record.ut_line));
43fc079
+    } else if (g_str_has_prefix (console_name, ":")) {
43fc079
+	    strncpy (record.ut_line, 
43fc079
+		     console_name,
43fc079
+		     sizeof (record.ut_line));
43fc079
+    }
43fc079
+
43fc079
+    gdm_debug ("using line %.*s",
43fc079
+	       sizeof (record.ut_line),
43fc079
+	       record.ut_line);
43fc079
+
43fc079
+    host = NULL;
43fc079
+    if ((host_name != NULL) &&
43fc079
+	g_str_has_prefix (console_name, ":"))
43fc079
+	    host = g_strdup_printf ("%s%s",
43fc079
+				    host_name,
43fc079
+				    console_name);
43fc079
+    else if ((host_name != NULL) && 
43fc079
+	     !strstr (console_name, ":"))
43fc079
+	    host = g_strdup (host_name);
43fc079
+    else if (!g_str_has_prefix (console_name, ":") &&
43fc079
+	     strstr (console_name, ":"))
43fc079
+	    host = g_strdup (console_name);
43fc079
+
43fc079
+    if (host)
43fc079
+    {
43fc079
+	    strncpy (record.ut_host, host, sizeof (record.ut_host));
43fc079
+	    g_free (host);
43fc079
+	    gdm_debug ("using hostname %.*s",
43fc079
+		       sizeof (record.ut_host),
43fc079
+		       record.ut_host);
43fc079
+    }
43fc079
+
43fc079
+    g_get_current_time (&now;;
43fc079
+    record.ut_tv.tv_sec = now.tv_sec;
43fc079
+    record.ut_tv.tv_usec = now.tv_usec;
43fc079
+
43fc079
+    gdm_debug ("using time %ld", (glong) record.ut_tv.tv_sec);
43fc079
+
43fc079
+    record.ut_type = USER_PROCESS; 
43fc079
+    gdm_debug ("using type USER_PROCESS"); 
43fc079
+
43fc079
+    record.ut_pid = pid;
43fc079
+
43fc079
+    gdm_debug ("using pid %d", (gint) record.ut_pid);
43fc079
+
43fc079
+    switch (record_type)
43fc079
+    {
43fc079
+	    case GDM_VERIFY_RECORD_TYPE_LOGIN:
43fc079
+		    gdm_debug ("writing session record to " 
43fc079
+			       GDM_NEW_RECORDS_FILE);
43fc079
+		    updwtmp (GDM_NEW_RECORDS_FILE, &record);
43fc079
+		    break;
43fc079
+
43fc079
+	    case GDM_VERIFY_RECORD_TYPE_LOGOUT: 
43fc079
+		    gdm_debug ("writing logout record to " 
43fc079
+			       GDM_NEW_RECORDS_FILE);
43fc079
+		    updwtmp (GDM_NEW_RECORDS_FILE, &record);
43fc079
+		    break;
43fc079
+
43fc079
+	    case GDM_VERIFY_RECORD_TYPE_FAILED_ATTEMPT:
43fc079
+		    gdm_debug ("writing failed session attempt record to " 
43fc079
+			       GDM_BAD_RECORDS_FILE);
43fc079
+		    updwtmp (GDM_BAD_RECORDS_FILE, &record);
43fc079
+		    break;
43fc079
+    }
43fc079
+
43fc079
+}
43fc079
+
43fc079
 static const char *
43fc079
 perhaps_translate_message (const char *msg)
43fc079
 {
43fc079
@@ -1173,6 +1301,12 @@ authenticate_again:
43fc079
      * message from the PAM subsystem */
43fc079
     if ( ! error_msg_given &&
43fc079
 	gdm_slave_action_pending ()) {
43fc079
+
43fc079
+	    gdm_verify_write_record (d, GDM_VERIFY_RECORD_TYPE_FAILED_ATTEMPT,
43fc079
+				     login == NULL? tmp_PAM_USER : login, display, 
43fc079
+				     d->attached? NULL : d->hostname,
43fc079
+				     getpid ());
43fc079
+
43fc079
 	    /* I'm not sure yet if I should display this message for any other issues - heeten */
43fc079
 	    if (pamerr == PAM_AUTH_ERR ||
43fc079
 		pamerr == PAM_USER_UNKNOWN) {