summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2018-03-13 17:46:34 -0400
committerAdam Jackson <ajax@redhat.com>2018-03-21 10:58:39 -0400
commit9ef602de46de2beae1d6231dc72a1a783a26122f (patch)
treeec24fcac5c81fae01ef9b0f201c60a508d557b5e /os
parent1519475a4382066707276d7463c7c6e52c382caa (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.c63
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