http://ftp.x.org/contrib/applications/xscreensaver-3.26.tar.gz
[xscreensaver] / driver / setuid.c
index 83ad494e364edacfcb998ba30f578d1b62a7785b..343dcf097dba0bb5b0b8a234492420a6ddeb6145 100644 (file)
@@ -75,12 +75,12 @@ describe_uids (saver_info *si, FILE *out)
 
 
 static int
-set_ids_by_name (struct passwd *p, struct group *g, char **message_ret)
+set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
 {
   int uid_errno = 0;
   int gid_errno = 0;
-  uid_t uid = p->pw_uid;
-  gid_t gid = g->gr_gid;
+  struct passwd *p = getpwuid (uid);
+  struct group  *g = getgrgid (gid);
 
   if (message_ret)
     *message_ret = 0;
@@ -90,7 +90,8 @@ set_ids_by_name (struct passwd *p, struct group *g, char **message_ret)
      -1, then that would be Really Bad.  Rumor further has it that such
      systems really ought to be using -2 for "nobody", since that works.
      So, if we get a uid (or gid, for good measure) of -1, switch to -2
-     instead.
+     instead.  Note that this must be done after we've looked up the
+     user/group names with getpwuid(-1) and/or getgrgid(-1).
    */
   if (gid == (gid_t) -1) gid = (gid_t) -2;
   if (uid == (uid_t) -1) uid = (uid_t) -2;
@@ -107,7 +108,8 @@ set_ids_by_name (struct passwd *p, struct group *g, char **message_ret)
     {
       static char buf [1024];
       sprintf (buf, "changed uid/gid to %s/%s (%ld/%ld).",
-              p->pw_name, (g ? g->gr_name : "???"),
+              (p && p->pw_name ? p->pw_name : "???"),
+               (g && g->gr_name ? g->gr_name : "???"),
               (long) uid, (long) gid);
       if (message_ret)
        *message_ret = buf;
@@ -120,7 +122,7 @@ set_ids_by_name (struct passwd *p, struct group *g, char **message_ret)
        {
          sprintf (buf, "%s: couldn't set gid to %s (%ld)",
                   blurb(),
-                  (g ? g->gr_name : "???"),
+                  (g && g->gr_name ? g->gr_name : "???"),
                   (long) gid);
          if (gid_errno == -1)
            fprintf(stderr, "%s: unknown error\n", buf);
@@ -132,7 +134,7 @@ set_ids_by_name (struct passwd *p, struct group *g, char **message_ret)
        {
          sprintf (buf, "%s: couldn't set uid to %s (%ld)",
                   blurb(),
-                  (p ? p->pw_name : "???"),
+                  (p && p->pw_name ? p->pw_name : "???"),
                   (long) uid);
          if (uid_errno == -1)
            fprintf(stderr, "%s: unknown error\n", buf);
@@ -144,43 +146,6 @@ set_ids_by_name (struct passwd *p, struct group *g, char **message_ret)
     }
 }
 
-static int
-set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
-{
-  struct passwd *p;
-  struct group *g;
-
-  errno = 0;
-  p = getpwuid (uid);
-  if (!p)
-    {
-      char buf [1024];
-      sprintf (buf, "%s: error looking up name of user %d", blurb(),
-              (long) uid);
-      if (errno)
-       perror (buf);
-      else
-       fprintf (stderr, "%s: unknown error.\n", buf);
-      return -1;
-    }
-
-  errno = 0;
-  g = getgrgid (gid);
-  if (!g)
-    {
-      char buf [1024];
-      sprintf (buf, "%s: error looking up name of group %d", blurb(),
-              (long) gid);
-      if (errno)
-       perror (buf);
-      else
-       fprintf (stderr, "%s: unknown error.\n", buf);
-      return -1;
-    }
-
-  return set_ids_by_name (p, g, message_ret);
-}
-
 
 /* 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