|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)su.c 4.6 (Berkeley) 7/6/83";
3: #endif
4:
5: #include <stdio.h>
6: #include <pwd.h>
7: #include <sys/types.h>
8: #include <sys/time.h>
9: #include <sys/resource.h>
10:
11: char userbuf[16] = "USER=";
12: char homebuf[128] = "HOME=";
13: char shellbuf[128] = "SHELL=";
14: char pathbuf[128] = "PATH=:/usr/ucb:/bin:/usr/bin";
15: char *cleanenv[] = { userbuf, homebuf, shellbuf, pathbuf, 0, 0 };
16: char *user = "root";
17: char *shell = "/bin/sh";
18: int fulllogin;
19: int fastlogin;
20:
21: extern char **environ;
22: struct passwd *pwd,*getpwnam();
23: char *crypt();
24: char *getpass();
25: char *getenv();
26:
27: main(argc,argv)
28: int argc;
29: char *argv[];
30: {
31: char *password;
32:
33: again:
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);
52: exit(1);
53: }
54: if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
55: goto ok;
56: password = getpass("Password:");
57: if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
58: fprintf(stderr, "Sorry\n");
59: if (pwd->pw_uid == 0) {
60: FILE *console = fopen("/dev/console", "w");
61: if (console != NULL) {
62: fprintf(console, "BADSU: %s %s\r\n",
63: getlogin(), ttyname(2));
64: fclose(console);
65: }
66: }
67: exit(2);
68: }
69: ok:
70: endpwent();
71: if (pwd->pw_uid == 0) {
72: FILE *console = fopen("/dev/console", "w");
73: if (console != NULL) {
74: fprintf(console, "SU: %s %s\r\n",
75: getlogin(), ttyname(2));
76: fclose(console);
77: }
78: }
79: if (setgid(pwd->pw_gid) < 0) {
80: perror("su: setgid");
81: exit(3);
82: }
83: if (initgroups(user, pwd->pw_gid)) {
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: }
91: if (pwd->pw_shell && *pwd->pw_shell)
92: shell = pwd->pw_shell;
93: if (fulllogin) {
94: cleanenv[4] = getenv("TERM");
95: environ = cleanenv;
96: }
97: if (strcmp(user, "root"))
98: setenv("USER", pwd->pw_name, userbuf);
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);
116: }
117:
118: setenv(ename, eval, buf)
119: char *ename, *eval, *buf;
120: {
121: register char *cp, *dp;
122: register char **ep = environ;
123:
124: /*
125: * this assumes an environment variable "ename" already exists
126: */
127: while (dp = *ep++) {
128: for (cp = ename; *cp == *dp && *cp; cp++, dp++)
129: continue;
130: if (*cp == 0 && (*dp == '=' || *dp == 0)) {
131: strcat(buf, eval);
132: *--ep = buf;
133: return;
134: }
135: }
136: }
137:
138: char *
139: getenv(ename)
140: char *ename;
141: {
142: register char *cp, *dp;
143: register char **ep = environ;
144:
145: while (dp = *ep++) {
146: for (cp = ename; *cp == *dp && *cp; cp++, dp++)
147: continue;
148: if (*cp == 0 && (*dp == '=' || *dp == 0))
149: return (*--ep);
150: }
151: return ((char *)0);
152: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.