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: }