aboutsummaryrefslogtreecommitdiffstats
path: root/testing/gdm/0001-gdm-session-record-alpine-does-not-have-utmp.patch
blob: 57990ea047d95219288969550865714bfbfa6d1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
From 4d25e3bbd9e22a4db5dfb3c9267f0336761ea904 Mon Sep 17 00:00:00 2001
From: William Pitcock <nenolod@dereferenced.org>
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 <utmp.h>
 #endif
 
+#if defined(HAVE_UTIL_H)
+#include <util.h>
+#endif
+
+#if defined(HAVE_GETTTYENT)
+#include <fcntl.h> /* open(2) */
+#include <ttyent.h>
+static int fd = -1;
+#endif
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
@@ -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