summaryrefslogtreecommitdiffstats
path: root/login-utils/last.c
diff options
context:
space:
mode:
authorSami Kerola2014-08-12 00:04:26 +0200
committerSami Kerola2014-09-19 20:31:01 +0200
commit8813da1ea2d42776c98943617e673d9cf8ec8a77 (patch)
tree29be53f400c5451ccb6849a35b7563552306fa56 /login-utils/last.c
parentlib: remove xgetpass() (diff)
downloadkernel-qcow2-util-linux-8813da1ea2d42776c98943617e673d9cf8ec8a77.tar.gz
kernel-qcow2-util-linux-8813da1ea2d42776c98943617e673d9cf8ec8a77.tar.xz
kernel-qcow2-util-linux-8813da1ea2d42776c98943617e673d9cf8ec8a77.zip
last: make is_phantom() when kernel config does not include audit support
When kernel CONFIG_AUDIT is not set the /proc/<pid>/loginuid information is not present resulting live sessions to be marked 'gone - no logout' in last(1) print out. To go-around this change makes last(1) to look /dev/<tty> device ownership as a substitute of loginuid. The go-around seems to work fairly well, but it has it short comings. For example after closing a X window session the /dev/ttyN file seems to be owned by root, not the user who had it before entering to the X session. While that is suboptimal it is still better than an attmempt to determine uid_t by looking owner of the /proc/<struct utmp ut_pid>, that is a login(1) process running as root. The issue was found using Archlinux installation. $ pacman -Qi linux Name : linux Version : 3.16-2 [...] Build Date : Mon Aug 4 18:06:51 2014 Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'login-utils/last.c')
-rw-r--r--login-utils/last.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/login-utils/last.c b/login-utils/last.c
index f7a2576f4..fb82f31c0 100644
--- a/login-utils/last.c
+++ b/login-utils/last.c
@@ -582,8 +582,6 @@ static int is_phantom(const struct last_control *ctl, struct utmp *ut)
{
struct passwd *pw;
char path[32];
- FILE *f = NULL;
- unsigned int loginuid;
int ret = 0;
if (ut->UL_UT_TIME < ctl->boot_time.tv_sec)
@@ -592,14 +590,26 @@ static int is_phantom(const struct last_control *ctl, struct utmp *ut)
if (!pw)
return 1;
sprintf(path, "/proc/%u/loginuid", ut->ut_pid);
- if (access(path, R_OK) != 0 || !(f = fopen(path, "r")))
- return 1;
+ if (access(path, R_OK) == 0) {
+ unsigned int loginuid;
+ FILE *f = NULL;
+
+ if (!(f = fopen(path, "r")))
+ return 1;
+ if (fscanf(f, "%u", &loginuid) != 1)
+ ret = 1;
+ fclose(f);
+ if (!ret && pw->pw_uid != loginuid)
+ return 1;
+ } else {
+ struct stat st;
- if (fscanf(f, "%u", &loginuid) != 1)
- ret = 1;
- fclose(f);
- if (!ret && pw->pw_uid != loginuid)
- return 1;
+ sprintf(path, "/dev/%s", ut->ut_line);
+ if (stat(path, &st))
+ return 1;
+ if (pw->pw_uid != st.st_uid)
+ return 1;
+ }
return ret;
}