为了删除所有权限(用户和组),您需要在用户之前删除组。鉴于userid
andgroupid
包含用户的 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("/")
或到任何其他目录,以便该进程不会保留在根拥有的目录中。
由于您的问题通常是关于 Unix 的,因此这是非常通用的方法。请注意,在 Linux 中,这不再是首选方法。在当前的 Linux 版本中,您应该在可执行文件上设置CAP_NET_BIND_SERVICE
功能,并以普通用户身份运行它。不需要 root 访问权限。