From 4d25e3bbd9e22a4db5dfb3c9267f0336761ea904 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 6 Jun 2017 00:23:34 +0000 Subject: [PATCH 1/3] gdm-session-record: alpine does not have utmp --- daemon/gdm-session-record.c | 100 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c index 32933ef0..3154df2e 100644 --- a/daemon/gdm-session-record.c +++ b/daemon/gdm-session-record.c @@ -33,6 +33,16 @@ #include #endif +#if defined(HAVE_UTIL_H) +#include +#endif + +#if defined(HAVE_GETTTYENT) +#include /* open(2) */ +#include +static int fd = -1; +#endif + #include #include #include @@ -43,6 +53,9 @@ #define GDM_BAD_SESSION_RECORDS_FILE "/var/log/btmp" #endif +static void write_utmp_login_manually (struct utmp *ut); +static void write_utmp_logout_manually (char *); + #if !defined(GDM_NEW_SESSION_RECORDS_FILE) # if defined(WTMPX_FILE) # define GDM_NEW_SESSION_RECORDS_FILE WTMPX_FILE @@ -183,6 +196,84 @@ record_set_line (UTMP *u, g_debug ("using ut_line %.*s", (int) sizeof (u->ut_line), u->ut_line); } +static void +write_utmp_login_manually (struct utmp *ut) +{ +#if defined(HAVE_GETTTYENT) && defined(HAVE_UTMP_H) + UTMP ubuf; + int topslot = -1; + + g_debug ("Adding new utmp record"); + + /* + * First, loop through /etc/ttys, if needed, to initialize the + * top of the tty slots, since gdm has no tty. + */ + if (topslot < 0) { + topslot = 0; + while (getttyent () != (struct ttyent *) NULL) + topslot++; + } + if ((topslot < 0) || ((fd < 0) && + (fd = open (_PATH_UTMP, O_RDWR|O_CREAT, 0644)) < 0)) + return; + + /* + * Now find a slot that's not in use... + */ + (void) lseek (fd, (off_t) (topslot * sizeof (struct utmp)), SEEK_SET); + + while (1) { + if (read (fd, &ubuf, sizeof (struct utmp)) == + sizeof (struct utmp)) { + if (!ubuf.ut_name[0]) { + (void) lseek (fd, -(off_t) sizeof (struct utmp), + SEEK_CUR); + break; + } + topslot++; + } else { + (void) lseek (fd, (off_t) (topslot * + sizeof (struct utmp)), SEEK_SET); + break; + } + } + + (void) write (fd, ut, sizeof (struct utmp)); +#endif +} + +static void +write_utmp_logout_manually (char *line) +{ +#if defined(HAVE_GETTTYENT) && defined(HAVE_UTMP_H) + int rval = 1; + struct timeval tv; + UTMP ut; + + g_debug ("Removing utmp record"); + + if (fd >= 0) { + (void) lseek (fd, 0, SEEK_SET); + while (read (fd, &ut, sizeof (struct utmp)) == sizeof (struct utmp)) { + if (!ut.ut_name[0] || + strncmp (ut.ut_line, line, UT_LINESIZE)) + continue; + bzero (ut.ut_name, UT_NAMESIZE); + bzero (ut.ut_host, UT_HOSTSIZE); + gettimeofday (&tv, NULL); + ut.ut_time = tv.tv_sec; + (void) lseek (fd, -(off_t) sizeof (struct utmp), SEEK_CUR); + (void) write (fd, &ut, sizeof (struct utmp)); + rval = 0; + } + } + + if (rval != 0) + g_debug ("Failed to remove utmp record"); +#endif +} + void gdm_session_record_login (GPid session_pid, const char *user_name, @@ -227,8 +318,9 @@ gdm_session_record_login (GPid session_pid, #if defined(HAVE_GETUTXENT) g_debug ("Adding or updating utmp record for login"); pututxline (&session_record); -#elif defined(HAVE_LOGIN) - login (&session_record); +#else + if (strcmp (session_record.ut_name, "(unknown)") != 0) + write_utmp_login_manually (&session_record); #endif } @@ -270,8 +362,8 @@ gdm_session_record_logout (GPid session_pid, #if defined(HAVE_GETUTXENT) g_debug ("Adding or updating utmp record for logout"); pututxline (&session_record); -#elif defined(HAVE_LOGOUT) - logout (session_record.ut_line); +#else + write_utmp_logout_manually (session_record.ut_line); #endif } -- 2.13.0