为了删除所有权限(用户和组),您需要在用户之前删除组。鉴于userid
and groupid
包含您想要删除到的用户和组的 ID,并假设有效 ID 也是 root,这是通过调用来完成的setuid() http://linux.die.net/man/2/setuid and setgid() http://linux.die.net/man/2/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() http://linux.die.net/man/2/seteuid and setegid() http://linux.die.net/man/2/setegid也是如此,但这不是必需的,因为如果进程由 root 拥有,setuid() 和 setgid() 已经设置了所有 ID。
补充组列表是一个问题,因为没有 POSIX 函数来设置补充组(有获取组() http://linux.die.net/man/2/getgroups,但没有 setgroups())。有 BSD 和 Linux 扩展设置组() http://linux.die.net/man/2/setgroups您可以使用它,这与您有关。
你也应该chdir("/") http://linux.die.net/man/2/chdir或任何其他目录,以便该进程不会保留在根拥有的目录中。
由于您的问题总体上是关于 Unix 的,因此这是非常通用的方法。请注意,在 Linux 中这不再是首选方法。在当前的 Linux 版本中,您应该设置CAP_NET_BIND_SERVICE能力 http://linux.die.net/man/7/capabilities可执行文件,并以普通用户身份运行它。不需要 root 访问权限。