我正在编写一些bash
代码,我想检查脚本是否具有 root 权限。我从其他人那里看到的所有代码都只检查$EUID == 0
.完全有可能让其他程序以 UID = 0 和 EUID > 0 运行。我的代码不应该检查这两者吗?或者 bash 有什么东西可以防止这种(奇怪的)情况发生吗?
对于那些想要看到这种情况的人,这里有一个概念证明:
[root@new-host bennett]# cp /bin/sleep .
[root@new-host bennett]# chown bennett sleep
[root@new-host bennett]# chmod 4755 sleep
[root@new-host bennett]# ll sleep
-rwsr-xr-x. 1 bennett root 32188 Sep 9 02:38 sleep
[root@new-host bennett]# ./sleep 1000 &
[root@new-host bennett]# ps -e -o user= -o ruser= -o comm= | awk '$1 != $2'
bennett root sleep
回顾一下这个问题:在任何情况下bash
都可能遇到这样的情况吗?(( $UID == 0 && $EUID > 0 ))
其他程序可以。
答案1
是的:
$ env UID=0 EUID=90 bash -c 'echo $UID $EUID'
0 90
请注意,上面只是更改了变量的值。这实际的UID 和 EUID 不受影响。
你应该改用id
。参见例如问题如果不是 root,如何阻止脚本运行(并回显“未以 root 身份运行!正在退出...”)
如果脚本设置了 set-uid 位(并且运行此类脚本 set-uid 是 Unix 上的事情),则有效用户 ID 也将与真实 ID 不同。在这种情况下,UID 将是调用脚本的用户的 UID,而 EUID 将是脚本所有者的 UID。
答案2
Bash 在启动时会删除权限,因此您不会经常遇到使用不同的有效 UID 和真实 UID 运行的 bash 进程。这对于其他 sh 实现是可能的。
请注意,如果您想测试您的脚本是否以 root 身份运行,请检查 EUID 是否正确,并且您不应该关心真实的 UID。
而且即使检查EUID也常常是不对的。您如何知道需要 root 访问权限?也许所有文件和设备都具有允许非 root 用户访问它们的权限,并且如果您需要使用某些确实需要不受访问权限控制的权限的工具,则您的脚本可能会以它们所需的功能运行,或者可能会被嘲笑(即为了测试目的而模拟)。
答案3
如果您使用选项将 bash 作为子进程启动-p
,并且您的父进程具有 ruid=0 但具有不同的 euid,则这是可能的。
按照bash(1) 手册页:
如果 shell 启动时有效用户(组)id 不等于真实用户(组)id,并且
-p
未提供该选项,则不会读取启动文件,shell 功能不会从环境继承,则SHELLOPTS
,BASHOPTS
,CDPATH
,如果变量GLOBIGNORE
出现在环境中,则将被忽略,并将有效用户 ID 设置为真实用户 ID。如果-p
在调用时提供该选项,则启动行为是相同的,但不会重置有效用户 ID。