-
-
-\f
-/* Change the uid/gid of the screensaver process, so that it is safe for it
- to run setuid root (which it needs to do on some systems to read the
- encrypted passwords from the passwd file.)
-
- hack_uid() is run before opening the X connection, so that XAuth works.
- hack_uid_warn() is called after the connection is opened and the command
- line arguments are parsed, so that the messages from hack_uid() get
- printed after we know whether we're in `verbose' mode.
- */
-
-#ifndef NO_SETUID
-
-static int hack_uid_errno;
-static char hack_uid_buf [255], *hack_uid_error;
-
-void
-hack_uid (saver_info *si)
-{
-
- /* If we've been run as setuid or setgid to someone else (most likely root)
- turn off the extra permissions so that random user-specified programs
- don't get special privileges. (On some systems it might be necessary
- to install this as setuid root in order to read the passwd file to
- implement lock-mode...)
- */
- setgid (getgid ());
- setuid (getuid ());
-
- hack_uid_errno = 0;
- hack_uid_error = 0;
-
- /* If we're being run as root (as from xdm) then switch the user id
- to something safe. */
- if (getuid () == 0)
- {
- struct passwd *p;
- /* 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.)
- */
- si->locking_disabled_p = True;
- si->nolock_reason = "running as root";
- p = getpwnam ("nobody");
- if (! p) p = getpwnam ("noaccess");
- if (! p) p = getpwnam ("daemon");
- if (! p) p = getpwnam ("bin");
- if (! p) p = getpwnam ("sys");
- if (! p)
- {
- hack_uid_error = "couldn't find safe uid; running as root.";
- hack_uid_errno = -1;
- }
- else
- {
- struct group *g = getgrgid (p->pw_gid);
- hack_uid_error = hack_uid_buf;
- sprintf (hack_uid_error, "changing uid/gid to %s/%s (%ld/%ld).",
- p->pw_name, (g ? g->gr_name : "???"),
- (long) p->pw_uid, (long) p->pw_gid);
-
- /* Change the gid to be a safe one. If we can't do that, then
- print a warning. We change the gid before the uid so that we
- change the gid while still root. */
- if (setgid (p->pw_gid) != 0)
- {
- hack_uid_errno = errno;
- sprintf (hack_uid_error, "couldn't set gid to %s (%ld)",
- (g ? g->gr_name : "???"), (long) p->pw_gid);
- }
-
- /* Now change the uid to be a safe one. */
- if (setuid (p->pw_uid) != 0)
- {
- hack_uid_errno = errno;
- sprintf (hack_uid_error, "couldn't set uid to %s (%ld)",
- p->pw_name, (long) p->pw_uid);
- }
- }
- }
-# ifndef NO_LOCKING
- else /* disable locking if already being run as "someone else" */
- {
- struct passwd *p = getpwuid (getuid ());
- if (!p ||
- !strcmp (p->pw_name, "root") ||
- !strcmp (p->pw_name, "nobody") ||
- !strcmp (p->pw_name, "noaccess") ||
- !strcmp (p->pw_name, "daemon") ||
- !strcmp (p->pw_name, "bin") ||
- !strcmp (p->pw_name, "sys"))
- {
- si->locking_disabled_p = True;
- si->nolock_reason = hack_uid_buf;
- sprintf (si->nolock_reason, "running as %s", p->pw_name);
- }
- }
-# endif /* !NO_LOCKING */
-}
-
-void
-hack_uid_warn (saver_info *si)
-{
- saver_preferences *p = &si->prefs;
-
- if (! hack_uid_error)
- ;
- else if (hack_uid_errno == 0)
- {
- if (p->verbose_p)
- printf ("%s: %s\n", blurb(), hack_uid_error);
- }
- else
- {
- char buf [255];
- sprintf (buf, "%s: %s", blurb(), hack_uid_error);
- if (hack_uid_errno == -1)
- fprintf (stderr, "%s\n", buf);
- else
- {
- errno = hack_uid_errno;
- perror (buf);
- }
- }
-}
-
-#endif /* !NO_SETUID */