程序能否知道它是在 sudo 下运行?

程序能否知道它是在 sudo 下运行?

我有一个程序,如果在“sudo”下运行,其行为会有所不同。有没有办法可以确定它是否在 sudo 下运行?

更新:有人问我为什么要这样做。在这种情况下,在使用 MacPorts 的 Mac 上,会有一个输出告诉您剪切并粘贴特定命令。如果使用“sudo”运行 MacPorts 命令,则它应该在示例命令中包含 sudo:

$ sudo port selfupdate 
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.2.1 installed,
MacPorts base version 2.2.1 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
  port upgrade outdated

^^^^^^^^^ it would be really sweet if it output "sudo port upgrade outdated" instead.  It would be even better if it just did it for you :-)

答案1

是的,程序在 sudo 下运行时设置了 4 个环境变量:

$ sudo env |grep SUDO
SUDO_COMMAND=/usr/bin/env
SUDO_USER=tal
SUDO_UID=501
SUDO_GID=20

请注意,只需设置它们即可伪造它们。不要相信它们用于任何关键的事情。

例如:在这个程序中,我们需要告诉用户运行其他程序。如果当前程序使用 sudo 运行,则另一个程序也会使用 sudo 运行。

#!/bin/bash

echo 'Thank you for running me.'

if [[ $(id -u) == 0 ]]; then
  if [[ -z "$SUDO_COMMAND" ]]; then
    echo 'Please now run: next_command'
  else
    echo 'Please now run: sudo next_command'
  fi
else  echo 'Error: Sadly you need to run me as root.'
  exit 1
fi

请注意,它只在能够首先证明其以 root 身份运行时才测试 SUDO_* 变量。即便如此,它也只会使用它来更改一些有用的文本。

答案2

这并没有直接回答问题,但我认为这里问的不是正确的问题。在我看来,提问者想要一个程序,如果程序具有某些权限,其行为可能会有所不同,但我认为检查 sudo 不是这样做的方法。首先,许多系统可能没有实现“sudo”,Linux 或许多 Unix 系统绝对不需要它。

例如,用户可能已经以 root 身份登录,这使得 sudo 变得毫无意义,或者系统中存在非 root 用户,但他们仍有权执行程序希望执行的管理任务。最后,也许系统根本没有 root 或 sudo,而是使用具有不同功能的强制访问控制系统,并且没有可供 sudo 的所有超级用户。或者用户可能会被 sudo,但出于安全原因,进入一个权限低于其自己帐户的帐户(我经常使用临时的非特权用户运行不受信任的代码,该用户只能写入 ramdisk 以删除而不是提高我的权限)。总体而言,假设特定的权限模型(如 sudo)或 root 的存在,或者假设被 sudo 的用户具有任何特定权限,都是一个坏主意。

如果你想知道你是否有权执行某项操作,最好的方法通常是简单地尝试执行它,然后检查 errno 是否存在权限问题,如果失败,或者它是一个多阶段操作,要么全部失败,要么全部成功,你可以检查操作是否可以使用 POSIX 之类的函数使用权功能(如果权限正在被主动改变,请注意这里可能出现的竞争条件)

如果你还需要知道 sudo 背后的真实用户,你可以使用登录该函数适用于与底层终端的任何交互式会话,并允许您例如查找谁“真正”运行审计命令或找到真实用户的主目录以保存日志。

最后,如果你真正想要的是找出用户是否具有 root 访问权限(仍然是一个坏主意,但不太具体),你可以使用盖特伊德检查 uid 是否为 0,从而确定 root 身份。

答案3

有两种机制可供使用。

  • 检查环境变量可以用任何一种方式伪造,但这是最简单的方法。 growisofs不喜欢在 SUDO 下运行,因此我在使用它的脚本中取消设置 SUDO 变量。它可以用另一种方式伪造。(对于在 at 和 batch 命令下运行的脚本,SUDO 变量也会被带入环境中。)
  • 另一种查看您是否在 sudo 下运行的方法是从父进程开始遍历进程列表以查找 sudo。这种方式很难隐藏您在 sudo 下运行,但更复杂。仍然可以伪造您在 sudo 下运行。

更常见的做法是检查您是否以适当的用户身份运行。id可以使用该命令来执行此操作。TomOnTime 的脚本使用该id命令来确定是否sudo可能需要运行下一个命令。

答案4

您可以检查有效 UID(EUID)变量,如下所示:

if [[ $EUID -eq 0 ]]; then
    echo "running as root"
else
    echo "not running as root"
fi

相关内容