diff options
Diffstat (limited to 'toys/pending/su.c')
-rw-r--r-- | toys/pending/su.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/toys/pending/su.c b/toys/pending/su.c index cf9b5997..f49bcb0f 100644 --- a/toys/pending/su.c +++ b/toys/pending/su.c @@ -10,7 +10,7 @@ config SU bool "su" default n help - usage: su [-lmp] [-c cmd] [-s shell] [user [argu...]] + usage: su [-lmp] [-c CMD] [-s SHELL] [USER [ARGS...]] Switch to given user, or root if not given, and call a shell with the given arguments. @@ -27,12 +27,10 @@ config SU #include "toys.h" GLOBALS( - char *sArgu; - char *cArgu; + char *s; + char *c; ) -extern char **environ; - static void deny () { printf ("Denied\n"); xexit (); @@ -55,7 +53,7 @@ void su_main () { } else name = "root"; shp = getspnam (name); - if (!shp) perror_exit ("failed to find password"); + if (!shp) perror_exit ("can't find password"); switch (shp -> sp_pwdp[0]) { case '!': deny (); @@ -63,36 +61,37 @@ void su_main () { default : error_exit ("bad password format"); } - if (read_password (toybuf, sizeof (toybuf), "Password: ") != 0) perror_exit ("failed to read password"); + if (read_password (toybuf, sizeof (toybuf), "Password: ") != 0) perror_exit ("can't read password"); passhash = crypt (toybuf, shp -> sp_pwdp); - if (!passhash) perror_exit ("failed to compute password hash"); for (ii = 0; toybuf[ii]; ii++) toybuf[ii] = 0; + if (!passhash) perror_exit ("can't crypt"); if (strcmp (passhash, shp -> sp_pwdp) != 0) deny (); up = getpwnam (name); - if (!up) perror_exit ("failed to getpwnam"); + if (!up) perror_exit ("can't getpwnam"); - if (setuid (up -> pw_uid) < 0) perror_exit ("failed to setuid"); - if (chdir (up -> pw_dir) < 0) perror_exit ("failed to chdir"); + xsetuid (up -> pw_uid); + xchdir (up -> pw_dir); argu = xmalloc (sizeof (char *)*(toys.optc + 4)); argv = argu; - argv[0] = toys.optflags & FLAG_s ? TT.sArgu : up -> pw_shell; + argv[0] = toys.optflags & FLAG_s ? TT.s : up -> pw_shell; + if (toys.optflags & FLAG_l) (argv++)[1] = "-l"; if (toys.optflags & FLAG_c) { - argv[1] = toys.optflags & FLAG_l ? "-lc" : "-c"; - argv[2] = TT.cArgu; + argv[1] = "-c"; + argv[2] = TT.c; argv += 2; } - else if (toys.optflags & FLAG_l) (argv++)[1] = "-l"; - for (ii = 0; ii < toys.optc; ii++) argv[ii + 1] = toys.optargs[ii]; - if (execve (argu[0], argu, - toys.optflags & FLAG_l ? (char *[]){ - xmsprintf ( "HOME=%s", up -> pw_dir), - xmsprintf ("SHELL=%s", up -> pw_shell), - xmsprintf ( "USER=%s", up -> pw_name), - xmsprintf ( "TERM=%s", getenv ("TERM")), - 0 - } : environ) < 0) perror_exit ("failed to exec %s", argu[0]); + memcpy (argv + 1, toys.optargs, sizeof (char *)*toys.optc); + execve (argu[0], argu, + toys.optflags & FLAG_l ? (char *[]){ + xmsprintf ( "HOME=%s", up -> pw_dir), + xmsprintf ("SHELL=%s", up -> pw_shell), + xmsprintf ( "USER=%s", up -> pw_name), + xmsprintf ( "TERM=%s", getenv ("TERM")), + 0 + } : environ); + perror_exit ("can't exec %s", argu[0]); } |