summaryrefslogtreecommitdiffstats
path: root/driver/setuid.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/setuid.c')
-rw-r--r--driver/setuid.c229
1 files changed, 69 insertions, 160 deletions
diff --git a/driver/setuid.c b/driver/setuid.c
index 3ac78e4..164576f 100644
--- a/driver/setuid.c
+++ b/driver/setuid.c
@@ -1,5 +1,5 @@
/* setuid.c --- management of runtime privileges.
- * xscreensaver, Copyright (c) 1993-1998, 2005 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright © 1993-2021 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -14,24 +14,20 @@
# include "config.h"
#endif
-#include <X11/Xlib.h> /* not used for much... */
-
-/* This file doesn't need the Xt headers, so stub these types out... */
-#undef XtPointer
-#define XtAppContext void*
-#define XrmDatabase void*
-#define XtIntervalId void*
-#define XtPointer void*
-#define Widget void*
-
-#include "xscreensaver.h"
-
-#ifndef EPERM
-#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
#endif
+#include <string.h>
#include <pwd.h> /* for getpwnam() and struct passwd */
#include <grp.h> /* for getgrgid() and struct group */
+#include <errno.h>
+
+#include "blurb.h"
+#include "auth.h"
+
static const char *
uid_gid_string (uid_t uid, gid_t gid)
@@ -49,31 +45,6 @@ uid_gid_string (uid_t uid, gid_t gid)
}
-void
-describe_uids (saver_info *si, FILE *out)
-{
- uid_t uid = getuid();
- gid_t gid = getgid();
- uid_t euid = geteuid();
- gid_t egid = getegid();
- char *s1 = strdup (uid_gid_string (uid, gid));
- char *s2 = strdup (uid_gid_string (euid, egid));
-
- if (si->orig_uid && *si->orig_uid &&
- (!!strcmp (si->orig_uid, s1) ||
- !!strcmp (si->orig_uid, s2)))
- fprintf (out, "%s: initial effective uid/gid was %s\n", blurb(),
- si->orig_uid);
-
- fprintf (out, "%s: running as %s", blurb(), s1);
- if (uid != euid || gid != egid)
- fprintf (out, "; effectively %s", s2);
- fprintf(out, "\n");
- free(s1);
- free(s2);
-}
-
-
/* Returns true if we need to call setgroups().
Without calling setgroups(), the process will retain any supplementary
@@ -113,7 +84,7 @@ setgroups_needed_p (uid_t target_group)
static int
-set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
+set_ids_by_number (uid_t uid, gid_t gid)
{
int uid_errno = 0;
int gid_errno = 0;
@@ -121,9 +92,6 @@ set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
struct passwd *p = getpwuid (uid);
struct group *g = getgrgid (gid);
- if (message_ret)
- *message_ret = 0;
-
/* Rumor has it that some implementations of of setuid() do nothing
when called with -1; therefore, if the "nobody" user has a uid of
-1, then that would be Really Bad. Rumor further has it that such
@@ -150,13 +118,12 @@ set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
if (uid_errno == 0 && gid_errno == 0 && sgs_errno == 0)
{
- static char buf [1024];
- sprintf (buf, "changed uid/gid to %.100s/%.100s (%ld/%ld).",
- (p && p->pw_name ? p->pw_name : "???"),
- (g && g->gr_name ? g->gr_name : "???"),
- (long) uid, (long) gid);
- if (message_ret)
- *message_ret = buf;
+ if (verbose_p)
+ fprintf (stderr, "%s: changed uid/gid to %.100s/%.100s (%ld/%ld)\n",
+ blurb(),
+ (p && p->pw_name ? p->pw_name : "???"),
+ (g && g->gr_name ? g->gr_name : "???"),
+ (long) uid, (long) gid);
return 0;
}
else
@@ -176,7 +143,7 @@ set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
else
{
errno = sgs_errno;
- perror(buf);
+ perror (buf);
}
fprintf (stderr, "%s: effective group list: ", blurb());
@@ -206,11 +173,11 @@ set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
(g && g->gr_name ? g->gr_name : "???"),
(long) gid);
if (gid_errno == -1)
- fprintf(stderr, "%s: unknown error\n", buf);
+ fprintf (stderr, "%s: unknown error\n", buf);
else
{
errno = gid_errno;
- perror(buf);
+ perror (buf);
}
}
@@ -241,121 +208,63 @@ set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
lock-mode.)
*** WARNING: DO NOT DISABLE ANY OF THE FOLLOWING CODE!
- If you do so, you will open a security hole. See the sections
- of the xscreensaver manual titled "LOCKING AND ROOT LOGINS",
- and "USING XDM".
+ If you do so, you will open a security hole.
+ Do not log in to an X11 desktop as root.
+ Log in as a normal users and 'sudo' as needed.
*/
void
-hack_uid (saver_info *si)
+disavow_privileges (void)
{
+ uid_t euid = geteuid();
+ gid_t egid = getegid();
+ uid_t uid = getuid();
+ gid_t gid = getgid();
+ struct passwd *p;
- /* Discard privileges, and set the effective user/group ids to the
- real user/group ids. That is, give up our "chmod +s" rights.
- */
- {
- uid_t euid = geteuid();
- gid_t egid = getegid();
- uid_t uid = getuid();
- gid_t gid = getgid();
-
- si->orig_uid = strdup (uid_gid_string (euid, egid));
-
- if (uid != euid || gid != egid)
- if (set_ids_by_number (uid, gid, &si->uid_message) != 0)
- saver_exit (si, 1, 0);
- }
-
-
- /* Locking can't work when running as root, because we have no way of
- knowing what the user id of the logged in user is (so we don't know
- whose password to prompt for.)
-
- *** WARNING: DO NOT DISABLE THIS CODE!
- If you do so, you will open a security hole. See the sections
- of the xscreensaver manual titled "LOCKING AND ROOT LOGINS",
- and "USING XDM".
- */
- if (getuid() == (uid_t) 0)
+ if (uid != euid || gid != egid)
{
- si->locking_disabled_p = True;
- si->nolock_reason = "running as root";
+ if (verbose_p)
+ fprintf (stderr, "%s: initial effective uid/gid was %s\n", blurb(),
+ uid_gid_string (euid, egid));
+ if (set_ids_by_number (uid, gid) != 0)
+ exit (1); /* already printed error */
}
-
- /* If we're running as root, switch to a safer user. This is above and
- beyond the fact that we've disabling locking, above -- the theory is
- that running graphics demos as root is just always a stupid thing
- to do, since they have probably never been security reviewed and are
- more likely to be buggy than just about any other kind of program.
- (And that assumes non-malicious code. There are also attacks here.)
-
- *** WARNING: DO NOT DISABLE THIS CODE!
- If you do so, you will open a security hole. See the sections
- of the xscreensaver manual titled "LOCKING AND ROOT LOGINS",
- and "USING XDM".
+ /* If we're still running as root, or if the user we are running at seems
+ to be in any way hinky, exit and do not allow password authentication
+ to continue.
*/
- if (getuid() == (uid_t) 0)
- {
- struct passwd *p;
-
- p = getpwnam ("nobody");
- if (! p) p = getpwnam ("noaccess");
- if (! p) p = getpwnam ("daemon");
- if (! p)
- {
- fprintf (stderr,
- "%s: running as root, and couldn't find a safer uid.\n",
- blurb());
- saver_exit(si, 1, 0);
- }
+ uid = getuid (); /* get it again */
+ p = getpwuid (uid);
- if (set_ids_by_number (p->pw_uid, p->pw_gid, &si->uid_message) != 0)
- saver_exit (si, -1, 0);
+ if (!p ||
+ uid == (uid_t) 0 ||
+ uid == (uid_t) -1 ||
+ uid == (uid_t) -2 ||
+ p->pw_uid == (uid_t) 0 ||
+ p->pw_uid == (uid_t) -1 ||
+ p->pw_uid == (uid_t) -2 ||
+ !p->pw_name ||
+ !*p->pw_name ||
+ !strcmp (p->pw_name, "root") ||
+ !strcmp (p->pw_name, "nobody") ||
+ !strcmp (p->pw_name, "noaccess") ||
+ !strcmp (p->pw_name, "operator") ||
+ !strcmp (p->pw_name, "daemon") ||
+ !strcmp (p->pw_name, "bin") ||
+ !strcmp (p->pw_name, "adm") ||
+ !strcmp (p->pw_name, "sys") ||
+ !strcmp (p->pw_name, "games"))
+ {
+ fprintf (stderr,
+ "%s: running as user \"%s\" -- authentication disallowed\n",
+ blurb(),
+ (p && p->pw_name && *p->pw_name
+ ? p->pw_name
+ : "<unknown>"));
+ exit (1);
}
-
- /* If there's anything even remotely funny looking about the passwd struct,
- or if we're running as some other user from the list below (a
- non-comprehensive selection of users known to be privileged in some way,
- and not normal end-users) then disable locking. If it was possible,
- switching to "nobody" would be the thing to do, but only root itself has
- the privs to do that.
-
- *** WARNING: DO NOT DISABLE THIS CODE!
- If you do so, you will open a security hole. See the sections
- of the xscreensaver manual titled "LOCKING AND ROOT LOGINS",
- and "USING XDM".
- */
- {
- uid_t uid = getuid (); /* get it again */
- struct passwd *p = getpwuid (uid); /* get it again */
-
- if (!p ||
- uid == (uid_t) 0 ||
- uid == (uid_t) -1 ||
- uid == (uid_t) -2 ||
- p->pw_uid == (uid_t) 0 ||
- p->pw_uid == (uid_t) -1 ||
- p->pw_uid == (uid_t) -2 ||
- !p->pw_name ||
- !*p->pw_name ||
- !strcmp (p->pw_name, "root") ||
- !strcmp (p->pw_name, "nobody") ||
- !strcmp (p->pw_name, "noaccess") ||
- !strcmp (p->pw_name, "operator") ||
- !strcmp (p->pw_name, "daemon") ||
- !strcmp (p->pw_name, "bin") ||
- !strcmp (p->pw_name, "adm") ||
- !strcmp (p->pw_name, "sys") ||
- !strcmp (p->pw_name, "games"))
- {
- static char buf [1024];
- sprintf (buf, "running as %.100s",
- (p && p->pw_name && *p->pw_name
- ? p->pw_name : "<unknown>"));
- si->nolock_reason = buf;
- si->locking_disabled_p = True;
- si->dangerous_uid_p = True;
- }
- }
+ if (verbose_p)
+ fprintf (stderr, "%s: running as user \"%s\"\n", blurb(), p->pw_name);
}