linux 命令回到初始,linux - 如何通过多个sudo和su命令找到原始用户?

linux - 如何通过多个sudo和su命令找到原始用户?

通过sudo或su运行脚本时我想获得原始用户。 无论多个sudo或su在彼此内部运行,特别是sudo su -,都应该发生这种情况。

evan asked 2019-05-07T23:52:05Z

8个解决方案

118 votes

结果:

使用who am i | awk '{print $1}'或logname,因为没有其他方法可以保证。

以自己身份登录:

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>

普通的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 - ; 苏姆:

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$

evan answered 2019-05-07T23:52:45Z

11 votes

没有完美的答案。 更改用户ID时,通常不会保留原始用户ID,因此信息会丢失。 某些程序(例如joe和su)实施了一个hack,他们检查哪个终端连接到STDIN,然后检查该终端上登录的用户。

这种解决方案通常有效,但并非万无一失,当然也不应该被认为是安全的。 例如,假设joe输出以下内容:

tom pts/0 2011-07-03 19:18 (1.2.3.4)

joe pts/1 2011-07-03 19:10 (5.6.7.8)

joe使用su获取root用户身份,然后运行您的程序。 如果没有重定向STDIN,那么像logname这样的程序将输出tom.如果它被重定向(例如从文件中),如下所示:

logname < /some/file

然后结果是“joe”,因为输入不是终端。 但更有趣的是,用户可以将其作为不同的登录用户。 由于Joe在pts / 1上登录,Tom可以通过跑步假装成为他

logname < /dev/pts1

现在,它说joe即使汤姆是运行命令的人。 换句话说,如果你在任何安全角色中使用这种机制,那你就疯了。

tylerl answered 2019-05-07T23:53:39Z

8 votes

这是我在HP-UX上编写的ksh函数。 我不知道它在Linux中如何与Bash一起使用。 这个想法是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

}

我知道最初的问题来自很久以前,但人们(比如我)仍然在问,这看起来是一个提出解决方案的好地方。

user1683793 answered 2019-05-07T23:54:12Z

5 votes

如何使用logname(1)获取用户的登录名?

sam answered 2019-05-07T23:54:38Z

2 votes

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"

asdfghjkl answered 2019-05-07T23:55:05Z

2 votes

骑自行车返回并提供用户列表

根据user1683793的回答

通过排除非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或who am i并没有给我想要的答案,尤其是su user1,su user2,su user3,...

我知道最初的问题来自很久以前,但人们(比如我)仍然在问,这看起来是一个提出解决方案的好地方。

ULick answered 2019-05-07T23:55:55Z

1 votes

THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`

这是唯一对我有用的东西。

Grey Christoforo answered 2019-05-07T23:56:23Z

0 votes

替代多次调用ps:执行一次pstree调用

pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1

输出(以偶数方式登录时):()

pstree参数:

-l:长线(不缩短)

-u:当用户更改为(userName)时显示

-s $$:显示此进程的父级

使用()和head获取第一个用户更改(登录)。

限制:该命令可能不包含任何大括号()(通常不会)

simohe answered 2019-05-07T23:57:37Z

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值