在C语言中如何检查用户是否为root?

47

如何验证用户是否为root?


15
通常来说,这样简短的问题是不完整的。但在这种情况下,它只是简洁明了。 - T.J. Crowder
2
你不应该这样做。看看我的回答。 - R.. GitHub STOP HELPING ICE
3个回答

67

通常测试用户是否为root是一个错误。POSIX甚至不需要root用户,而是将权限如何工作留给实现来确定。像这样的代码:

if (i_am_root) do_privileged_op(); else print_error();

对于拥有高级权限模型的用户,不需要 root 权限即可执行所需的特权操作可能会真正惹恼他们。我还记得在 Linux 上烧录 CD 的早期,我不得不修改 cdrecord 源码中所有无用的检查,以便在具有读取/dev/sga权限时可以正常工作。

相反地,你应该总是尝试执行你需要执行的特殊操作,并检查是否返回EPERM或类似错误码,如果操作失败则通知用户他们权限不足(也许应该尝试以 root 身份重新运行)。

唯一有用的情况是检查程序是否以"suid-root"模式运行。一个合理的测试方法是:

uid_t uid=getuid(), euid=geteuid();
if (uid<0 || uid!=euid) {
    /* We might have elevated privileges beyond that of the user who invoked
     * the program, due to suid bit. Be very careful about trusting any data! */
} else {
    /* Anything goes. */
}

请注意,我考虑了一种可能性(虽然很遥远,但最好保持警惕),即调用get uid / euid的任一次可能失败,在失败的情况下,我们应该假设我们是suid,并且恶意用户已经以某种方式导致系统调用失败,试图隐藏我们是suid。


4
Linux标准基础确实需要一个root用户,但只是为了记录。当然,我并不反对总体前提。 :) - dannysauer
4
LSB存在很多漏洞,例如要求应用程序能够访问意外暴露的内部glibc函数。 :-) - R.. GitHub STOP HELPING ICE
1
@beeonrope:现代Unix并没有定义root。因此,考虑到问题的标签,它可能没有答案。 :) - R.. GitHub STOP HELPING ICE
这也可以是你回答中提到的一个好点。总的来说,我仍然强烈倾向于在某些情况下实际给出实用的答案,比如“...但在大多数现代Unix系统中,geteuid() == 0表示进程正在以超级用户权限(或其他权限)运行。” - BeeOnRope
1
@rralf:确实,如规定的那样,“getuid()函数应始终成功,没有保留返回值来指示错误。” - R.. GitHub STOP HELPING ICE
显示剩余5条评论

44

getuid 或者 geteuid,取决于你真正的意图。在任何情况下,0表示root。

#include <stdio.h>
#include <unistd.h>

if (geteuid() != 0) {
    fprintf(stderr, "App needs root\n");
    exit(1);
}

R所提出的观点是正确的。您应该考虑试错,或者采用另一种不需要显式要求root权限的方法。


2
getuid和geteuid有什么区别? - Mohit Deshpande
3
geteuid返回有效用户ID,考虑了对seteuid或类似函数的调用。 getuid返回实际用户ID。 - Matthew Flaschen
11
“e”代表“有效的”,euid是实际用于权限检查的用户ID。通常情况下,uid和euid是相同的,但如果您在一个setuid程序中,当它启动时,getuid将返回调用该程序的用户的uid,而geteuid将返回可执行文件所有者的uid。您可以通过使用seteuid()将euid设置为uid,并进行还原。具体规则太复杂了,无法在评论中解释。 - zwol
4
@Zack: 为什么“太复杂了,不适合在评论中讨论”的评论总是让我想起费马大定理?;-) - R.. GitHub STOP HELPING ICE
你能引用一下你的答案吗?很高兴你这么说,但是我的操作系统有什么保证呢?我猜这不是 POSIX 强制要求的(因为 POSIX 不需要 root),所以只有在 root 是我电脑上创建的第一个帐户时才是这样吗?Linux 强制执行吗?谢谢回答。 - lmat - Reinstate Monica
显示剩余2条评论

1
最好使用getuid或geteuid,但它在zconf.h头文件中,您必须像下面这样输入:
#include <zconf.h>
#include <stdio.h>
int main()
{
int a;
a=getuid();
//or you can use  a=geteuid();
//euid is effective user id and uid is user id 
// both euid and uid are zero when you are root user 
if (a==0){
printf("you are root user");
//so you can do what`enter code here`ever `enter code here` you want as root user
}
else
printf("please run the script as root user !");
return 0;
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接