How can I verify if the user is root?
-
15Normally, a question this short is incomplete. In this case, it's just concise. – T.J. Crowder Nov 11 '10 at 22:31
-
2You shouldn't. See my answer. – R.. GitHub STOP HELPING ICE Nov 11 '10 at 23:46
3 Answers
Usually it's a mistake to test if the user is root. POSIX does not even require a root user, but leaves it to the implementation to determine how permissions work. Code such as:
if (i_am_root) do_privileged_op(); else print_error();
will really annoy users with advanced privilege models where root is not necessary to perform the necessary privileged operations. I remember back in the early days of cd burning on Linux, I had to hack all over the cdrecord
source to remove all the useless checks to see if it was running as root, when it worked just fine with permission to read /dev/sga
.
Instead, you should always attempt the privileged operation you need to perform, and check for EPERM
or similar if it fails to notify the user that they have insufficient privileges (and perhaps should retry running as root).
The one case where it's useful to check for root is checking if your program was invoked "suid-root". A reasonable test would be:
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. */
}
Note that I allowed for the possibility (far-fetched, but best to be paranoid) that either of the calls to get uid/euid could fail, and that in the failure case we should assume we're suid and a malicious user has somehow caused the syscalls to fail in an attempt to hide that we're suid.

- 208,859
- 35
- 376
- 711
-
4The Linux Standards Base does require a root user, however. Just for the record. Not that I disagree with the overall premise, of course. :) – dannysauer Nov 12 '10 at 00:22
-
4LSB has a lot of bugs, like requiring accidentally-left-visible internal glibc functions to be available to applications. :-) – R.. GitHub STOP HELPING ICE Nov 12 '10 at 01:07
-
It turns out if any of the get*uid calls fail either your libc is compromised (in which case you've already lost) or your code is not setuid. The system calls are not allowed to fail in kernel, but negative UID is possible on 32 bit systems. – Joshua Mar 20 '12 at 21:27
-
What could be the purpose of allowing negative uid values? Seems like that's just asking for problems. Fortunately they won't arise unless the admin creates such users... – R.. GitHub STOP HELPING ICE Mar 20 '12 at 22:56
-
This seems like good advice, but not in any limited to checking for root. This is a general design principle. Is it documented anywhere? I've been using it for a while and it affects even things like "in a GUI, do I disable buttons that aren't applicable?". I tend to leave the buttons enabled, and let it fail where it *needs* to fail. – lmat - Reinstate Monica Jun 28 '12 at 15:29
-
Although I don't disagree with the thrust of the message, this doesn't answer the question - although it could (i.e., there is a way to check for root). – BeeOnRope Aug 20 '18 at 05:10
-
1@beeonrope: Modern unix **does not define** root. So given the tagging of the question, it arguably has no answer. :) – R.. GitHub STOP HELPING ICE Aug 20 '18 at 12:11
-
That could also be a good point to mention in your answer. All told I still have a strong personal preference for actually giving the practical answer at some but, like "... but on most modern Unix systems `geteuid() == 0` indicates the process is running with superuser privileges (or whatever). – BeeOnRope Aug 20 '18 at 14:55
-
This can not be the whole truth: uid_t is usually defined as unsigned integer, uid < 0 will always be true. – rralf Mar 12 '19 at 15:57
-
1@rralf: Indee, as specified, "The getuid() function shall always be successful and no return value is reserved to indicate the error." – R.. GitHub STOP HELPING ICE Mar 12 '19 at 16:26
getuid
or geteuid
, depending on what you really mean. In either case, 0
means root.
#include <stdio.h>
#include <unistd.h>
if (geteuid() != 0) {
fprintf(stderr, "App needs root\n");
exit(1);
}
The point made by R is valid. You should consider trial and error, or another approach that does not explicitly require root.

- 4,523
- 3
- 33
- 44

- 278,309
- 50
- 514
- 539
-
2
-
3`geteuid` returns the effective user id, taking into account calls to [`seteuid`](http://www.opengroup.org/onlinepubs/009695399/functions/seteuid.html) or similar. `getuid` returns the real user id. – Matthew Flaschen Nov 11 '10 at 22:44
-
11'e' is for 'effective'; the euid is the one that is actually used for permission checks. Normally the uid and the euid are the same, but if you're in a setuid program, when it starts, `getuid` will return the uid of the user who invoked the program and `geteuid` will return the uid of the user that owns the executable. You can set the euid to the uid, and back, with `seteuid()`. The precise rules are too complicated for a comment. – zwol Nov 11 '10 at 22:46
-
effective userid can differ from user's actual ID (to be precise be the program's owner's ID) if setuid program is executed - see http://www.lst.de/~okir/blackhats/node23.html – DVK Nov 11 '10 at 22:46
-
4@Zack: Why is it that "too complicated for a comment" comments always remind me of Fermat? ;-) – R.. GitHub STOP HELPING ICE Jan 02 '12 at 15:34
-
Can you cite your answer? It's great that you say so, but what guarantees do I have from my OS about this? I'm guessing this isn't POSIX mandated (since POSIX doesn't require a root), so is it only this way if root is the first account created on my computer? Does Linux mandate it? Thanks for the answer. – lmat - Reinstate Monica Jun 28 '12 at 15:30
-
@LimitedAtonement, I know of no guarantee for this. LSB [requires](http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/usernames.html) a root user and root group, but even it does not assign numeric uids or gids. – Matthew Flaschen Jun 28 '12 at 21:35
better to use getuid or geteuid but it is in zconf.h header file and you must enter that like bellow :
#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;
}

- 11
- 1