Change directory after becoming someone else, instead of before. This
authormdw <mdw>
Thu, 25 Sep 1997 16:04:48 +0000 (16:04 +0000)
committermdw <mdw>
Thu, 25 Sep 1997 16:04:48 +0000 (16:04 +0000)
avoids problems with root-squashed NFS mounts.

src/become.c

index e73f5da..54e5551 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: become.c,v 1.11 1997/09/24 09:48:45 mdw Exp $
+ * $Id: become.c,v 1.12 1997/09/25 16:04:48 mdw Exp $
  *
  * Main code for `become'
  *
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: become.c,v $
- * Revision 1.11  1997/09/24 09:48:45  mdw
+ * Revision 1.12  1997/09/25 16:04:48  mdw
+ * Change directory after becoming someone else, instead of before.  This
+ * avoids problems with root-squashed NFS mounts.
+ *
+ * Revision 1.11  1997/09/24  09:48:45  mdw
  * Fix (scary) overrun bug in group allocation stuff.
  *
  * Revision 1.10  1997/09/17  10:14:10  mdw
@@ -471,7 +475,7 @@ int main(int argc, char *argv[])
   enum {
     f_daemon = 1,                      /* Start up in daemon mode */
     f_duff = 2,                                /* Fault in arguments */
-    f_login = 4,                       /* Execute as a login shell */
+    f_shell = 4,                       /* Run a default shell */
     f_dummy = 8,                       /* Don't actually do anything */
     f_setuid = 16,                     /* We're running setuid */
     f_havegroup = 32                   /* Set a default group */
@@ -1046,45 +1050,48 @@ done_options:
     binary = todo[0];
   }
 
-  else switch (style) {
+  else {
+    flags |= f_shell;
 
-    /* --- An unadorned becoming requires little work --- */
+    switch (style) {
 
-    case l_preserve:
-      shell[0] = getenv("SHELL");
-      if (!shell[0])
-       shell[0] = from_pw->pw_shell;
-      shell[1] = 0;
-      todo = shell;
-      binary = todo[0];
-      break;
+      /* --- An unadorned becoming requires little work --- */
 
-    /* --- An su-like login needs slightly less effort --- */
+      case l_preserve:
+       shell[0] = getenv("SHELL");
+       if (!shell[0])
+         shell[0] = from_pw->pw_shell;
+       shell[1] = 0;
+       todo = shell;
+       binary = todo[0];
+       break;
 
-    case l_setuser:
-      shell[0] = to_pw->pw_shell;
-      shell[1] = 0;
-      todo = shell;
-      binary = todo[0];
-      break;
+      /* --- An su-like login needs slightly less effort --- */
+
+      case l_setuser:
+       shell[0] = to_pw->pw_shell;
+       shell[1] = 0;
+       todo = shell;
+       binary = todo[0];
+       break;
+
+      /* --- A login request needs a little bit of work --- */
 
-    /* --- A login request needs a little bit of work --- */
-
-    case l_login: {
-      const char *p = strrchr(to_pw->pw_shell, '/');
-
-      if (p)
-       p++;
-      else
-       p = to_pw->pw_shell;
-      shell[0] = xmalloc(strlen(p) + 2);
-      shell[0][0] = '-';
-      strcpy(shell[0] + 1, p);
-      shell[1] = 0;
-      todo = shell;
-      binary = to_pw->pw_shell;
-      chdir(to_pw->pw_dir);
-    } break;
+      case l_login: {
+       const char *p = strrchr(to_pw->pw_shell, '/');
+
+       if (p)
+         p++;
+       else
+         p = to_pw->pw_shell;
+       shell[0] = xmalloc(strlen(p) + 2);
+       shell[0][0] = '-';
+       strcpy(shell[0] + 1, p);
+       shell[1] = 0;
+       todo = shell;
+       binary = to_pw->pw_shell;
+      } break;
+    }
   }
 
   /* --- Mangle the environment --- *
@@ -1423,7 +1430,7 @@ done_options:
 
   if (rq.from == rq.to) {
     moan("you already are `%s'!", to_pw->pw_name);
-    if (!cmd && todo == shell) {
+    if (flags & f_shell) {
       moan("(to prevent confusion, I'm not spawning a shell)");
       exit(0);
     }
@@ -1458,6 +1465,13 @@ done_options:
   if (setuid(rq.to) < 0)
     die("couldn't set uid: %s", strerror(errno));
 
+  /* --- If this was a login, change current directory --- */
+
+  if (flags & f_shell && style == l_login && chdir(to_pw->pw_dir) < 0) {
+    moan("couldn't change directory to `%s': %s",
+        to_pw->pw_dir, strerror(errno));
+  }
+
   /* --- Finally, call the program --- */
 
   fflush(0);