diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2018-03-13 17:46:34 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2018-03-21 10:58:39 -0400 |
commit | 9ef602de46de2beae1d6231dc72a1a783a26122f (patch) | |
tree | ec24fcac5c81fae01ef9b0f201c60a508d557b5e /os | |
parent | 1519475a4382066707276d7463c7c6e52c382caa (diff) |
os: move xf86PrivsElevated here
Having different types of code all trying to check for elevated privileges
is a bad idea. This implementation is the most thorough one.
Signed-off-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Reviewed-by: Ben Crocker <bcrocker@redhat.com>
Reviewed-by: Antoine Martin <antoine@nagafix.co.uk>
Tested-by: Ben Crocker <bcrocker@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Diffstat (limited to 'os')
-rw-r--r-- | os/utils.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/os/utils.c b/os/utils.c index 4a8d1249f..4305dab26 100644 --- a/os/utils.c +++ b/os/utils.c @@ -1719,6 +1719,69 @@ System(const char *cmdline) } #endif +Bool +PrivsElevated(void) +{ + static Bool privsTested = FALSE; + static Bool privsElevated = TRUE; + + if (!privsTested) { +#if defined(WIN32) + privsElevated = FALSE; +#else + if ((getuid() != geteuid()) || (getgid() != getegid())) { + privsElevated = TRUE; + } + else { +#if defined(HAVE_ISSETUGID) + privsElevated = issetugid(); +#elif defined(HAVE_GETRESUID) + uid_t ruid, euid, suid; + gid_t rgid, egid, sgid; + + if ((getresuid(&ruid, &euid, &suid) == 0) && + (getresgid(&rgid, &egid, &sgid) == 0)) { + privsElevated = (euid != suid) || (egid != sgid); + } + else { + printf("Failed getresuid or getresgid"); + /* Something went wrong, make defensive assumption */ + privsElevated = TRUE; + } +#else + if (getuid() == 0) { + /* running as root: uid==euid==0 */ + privsElevated = FALSE; + } + else { + /* + * If there are saved ID's the process might still be privileged + * even though the above test succeeded. If issetugid() and + * getresgid() aren't available, test this by trying to set + * euid to 0. + */ + unsigned int oldeuid; + + oldeuid = geteuid(); + + if (seteuid(0) != 0) { + privsElevated = FALSE; + } + else { + if (seteuid(oldeuid) != 0) { + FatalError("Failed to drop privileges. Exiting\n"); + } + privsElevated = TRUE; + } + } +#endif + } +#endif + privsTested = TRUE; + } + return privsElevated; +} + /* * CheckUserParameters: check for long command line arguments and long * environment variables. By default, these checks are only done when |