4.1cBSD/usr/src/bin/su.c

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

#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;
		}
	}
}