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