date and time created 83/02/11 15:45:15 by rrh
[unix-history] / usr / src / usr.bin / su / su.c
#ifndef lint
static char *sccsid = "@(#)su.c 4.4 (Berkeley) 4.4";
#endif
#include <stdio.h>
#include <pwd.h>
struct passwd *pwd,*getpwnam();
char *crypt();
char *getpass();
main(argc,argv)
int argc;
char **argv;
{
char *nptr = "root";
char *password;
char *shell = "/bin/sh";
if (argc > 1)
nptr = argv[1];
if ((pwd = getpwnam(nptr)) == NULL) {
printf("Unknown id: %s\n",nptr);
exit(1);
}
if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
goto ok;
password = getpass("Password:");
if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
printf("Sorry\n");
if (pwd->pw_uid == 0) {
FILE *console = fopen("/dev/console", "w");
if (console != NULL) {
fprintf(console, "BADSU: %s %s\r\n",
getlogin(), ttyname(2));
fclose(console);
}
}
exit(2);
}
ok:
endpwent();
if (pwd->pw_uid == 0) {
FILE *console = fopen("/dev/console", "w");
if (console != NULL) {
fprintf(console, "SU: %s %s\r\n",
getlogin(), ttyname(2));
fclose(console);
}
}
if (setgid(pwd->pw_gid) < 0) {
perror("su: setgid");
exit(3);
}
if (initgroups(nptr, pwd->pw_gid)) {
fprintf(stderr, "su: initgroups failed\n");
exit(4);
}
if (setuid(pwd->pw_uid) < 0) {
perror("su: setuid");
exit(5);
}
if (pwd->pw_shell && *pwd->pw_shell)
shell = pwd->pw_shell;
homeis(pwd->pw_dir);
shellis(shell);
execl(shell, "su", 0);
printf("No shell\n");
exit(3);
}
char **environ;
homeis(hp)
char *hp;
{
register char *cp, *dp;
register char **ep = environ;
static char homebuf[128];
while (dp = *ep++) {
for (cp = "HOME"; *cp == *dp && *cp; cp++, dp++)
continue;
if (*cp == 0 && (*dp == '=' || *dp == 0)) {
strcpy(homebuf, "HOME=");
strcat(homebuf, hp);
*--ep = homebuf;
return;
}
}
}
shellis(sp)
char *sp;
{
register char *cp, *dp;
register char **ep = environ;
static char shellbuf[128];
while (dp = *ep++) {
for (cp = "SHELL"; *cp == *dp && *cp; cp++, dp++)
continue;
if (*cp == 0 && (*dp == '=' || *dp == 0)) {
strcpy(shellbuf, "SHELL=");
strcat(shellbuf, sp);
*--ep = shellbuf;
return;
}
}
}