Add spl's around queue manipulation
[unix-history] / usr / src / usr.bin / su / su.c
CommitLineData
13dd8b1d 1#ifndef lint
56f24790 2static char *sccsid = "@(#)su.c 4.9 (Berkeley) %G%";
13dd8b1d
SL
3#endif
4
3a265c7a
BJ
5#include <stdio.h>
6#include <pwd.h>
b3d7f31f 7#include <grp.h>
4f4c2c68
SL
8#include <sys/types.h>
9#include <sys/time.h>
10#include <sys/resource.h>
3a265c7a 11
4f4c2c68
SL
12char userbuf[16] = "USER=";
13char homebuf[128] = "HOME=";
14char shellbuf[128] = "SHELL=";
15char pathbuf[128] = "PATH=:/usr/ucb:/bin:/usr/bin";
16char *cleanenv[] = { userbuf, homebuf, shellbuf, pathbuf, 0, 0 };
17char *user = "root";
18char *shell = "/bin/sh";
19int fulllogin;
20int fastlogin;
21
22extern char **environ;
b3d7f31f 23struct passwd *pwd;
3a265c7a
BJ
24char *crypt();
25char *getpass();
4f4c2c68 26char *getenv();
3a265c7a
BJ
27
28main(argc,argv)
13dd8b1d 29 int argc;
4f4c2c68 30 char *argv[];
3a265c7a 31{
3a265c7a 32 char *password;
a8a168db
RC
33 char buf[1000];
34 FILE *fp;
3a265c7a 35
4f4c2c68
SL
36again:
37 if (argc > 1 && strcmp(argv[1], "-f") == 0) {
38 fastlogin++;
39 argc--, argv++;
40 goto again;
41 }
42 if (argc > 1 && strcmp(argv[1], "-") == 0) {
43 fulllogin++;
44 argc--, argv++;
45 goto again;
46 }
47 if (argc > 1 && argv[1][0] != '-') {
48 user = argv[1];
49 argc--, argv++;
50 }
96f93d9e
RC
51 if ((pwd = getpwuid(getuid())) == NULL) {
52 fprintf(stderr, "Who are you?\n");
53 exit(1);
54 }
55 strcpy(buf, pwd->pw_name);
56 if ((pwd = getpwnam(user)) == NULL) {
57 fprintf(stderr, "Unknown login: %s\n", user);
58 exit(1);
59 }
60 /*
61 * Only allow those in group zero to su to root.
62 */
63 if (pwd->pw_uid == 0) {
b3d7f31f
RC
64 struct group *gr;
65 int i;
66
b3d7f31f
RC
67 if ((gr = getgrgid(0)) != NULL) {
68 for (i = 0; gr->gr_mem[i] != NULL; i++)
96f93d9e 69 if (strcmp(buf, gr->gr_mem[i]) == 0)
a8a168db 70 goto userok;
96f93d9e
RC
71 fprintf(stderr, "You do not have permission to su %s\n",
72 user);
a8a168db
RC
73 exit(1);
74 }
75 userok:
4f4c2c68 76 setpriority(PRIO_PROCESS, 0, -2);
a8a168db
RC
77 }
78
13dd8b1d 79 if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
3a265c7a
BJ
80 goto ok;
81 password = getpass("Password:");
13dd8b1d 82 if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
4f4c2c68 83 fprintf(stderr, "Sorry\n");
13dd8b1d 84 if (pwd->pw_uid == 0) {
3a265c7a
BJ
85 FILE *console = fopen("/dev/console", "w");
86 if (console != NULL) {
13dd8b1d
SL
87 fprintf(console, "BADSU: %s %s\r\n",
88 getlogin(), ttyname(2));
3a265c7a
BJ
89 fclose(console);
90 }
91 }
92 exit(2);
93 }
94ok:
95 endpwent();
13dd8b1d 96 if (pwd->pw_uid == 0) {
3a265c7a
BJ
97 FILE *console = fopen("/dev/console", "w");
98 if (console != NULL) {
13dd8b1d
SL
99 fprintf(console, "SU: %s %s\r\n",
100 getlogin(), ttyname(2));
3a265c7a
BJ
101 fclose(console);
102 }
103 }
13dd8b1d
SL
104 if (setgid(pwd->pw_gid) < 0) {
105 perror("su: setgid");
106 exit(3);
107 }
4f4c2c68 108 if (initgroups(user, pwd->pw_gid)) {
13dd8b1d
SL
109 fprintf(stderr, "su: initgroups failed\n");
110 exit(4);
111 }
112 if (setuid(pwd->pw_uid) < 0) {
113 perror("su: setuid");
114 exit(5);
115 }
3a265c7a
BJ
116 if (pwd->pw_shell && *pwd->pw_shell)
117 shell = pwd->pw_shell;
4f4c2c68
SL
118 if (fulllogin) {
119 cleanenv[4] = getenv("TERM");
120 environ = cleanenv;
121 }
c399698a
SL
122 if (strcmp(user, "root"))
123 setenv("USER", pwd->pw_name, userbuf);
4f4c2c68
SL
124 setenv("SHELL", shell, shellbuf);
125 setenv("HOME", pwd->pw_dir, homebuf);
126 setpriority(PRIO_PROCESS, 0, 0);
127 if (fastlogin) {
128 *argv-- = "-f";
129 *argv = "su";
130 } else if (fulllogin) {
131 if (chdir(pwd->pw_dir) < 0) {
132 fprintf(stderr, "No directory\n");
133 exit(6);
134 }
135 *argv = "-su";
136 } else
137 *argv = "su";
138 execv(shell, argv);
139 fprintf(stderr, "No shell\n");
140 exit(7);
3a265c7a
BJ
141}
142
4f4c2c68
SL
143setenv(ename, eval, buf)
144 char *ename, *eval, *buf;
3a265c7a
BJ
145{
146 register char *cp, *dp;
147 register char **ep = environ;
3a265c7a 148
4f4c2c68
SL
149 /*
150 * this assumes an environment variable "ename" already exists
151 */
3a265c7a 152 while (dp = *ep++) {
4f4c2c68 153 for (cp = ename; *cp == *dp && *cp; cp++, dp++)
3a265c7a
BJ
154 continue;
155 if (*cp == 0 && (*dp == '=' || *dp == 0)) {
4f4c2c68
SL
156 strcat(buf, eval);
157 *--ep = buf;
3a265c7a
BJ
158 return;
159 }
160 }
161}
162
4f4c2c68
SL
163char *
164getenv(ename)
165 char *ename;
3a265c7a
BJ
166{
167 register char *cp, *dp;
168 register char **ep = environ;
3a265c7a
BJ
169
170 while (dp = *ep++) {
4f4c2c68 171 for (cp = ename; *cp == *dp && *cp; cp++, dp++)
3a265c7a 172 continue;
4f4c2c68
SL
173 if (*cp == 0 && (*dp == '=' || *dp == 0))
174 return (*--ep);
3a265c7a 175 }
4f4c2c68 176 return ((char *)0);
3a265c7a 177}