gdm/gdm-2.19.1-wtmp.patch
2007-05-21 18:00:19 +00:00

247 lines
7.1 KiB
Diff

--- gdm-2.19.1/config/PreSession.in.wtmp 2007-05-13 22:08:25.000000000 -0400
+++ gdm-2.19.1/config/PreSession.in 2007-05-21 13:17:09.000000000 -0400
@@ -68,17 +68,4 @@ if [ "x$XSETROOT" != "x" ] ; then
"$XSETROOT" -cursor_name left_ptr -solid "$BACKCOLOR"
fi
-
-SESSREG=`gdmwhich sessreg`
-if [ "x$SESSREG" != "x" ] ; then
- # some output for easy debugging
- echo "$0: Registering your session with wtmp and utmp"
- echo "$0: running: $SESSREG -a -w /var/log/wtmp -u /var/run/utmp -x \"$X_SERVERS\" -h \"$REMOTE_HOST\" -l \"$DISPLAY\" \"$USER\""
-
- exec "$SESSREG" -a -w /var/log/wtmp -u /var/run/utmp -x "$X_SERVERS" -h "$REMOTE_HOST" -l "$DISPLAY" "$USER"
- # this is not reached
-fi
-
-# some output for easy debugging
-echo "$0: could not find the sessreg utility, cannot update wtmp and utmp"
exit 0
--- gdm-2.19.1/daemon/slave.c.wtmp 2007-05-21 13:17:09.000000000 -0400
+++ gdm-2.19.1/daemon/slave.c 2007-05-21 13:20:51.000000000 -0400
@@ -4426,6 +4426,13 @@ gdm_slave_session_start (void)
g_free (language);
g_free (gnome_session);
+ gdm_verify_write_record (d,
+ GDM_VERIFY_RECORD_TYPE_LOGIN,
+ pwent->pw_name,
+ d->name,
+ !d->attached? d->hostname : NULL,
+ pid);
+
gdm_slave_send_num (GDM_SOP_SESSPID, pid);
gdm_sigchld_block_push ();
@@ -4488,6 +4495,17 @@ gdm_slave_session_start (void)
}
#endif
+ if ((pid != 0) && (d->last_sess_status != -1)) {
+ gdm_debug ("session '%d' exited with status '%d', recording logout",
+ pid, d->last_sess_status);
+ gdm_verify_write_record (d,
+ GDM_VERIFY_RECORD_TYPE_LOGOUT,
+ pwent->pw_name,
+ d->name,
+ !d->attached? d->hostname : NULL,
+ pid);
+ }
+
gdm_slave_session_stop (pid != 0 /* run_post_session */,
FALSE /* no_shutdown_check */);
--- gdm-2.19.1/daemon/verify-pam.c.wtmp 2007-05-21 13:17:09.000000000 -0400
+++ gdm-2.19.1/daemon/verify-pam.c 2007-05-21 13:23:28.000000000 -0400
@@ -32,6 +32,7 @@
#ifdef __sun
#include <fcntl.h>
#endif
+#include <utmp.h>
#include <glib/gi18n.h>
@@ -63,6 +64,14 @@
#define log_to_audit_system(l,h,d,s) do { ; } while (0)
#endif
+#ifndef GDM_BAD_RECORDS_FILE
+#define GDM_BAD_RECORDS_FILE "/var/log/btmp"
+#endif
+
+#ifndef GDM_NEW_RECORDS_FILE
+#define GDM_NEW_RECORDS_FILE "/var/log/wtmp"
+#endif
+
/* Evil, but this way these things are passed to the child session */
static pam_handle_t *pamh = NULL;
@@ -427,6 +436,125 @@ gdm_verify_select_user (const char *user
selected_user = g_strdup (user);
}
+void
+gdm_verify_write_record (GdmDisplay *d,
+ GdmVerifyRecordType record_type,
+ const gchar *username,
+ const gchar *console_name,
+ const gchar *host_name,
+ GPid pid)
+{
+ struct utmp record = { 0 };
+ GTimeVal now = { 0 };
+ gchar *host;
+
+ gdm_debug ("writing %s record",
+ record_type == GDM_VERIFY_RECORD_TYPE_LOGIN? "session" :
+ record_type == GDM_VERIFY_RECORD_TYPE_LOGOUT? "logout" :
+ "failed session attempt");
+
+ if (record_type != GDM_VERIFY_RECORD_TYPE_LOGOUT)
+ {
+ /* it's possible that PAM failed before
+ * it mapped the user input into a valid username
+ * so we fallback to try using "(unknown)"
+ */
+ if (username != NULL)
+ strncpy (record.ut_user,
+ username,
+ sizeof (record.ut_user));
+ else
+ strncpy (record.ut_user,
+ "(unknown)",
+ sizeof (record.ut_user));
+ }
+
+ gdm_debug ("using username %.*s",
+ sizeof (record.ut_user),
+ record.ut_user);
+
+ strncpy (record.ut_id,
+ console_name +
+ strlen (console_name) -
+ sizeof (record.ut_id),
+ sizeof (record.ut_id));
+
+ gdm_debug ("using id %.*s",
+ sizeof (record.ut_id),
+ record.ut_id);
+
+ if (g_str_has_prefix (console_name, "/dev/")) {
+ strncpy (record.ut_line,
+ console_name + strlen ("/dev/"),
+ sizeof (record.ut_line));
+ } else if (g_str_has_prefix (console_name, ":")) {
+ strncpy (record.ut_line,
+ console_name,
+ sizeof (record.ut_line));
+ }
+
+ gdm_debug ("using line %.*s",
+ sizeof (record.ut_line),
+ record.ut_line);
+
+ host = NULL;
+ if ((host_name != NULL) &&
+ g_str_has_prefix (console_name, ":"))
+ host = g_strdup_printf ("%s%s",
+ host_name,
+ console_name);
+ else if ((host_name != NULL) &&
+ !strstr (console_name, ":"))
+ host = g_strdup (host_name);
+ else if (!g_str_has_prefix (console_name, ":") &&
+ strstr (console_name, ":"))
+ host = g_strdup (console_name);
+
+ if (host)
+ {
+ strncpy (record.ut_host, host, sizeof (record.ut_host));
+ g_free (host);
+ gdm_debug ("using hostname %.*s",
+ sizeof (record.ut_host),
+ record.ut_host);
+ }
+
+ g_get_current_time (&now);
+ record.ut_tv.tv_sec = now.tv_sec;
+ record.ut_tv.tv_usec = now.tv_usec;
+
+ gdm_debug ("using time %ld", (glong) record.ut_tv.tv_sec);
+
+ record.ut_type = USER_PROCESS;
+ gdm_debug ("using type USER_PROCESS");
+
+ record.ut_pid = pid;
+
+ gdm_debug ("using pid %d", (gint) record.ut_pid);
+
+ switch (record_type)
+ {
+ case GDM_VERIFY_RECORD_TYPE_LOGIN:
+ gdm_debug ("writing session record to "
+ GDM_NEW_RECORDS_FILE);
+ updwtmp (GDM_NEW_RECORDS_FILE, &record);
+ break;
+
+ case GDM_VERIFY_RECORD_TYPE_LOGOUT:
+ gdm_debug ("writing logout record to "
+ GDM_NEW_RECORDS_FILE);
+ updwtmp (GDM_NEW_RECORDS_FILE, &record);
+ break;
+
+ case GDM_VERIFY_RECORD_TYPE_FAILED_ATTEMPT:
+ gdm_debug ("writing failed session attempt record to "
+ GDM_BAD_RECORDS_FILE);
+ updwtmp (GDM_BAD_RECORDS_FILE, &record);
+ break;
+ }
+
+}
+
static const char *
perhaps_translate_message (const char *msg)
{
@@ -1234,6 +1362,11 @@ gdm_verify_user (GdmDisplay *d,
* message from the PAM subsystem */
if ( ! error_msg_given &&
gdm_slave_action_pending ()) {
+ gdm_verify_write_record (d, GDM_VERIFY_RECORD_TYPE_FAILED_ATTEMPT,
+ login, display,
+ d->attached? NULL : d->hostname,
+ getpid ());
+
/*
* I'm not sure yet if I should display this message for any
* other issues - heeten
--- gdm-2.19.1/daemon/verify.h.wtmp 2007-05-13 22:08:25.000000000 -0400
+++ gdm-2.19.1/daemon/verify.h 2007-05-21 13:17:09.000000000 -0400
@@ -22,6 +22,12 @@
#include "gdm.h"
#include "display.h"
+typedef enum {
+ GDM_VERIFY_RECORD_TYPE_LOGIN,
+ GDM_VERIFY_RECORD_TYPE_LOGOUT,
+ GDM_VERIFY_RECORD_TYPE_FAILED_ATTEMPT
+} GdmVerifyRecordType;
+
/* If username is NULL, we ask, if local is FALSE, don't start
* the timed login timer */
gchar *gdm_verify_user (GdmDisplay *d,
@@ -32,6 +38,13 @@ gchar *gdm_verify_user (GdmDisplay *d
void gdm_verify_cleanup (GdmDisplay *d);
void gdm_verify_check (void);
void gdm_verify_select_user (const char *user);
+void gdm_verify_write_record (GdmDisplay *d,
+ GdmVerifyRecordType record_type,
+ const gchar *username,
+ const gchar *console_name,
+ const gchar *host_name,
+ GPid pid);
+
/* used in pam */
gboolean gdm_verify_setup_env (GdmDisplay *d);
gboolean gdm_verify_setup_user (GdmDisplay *d,