[Toybox] [patch] add su
Strake
strake888 at gmail.com
Thu Aug 15 17:01:56 PDT 2013
On 14/08/2013, Rob Landley <rob at landley.net> wrote:
> The root user is uid 0, which could be _named_ anything. (Crazy people
> say "wheel".) So we need a getwpuid(0) else getpwnam(name) and then do
> the shadow lookup based on that name.
I would likely write a function getspuid, but I'm not sure how you
wish to do this, so I'll leave it for now.
>> + passhash = crypt (toybuf, shp -> sp_pwdp);
>> + if (!passhash) perror_exit ("failed to compute password hash");
>> + for (ii = 0; toybuf[ii]; ii++) toybuf[ii] = 0;
>
> Proper paranoia would probably swap those last two lines.
Derp.
> Hmmm, should the suid plumbing in main.c mlockall() when we don't drop
> privs?
I think so. Particularly if someone can read the swap medium but not /dev/mem.
>> + if (toys.optflags & FLAG_c) {
>> + argv[1] = toys.optflags & FLAG_l ? "-lc" : "-c";
>> + argv[2] = TT.cArgu;
>> + argv += 2;
>> + }
>> + else if (toys.optflags & FLAG_l) (argv++)[1] = "-l";
>
> Is there a reason you can't do -l -c as two arguments and just test
> once?
No, was just stupid.
>From 29dc3c3206c7280d159c9d0e27125fdbe1dd0a61 Mon Sep 17 00:00:00 2001
From: Strake <strake888 at gmail.com>
Date: Mon, 30 Jun 2003 15:50:05 -0500
Subject: [PATCH] su: cleanery
* make help message more like others
* s/TT\.(.)Argu/TT.\1/g
* move environ to toys.h
* simplify failure messages
* clear password before quit
* not check what execve returns
* -lc
---
toys.h | 2 ++
toys/pending/su.c | 67 +++++++++++++++++++++++++++----------------------------
2 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/toys.h b/toys.h
index 2ce1d0a..c810123 100644
--- a/toys.h
+++ b/toys.h
@@ -117,6 +117,8 @@ extern struct toy_context {
extern char toybuf[4096];
+extern char **environ;
+
#define GLOBALS(...)
#define ARRAY_LEN(array) (sizeof(array)/sizeof(*array))
diff --git a/toys/pending/su.c b/toys/pending/su.c
index cf9b599..529042b 100644
--- a/toys/pending/su.c
+++ b/toys/pending/su.c
@@ -10,14 +10,14 @@ 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.
-
+
options:
-s shell to call
-c command to pass to shell with -c
-
+
flags:
-l login shell
-(m|p) preserve environment
@@ -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 ();
@@ -43,56 +41,57 @@ void su_main () {
struct passwd *up;
struct spwd *shp;
long ii;
-
+
if (toys.optc && strcmp ("-", toys.optargs[0]) == 0) {
toys.optflags |= FLAG_l;
toys.optc--; toys.optargs++;
}
-
+
if (toys.optc) {
name = toys.optargs[0];
toys.optc--; toys.optargs++;
}
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 ();
case '$': break;
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 (setuid (up -> pw_uid) < 0) perror_exit ("failed to setuid");
- if (chdir (up -> pw_dir) < 0) perror_exit ("failed to chdir");
-
+ if (!up) perror_exit ("can't getpwnam");
+
+ 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]);
}
--
1.8.3.4
More information about the Toybox
mailing list