Skip to content

Commit 45a77fb

Browse files
committed
Log to wtmp and btmp
1 parent 2af8dde commit 45a77fb

File tree

10 files changed

+259
-38
lines changed

10 files changed

+259
-38
lines changed

src/session-child.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <grp.h>
1414
#include <glib.h>
1515
#include <security/pam_appl.h>
16+
#include <utmp.h>
1617
#include <utmpx.h>
1718
#include <sys/mman.h>
1819

@@ -196,6 +197,29 @@ read_xauth (void)
196197
return x_authority_new (x_authority_family, x_authority_address, x_authority_address_length, x_authority_number, x_authority_name, x_authority_data, x_authority_data_length);
197198
}
198199

200+
/* GNU provides this but we can't rely on that so let's make our own version */
201+
static void
202+
updwtmpx (const gchar *wtmp_file, struct utmpx *ut)
203+
{
204+
struct utmp u;
205+
206+
memset (&u, 0, sizeof (u));
207+
u.ut_type = ut->ut_type;
208+
u.ut_pid = ut->ut_pid;
209+
if (ut->ut_line)
210+
strncpy (u.ut_line, ut->ut_line, sizeof (u.ut_line));
211+
if (ut->ut_id)
212+
strncpy (u.ut_id, ut->ut_id, sizeof (u.ut_id));
213+
if (ut->ut_user)
214+
strncpy (u.ut_user, ut->ut_user, sizeof (u.ut_user));
215+
if (ut->ut_host)
216+
strncpy (u.ut_host, ut->ut_host, sizeof (u.ut_host));
217+
u.ut_tv.tv_sec = ut->ut_tv.tv_sec;
218+
u.ut_tv.tv_usec = ut->ut_tv.tv_usec;
219+
220+
updwtmp (wtmp_file, &u);
221+
}
222+
199223
int
200224
session_child_run (int argc, char **argv)
201225
{
@@ -333,6 +357,34 @@ session_child_run (int argc, char **argv)
333357
g_free (username);
334358
username = g_strdup (new_username);
335359

360+
/* Write record to btmp database */
361+
if (authentication_result == PAM_AUTH_ERR)
362+
{
363+
struct utmpx ut;
364+
struct timeval tv;
365+
366+
memset (&ut, 0, sizeof (ut));
367+
ut.ut_type = USER_PROCESS;
368+
ut.ut_pid = getpid ();
369+
if (xdisplay)
370+
{
371+
strncpy (ut.ut_line, xdisplay, sizeof (ut.ut_line));
372+
strncpy (ut.ut_id, xdisplay, sizeof (ut.ut_id));
373+
}
374+
else if (tty)
375+
strncpy (ut.ut_line, tty + strlen ("/dev/"), sizeof (ut.ut_line));
376+
strncpy (ut.ut_user, username, sizeof (ut.ut_user));
377+
if (xdisplay)
378+
strncpy (ut.ut_host, xdisplay, sizeof (ut.ut_host));
379+
else if (remote_host_name)
380+
strncpy (ut.ut_host, remote_host_name, sizeof (ut.ut_host));
381+
gettimeofday (&tv, NULL);
382+
ut.ut_tv.tv_sec = tv.tv_sec;
383+
ut.ut_tv.tv_usec = tv.tv_usec;
384+
385+
updwtmpx ("/var/log/btmp", &ut);
386+
}
387+
336388
/* Check account is valid */
337389
if (authentication_result == PAM_SUCCESS)
338390
authentication_result = pam_acct_mgmt (pam_handle, 0);
@@ -617,10 +669,12 @@ session_child_run (int argc, char **argv)
617669
ut.ut_tv.tv_sec = tv.tv_sec;
618670
ut.ut_tv.tv_usec = tv.tv_usec;
619671

672+
/* Write records to utmp/wtmp databases */
620673
setutxent ();
621674
if (!pututxline (&ut))
622675
g_printerr ("Failed to write utmpx: %s\n", strerror (errno));
623676
endutxent ();
677+
updwtmpx ("/var/log/wtmp", &ut);
624678
}
625679

626680
waitpid (child_pid, &return_code, 0);
@@ -651,10 +705,12 @@ session_child_run (int argc, char **argv)
651705
ut.ut_tv.tv_sec = tv.tv_sec;
652706
ut.ut_tv.tv_usec = tv.tv_usec;
653707

708+
/* Write records to utmp/wtmp databases */
654709
setutxent ();
655710
if (!pututxline (&ut))
656711
g_printerr ("Failed to write utmpx: %s\n", strerror (errno));
657712
endutxent ();
713+
updwtmpx ("/var/log/wtmp", &ut);
658714
}
659715
}
660716

tests/Makefile.am

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ TESTS = \
144144
test-vnc-open-file-descriptors \
145145
test-xdmcp-client \
146146
test-xdmcp-server-login \
147-
test-utmp \
147+
test-utmp-login \
148+
test-utmp-autologin \
149+
test-utmp-wrong-password \
148150
test-no-accounts-service \
149151
test-console-kit \
150152
test-no-console-kit \
@@ -476,7 +478,9 @@ EXTRA_DIST = \
476478
scripts/user-renamed.conf \
477479
scripts/user-renamed-invalid.conf \
478480
scripts/user-session.conf \
479-
scripts/utmp.conf \
481+
scripts/utmp-autologin.conf \
482+
scripts/utmp-login.conf \
483+
scripts/utmp-wrong-password.conf \
480484
scripts/vnc-command.conf \
481485
scripts/vnc-dimensions.conf \
482486
scripts/vnc-login.conf \

tests/scripts/utmp.conf renamed to tests/scripts/utmp-autologin.conf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Check UTMP records written on login
2+
# Check UTMP records written on autologin
33
#
44

55
[test-utmp-config]
@@ -20,8 +20,9 @@ user-session=default
2020
#?XSERVER-0 INDICATE-READY
2121
#?XSERVER-0 ACCEPT-CONNECT
2222

23-
# UTMP record written
23+
# UTMP/WTMP record written
2424
#?UTMP TYPE=USER_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
25+
#?WTMP FILE=.*/wtmp TYPE=USER_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
2526

2627
# Autologin session starts
2728
#?SESSION-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_GREETER_DATA_DIR=.*/have-password1 DESKTOP_SESSION=default USER=have-password1
@@ -31,8 +32,9 @@ user-session=default
3132
# Logout session
3233
#?*SESSION-X-0 LOGOUT
3334

34-
# UTMP record written
35+
# UTMP/WTMP record written
3536
#?UTMP TYPE=DEAD_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
37+
#?WTMP FILE=.*/wtmp TYPE=DEAD_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
3638

3739
# X server stops
3840
#?XSERVER-0 TERMINATE SIGNAL=15

tests/scripts/utmp-login.conf

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#
2+
# Check UTMP records written on login
3+
#
4+
5+
[test-utmp-config]
6+
check-events=true
7+
8+
[SeatDefaults]
9+
user-session=default
10+
11+
#?*START-DAEMON
12+
#?RUNNER DAEMON-START
13+
14+
# X server starts
15+
#?XSERVER-0 START VT=7 SEAT=seat0
16+
17+
# Daemon connects when X server is ready
18+
#?*XSERVER-0 INDICATE-READY
19+
#?XSERVER-0 INDICATE-READY
20+
#?XSERVER-0 ACCEPT-CONNECT
21+
22+
# Greeter starts
23+
#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
24+
#?XSERVER-0 ACCEPT-CONNECT
25+
#?GREETER-X-0 CONNECT-XSERVER
26+
#?GREETER-X-0 CONNECT-TO-DAEMON
27+
#?GREETER-X-0 CONNECTED-TO-DAEMON
28+
29+
# Log into account with a password
30+
#?*GREETER-X-0 AUTHENTICATE USERNAME=have-password1
31+
#?GREETER-X-0 SHOW-PROMPT TEXT="Password:"
32+
#?*GREETER-X-0 RESPOND TEXT="password"
33+
#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=have-password1 AUTHENTICATED=TRUE
34+
#?*GREETER-X-0 START-SESSION
35+
#?GREETER-X-0 TERMINATE SIGNAL=15
36+
37+
# UTMP/WTMP record written
38+
#?UTMP TYPE=USER_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
39+
#?WTMP FILE=.*/wtmp TYPE=USER_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
40+
41+
# Session starts
42+
#?SESSION-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_GREETER_DATA_DIR=.*/have-password1 DESKTOP_SESSION=default USER=have-password1
43+
#?XSERVER-0 ACCEPT-CONNECT
44+
#?SESSION-X-0 CONNECT-XSERVER
45+
46+
# Logout session
47+
#?*SESSION-X-0 LOGOUT
48+
49+
# UTMP/WTMP record written
50+
#?UTMP TYPE=DEAD_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
51+
#?WTMP FILE=.*/wtmp TYPE=DEAD_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
52+
53+
# X server stops
54+
#?XSERVER-0 TERMINATE SIGNAL=15
55+
56+
# X server starts
57+
#?XSERVER-0 START VT=7 SEAT=seat0
58+
59+
# Daemon connects when X server is ready
60+
#?*XSERVER-0 INDICATE-READY
61+
#?XSERVER-0 INDICATE-READY
62+
#?XSERVER-0 ACCEPT-CONNECT
63+
64+
# Greeter starts
65+
#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
66+
#?XSERVER-0 ACCEPT-CONNECT
67+
#?GREETER-X-0 CONNECT-XSERVER
68+
#?GREETER-X-0 CONNECT-TO-DAEMON
69+
#?GREETER-X-0 CONNECTED-TO-DAEMON
70+
71+
# Cleanup
72+
#?*STOP-DAEMON
73+
#?GREETER-X-0 TERMINATE SIGNAL=15
74+
#?XSERVER-0 TERMINATE SIGNAL=15
75+
#?RUNNER DAEMON-EXIT STATUS=0
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#
2+
# Check BTMP records written on failed login
3+
#
4+
5+
[test-utmp-config]
6+
check-events=true
7+
8+
#?*START-DAEMON
9+
#?RUNNER DAEMON-START
10+
11+
# X server starts
12+
#?XSERVER-0 START VT=7 SEAT=seat0
13+
14+
# Daemon connects when X server is ready
15+
#?*XSERVER-0 INDICATE-READY
16+
#?XSERVER-0 INDICATE-READY
17+
#?XSERVER-0 ACCEPT-CONNECT
18+
19+
# Greeter starts
20+
#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
21+
#?XSERVER-0 ACCEPT-CONNECT
22+
#?GREETER-X-0 CONNECT-XSERVER
23+
#?GREETER-X-0 CONNECT-TO-DAEMON
24+
#?GREETER-X-0 CONNECTED-TO-DAEMON
25+
26+
# Login with invalid password
27+
#?*GREETER-X-0 AUTHENTICATE USERNAME=have-password1
28+
#?GREETER-X-0 SHOW-PROMPT TEXT="Password:"
29+
#?*GREETER-X-0 RESPOND TEXT="rubbish"
30+
#?WTMP FILE=.*/btmp TYPE=USER_PROCESS LINE=:0 ID=:0 USER=have-password1 HOST=:0
31+
#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=have-password1 AUTHENTICATED=FALSE
32+
33+
# Cleanup
34+
#?*STOP-DAEMON
35+
#?GREETER-X-0 TERMINATE SIGNAL=15
36+
#?XSERVER-0 TERMINATE SIGNAL=15
37+
#?RUNNER DAEMON-EXIT STATUS=0
38+

tests/src/libsystem.c

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <security/pam_appl.h>
1616
#include <fcntl.h>
1717
#include <dlfcn.h>
18+
#include <utmp.h>
1819
#include <utmpx.h>
1920
#ifdef __linux__
2021
#include <linux/vt.h>
@@ -1442,43 +1443,44 @@ void
14421443
setutxent (void)
14431444
{
14441445
}
1445-
1446+
14461447
struct utmpx *
14471448
pututxline (const struct utmpx *ut)
14481449
{
1449-
GString *status;
1450-
1451-
status = g_string_new ("UTMP");
1452-
switch (ut->ut_type)
1453-
{
1454-
case INIT_PROCESS:
1455-
g_string_append_printf (status, " TYPE=INIT_PROCESS");
1456-
break;
1457-
case LOGIN_PROCESS:
1458-
g_string_append_printf (status, " TYPE=LOGIN_PROCESS");
1459-
break;
1460-
case USER_PROCESS:
1461-
g_string_append_printf (status, " TYPE=USER_PROCESS");
1462-
break;
1463-
case DEAD_PROCESS:
1464-
g_string_append_printf (status, " TYPE=DEAD_PROCESS");
1465-
break;
1466-
default:
1467-
g_string_append_printf (status, " TYPE=%d", ut->ut_type);
1468-
}
1469-
if (ut->ut_line)
1470-
g_string_append_printf (status, " LINE=%s", ut->ut_line);
1471-
if (ut->ut_id)
1472-
g_string_append_printf (status, " ID=%s", ut->ut_id);
1473-
if (ut->ut_user)
1474-
g_string_append_printf (status, " USER=%s", ut->ut_user);
1475-
if (ut->ut_host)
1476-
g_string_append_printf (status, " HOST=%s", ut->ut_host);
1477-
14781450
connect_status ();
14791451
if (g_key_file_get_boolean (config, "test-utmp-config", "check-events", NULL))
1452+
{
1453+
GString *status;
1454+
1455+
status = g_string_new ("UTMP");
1456+
switch (ut->ut_type)
1457+
{
1458+
case INIT_PROCESS:
1459+
g_string_append_printf (status, " TYPE=INIT_PROCESS");
1460+
break;
1461+
case LOGIN_PROCESS:
1462+
g_string_append_printf (status, " TYPE=LOGIN_PROCESS");
1463+
break;
1464+
case USER_PROCESS:
1465+
g_string_append_printf (status, " TYPE=USER_PROCESS");
1466+
break;
1467+
case DEAD_PROCESS:
1468+
g_string_append_printf (status, " TYPE=DEAD_PROCESS");
1469+
break;
1470+
default:
1471+
g_string_append_printf (status, " TYPE=%d", ut->ut_type);
1472+
}
1473+
if (ut->ut_line)
1474+
g_string_append_printf (status, " LINE=%s", ut->ut_line);
1475+
if (ut->ut_id)
1476+
g_string_append_printf (status, " ID=%s", ut->ut_id);
1477+
if (ut->ut_user)
1478+
g_string_append_printf (status, " USER=%s", ut->ut_user);
1479+
if (ut->ut_host)
1480+
g_string_append_printf (status, " HOST=%s", ut->ut_host);
14801481
status_notify ("%s", status->str);
1481-
g_string_free (status, TRUE);
1482+
g_string_free (status, TRUE);
1483+
}
14821484

14831485
return (struct utmpx *)ut;
14841486
}
@@ -1488,6 +1490,46 @@ endutxent (void)
14881490
{
14891491
}
14901492

1493+
void
1494+
updwtmp (const char *wtmp_file, const struct utmp *ut)
1495+
{
1496+
connect_status ();
1497+
if (g_key_file_get_boolean (config, "test-utmp-config", "check-events", NULL))
1498+
{
1499+
GString *status;
1500+
1501+
status = g_string_new ("WTMP");
1502+
g_string_append_printf (status, " FILE=%s", wtmp_file);
1503+
switch (ut->ut_type)
1504+
{
1505+
case INIT_PROCESS:
1506+
g_string_append_printf (status, " TYPE=INIT_PROCESS");
1507+
break;
1508+
case LOGIN_PROCESS:
1509+
g_string_append_printf (status, " TYPE=LOGIN_PROCESS");
1510+
break;
1511+
case USER_PROCESS:
1512+
g_string_append_printf (status, " TYPE=USER_PROCESS");
1513+
break;
1514+
case DEAD_PROCESS:
1515+
g_string_append_printf (status, " TYPE=DEAD_PROCESS");
1516+
break;
1517+
default:
1518+
g_string_append_printf (status, " TYPE=%d", ut->ut_type);
1519+
}
1520+
if (ut->ut_line)
1521+
g_string_append_printf (status, " LINE=%s", ut->ut_line);
1522+
if (ut->ut_id)
1523+
g_string_append_printf (status, " ID=%s", ut->ut_id);
1524+
if (ut->ut_user)
1525+
g_string_append_printf (status, " USER=%s", ut->ut_user);
1526+
if (ut->ut_host)
1527+
g_string_append_printf (status, " HOST=%s", ut->ut_host);
1528+
status_notify ("%s", status->str);
1529+
g_string_free (status, TRUE);
1530+
}
1531+
}
1532+
14911533
struct xcb_connection_t
14921534
{
14931535
gchar *display;

tests/test-utmp

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)