|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)su.c 5.4 (Berkeley) 1/13/86";
15: #endif not lint
16:
17: #include <stdio.h>
18: #include <pwd.h>
19: #include <grp.h>
20: #include <syslog.h>
21: #include <sys/types.h>
22: #include <sys/time.h>
23: #include <sys/resource.h>
24:
25: char userbuf[16] = "USER=";
26: char homebuf[128] = "HOME=";
27: char shellbuf[128] = "SHELL=";
28: char pathbuf[128] = "PATH=:/usr/ucb:/bin:/usr/bin";
29: char *cleanenv[] = { userbuf, homebuf, shellbuf, pathbuf, 0, 0 };
30: char *user = "root";
31: char *shell = "/bin/sh";
32: int fulllogin;
33: int fastlogin;
34:
35: extern char **environ;
36: struct passwd *pwd;
37: char *crypt();
38: char *getpass();
39: char *getenv();
40: char *getlogin();
41:
42: main(argc,argv)
43: int argc;
44: char *argv[];
45: {
46: char *password;
47: char buf[1000];
48: FILE *fp;
49: register char *p;
50:
51: openlog("su", LOG_ODELAY, LOG_AUTH);
52:
53: again:
54: if (argc > 1 && strcmp(argv[1], "-f") == 0) {
55: fastlogin++;
56: argc--, argv++;
57: goto again;
58: }
59: if (argc > 1 && strcmp(argv[1], "-") == 0) {
60: fulllogin++;
61: argc--, argv++;
62: goto again;
63: }
64: if (argc > 1 && argv[1][0] != '-') {
65: user = argv[1];
66: argc--, argv++;
67: }
68: if ((pwd = getpwuid(getuid())) == NULL) {
69: fprintf(stderr, "Who are you?\n");
70: exit(1);
71: }
72: strcpy(buf, pwd->pw_name);
73: if ((pwd = getpwnam(user)) == NULL) {
74: fprintf(stderr, "Unknown login: %s\n", user);
75: exit(1);
76: }
77: /*
78: * Only allow those in group zero to su to root.
79: */
80: if (pwd->pw_uid == 0) {
81: struct group *gr;
82: int i;
83:
84: if ((gr = getgrgid(0)) != NULL) {
85: for (i = 0; gr->gr_mem[i] != NULL; i++)
86: if (strcmp(buf, gr->gr_mem[i]) == 0)
87: goto userok;
88: fprintf(stderr, "You do not have permission to su %s\n",
89: user);
90: exit(1);
91: }
92: userok:
93: setpriority(PRIO_PROCESS, 0, -2);
94: }
95:
96: #define Getlogin() (((p = getlogin()) && *p) ? p : buf)
97: if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
98: goto ok;
99: password = getpass("Password:");
100: if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
101: fprintf(stderr, "Sorry\n");
102: if (pwd->pw_uid == 0) {
103: syslog(LOG_CRIT, "BAD SU %s on %s",
104: Getlogin(), ttyname(2));
105: }
106: exit(2);
107: }
108: ok:
109: endpwent();
110: if (pwd->pw_uid == 0) {
111: syslog(LOG_NOTICE, "%s on %s", Getlogin(), ttyname(2));
112: closelog();
113: }
114: if (setgid(pwd->pw_gid) < 0) {
115: perror("su: setgid");
116: exit(3);
117: }
118: if (initgroups(user, pwd->pw_gid)) {
119: fprintf(stderr, "su: initgroups failed\n");
120: exit(4);
121: }
122: if (setuid(pwd->pw_uid) < 0) {
123: perror("su: setuid");
124: exit(5);
125: }
126: if (pwd->pw_shell && *pwd->pw_shell)
127: shell = pwd->pw_shell;
128: if (fulllogin) {
129: cleanenv[4] = getenv("TERM");
130: environ = cleanenv;
131: }
132: if (strcmp(user, "root"))
133: setenv("USER", pwd->pw_name, userbuf);
134: setenv("SHELL", shell, shellbuf);
135: setenv("HOME", pwd->pw_dir, homebuf);
136: setpriority(PRIO_PROCESS, 0, 0);
137: if (fastlogin) {
138: *argv-- = "-f";
139: *argv = "su";
140: } else if (fulllogin) {
141: if (chdir(pwd->pw_dir) < 0) {
142: fprintf(stderr, "No directory\n");
143: exit(6);
144: }
145: *argv = "-su";
146: } else
147: *argv = "su";
148: execv(shell, argv);
149: fprintf(stderr, "No shell\n");
150: exit(7);
151: }
152:
153: setenv(ename, eval, buf)
154: char *ename, *eval, *buf;
155: {
156: register char *cp, *dp;
157: register char **ep = environ;
158:
159: /*
160: * this assumes an environment variable "ename" already exists
161: */
162: while (dp = *ep++) {
163: for (cp = ename; *cp == *dp && *cp; cp++, dp++)
164: continue;
165: if (*cp == 0 && (*dp == '=' || *dp == 0)) {
166: strcat(buf, eval);
167: *--ep = buf;
168: return;
169: }
170: }
171: }
172:
173: char *
174: getenv(ename)
175: char *ename;
176: {
177: register char *cp, *dp;
178: register char **ep = environ;
179:
180: while (dp = *ep++) {
181: for (cp = ename; *cp == *dp && *cp; cp++, dp++)
182: continue;
183: if (*cp == 0 && (*dp == '=' || *dp == 0))
184: return (*--ep);
185: }
186: return ((char *)0);
187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.