【问题标题】:How can my C/C++ application determine if the root user is executing the command?我的 C/C++ 应用程序如何确定 root 用户是否正在执行命令?
【发布时间】:2011-03-13 23:02:03
【问题描述】:

我正在编写一个需要 root 用户权限才能执行的应用程序。如果由非 root 用户执行,它会退出并以错误消息终止,例如:

    pthread_getschedparam: Operation not permitted

我想让应用程序更加用户友好。作为其早期初始化的一部分,我希望它检查它是否由 root 执行。如果不是root,它会提示它只能由root运行,然后终止。

【问题讨论】:

  • 通常我们担心的是相反的情况:有多少程序警告说他们是 root 并放弃他们不需要的权限来更安全地运行代码?

标签: c++ c linux root


【解决方案1】:

getuidgeteuid 将是显而易见的选择。

getuid 检查实际用户的凭据。

geteuid 中添加的e 代表effective。它检查有效的凭据。

例如,如果您使用sudo 以 root(超级用户)身份运行程序,您的实际凭据仍然是您自己的帐户,但您的有效凭据是 root 帐户(或 wheel 组的成员)的凭据等)

例如,考虑如下代码:

#include <unistd.h>
#include <iostream>

int main() { 
    auto me = getuid();
    auto myprivs = geteuid();


    if (me == myprivs)
        std::cout << "Running as self\n";
    else
        std::cout << "Running as somebody else\n";
}

如果你正常运行,getuid()geteuid() 将返回相同的值,所以它会说“以自身身份运行”。如果您改为使用sudo ./a.outgetuid() 仍将返回您的用户 ID,但 geteuid() 将返回 root 或 wheel 的凭据,因此它会显示“以其他人身份运行”。

【讨论】:

  • 谢谢。我已经轻松创建了使用 getuid() 的逻辑,现在它可以满足我的需求了。
【解决方案2】:

我建议不要进行此更改,而是改进您的错误消息。您的应用程序实际上是否需要“root”是值得怀疑的;相反,它需要 root 具有的某些特权,但是具有细粒度安全控制的操作系统可能能够授予应用程序而不授予其完全 root 访问权限。即使现在不可能,但可能在 6 个月或 2 年后,如果您的程序拒绝基于权限模型的反向假设运行,而不是仅仅检查它是否成功执行,用户会感到恼火它需要的特权操作。

【讨论】:

  • 对于 AppArmor 和 SELinux 之类的东西,反过来也是如此,该进程可以以 root 身份运行,并且无法访问您认为理所当然的一些东西(例如能够编写任何地方),所以我同意,更准确的错误消息是更好的选择。
  • 我听到了你在说什么,但是这个错误信息不在我的掌控之中。它来自 perror() 和/或 strerror()。此外,目前还不清楚故障原因是什么。在这种情况下,返回的 errno 是 EPERM,它 perror() 和 strerror() 翻译为“不允许操作”当阅读 pthread_setschedparam() 的手册页时(ACK,我刚刚意识到上面的错误输出中有一个错字),它不是t 对我来说很明显返回了哪个 errno,但我最终在 EPERM 上进行了磨练,它有两个故障原因归结为“用户权限”或“无效参数”
  • 虽然,我想我可以添加这个 getuid() 检查 pthread_setschedparam() 是否因 EPERM 失败,如果它不是 root 建议以 root 身份重试?最终,这将保护我免受我的 QA 团队的影响,该团队将以非 root 身份运行应用程序,它会因上面列出的消息而失败,并且他们会记录一个缺陷,说它已损坏。即使文档说它必须以 root 权限运行。我想尝试在故障点尽可能清楚地说明问题所在。
  • 当您调用 pthread_setschedparam 时,请检查它是否因 EPERM 失败。如果是这样,请打印一条很好的消息,说明用户缺乏程序运行所需的权限,并建议以 root 身份运行。
【解决方案3】:

您真正要检查的是您是否拥有正确的功能集(CAP_SYS_NICE 我认为这是您需要的功能)请参阅手册页capabilities (7)capget (2) 这样如果您不会出错有能力做你想做的事,但你不是root。

【讨论】:

  • 功能是非常特定于 Linux 的,因此使用这种方法会损害程序的可移植性。我最喜欢的测试特权操作能力的方法就是尝试操作并检查错误。
  • @spudd86:感谢您的提示。我会调查一下。 @R ..:感谢您的警告。巧合的是,我正在编写一个 Linux 应用程序。授予的便携性很好。我可以抽象这个检查,以便如果它被移植到另一个平台,他们可以根据他们的平台扩展检查。
  • 好吧,如果只是为了打印更友好的输出,你可以把它全部放在 #ifdef HAVE_CAPABILITIES 之类的里面,如果它在其他系统上运行则跳过代码。
【解决方案4】:
#include <unistd.h> // getuid
#include <stdio.h> // printf

int main()
{
    if (getuid()) printf("%s", "You are not root!\n");
    else printf("%s", "OK, you are root.\n");
    return 0;
}

【讨论】:

  • +1 用于编写 if (getuid()) 而不是 if (getuid()!=0)。 :-) 如果程序应该与 suid 一起工作,你可能想要使用 geteuid() 而不是 getuid()。
  • @vannitotaro 能否修改您的第一个字符串以更清楚地说明用户当前不是root?我花了一点时间才按原意阅读它,因为“必须”这个词的使用是模棱两可的。
  • @ragerdl 在将近 9 年后,为什么不呢? :D 完成。
猜你喜欢
  • 2011-10-04
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2013-09-04
  • 2016-05-23
  • 2011-10-01
  • 1970-01-01
  • 2014-10-08
相关资源
最近更新 更多