V9/cmd/su.c

Compare this file to the similar file:
Show the results in this format:

#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(){}