如何通过多个sudo和su命令找到原始用户?
通过 sudo 或 su 运行脚本时,我想获取原始用户。无论多个 sudo
或 su
在彼此内部运行,特别是 sudo su -
,都应该发生这种情况。
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 -
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
结果:
使用
我是谁| awk '{print $1}'
或logname
因为不保证其他方法。以 self 身份登录:
普通 sudo:
sudo su - :
sudo su -;苏汤姆:
Results:
Use
who am i | awk '{print $1}'
ORlogname
as no other methods are guaranteed.Logged in as self:
Normal sudo:
sudo su - :
sudo su -; su tom :
没有完美的答案。当您更改用户 ID 时,通常不会保留原始用户 ID,因此信息会丢失。一些程序,例如
logname
和who -m
实施了一种 hack,它们检查哪个终端连接到stdin
,然后检查查看该终端上登录的用户。此解决方案通常有效,但并非万无一失,而且当然不应该被认为是安全的。例如,假设
who
输出以下内容:tom
使用su
获取 root 权限,并运行您的程序。如果STDIN
未重定向,则像logname
这样的程序将输出tom
。如果它是这样重定向的(例如从文件):那么结果是“
无登录名
”,因为输入不是终端。但更有趣的是,用户可以冒充不同的登录用户。由于 Joe 在 pts/1 上登录,Tom 可以通过运行Now 来假装是他,它会显示
joe
,即使 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
andwho -m
implement a hack where they check to see which terminal is connected tostdin
, 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
usedsu
to get to root, and runs your program. IfSTDIN
is not redirected, then a program likelogname
will outputtom
. If it IS redirected (e.g. from a file) as so: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 runningNow, 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.这是我在 HP-UX 上编写的一个
ksh
函数。我不知道它如何与 Linux 中的Bash
一起工作。这个想法是sudo
进程以原始用户身份运行,子进程是目标用户。通过循环回父进程,我们可以找到原始进程的用户。我知道最初的问题是很久以前的问题,但人们(比如我)仍然在问,这看起来是一个放置解决方案的好地方。
This is a
ksh
function I wrote on HP-UX. I don't know how it will work withBash
in Linux. The idea is that thesudo
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.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.
如果我们可以将进程生成层次结构排列成一棵树,那么我们就可以在该树的根部查找生成进程的用户。幸运的是,
pstree
命令为我们做了这样的安排。pstree
将正在运行的进程显示为树。该树以 pid 为根,此处给出为$$
,它在 bash 中扩展为当前 shell 的进程 id。因此,命令的第一部分列出了当前 shell 的所有祖先进程,并带有一些有趣的格式。该命令的其余部分放弃了有趣的格式,以挑选出拥有最旧祖先进程的用户的名称。与其他基于 pstree 的答案相比,主要改进是输出中不包含无关的括号。
If we could arrange the process spawn hierarchy into a tree, then we could look for the user who spawned the process at the root of that tree. Luckily the
pstree
command does that arrangement for us.pstree
shows running processes as a tree. The tree is rooted at a pid, here given as$$
, which in bash expands to the process id of the current shell. So the first part of the command lists all the ancestor processes of the current shell with some funny formatting. The rest of the command discards the funny formatting to pick out the name of the user that owns the oldest ancestor process.The main improvement over the other
pstree
-based answer here is that extraneous parentheses are not included in the output.使用 logname(1) 获取用户的登录名怎么样?
How about using logname(1) to get the user's login name?
在运行
systemd-logind
的系统上,systemd API 提供此信息。如果您想从 shell 脚本访问此信息,需要使用如下内容:loginctl
在没有参数的情况下具有不同的行为:session-status< /code> 使用当前会话,但
show-ssession
使用管理器。但是,由于其机器可读的输出,使用 show-session 更适合脚本使用。这就是需要两次调用loginctl
的原因。On systems running
systemd-logind
, the systemd API provides this information. If you want to access this information from a shell script, need to use something like this:The
session-status
andshow-ssession
system commands ofloginctl
have different behavior without arguments:session-status
uses the current session, butshow-ssession
uses the manager. However, usingshow-session
is preferable for script use due to its machine-readable output. This is why two invocations ofloginctl
are needed.user1683793 的 findUser() 函数移植到 bash 并进行了扩展,因此它也返回存储在 NSS 库中的用户名。
user1683793's findUser() function ported to
bash
and extended so it returns usernames stored in NSS libraries as well.给出用户列表
循环返回并根据 user1683793 的答案
通过排除非 TTY 进程,我跳过 root 作为登录的发起者。我不确定这是否会在某些情况下排除太多
logname
或who am i
没有给我想要的答案,尤其是在较长的列表中>su user1
,su user2
,su user3
,...
我知道原来的问题是很久以前的问题,但是人们(比如我)仍在询问,这看起来是一个放置解决方案的好地方。
cycling back and giving a list of users
based on user1683793's answer
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
logname
orwho am i
didn't give me the desired answer, especially not in longer lists ofsu 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.
多次调用 ps 的替代方法:执行一次 pstree 调用
输出(以 Even 身份登录时):
(evan)
pstree 参数:
使用
grep -o
和head
获取第一个用户更改(即登录)。限制:该命令不能包含任何大括号
()
(通常不会)Alternative to calling ps multiple times: do one pstree call
output (when logged in as even):
(evan)
pstree arguments:
Get the first user change (which is login) with
grep -o
andhead
.limitation:the command may not contain any braces
()
(it does not normally)您可以从控制终端的所有者那里获取它。下面是“whowasi”实用程序的旧 C 代码:http://sivann.gr/software/whowasi。
You can get it from the owner of the controlling terminal. Here's an old C code for a "whowasi" utility: http://sivann.gr/software/whowasi.c