annotate toys/lsb/su.c @ 1153:c4ac6a90963d draft

Promote su from pending to lsb.
author Rob Landley <rob@landley.net>
date Sun, 22 Dec 2013 15:48:44 -0600
parents toys/pending/su.c@b7ca3e926250
children faf7117c4489
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
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
13 help
1008
a55854bde872 su: cleanery
Strake <strake888@gmail.com>
parents: 1004
diff changeset
14 usage: su [-lmp] [-c CMD] [-s SHELL] [USER [ARGS...]]
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
15
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
16 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
17
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
18 -s shell to use
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
19 -c command to pass to shell with -c
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
20 -l login shell
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
21 -(m|p) preserve environment
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
22 */
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 #define FOR_su
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
25 #include "toys.h"
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
26
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
27 GLOBALS(
1008
a55854bde872 su: cleanery
Strake <strake888@gmail.com>
parents: 1004
diff changeset
28 char *s;
a55854bde872 su: cleanery
Strake <strake888@gmail.com>
parents: 1004
diff changeset
29 char *c;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
30 )
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
31
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
32 static char *snapshot_env(char *name)
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
33 {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
34 char *s = getenv(name);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
35
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
36 if (s) return xmsprintf("%s=%s", name, s);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
37
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
38 return 0;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
39 }
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
40
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
41 void su_main()
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
42 {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
43 char *name, *passhash = 0, **argu, **argv;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
44 struct passwd *up;
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
45 struct spwd *shp;
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
46
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
47 if (*toys.optargs && !strcmp("-", *toys.optargs)) {
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
48 toys.optflags |= FLAG_l;
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
49 toys.optargs++;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
50 }
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
51
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
52 if (*toys.optargs) name = *(toys.optargs++);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
53 else name = "root";
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
54
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
55 if (!(shp = getspnam(name))) perror_exit("no '%s'", name);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
56 if (*shp->sp_pwdp != '$') goto deny;
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
57 if (read_password(toybuf, sizeof(toybuf), "Password: ")) goto deny;
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
58 passhash = crypt(toybuf, shp->sp_pwdp);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
59 memset(toybuf, 0, sizeof(toybuf));
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
60 if (!passhash || strcmp(passhash, shp->sp_pwdp)) goto deny;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
61
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
62 up = xgetpwnam(name);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
63 xsetuid(up->pw_uid);
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
64
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
65 argv = argu = xmalloc(sizeof(char *)*(toys.optc + 4));
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
66 *(argv++) = TT.s ? TT.s : up->pw_shell;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
67
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
68 if (toys.optflags & FLAG_l) {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
69 int i;
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
70 char *stuff[] = {snapshot_env("TERM"), snapshot_env("DISPLAY"),
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
71 snapshot_env("COLORTERM"), snapshot_env("XAUTHORITY")};
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
72
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
73 clearenv();
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
74 for (i=0; i < sizeof(stuff)/sizeof(char *); i++) putenv(stuff[i]);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
75 *(argv++) = "-l";
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
76 xchdir(up->pw_dir);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
77 } else unsetenv("IFS");
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
78 setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
79 if (!(toys.optflags & (FLAG_m|FLAG_p))) {
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
80 setenv("HOME", up->pw_dir, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
81 setenv("SHELL", up->pw_shell, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
82 setenv("USER", up->pw_name, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
83 setenv("LOGNAME", up->pw_name, 1);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
84 } else unsetenv("IFS");
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
85
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
86 if (toys.optflags & FLAG_c) {
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
87 *(argv++) = "-c";
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
88 *(argv++) = TT.c;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
89 }
1152
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
90 while ((*(argv++) = *(toys.optargs++)));
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
91 xexec(argu);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
92 perror_exit("can't exec %s", *argu);
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
93
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
94 deny:
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
95 puts("No.");
b7ca3e926250 Cleanup su.
Rob Landley <rob@landley.net>
parents: 1008
diff changeset
96 toys.exitval = 1;
1004
13ac68b51d3d Add su.
M. Farkas-Dyck <strake888@gmail.com>
parents:
diff changeset
97 }