V10/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>

struct	passwd *pwd,*getpwnam();
char	*crypt();
char	*getpass();
char	**environ;
char *name = "root";
char *shell = "/bin/sh";
char *sulog = "/dev/console";

main(argc,argv)
int	argc;
char	**argv;
{
	register char **p;
	char *password;
	int newgid, newuid;
	if(argv[0][0] != '/'){
		fprintf(stderr, "su must be invoked with a full path\n");
		exit(1);
	}

	if(argc > 1)
		name = argv[1];
	if((pwd=getpwnam(name)) == NULL) {
		printf("Unknown id: %s\n",name);
		exit(1);
	}
	if(pwd->pw_passwd[0] != '\0' && getuid() != 0) {
		password = getpass("Password:");
		if(strcmp(pwd->pw_passwd,crypt(password,pwd->pw_passwd))!=0) {
			logit(sulog,0);
			printf("Sorry\n");
			exit(2);
		}
	}

	newgid = pwd->pw_gid;
	newuid = pwd->pw_uid;
	logit(sulog,1);
	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);
	perror(shell);
	exit(3);
}
logit(logfile,how)
char *logfile;
{
	int catch();
	long now, time();
	char *cuserid(), *strrchr();
	char *ttyn, *ttyname();
	FILE *logf = fopen(logfile,"a");
	struct tm *tmp, *localtime();

	if(logf == NULL) return;
	if((ttyn=ttyname(3))==NULL)
		ttyn="/dev/tty??";
	now = time((long *)0);
	tmp = localtime(&now);
	signal(SIGALRM, catch);
	alarm(5);
	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(),name);
	fclose(logf);
	alarm(0);
}
char *cuserid()
{
	static char s[20];
	struct passwd *getpwuid();
	int uid = getuid();
	struct passwd *pwd = getpwuid(uid);

	if(pwd && pwd->pw_name && *pwd->pw_name)
		return pwd->pw_name;
	sprintf(s, "%d", uid);
	return s;
}
catch(){}