1*10045Ssam #ifndef lint 2*10045Ssam static char *sccsid = "@(#)su.c 4.4 (Berkeley) 4.4"; 3*10045Ssam #endif 4*10045Ssam 51109Sbill #include <stdio.h> 61109Sbill #include <pwd.h> 71109Sbill 81109Sbill struct passwd *pwd,*getpwnam(); 91109Sbill char *crypt(); 101109Sbill char *getpass(); 111109Sbill 121109Sbill main(argc,argv) 13*10045Ssam int argc; 14*10045Ssam char **argv; 151109Sbill { 16*10045Ssam char *nptr = "root"; 171109Sbill char *password; 181109Sbill char *shell = "/bin/sh"; 191109Sbill 20*10045Ssam if (argc > 1) 211109Sbill nptr = argv[1]; 22*10045Ssam if ((pwd = getpwnam(nptr)) == NULL) { 231109Sbill printf("Unknown id: %s\n",nptr); 241109Sbill exit(1); 251109Sbill } 26*10045Ssam if (pwd->pw_passwd[0] == '\0' || getuid() == 0) 271109Sbill goto ok; 281109Sbill password = getpass("Password:"); 29*10045Ssam if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) { 301109Sbill printf("Sorry\n"); 31*10045Ssam if (pwd->pw_uid == 0) { 321109Sbill FILE *console = fopen("/dev/console", "w"); 331109Sbill if (console != NULL) { 34*10045Ssam fprintf(console, "BADSU: %s %s\r\n", 35*10045Ssam getlogin(), ttyname(2)); 361109Sbill fclose(console); 371109Sbill } 381109Sbill } 391109Sbill exit(2); 401109Sbill } 411109Sbill ok: 421109Sbill endpwent(); 43*10045Ssam if (pwd->pw_uid == 0) { 441109Sbill FILE *console = fopen("/dev/console", "w"); 451109Sbill if (console != NULL) { 46*10045Ssam fprintf(console, "SU: %s %s\r\n", 47*10045Ssam getlogin(), ttyname(2)); 481109Sbill fclose(console); 491109Sbill } 501109Sbill } 51*10045Ssam if (setgid(pwd->pw_gid) < 0) { 52*10045Ssam perror("su: setgid"); 53*10045Ssam exit(3); 54*10045Ssam } 55*10045Ssam if (initgroups(nptr, pwd->pw_gid)) { 56*10045Ssam fprintf(stderr, "su: initgroups failed\n"); 57*10045Ssam exit(4); 58*10045Ssam } 59*10045Ssam if (setuid(pwd->pw_uid) < 0) { 60*10045Ssam perror("su: setuid"); 61*10045Ssam exit(5); 62*10045Ssam } 631109Sbill if (pwd->pw_shell && *pwd->pw_shell) 641109Sbill shell = pwd->pw_shell; 651109Sbill homeis(pwd->pw_dir); 661109Sbill shellis(shell); 671109Sbill execl(shell, "su", 0); 681109Sbill printf("No shell\n"); 691109Sbill exit(3); 701109Sbill } 711109Sbill 721109Sbill char **environ; 731109Sbill 741109Sbill homeis(hp) 751109Sbill char *hp; 761109Sbill { 771109Sbill register char *cp, *dp; 781109Sbill register char **ep = environ; 791109Sbill static char homebuf[128]; 801109Sbill 811109Sbill while (dp = *ep++) { 821109Sbill for (cp = "HOME"; *cp == *dp && *cp; cp++, dp++) 831109Sbill continue; 841109Sbill if (*cp == 0 && (*dp == '=' || *dp == 0)) { 851109Sbill strcpy(homebuf, "HOME="); 861109Sbill strcat(homebuf, hp); 871109Sbill *--ep = homebuf; 881109Sbill return; 891109Sbill } 901109Sbill } 911109Sbill } 921109Sbill 931109Sbill shellis(sp) 941109Sbill char *sp; 951109Sbill { 961109Sbill register char *cp, *dp; 971109Sbill register char **ep = environ; 981109Sbill static char shellbuf[128]; 991109Sbill 1001109Sbill while (dp = *ep++) { 1011109Sbill for (cp = "SHELL"; *cp == *dp && *cp; cp++, dp++) 1021109Sbill continue; 1031109Sbill if (*cp == 0 && (*dp == '=' || *dp == 0)) { 1041109Sbill strcpy(shellbuf, "SHELL="); 1051109Sbill strcat(shellbuf, sp); 1061109Sbill *--ep = shellbuf; 1071109Sbill return; 1081109Sbill } 1091109Sbill } 1101109Sbill } 111