annotate toys/pending/su.c @ 1074:82c5eb459a91 draft

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