c - 删除 root 权限

标签 c unix root

我有一个以 root 身份启动的守护进程(因此它可以绑定(bind)到低端口)。出于安全原因,初始化后我非常想让它放弃 root 权限。

谁能告诉我一段已知正确的 C 代码可以做到这一点?

我阅读了手册页,查看了它在不同应用程序中的各种实现,它们各不相同,其中一些非常复杂。这是与安全相关的代码,我真的不想重蹈其他人的覆辙。我正在寻找的是一个最佳实践,已知良好的可移植库函数,我可以使用它,因为它会把它做好。有这种东西吗?

供引用:我以 root 身份启动;我需要更改以在不同的 uid 和 gid 下运行;我需要正确设置补充组;之后我不需要改回 root 权限。

最佳答案

为了删除所有权限(用户和组),您需要在删除用户之前删除组。鉴于 useridgroupid 包含用户的 ID 和您要放入的组,并假设有效 ID 也是 root,这是通过调用 setuid() 来完成的和 setgid():

if (getuid() == 0) {
    /* process is running as root, drop privileges */
    if (setgid(groupid) != 0)
        fatal("setgid: Unable to drop group privileges: %s", strerror(errno));
    if (setuid(userid) != 0)
        fatal("setuid: Unable to drop user privileges: %S", strerror(errno));
}

如果您有疑虑,您可以尝试取回您的 root 权限,但应该会失败。如果它没有失败,您将进行救助:

 if (setuid(0) != -1)
     fatal("ERROR: Managed to regain root privileges?");

此外,如果您仍然偏执,您可能还需要 seteuid()setegid(),但这不是必需的,因为如果进程由 root 拥有,setuid() 和 setgid() 已经设置了所有 ID。

补充组列表是个问题,因为没有设置补充组的 POSIX 函数(有 getgroups() ,但没有 setgroups())。您可以使用 BSD 和 Linux 扩展 setgroups(),这与您有关。

您还应该将 chdir("/") 或任何其他目录,以便该进程不会保留在 root 拥有的目录中。

由于您的问题一般是关于 Unix 的,因此这是非常通用的方法。请注意,在 Linux 中,这不再是首选方法。在当前的 Linux 版本中,您应该在可执行文件上设置 CAP_NET_BIND_SERVICE capability,并以普通用户身份运行它。不需要根访问权限。

关于c - 删除 root 权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3357737/

相关文章:

c - c中替换头文件iostream.h

c - 通过 tostring/checkstring 访问时整数减少为字符串?

没有变量声明的大括号

bash - 仅当程序成功时如何重定向程序的输出?

linux - 将位于两个字符之间的文件内容分隔成单独的文件

Mysql - 无法更改或添加新密码

c - 当父进程调用 exec 命令时,子进程会发生什么

Android 应用程序自动且无声地更新?

c++ - 如何授予对用户应用程序的根访问权限?

导致 NoClassDefFoundError 的 Java 系统参数