|
|
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.