4

The logname utility became unusable a while ago for many users, since it relies on something that has been broken intentionally due to security concerns, as discussed here. As I read the discussion, it is unlikely that the functionality is going to come back.

I lived with workarounds for a while, but now I feel that they start to fall on my feet, so I'm in search for a proper long-term solution and I'm surprised to see, that there does not seem to be much.

The solution most commonly linked to is presented here, but it originates from here where also a hint is present, that the proposed solution via the environment variable SUDO_USER is not portable.

Another proposed solution is to create a file containing the username and to write a bash alias or similar to emulate the logname functionality, but I wouldn't call this a proper replacement, at least since it assumes an amount of controllability regarding the environment that might not always be possible, better to say, in the least of cases.

The solution via who from here is interesting, but I could not find any information about if there are relevant reliability or portability limitations.

Apart from those approaches, the air is getting thin fast in this area, so I decided to ask here in hope for some new input regarding the topic and my thoughts so far.

Wanderer
  • 205
  • 2
  • 7
  • 4
    What problem are you _actually_ trying to solve? – Satō Katsura Feb 27 '17 at 13:17
  • That `logname` doesn't work anymore and that there does not seem to be a replacement with equivalent attributes. Sorry if I did not manage to make this clear from my question. – Wanderer Feb 27 '17 at 14:02
  • 1
    You re-iterated what you stated about seven times in your post. Well, if _that_'s your real problem then make sure `logname` gets fixed, since `logname(1)` is [part of POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/logname.html). Then again [so is who(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/who.html). _shrug_ – Satō Katsura Feb 27 '17 at 17:24
  • What behavior do you expect from `logname`? For example, across `su`, `sudo`, etc. Do you expect any security properties? – Gilles 'SO- stop being evil' Feb 27 '17 at 23:43
  • @Gilles I used `logname` in several scripts to obtain the username that was used to log into the console, no matter if this user is using `sudo`, `su`, etc. in the moment the script is executed. I basically want this functionality back and to make sure that I'm not going to face some hard-to-track bugs because the behaviour of the new solution is different from the old one, I want the new solution to be as close to `logname` as possible. Regarding security, the possibility to change the username should be limited to the superuser. – Wanderer Feb 28 '17 at 12:39

1 Answers1

5

TL,DR: you probably want /proc/PID/loginuid, even though its behavior doesn't always match logname. But it doesn't work out of the box on all distributions. Note that my answer assumes Linux, it does not apply to other Unix variants.

I don't think you'll find a fully satisfactory answer because you don't have clear expectations from what logname does. On the one hand, you're currently using logname, which is based on utmp records — records that associate a user with a terminal, and which are updated at the good will of the terminal emulator (many don't). On the other hand, you expect that “the possibility to change the username should be limited to the superuser”. This is not the case with utmp records! As explained in the very comment thread you cite, utmp records work most of the time, but they can be faked.

Defining “the username that was used to log into the console” is problematic. It's clear enough in nominal cases, but there are many complicated cases. What happens if a user calls su and attaches to another user's screen session? What happens if a user attaches to another user's X11 or VNC session? How do you trace processes to terminals — what do you do about processes that have no controlling terminal?

Linux actually does have a concept of “login UID”. It's visible for each process as /proc/PID/loginuid. This information is tracked by the kernel, but it's up to userland to let the kernel know when a login takes place. This is normally done via pam_loginuid. Under the hood it's done by writing to /proc/self/loginuid. Linux's login UID follows process ancestry, which is not always the right definition but has the benefit of being simple.

Beware that if a process's login UID is 4294967295 then the process may change it. Init starts with the login UID 4294967295 (equal to -1 as a 32-bit value); this normally indicates a process that's not part of any login session. As long as the login process sets the login UID correctly (just before it sets the real UID from root to the user who's logging in), that's fine. But if there's a way to log in without the login UID set then the user may declare any login UID of their choice. So this information is reliable only if all the ways to run a process on the system go through a step of setting the login UID — forget one and the information becomes useless.

Experimentally, on a Debian jessie machine, all my long-running processes whose login UID is -1 are system services. But there are ways to run a process with login UID of -1, for example via incron. I don't know how many other ways there are; incron was the first I tried and it worked. On Ubuntu 16.04 machine, the pam_loginuid entry for lightdm is commented out, I haven't investigated why. Maybe Ubuntu's lightdm and incron should be considered security bugs, but the fact is that today you can't rely on the login UID working out of the box in major distributions.

See also Loginuid, should be allowed to change or not (mutable or not)?, which is about a kernel option to prevent root from changing the login UID. But beware that it's only effective after the login UID has been set to a proper value; if a user gets to run a process with the login UID still set to -1 then they can set it to whatever they want. It would in fact be safer to make init switch to a different value, say -2, and have pam_loginuid override that value; then -1 would never happen and -2 would indicate “unknown”.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175