1004
|
1 /* su.c - switch user
|
|
2 *
|
|
3 * Copyright 2013 CE Strake <strake888@gmail.com>
|
|
4 *
|
|
5 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/su.html
|
|
6
|
|
7 USE_SU(NEWTOY(su, "lmpc:s:", TOYFLAG_BIN))
|
|
8
|
|
9 config SU
|
|
10 bool "su"
|
|
11 default n
|
|
12 help
|
1008
|
13 usage: su [-lmp] [-c CMD] [-s SHELL] [USER [ARGS...]]
|
1004
|
14
|
|
15 Switch to given user, or root if not given, and call a shell with the given arguments.
|
|
16
|
|
17 options:
|
|
18 -s shell to call
|
|
19 -c command to pass to shell with -c
|
|
20
|
|
21 flags:
|
|
22 -l login shell
|
|
23 -(m|p) preserve environment
|
|
24 */
|
|
25
|
|
26 #define FOR_su
|
|
27 #include "toys.h"
|
|
28
|
|
29 GLOBALS(
|
1008
|
30 char *s;
|
|
31 char *c;
|
1004
|
32 )
|
|
33
|
|
34 static void deny () {
|
|
35 printf ("Denied\n");
|
|
36 xexit ();
|
|
37 }
|
|
38
|
|
39 void su_main () {
|
|
40 char *name, *passhash, **argu, **argv;
|
|
41 struct passwd *up;
|
|
42 struct spwd *shp;
|
|
43 long ii;
|
|
44
|
|
45 if (toys.optc && strcmp ("-", toys.optargs[0]) == 0) {
|
|
46 toys.optflags |= FLAG_l;
|
|
47 toys.optc--; toys.optargs++;
|
|
48 }
|
|
49
|
|
50 if (toys.optc) {
|
|
51 name = toys.optargs[0];
|
|
52 toys.optc--; toys.optargs++;
|
|
53 }
|
|
54 else name = "root";
|
|
55 shp = getspnam (name);
|
1008
|
56 if (!shp) perror_exit ("can't find password");
|
1004
|
57
|
|
58 switch (shp -> sp_pwdp[0]) {
|
|
59 case '!': deny ();
|
|
60 case '$': break;
|
|
61 default : error_exit ("bad password format");
|
|
62 }
|
|
63
|
1008
|
64 if (read_password (toybuf, sizeof (toybuf), "Password: ") != 0) perror_exit ("can't read password");
|
1004
|
65
|
|
66 passhash = crypt (toybuf, shp -> sp_pwdp);
|
|
67 for (ii = 0; toybuf[ii]; ii++) toybuf[ii] = 0;
|
1008
|
68 if (!passhash) perror_exit ("can't crypt");
|
1004
|
69
|
|
70 if (strcmp (passhash, shp -> sp_pwdp) != 0) deny ();
|
|
71
|
|
72 up = getpwnam (name);
|
1008
|
73 if (!up) perror_exit ("can't getpwnam");
|
1004
|
74
|
1008
|
75 xsetuid (up -> pw_uid);
|
|
76 xchdir (up -> pw_dir);
|
1004
|
77
|
|
78 argu = xmalloc (sizeof (char *)*(toys.optc + 4));
|
|
79 argv = argu;
|
1008
|
80 argv[0] = toys.optflags & FLAG_s ? TT.s : up -> pw_shell;
|
|
81 if (toys.optflags & FLAG_l) (argv++)[1] = "-l";
|
1004
|
82 if (toys.optflags & FLAG_c) {
|
1008
|
83 argv[1] = "-c";
|
|
84 argv[2] = TT.c;
|
1004
|
85 argv += 2;
|
|
86 }
|
1008
|
87 memcpy (argv + 1, toys.optargs, sizeof (char *)*toys.optc);
|
|
88 execve (argu[0], argu,
|
|
89 toys.optflags & FLAG_l ? (char *[]){
|
|
90 xmsprintf ( "HOME=%s", up -> pw_dir),
|
|
91 xmsprintf ("SHELL=%s", up -> pw_shell),
|
|
92 xmsprintf ( "USER=%s", up -> pw_name),
|
|
93 xmsprintf ( "TERM=%s", getenv ("TERM")),
|
|
94 0
|
|
95 } : environ);
|
|
96 perror_exit ("can't exec %s", argu[0]);
|
1004
|
97 }
|