xref: /csrg-svn/usr.bin/login/login.c.1 (revision 2106)
1*2106Srootstatic	char *sccsid = "@(#)login.c.1	4.8 (Berkeley) 01/10/81";
21043Sbill/*
31043Sbill * login [ name ]
41043Sbill */
51043Sbill
61043Sbill#include <sys/types.h>
71043Sbill#include <sgtty.h>
81043Sbill#include <utmp.h>
91043Sbill#include <signal.h>
101043Sbill#include <pwd.h>
111043Sbill#include <stdio.h>
121043Sbill#include <sys/stat.h>
131043Sbill#include <lastlog.h>
141804Sbill#include <whoami.h>
151043Sbill#define SCPYN(a, b)	strncpy(a, b, sizeof(a))
161043Sbill
171043Sbill#define NMAX sizeof(utmp.ut_name)
181043Sbill#define LMAX sizeof(utmp.ut_line)
191043Sbill
201043Sbillchar	user[20];
211043Sbillchar	maildir[30] =	"/usr/spool/mail/";
221043Sbillchar	lastlog[] =	"/usr/adm/lastlog";
231043Sbillstruct	passwd nouser = {"", "nope"};
241043Sbillstruct	sgttyb ttyb;
251043Sbillstruct	utmp utmp;
261043Sbillchar	minusnam[16] = "-";
271043Sbillchar	homedir[64] = "HOME=";
281043Sbillchar	shell[64] = "SHELL=";
291043Sbillchar	term[64] = "TERM=";
301043Sbillchar	*envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0};
311043Sbillstruct	passwd *pwd;
321043Sbill
331043Sbillstruct	passwd *getpwnam();
341043Sbillchar	*strcat();
351043Sbillint	setpwent();
361043Sbillchar	*ttyname();
371043Sbillchar	*crypt();
381043Sbillchar	*getpass();
391043Sbillchar	*rindex();
401043Sbillchar	*stypeof();
411043Sbillextern	char **environ;
421043Sbill
431365Sbill#define	CTRL(c)	('c'&037)
441365Sbill#define	CERASE	'#'
451365Sbill#define	CEOT	CTRL(d)
461365Sbill#define	CKILL	'@'
471365Sbill#define	CQUIT	034		/* FS, cntl shift L */
481365Sbill#define	CINTR	0177		/* DEL */
491365Sbill#define	CSTOP	CTRL(s)
501365Sbill#define	CSTART	CTRL(q)
511365Sbill#define	CBRK	0377
521365Sbillstruct	tchars tc = {
531365Sbill	CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
541365Sbill};
551365Sbillstruct	ltchars ltc = {
561546Sbill	CTRL(z), CTRL(y), CTRL(r), CTRL(o), CTRL(w), CTRL(v)
571365Sbill};
581365Sbill
591043Sbillmain(argc, argv)
601043Sbillchar **argv;
611043Sbill{
621043Sbill	register char *namep;
631043Sbill	int t, f, c;
641043Sbill	char *ttyn;
651043Sbill	int ldisc = 0;
661043Sbill
671043Sbill	alarm(60);
681043Sbill	signal(SIGQUIT, SIG_IGN);
691043Sbill	signal(SIGINT, SIG_IGN);
701043Sbill	nice(-100);
711043Sbill	nice(20);
721043Sbill	nice(0);
731043Sbill	ioctl(0, TIOCLSET, 0);
741547Sbill	ioctl(0, TIOCNXCL, 0);
751043Sbill	gtty(0, &ttyb);
761043Sbill	ttyb.sg_erase = '#';
771043Sbill	ttyb.sg_kill = '@';
781043Sbill	stty(0, &ttyb);
791365Sbill	ioctl(0, TIOCSETC, &tc);
801365Sbill	ioctl(0, TIOCSLTC, &ltc);
811043Sbill	for (t=3; t<20; t++)
821043Sbill		close(t);
831043Sbill	ttyn = ttyname(0);
841043Sbill	if (ttyn==0)
851043Sbill		ttyn = "/dev/tty??";
861043Sbill
871043Sbill    loop:
881547Sbill	ldisc = 0;
891547Sbill	ioctl(0, TIOCSETD, &ldisc);
901043Sbill	SCPYN(utmp.ut_name, "");
911043Sbill	if (argc>1) {
921043Sbill		SCPYN(utmp.ut_name, argv[1]);
931043Sbill		argc = 0;
941043Sbill	}
951043Sbill	while (utmp.ut_name[0] == '\0') {
961043Sbill		namep = utmp.ut_name;
971043Sbill		printf("login: ");
981043Sbill		while ((c = getchar()) != '\n') {
991043Sbill			if(c == ' ')
1001043Sbill				c = '_';
1011043Sbill			if (c == EOF)
1021043Sbill				exit(0);
1031043Sbill			if (namep < utmp.ut_name+NMAX)
1041043Sbill				*namep++ = c;
1051043Sbill		}
1061043Sbill	}
1071043Sbill	setpwent();
1081043Sbill	if ((pwd = getpwnam(utmp.ut_name)) == NULL)
1091043Sbill		pwd = &nouser;
1101043Sbill	endpwent();
1111547Sbill	if (!strcmp(pwd->pw_shell, "/bin/csh")) {
1121547Sbill		ldisc = NTTYDISC;
1131547Sbill		ioctl(0, TIOCSETD, &ldisc);
1141547Sbill	}
1151043Sbill	if (*pwd->pw_passwd != '\0') {
1161547Sbill		nice(-4);
1171043Sbill		namep = crypt(getpass("Password:"),pwd->pw_passwd);
1181547Sbill		nice(4);
1191043Sbill		if (strcmp(namep, pwd->pw_passwd)) {
1201043Sbillbad:
1211043Sbill			printf("Login incorrect\n");
1221043Sbill			if (ttyn[LMAX] == 'd') {
1231043Sbill				FILE *console = fopen("/dev/console", "w");
1241043Sbill				if (console != NULL) {
1251043Sbill					fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name);
1261043Sbill					fclose(console);
1271043Sbill				}
1281043Sbill			}
1291043Sbill			goto loop;
1301043Sbill		}
1311043Sbill	}
1321043Sbill	sprintf(user, "USER=%.*s", NMAX, pwd->pw_name);
1331804Sbill#ifdef ERNIE
1341043Sbill	if (pwd->pw_uid == 0 && ttyn[5] != 'c')
1351043Sbill		goto bad;
1361804Sbill#endif
1371043Sbill	if (ttyn[LMAX] == 'd') {
1381043Sbill		FILE *console = fopen("/dev/console", "w");
1391043Sbill		if (console != NULL) {
1401043Sbill			fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name);
1411043Sbill			fclose(console);
1421043Sbill		}
1431043Sbill	}
1441043Sbill	if((f = open(lastlog, 2)) >= 0) {
1451043Sbill		struct lastlog ll;
1461043Sbill
1471601Smark		lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0);
1481043Sbill		if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) {
1491043Sbill			register char *ep = (char *) ctime(&ll.ll_time);
1501043Sbill			printf("Last login: ");
1511043Sbill			ep[24 - 5] = 0;
1521043Sbill			printf("%s on %.*s\n", ep, LMAX, ll.ll_line);
1531043Sbill		}
1541601Smark		lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0);
1551043Sbill		time(&ll.ll_time);
1561043Sbill		strcpyn(ll.ll_line, ttyn+5, LMAX);
1571043Sbill		write(f, (char *) &ll, sizeof ll);
1581043Sbill		close(f);
1591043Sbill	}
1601043Sbill	if(chdir(pwd->pw_dir) < 0) {
161*2106Sroot	    printf("Logging with home=/\n");
162*2106Sroot	    pwd->pw_dir = "/";
163*2106Sroot	    if(chdir("/") < 0) {
1641043Sbill		printf("No directory\n");
1651043Sbill		goto loop;
1661882Sbill	    }
1671043Sbill	}
1681043Sbill	time(&utmp.ut_time);
1691043Sbill	t = ttyslot();
1701043Sbill	if (t>0 && (f = open("/etc/utmp", 1)) >= 0) {
1711043Sbill		lseek(f, (long)(t*sizeof(utmp)), 0);
1721043Sbill		SCPYN(utmp.ut_line, rindex(ttyn, '/')+1);
1731043Sbill		write(f, (char *)&utmp, sizeof(utmp));
1741043Sbill		close(f);
1751043Sbill	}
1761043Sbill	if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
1771043Sbill		lseek(f, 0L, 2);
1781043Sbill		write(f, (char *)&utmp, sizeof(utmp));
1791043Sbill		close(f);
1801043Sbill	}
1811043Sbill	chown(ttyn, pwd->pw_uid, pwd->pw_gid);
1821043Sbill	setgid(pwd->pw_gid);
1831043Sbill	setuid(pwd->pw_uid);
1841043Sbill	if (*pwd->pw_shell == '\0')
1851043Sbill		pwd->pw_shell = "/bin/sh";
1861043Sbill	environ = envinit;
1871043Sbill	strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
1881043Sbill	strncat(shell, pwd->pw_shell, sizeof(shell)-7);
1891043Sbill	strncat(term, stypeof(ttyn), sizeof(term)-6);
1901043Sbill	if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
1911043Sbill		namep = pwd->pw_shell;
1921043Sbill	else
1931043Sbill		namep++;
1941043Sbill	strcat(minusnam, namep);
1951043Sbill	alarm(0);
1961043Sbill	umask(022);
1971043Sbill	showmotd();
1981043Sbill	strcat(maildir, pwd->pw_name);
1991043Sbill	if(access(maildir,4)==0) {
2001043Sbill		struct stat statb;
2011043Sbill		stat(maildir, &statb);
2021043Sbill		if (statb.st_size)
2031043Sbill			printf("You have mail.\n");
2041043Sbill	}
2051043Sbill	signal(SIGQUIT, SIG_DFL);
2061043Sbill	signal(SIGINT, SIG_DFL);
2071043Sbill	execlp(pwd->pw_shell, minusnam, 0);
2081043Sbill	printf("No shell\n");
2091043Sbill	exit(0);
2101043Sbill}
2111043Sbill
2121043Sbillint	stopmotd;
2131043Sbillcatch()
2141043Sbill{
2151043Sbill	signal(SIGINT, SIG_IGN);
2161043Sbill	stopmotd++;
2171043Sbill}
2181043Sbill
2191043Sbillshowmotd()
2201043Sbill{
2211043Sbill	FILE *mf;
2221043Sbill	register c;
2231043Sbill
2241043Sbill	signal(SIGINT, catch);
2251043Sbill	if((mf = fopen("/etc/motd","r")) != NULL) {
2261043Sbill		while((c = getc(mf)) != EOF && stopmotd == 0)
2271043Sbill			putchar(c);
2281043Sbill		fclose(mf);
2291043Sbill	}
2301043Sbill	signal(SIGINT, SIG_IGN);
2311043Sbill}
2321043Sbill
2331043Sbill#define UNKNOWN "su"
2341043Sbill
2351043Sbillchar *
2361043Sbillstypeof(ttyid)
2371043Sbillchar	*ttyid;
2381043Sbill{
2391043Sbill	static char	typebuf[16];
2401043Sbill	char		buf[50];
2411043Sbill	register FILE	*f;
2421043Sbill	register char	*p, *t, *q;
2431043Sbill
2441043Sbill	if (ttyid == NULL)
2451043Sbill		return (UNKNOWN);
2461043Sbill	f = fopen("/etc/ttytype", "r");
2471043Sbill	if (f == NULL)
2481043Sbill		return (UNKNOWN);
2491043Sbill	/* split off end of name */
2501043Sbill	for (p = q = ttyid; *p != 0; p++)
2511043Sbill		if (*p == '/')
2521043Sbill			q = p + 1;
2531043Sbill
2541043Sbill	/* scan the file */
2551043Sbill	while (fgets(buf, sizeof buf, f) != NULL)
2561043Sbill	{
2571043Sbill		for (t=buf; *t!=' '; t++)
2581043Sbill			;
2591043Sbill		*t++ = 0;
2601043Sbill		for (p=t; *p>' '; p++)
2611043Sbill			;
2621043Sbill		*p = 0;
2631043Sbill		if (strcmp(q,t)==0) {
2641043Sbill			strcpy(typebuf, buf);
2651043Sbill			fclose(f);
2661043Sbill			return (typebuf);
2671043Sbill		}
2681043Sbill	}
2691043Sbill	fclose (f);
2701043Sbill	return (UNKNOWN);
2711043Sbill}
272