William Jon McCann d494774
Index: gnome-screensaver/src/gnome-screensaver-dialog.c
William Jon McCann d494774
===================================================================
William Jon McCann d494774
--- gnome-screensaver/src/gnome-screensaver-dialog.c	(revision 1398)
William Jon McCann d494774
+++ gnome-screensaver/src/gnome-screensaver-dialog.c	(working copy)
William Jon McCann d494774
@@ -41,6 +41,8 @@
William Jon McCann d494774
 
William Jon McCann d494774
 #include "gs-debug.h"
William Jon McCann d494774
 
William Jon McCann d494774
+#define MAX_FAILURES 5
William Jon McCann d494774
+
William Jon McCann d494774
 static gboolean verbose        = FALSE;
William Jon McCann d494774
 static gboolean show_version   = FALSE;
William Jon McCann d494774
 static gboolean enable_logout  = FALSE;
William Jon McCann d494774
@@ -299,8 +301,6 @@ do_auth_check (GSLockPlug *plug)
William Jon McCann d494774
                         gs_lock_plug_show_message (plug, _("Authentication failed."));
William Jon McCann d494774
                 }
William Jon McCann d494774
 
William Jon McCann d494774
-                g_timeout_add (3000, (GSourceFunc)reset_idle_cb, plug);
William Jon McCann d494774
-
William Jon McCann d494774
                 printf ("NOTICE=AUTH FAILED\n");
William Jon McCann d494774
                 fflush (stdout);
William Jon McCann d494774
 
William Jon McCann d494774
@@ -325,15 +325,28 @@ response_cb (GSLockPlug *plug,
William Jon McCann d494774
 static gboolean
William Jon McCann d494774
 auth_check_idle (GSLockPlug *plug)
William Jon McCann d494774
 {
William Jon McCann d494774
-        gboolean res;
William Jon McCann d494774
+        gboolean     res;
William Jon McCann d494774
+        gboolean     again;
William Jon McCann d494774
+        static guint loop_counter = 0;
William Jon McCann d494774
 
William Jon McCann d494774
+        again = TRUE;
William Jon McCann d494774
         res = do_auth_check (plug);
William Jon McCann d494774
 
William Jon McCann d494774
         if (res) {
William Jon McCann d494774
+                again = FALSE;
William Jon McCann d494774
                 g_idle_add ((GSourceFunc)quit_response_ok, NULL);
William Jon McCann d494774
+        } else {
William Jon McCann d494774
+                loop_counter++;
William Jon McCann d494774
+
William Jon McCann d494774
+                if (loop_counter < MAX_FAILURES) {
William Jon McCann d494774
+                        g_timeout_add (3000, (GSourceFunc)reset_idle_cb, plug);
William Jon McCann d494774
+                } else {
William Jon McCann d494774
+                        again = FALSE;
William Jon McCann d494774
+                        gtk_main_quit ();
William Jon McCann d494774
+                }
William Jon McCann d494774
         }
William Jon McCann d494774
 
William Jon McCann d494774
-        return !res;
William Jon McCann d494774
+        return again;
William Jon McCann d494774
 }
William Jon McCann d494774
 
William Jon McCann d494774
 static void
William Jon McCann d494774
Index: gnome-screensaver/src/setuid.c
William Jon McCann d494774
===================================================================
William Jon McCann d494774
--- gnome-screensaver/src/setuid.c	(revision 1398)
William Jon McCann d494774
+++ gnome-screensaver/src/setuid.c	(working copy)
William Jon McCann d494774
@@ -48,7 +48,7 @@ uid_gid_string (uid_t uid,
William Jon McCann d494774
         return buf;
William Jon McCann d494774
 }
William Jon McCann d494774
 
William Jon McCann d494774
-static int
William Jon McCann d494774
+static gboolean
William Jon McCann d494774
 set_ids_by_number (uid_t  uid,
William Jon McCann d494774
                    gid_t  gid,
William Jon McCann d494774
                    char **message_ret)
William Jon McCann d494774
@@ -96,7 +96,7 @@ set_ids_by_number (uid_t  uid,
William Jon McCann d494774
 
William Jon McCann d494774
                 g_free (reason);
William Jon McCann d494774
 
William Jon McCann d494774
-                return 0;
William Jon McCann d494774
+                return TRUE;
William Jon McCann d494774
         } else {
William Jon McCann d494774
                 char *reason = NULL;
William Jon McCann d494774
 
William Jon McCann d494774
@@ -141,9 +141,9 @@ set_ids_by_number (uid_t  uid,
William Jon McCann d494774
                         g_free (reason);
William Jon McCann d494774
                         reason = NULL;
William Jon McCann d494774
                 }
William Jon McCann d494774
-
William Jon McCann d494774
-                return -1;
William Jon McCann d494774
+                return FALSE;
William Jon McCann d494774
         }
William Jon McCann d494774
+        return FALSE;
William Jon McCann d494774
 }
William Jon McCann d494774
 
William Jon McCann d494774
 
William Jon McCann d494774
@@ -165,12 +165,21 @@ hack_uid (char **nolock_reason,
William Jon McCann d494774
           char **orig_uid,
William Jon McCann d494774
           char **uid_message)
William Jon McCann d494774
 {
William Jon McCann d494774
-        if (nolock_reason)
William Jon McCann d494774
+        char    *reason;
William Jon McCann d494774
+        gboolean ret;
William Jon McCann d494774
+
William Jon McCann d494774
+        ret = TRUE;
William Jon McCann d494774
+        reason = NULL;
William Jon McCann d494774
+
William Jon McCann d494774
+        if (nolock_reason != NULL) {
William Jon McCann d494774
                 *nolock_reason = NULL;
William Jon McCann d494774
-        if (orig_uid)
William Jon McCann d494774
+        }
William Jon McCann d494774
+        if (orig_uid != NULL) {
William Jon McCann d494774
                 *orig_uid = NULL;
William Jon McCann d494774
-        if (uid_message)
William Jon McCann d494774
+        }
William Jon McCann d494774
+        if (uid_message != NULL) {
William Jon McCann d494774
                 *uid_message = NULL;
William Jon McCann d494774
+        }
William Jon McCann d494774
 
William Jon McCann d494774
         /* Discard privileges, and set the effective user/group ids to the
William Jon McCann d494774
            real user/group ids.  That is, give up our "chmod +s" rights.
William Jon McCann d494774
@@ -181,12 +190,18 @@ hack_uid (char **nolock_reason,
William Jon McCann d494774
                 uid_t uid  = getuid ();
William Jon McCann d494774
                 gid_t gid  = getgid ();
William Jon McCann d494774
 
William Jon McCann d494774
-                if (orig_uid)
William Jon McCann d494774
+                if (orig_uid != NULL) {
William Jon McCann d494774
                         *orig_uid = uid_gid_string (euid, egid);
William Jon McCann d494774
+                }
William Jon McCann d494774
+
William Jon McCann d494774
+                if (uid != euid || gid != egid) {
William Jon McCann d494774
+                        if (! set_ids_by_number (uid, gid, uid_message)) {
William Jon McCann d494774
+                                reason = g_strdup ("unable to discard privileges.");
William Jon McCann d494774
 
William Jon McCann d494774
-                if (uid != euid || gid != egid)
William Jon McCann d494774
-                        if (set_ids_by_number (uid, gid, uid_message) != 0)
William Jon McCann d494774
-                                return FALSE;
William Jon McCann d494774
+                                ret = FALSE;
William Jon McCann d494774
+                                goto out;
William Jon McCann d494774
+                        }
William Jon McCann d494774
+                }
William Jon McCann d494774
         }
William Jon McCann d494774
 
William Jon McCann d494774
 
William Jon McCann d494774
@@ -200,81 +215,16 @@ hack_uid (char **nolock_reason,
William Jon McCann d494774
            and "USING XDM".
William Jon McCann d494774
         */
William Jon McCann d494774
         if (getuid () == (uid_t) 0) {
William Jon McCann d494774
-                if (nolock_reason)
William Jon McCann d494774
-                        *nolock_reason = g_strdup ("running as root");
William Jon McCann d494774
-                return FALSE;
William Jon McCann d494774
+                reason = g_strdup ("running as root");
William Jon McCann d494774
+                ret = FALSE;
William Jon McCann d494774
+                goto out;
William Jon McCann d494774
         }
William Jon McCann d494774
 
William Jon McCann d494774
-        /* If we're running as root, switch to a safer user.  This is above and
William Jon McCann d494774
-           beyond the fact that we've disabling locking, above -- the theory is
William Jon McCann d494774
-           that running graphics demos as root is just always a stupid thing
William Jon McCann d494774
-           to do, since they have probably never been security reviewed and are
William Jon McCann d494774
-           more likely to be buggy than just about any other kind of program.
William Jon McCann d494774
-           (And that assumes non-malicious code.  There are also attacks here.)
William Jon McCann d494774
-
William Jon McCann d494774
-           *** WARNING: DO NOT DISABLE THIS CODE!
William Jon McCann d494774
-           If you do so, you will open a security hole.  See the sections
William Jon McCann d494774
-           of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", 
William Jon McCann d494774
-           and "USING XDM".
William Jon McCann d494774
-        */
William Jon McCann d494774
-        if (getuid () == (uid_t) 0) {
William Jon McCann d494774
-                struct passwd *p;
William Jon McCann d494774
-
William Jon McCann d494774
-                p = getpwnam ("nobody");
William Jon McCann d494774
-                if (! p) p = getpwnam ("noaccess");
William Jon McCann d494774
-                if (! p) p = getpwnam ("daemon");
William Jon McCann d494774
-                if (! p) {
William Jon McCann d494774
-                        g_warning ("running as root, and couldn't find a safer uid.");
William Jon McCann d494774
-                        return FALSE;
William Jon McCann d494774
-                }
William Jon McCann d494774
-
William Jon McCann d494774
-                if (set_ids_by_number (p->pw_uid, p->pw_gid, uid_message) != 0)
William Jon McCann d494774
-                        return FALSE;
William Jon McCann d494774
-        }
William Jon McCann d494774
-
William Jon McCann d494774
-
William Jon McCann d494774
-        /* If there's anything even remotely funny looking about the passwd struct,
William Jon McCann d494774
-           or if we're running as some other user from the list below (a
William Jon McCann d494774
-           non-comprehensive selection of users known to be privileged in some way,
William Jon McCann d494774
-           and not normal end-users) then disable locking.  If it was possible,
William Jon McCann d494774
-           switching to "nobody" would be the thing to do, but only root itself has
William Jon McCann d494774
-           the privs to do that.
William Jon McCann d494774
-
William Jon McCann d494774
-           *** WARNING: DO NOT DISABLE THIS CODE!
William Jon McCann d494774
-           If you do so, you will open a security hole.  See the sections
William Jon McCann d494774
-           of the xscreensaver manual titled "LOCKING AND ROOT LOGINS",
William Jon McCann d494774
-           and "USING XDM".
William Jon McCann d494774
-        */
William Jon McCann d494774
-        {
William Jon McCann d494774
-                uid_t          uid = getuid ();		/* get it again */
William Jon McCann d494774
-                struct passwd *p   = getpwuid (uid);	/* get it again */
William Jon McCann d494774
-
William Jon McCann d494774
-                if (!p ||
William Jon McCann d494774
-                    uid == (uid_t)  0 ||
William Jon McCann d494774
-                    uid == (uid_t) -1 ||
William Jon McCann d494774
-                    uid == (uid_t) -2 ||
William Jon McCann d494774
-                    p->pw_uid == (uid_t)  0 ||
William Jon McCann d494774
-                    p->pw_uid == (uid_t) -1 ||
William Jon McCann d494774
-                    p->pw_uid == (uid_t) -2 ||
William Jon McCann d494774
-                    !p->pw_name ||
William Jon McCann d494774
-                    !*p->pw_name ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "root") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "nobody") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "noaccess") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "operator") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "daemon") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "bin") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "adm") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "sys") ||
William Jon McCann d494774
-                    !strcmp (p->pw_name, "games")) {
William Jon McCann d494774
-                        if (nolock_reason)
William Jon McCann d494774
-                                *nolock_reason = g_strdup_printf ("running as %s",
William Jon McCann d494774
-                                                                  (p && p->pw_name
William Jon McCann d494774
-                                                                   && *p->pw_name
William Jon McCann d494774
-                                                                   ? p->pw_name : "<unknown>"));
William Jon McCann d494774
-                        return FALSE;
William Jon McCann d494774
-                }
William Jon McCann d494774
+ out:
William Jon McCann d494774
+        if (nolock_reason != NULL) {
William Jon McCann d494774
+                *nolock_reason = g_strdup (reason);
William Jon McCann d494774
         }
William Jon McCann d494774
+        g_free (reason);
William Jon McCann d494774
 
William Jon McCann d494774
-        return TRUE;
William Jon McCann d494774
+        return ret;
William Jon McCann d494774
 }