How do you find the original user through multiple sudo and su commands?
When running a script via sudo or su I want to get the original user. This should happen regardless of multiple sudo
or su
runs inside of each other and specifically sudo su -
.
Results:
Use who am i | awk '{print $1}'
OR logname
as no other methods are guaranteed.
Logged in as self:
evan> echo $USER
evan
evan> echo $SUDO_USER
evan> echo $LOGNAME
evan
evan> whoami
evan
evan> who am i | awk '{print $1}'
evan
evan> logname
evan
evan>
Normal sudo:
evan> sudo -s
root> echo $USER
root
root> echo $SUDO_USER
evan
root> echo $LOGNAME
root
root> whoami
root
root> who am i | awk '{print $1}'
evan
root> logname
evan
root>
sudo su - :
evan> sudo su -
[root ]# echo $USER
root
[root ]# echo $SUDO_USER
[root ]# echo $LOGNAME
root
[root ]# whoami
root
[root ]# who am i | awk '{print $1}'
evan
[root ]# logname
evan
[root ]#
sudo su -; su tom :
evan> sudo su -
[root ]# su tom
tom$ echo $USER
tom
tom$ echo $SUDO_USER
tom$ echo $LOGNAME
tom
tom$ whoami
tom
tom$ who am i | awk '{print $1}'
evan
tom$ logname
evan
tom$
There's no perfect answer. When you change user IDs, the original user ID is not usually preserved, so the information is lost. Some programs, such as logname
and who -m
implement a hack where they check to see which terminal is connected to stdin
, and then check to see what user is logged in on that terminal.
This solution often works, but isn't foolproof, and certainly shouldn't be considered secure. For example, imagine if who
outputs the following:
tom pts/0 2011-07-03 19:18 (1.2.3.4)
joe pts/1 2011-07-03 19:10 (5.6.7.8)
tom
used su
to get to root, and runs your program. If STDIN
is not redirected, then a program like logname
will output tom
. If it IS redirected (e.g. from a file) as so:
logname < /some/file
Then the result is "no login name
", since the input isn't the terminal. More interestingly still, though, is the fact that the user could pose as a different logged in user. Since Joe is logged in on pts/1, Tom could pretend to be him by running
logname < /dev/pts1
Now, it says joe
even though tom is the one who ran the command. In other words, if you use this mechanism in any sort of security role, you're crazy.