1 #ifndef lint 2 static char *sccsid = "@(#)su.c 4.4 (Berkeley) 4.4"; 3 #endif 4 5 #include <stdio.h> 6 #include <pwd.h> 7 8 struct passwd *pwd,*getpwnam(); 9 char *crypt(); 10 char *getpass(); 11 12 main(argc,argv) 13 int argc; 14 char **argv; 15 { 16 char *nptr = "root"; 17 char *password; 18 char *shell = "/bin/sh"; 19 20 if (argc > 1) 21 nptr = argv[1]; 22 if ((pwd = getpwnam(nptr)) == NULL) { 23 printf("Unknown id: %s\n",nptr); 24 exit(1); 25 } 26 if (pwd->pw_passwd[0] == '\0' || getuid() == 0) 27 goto ok; 28 password = getpass("Password:"); 29 if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) { 30 printf("Sorry\n"); 31 if (pwd->pw_uid == 0) { 32 FILE *console = fopen("/dev/console", "w"); 33 if (console != NULL) { 34 fprintf(console, "BADSU: %s %s\r\n", 35 getlogin(), ttyname(2)); 36 fclose(console); 37 } 38 } 39 exit(2); 40 } 41 ok: 42 endpwent(); 43 if (pwd->pw_uid == 0) { 44 FILE *console = fopen("/dev/console", "w"); 45 if (console != NULL) { 46 fprintf(console, "SU: %s %s\r\n", 47 getlogin(), ttyname(2)); 48 fclose(console); 49 } 50 } 51 if (setgid(pwd->pw_gid) < 0) { 52 perror("su: setgid"); 53 exit(3); 54 } 55 if (initgroups(nptr, pwd->pw_gid)) { 56 fprintf(stderr, "su: initgroups failed\n"); 57 exit(4); 58 } 59 if (setuid(pwd->pw_uid) < 0) { 60 perror("su: setuid"); 61 exit(5); 62 } 63 if (pwd->pw_shell && *pwd->pw_shell) 64 shell = pwd->pw_shell; 65 homeis(pwd->pw_dir); 66 shellis(shell); 67 execl(shell, "su", 0); 68 printf("No shell\n"); 69 exit(3); 70 } 71 72 char **environ; 73 74 homeis(hp) 75 char *hp; 76 { 77 register char *cp, *dp; 78 register char **ep = environ; 79 static char homebuf[128]; 80 81 while (dp = *ep++) { 82 for (cp = "HOME"; *cp == *dp && *cp; cp++, dp++) 83 continue; 84 if (*cp == 0 && (*dp == '=' || *dp == 0)) { 85 strcpy(homebuf, "HOME="); 86 strcat(homebuf, hp); 87 *--ep = homebuf; 88 return; 89 } 90 } 91 } 92 93 shellis(sp) 94 char *sp; 95 { 96 register char *cp, *dp; 97 register char **ep = environ; 98 static char shellbuf[128]; 99 100 while (dp = *ep++) { 101 for (cp = "SHELL"; *cp == *dp && *cp; cp++, dp++) 102 continue; 103 if (*cp == 0 && (*dp == '=' || *dp == 0)) { 104 strcpy(shellbuf, "SHELL="); 105 strcat(shellbuf, sp); 106 *--ep = shellbuf; 107 return; 108 } 109 } 110 } 111