V9/cmd/su.c
#include <stdio.h>
#include <pwd.h>
#include <time.h>
#include <signal.h>
#define SULOG "/dev/console"
struct passwd *pwd,*getpwnam();
char *crypt();
char *getpass();
char **environ;
main(argc,argv)
int argc;
char **argv;
{
register char **p;
char *nptr;
char *password;
int badsw = 0;
int newgid, newuid;
char *shell = "/bin/sh";
if(argv[0][0] != '/'){
fprintf(stderr, "su must be invoked with a full path\n");
exit(1);
}
if(argc > 1)
nptr = argv[1];
else
nptr = "root";
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(badsw || (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0)) {
log(SULOG,nptr,0);
printf("Sorry\n");
exit(2);
}
ok:
newgid = pwd->pw_gid;
newuid = pwd->pw_uid;
log(SULOG,nptr,1);
endpwent();
setgid(newgid);
setuid(newuid);
if (pwd->pw_shell && *pwd->pw_shell)
shell = pwd->pw_shell;
if (newuid == 0)
for (p=environ; *p; p++) {
if (strncmp("PS1=", *p, 4) == 0)
*p = "PS1=# ";
else if (strncmp("PATH=", *p, 5) == 0)
*p = "PATH=/bin:/usr/bin:/etc";
}
execl(shell, "su", "-p", 0);
printf("No shell\n");
exit(3);
}
log(where, towho, how)
char *where, *towho;
int how;
{
int catch();
FILE *logf;
long now, time();
char *cuserid(), *strrchr();
char *ttyn, *ttyname();
struct tm *tmp, *localtime();
if((ttyn=ttyname(0))==NULL)
if((ttyn=ttyname(1))==NULL)
if((ttyn=ttyname(2))==NULL)
if((ttyn=ttyname(3))==NULL)
ttyn="/dev/tty??";
now = time((long *)0);
tmp = localtime(&now);
signal(SIGALRM, catch);
alarm(5);
if((logf=fopen(where,"a")) == NULL) return;
fprintf(logf,"\r\nSU %.2d/%.2d %.2d:%.2d %c %s %s-%s\r\n",
tmp->tm_mon+1,tmp->tm_mday,tmp->tm_hour,tmp->tm_min,
how?'+':'-',(strrchr(ttyn,'/')+1),cuserid((char *)0),towho);
fclose(logf);
alarm(0);
}
char *cuserid(x)
char *x;
{
struct passwd *getpwuid();
return getpwuid(getuid())->pw_name;
}
catch(){}