Linux 如何通过多个sudo和su命令找到原始用户?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4598001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you find the original user through multiple sudo and su commands?
提问by evan
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 -
.
通过 sudo 或 su 运行脚本时,我想获取原始用户。这应该发生,无论多个sudo
还是su
在彼此内部运行,特别是sudo su -
。
采纳答案by evan
Results:
结果:
Use who am i | awk '{print $1}'
OR logname
as no other methods are guaranteed.
使用who am i | awk '{print $1}'
OR,logname
因为不保证其他方法。
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 }'
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 }'
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 }'
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 }'
evan
tom$ logname
evan
tom$
回答by sam
How about using logname(1) to get the user's login name?
如何使用 logname(1) 获取用户的登录名?
回答by tylerl
There's no perfectanswer. 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.
没有完美的答案。更改用户 ID 时,通常不会保留原始用户 ID,因此信息会丢失。一些程序,例如logname
和who -m
实现了一个hack,它们检查连接到哪个终端stdin
,然后检查哪个用户登录到该终端。
This solution oftenworks, but isn't foolproof, and certainly shouldn't be considered secure. For example, imagine if who
outputs the following:
此解决方案通常有效,但并非万无一失,当然不应被视为安全。例如,想象一下如果who
输出以下内容:
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:
tom
用于su
获得root权限并运行您的程序。如果STDIN
未重定向,则类似的程序logname
将输出tom
. 如果它被重定向(例如从文件),如下所示:
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
那么结果是“ no login name
”,因为输入不是终端。然而,更有趣的是,用户可以伪装成不同的登录用户。由于 Joe 在 pts/1 上登录,Tom 可以通过运行来伪装成他
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.
现在,它说joe
即使汤姆是运行命令的人。换句话说,如果你在任何类型的安全角色中使用这种机制,你就疯了。
回答by user1683793
This is a ksh
function I wrote on HP-UX. I don't know how it will work with Bash
in Linux. The idea is that the sudo
process is running as the original user and the child processes are the target user. By cycling back through parent processes, we can find the user of the original process.
这是ksh
我在HP-UX 上写的一个函数。我不知道它将如何Bash
在 Linux 中使用。这个想法是sudo
进程作为原始用户运行,子进程是目标用户。通过循环返回父进程,我们可以找到原始进程的用户。
#
# The options of ps require UNIX_STD=2003. I am setting it
# in a subshell to avoid having it pollute the parent's namespace.
#
function findUser
{
thisPID=$$
origUser=$(whoami)
thisUser=$origUser
while [ "$thisUser" = "$origUser" ]
do
( export UNIX_STD=2003; ps -p$thisPID -ouser,ppid,pid,comm ) | grep $thisPID | read thisUser myPPid myPid myComm
thisPID=$myPPid
done
if [ "$thisUser" = "root" ]
then
thisUser=$origUser
fi
if [ "$#" -gt "0" ]
then
echo $origUser--$thisUser--$myComm
else
echo $thisUser
fi
return 0
}
I know the original question was from a long time ago but people (such as me) are still asking and this looked like a good place to put the solution.
我知道最初的问题是很久以前的问题,但人们(比如我)仍在问,这看起来是一个放置解决方案的好地方。
回答by asdfghjkl
user1683793's findUser() function ported to bash
and extended so it returns usernames stored in NSS libraries as well.
user1683793 的 findUser() 函数被移植bash
并扩展,因此它也返回存储在 NSS 库中的用户名。
#!/bin/bash
function findUser() {
thisPID=$$
origUser=$(whoami)
thisUser=$origUser
while [ "$thisUser" = "$origUser" ]
do
ARR=($(ps h -p$thisPID -ouser,ppid;))
thisUser="${ARR[0]}"
myPPid="${ARR[1]}"
thisPID=$myPPid
done
getent passwd "$thisUser" | cut -d: -f1
}
user=$(findUser)
echo "logged in: $user"
回答by ULick
cycling back and giving a list of users
循环返回并提供用户列表
based on user1683793's answer
基于 user1683793 的回答
By exlcuding non-TTY processes, I skip root as the initiator of the login. I'm not sure if that may exlcude too much in some case
通过排除非 TTY 进程,我跳过 root 作为登录的发起者。我不确定在某些情况下是否会排除太多
#!/bin/ksh
function findUserList
{
typeset userList prevUser thisPID thisUser myPPid myPid myTTY myComm
thisPID=$$ # starting with this process-ID
while [ "$thisPID" != 1 ] # and cycling back to the origin
do
( ps -p$thisPID -ouser,ppid,pid,tty,comm ) | grep $thisPID | read thisUser myPPid myPid myTTY myComm
thisPID=$myPPid
[[ $myComm =~ ^su ]] && continue # su is always run by root -> skip it
[[ $myTTY == '?' ]] && continue # skip what is running somewhere in the background (without a terminal)
if [[ $prevUser != $thisUser ]]; then # we only want the change of user
prevUser="$thisUser" # keep the user for comparing
userList="${userList:+$userList }$thisUser" # and add the new user to the list
fi
#print "$thisPID=$thisUser: $userList -> $thisUser -> $myComm " >&2
done
print "$userList"
return 0
}
logname
or who am i
didn't give me the desired answer, especially not in longer lists of su user1
, su user2
, su user3
, ...
logname
或者who am i
没有给我想要的答案,尤其是在更长的su user1
, su user2
, su user3
,列表中...
I know the original question was from a long time ago but people (such as me) are still asking and this looked like a good place to put the solution.
我知道最初的问题是很久以前的问题,但人们(比如我)仍在问,这看起来是一个放置解决方案的好地方。
回答by simohe
Alternative to calling ps multiple times: do one pstree call
多次调用 ps 的替代方法:执行一次 pstree 调用
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
output (when logged in as even): (evan)
输出(以偶数登录时): (evan)
pstree arguments:
pstree 参数:
- -l: long lines (not shortening)
- -u: show when user changes as (userName)
- -s $$: show parents of this process
- -l:长行(不缩短)
- -u:显示用户何时更改为(用户名)
- -s $$:显示这个进程的父进程
Get the first user change (which is login) with grep -o
and head
.
获取与第一用户的变化(这是登录)grep -o
和head
。
limitation:the command may not contain any braces ()
(it does not normally)
限制:该命令可能不包含任何大括号()
(通常不包含)
回答by Grey Christoforo
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
That's the only thing that worked for me.
这是唯一对我有用的东西。