annotate toys/lsb/su.c @ 1564:685a0da6ca59 draft

probe for getspnam(), forkpty(), utmpx, replace sethostname() Android is missing all of these; we need to probe for some so we have a config symbol to depend on. sethostname() is easily replaced. We got termios.h via pty.h; now it's not included in configure-step tools, so we need termios.h to generate globals.
author Isaac Dunham <ibid.ag@gmail.com>
date Wed, 19 Nov 2014 16:38:46 -0600
parents 407357afa07f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
1 /* su.c - switch user
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
2 *
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
3 * Copyright 2013 CE Strake <strake888@gmail.com>
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
4 *
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
5 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/su.html
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
6 * TODO: log su attempts
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
7
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
8 USE_SU(NEWTOY(su, "lmpc:s:", TOYFLAG_BIN|TOYFLAG_ROOTONLY))
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
9
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
10 config SU
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
11 bool "su"
1153
c4ac6a90963d Promote su from pending to lsb.
Rob Landley <rob@landley.net>
parents: 1152
diff changeset
12 default y
1564
685a0da6ca59 probe for getspnam(), forkpty(), utmpx, replace sethostname()
Isaac Dunham <ibid.ag@gmail.com>
parents: 1248
diff changeset
13 depends on TOYBOX_SHADOW
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
14 help
1008
a55854bde872 su: cleanery
Strake <strake888@gmail.com>
parents: 1004
diff changeset
15 usage: su [-lmp] [-c CMD] [-s SHELL] [USER [ARGS...]]
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
16
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
17 Switch to user (or root) and run shell (with optional command line).
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
18
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
19 -s shell to use
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
20 -c command to pass to shell with -c
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
21 -l login shell
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
22 -(m|p) preserve environment
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
23 */
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
24
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
25 #define FOR_su
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
26 #include "toys.h"
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
27
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
28 GLOBALS(
1008
a55854bde872 su: cleanery
Strake <strake888@gmail.com>
parents: 1004
diff changeset
29 char *s;
a55854bde872 su: cleanery
Strake <strake888@gmail.com>
parents: 1004
diff changeset
30 char *c;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
31 )
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
32
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
33 static char *snapshot_env(char *name)
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
34 {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
35 char *s = getenv(name);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
36
1183
0752b2d58909 Rename xmsprintf() to just xmprintf().
Rob Landley <rob@landley.net>
parents: 1156
diff changeset
37 if (s) return xmprintf("%s=%s", name, s);
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
38
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
39 return 0;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
40 }
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
41
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
42 void su_main()
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
43 {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
44 char *name, *passhash = 0, **argu, **argv;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
45 struct passwd *up;
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
46 struct spwd *shp;
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
47
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
48 if (*toys.optargs && !strcmp("-", *toys.optargs)) {
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
49 toys.optflags |= FLAG_l;
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
50 toys.optargs++;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
51 }
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
52
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
53 if (*toys.optargs) name = *(toys.optargs++);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
54 else name = "root";
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
55
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
56 if (!(shp = getspnam(name))) perror_exit("no '%s'", name);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
57 if (*shp->sp_pwdp != '$') goto deny;
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
58 if (read_password(toybuf, sizeof(toybuf), "Password: ")) goto deny;
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
59 passhash = crypt(toybuf, shp->sp_pwdp);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
60 memset(toybuf, 0, sizeof(toybuf));
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
61 if (!passhash || strcmp(passhash, shp->sp_pwdp)) goto deny;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
62
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
63 up = xgetpwnam(name);
1156
faf7117c4489 Fix some issues raised (albeit indirectly) by Isaac Dunham.
Rob Landley <rob@landley.net>
parents: 1153
diff changeset
64 xsetuser(up);
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
65
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
66 argv = argu = xmalloc(sizeof(char *)*(toys.optc + 4));
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
67 *(argv++) = TT.s ? TT.s : up->pw_shell;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
68
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
69 if (toys.optflags & FLAG_l) {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
70 int i;
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
71 char *stuff[] = {snapshot_env("TERM"), snapshot_env("DISPLAY"),
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
72 snapshot_env("COLORTERM"), snapshot_env("XAUTHORITY")};
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
73
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
74 clearenv();
1248
407357afa07f Bugfix: if $TERM and friends aren't set, putenv() got passed a NULL.
Rob Landley <rob@landley.net>
parents: 1183
diff changeset
75 for (i=0; i < ARRAY_LEN(stuff); i++) if (stuff[i]) putenv(stuff[i]);
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
76 *(argv++) = "-l";
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
77 xchdir(up->pw_dir);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
78 } else unsetenv("IFS");
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
79 setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
80 if (!(toys.optflags & (FLAG_m|FLAG_p))) {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
81 setenv("HOME", up->pw_dir, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
82 setenv("SHELL", up->pw_shell, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
83 setenv("USER", up->pw_name, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
84 setenv("LOGNAME", up->pw_name, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
85 } else unsetenv("IFS");
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
86
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
87 if (toys.optflags & FLAG_c) {
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
88 *(argv++) = "-c";
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
89 *(argv++) = TT.c;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
90 }
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
91 while ((*(argv++) = *(toys.optargs++)));
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
92 xexec(argu);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
93 perror_exit("can't exec %s", *argu);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
94
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
95 deny:
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
96 puts("No.");
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
97 toys.exitval = 1;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
98 }