Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Wrong emulation mode if exec'd by su

On Jun 15,  3:58pm, Martin Aumueller wrote:
} Subject: Wrong emulation mode if exec'd by su
} I have a problem with zsh-3.1.4: If I su - to an account the zsh sees
} "su" as executable name -- starting with 's' -- and thus switches to
} Bourne shell emulation mode, not the behaviour desired by me. I have
} solved this problem by testing the full executable names against "sh",
} "csh" and "ksh" with strcmp and now it works as I expect it.

On Jun 15,  8:52am, Bart Schaefer wrote:
} Subject: Re: Wrong emulation mode if exec'd by su
} However, the fix in the patch is the wrong one.  Rather than looking for
} every possible shell name in argv[0], the right thing would be to look
} for "su" in argv[0], before testing the first letter for emulation, and
} in that case do the emulation test on the value of $SHELL rather than on
} argv[0].

Here's the promised patch.  This avoids changing emulate() at all; rather,
it checks argv[0] against "su" in main() before deciding what to pass to
emulate(), and if it matches then it uses zgetenv("SHELL") instead.  Note
that different implementations of "su" work differently; as far as I know
they all run the target user's login shell on "su -", but some otherwise
keep the calling user's current $SHELL and change only the uid, whereas
others always run the shell of the target user.

There's some extra code in here to failsafe in case $SHELL is not set or
is empty, or in case it is set to (some path ending in) "su" (in which
case we emulate sh).  Tested by running ARGV0=su ./zsh.

Index: Src/main.c
--- main.c	1998/06/01 17:08:44
+++ main.c	1998/06/16 05:52:59
@@ -45,12 +45,24 @@
     for (t = argv; *t; *t = metafy(*t, -1, META_ALLOC), t++);
-    if (!(zsh_name = strrchr(argv[0], '/')))
-	zsh_name = argv[0];
-    else
-	zsh_name++;
-    if (*zsh_name == '-')
-	zsh_name++;
+    zsh_name = argv[0];
+    do {
+      char *arg0 = zsh_name;
+      if (!(zsh_name = strrchr(arg0, '/')))
+	  zsh_name = arg0;
+      else
+	  zsh_name++;
+      if (*zsh_name == '-')
+	  zsh_name++;
+      if (strcmp(zsh_name, "su") == 0) {
+	  char *sh = zgetenv("SHELL");
+	  if (sh && *sh && arg0 != sh)
+	      zsh_name = sh;
+	  else
+	      break;
+      } else
+	  break;
+    } while (zsh_name);
     fdtable_size = OPEN_MAX;
     fdtable = zcalloc(fdtable_size);

Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Messages sorted by: Reverse Date, Date, Thread, Author