xref: /csrg-svn/usr.bin/login/login.c.1 (revision 32313)
119843Sdist/*
231695Skarels * Copyright (c) 1980,1987 Regents of the University of California.
319843Sdist * All rights reserved.  The Berkeley software License Agreement
419843Sdist * specifies the terms and conditions for redistribution.
519843Sdist */
619843Sdist
712678Ssam#ifndef lint
819843Sdistchar copyright[] =
919843Sdist"@(#) Copyright (c) 1980 Regents of the University of California.\n\
1019843Sdist All rights reserved.\n";
1119843Sdist#endif not lint
1212678Ssam
1319843Sdist#ifndef lint
14*32313Sbosticstatic char sccsid[] = "@(#)login.c.1	5.20 (Berkeley) 10/01/87";
1519843Sdist#endif not lint
1619843Sdist
171043Sbill/*
181043Sbill * login [ name ]
1931695Skarels * login -r hostname	(for rlogind)
2031695Skarels * login -h hostname	(for telnetd, etc.)
2131695Skarels * login -f name	(for pre-authenticated login: datakit, xterm, etc.)
221043Sbill */
231043Sbill
2412984Ssam#include <sys/param.h>
2512687Ssam#include <sys/quota.h>
2612687Ssam#include <sys/stat.h>
2712687Ssam#include <sys/time.h>
2812687Ssam#include <sys/resource.h>
2916453Sroot#include <sys/file.h>
3012687Ssam
311043Sbill#include <sgtty.h>
321043Sbill#include <utmp.h>
331043Sbill#include <signal.h>
341043Sbill#include <pwd.h>
351043Sbill#include <stdio.h>
361043Sbill#include <lastlog.h>
3712678Ssam#include <errno.h>
3816453Sroot#include <ttyent.h>
3916453Sroot#include <syslog.h>
4026862Smckusick#include <grp.h>
411043Sbill
4227056Skarels#define TTYGRPNAME	"tty"		/* name of group to own ttys */
4327056Skarels#define TTYGID(gid)	tty_gid(gid)	/* gid that owns all ttys */
4426862Smckusick
4516453Sroot#define	SCMPN(a, b)	strncmp(a, b, sizeof(a))
462822Swnj#define	SCPYN(a, b)	strncpy(a, b, sizeof(a))
472822Swnj
486197Sroot#define NMAX	sizeof(utmp.ut_name)
4925230Smckusick#define HMAX	sizeof(utmp.ut_host)
501043Sbill
512822Swnj#define	FALSE	0
522822Swnj#define	TRUE	-1
532822Swnj
542822Swnjchar	nolog[] =	"/etc/nologin";
552822Swnjchar	qlog[]  =	".hushlogin";
561043Sbillchar	maildir[30] =	"/usr/spool/mail/";
571043Sbillchar	lastlog[] =	"/usr/adm/lastlog";
589867Ssamstruct	passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" };
591043Sbillstruct	sgttyb ttyb;
601043Sbillstruct	utmp utmp;
611043Sbillchar	minusnam[16] = "-";
6230606Sbosticchar	*envinit[1];			/* now set by setenv calls */
6312687Ssam/*
6412687Ssam * This bounds the time given to login.  We initialize it here
6512687Ssam * so it can be patched on machines where it's too small.
6612687Ssam */
6731509Sbosticint	timeout = 300;
686005Swnj
6918549Ssamchar	term[64];
706005Swnj
711043Sbillstruct	passwd *pwd;
7230606Sbosticchar	*strcat(), *rindex(), *index();
7312687Ssamint	timedout();
741043Sbillchar	*ttyname();
751043Sbillchar	*crypt();
761043Sbillchar	*getpass();
771043Sbillchar	*stypeof();
7812678Ssamextern	int errno;
791043Sbill
8013074Ssamstruct	tchars tc = {
8113074Ssam	CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
821365Sbill};
8313074Ssamstruct	ltchars ltc = {
8413074Ssam	CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
8513074Ssam};
861365Sbill
8718549Ssamstruct winsize win = { 0, 0, 0, 0 };
8818549Ssam
896005Swnjint	rflag;
9024712Sbloomint	usererr = -1;
916197Srootchar	rusername[NMAX+1], lusername[NMAX+1];
926005Swnjchar	rpassword[NMAX+1];
936878Smckusickchar	name[NMAX+1];
9429992Skarelschar	me[MAXHOSTNAMELEN];
956197Srootchar	*rhost;
966005Swnj
971043Sbillmain(argc, argv)
9812687Ssam	char *argv[];
991043Sbill{
10030606Sbostic	extern	char **environ;
1011043Sbill	register char *namep;
10231695Skarels	int pflag = 0, hflag = 0, fflag = 0, t, f, c;
10312687Ssam	int invalid, quietlog;
1042822Swnj	FILE *nlfd;
10516453Sroot	char *ttyn, *tty;
10618549Ssam	int ldisc = 0, zero = 0, i;
10729992Skarels	char *p, *domain, *index();
1081043Sbill
10912687Ssam	signal(SIGALRM, timedout);
11012687Ssam	alarm(timeout);
1111043Sbill	signal(SIGQUIT, SIG_IGN);
1121043Sbill	signal(SIGINT, SIG_IGN);
11312687Ssam	setpriority(PRIO_PROCESS, 0, 0);
11412678Ssam	quota(Q_SETUID, 0, 0, 0);
11512687Ssam	/*
11618549Ssam	 * -p is used by getty to tell login not to destroy the environment
11712687Ssam	 * -r is used by rlogind to cause the autologin protocol;
11831695Skarels 	 * -f is used to skip a second login authentication
11912687Ssam	 * -h is used by other servers to pass the name of the
12012687Ssam	 * remote host to login so that it may be placed in utmp and wtmp
12112687Ssam	 */
12229992Skarels	(void) gethostname(me, sizeof(me));
12329992Skarels	domain = index(me, '.');
12424712Sbloom	while (argc > 1) {
12512687Ssam		if (strcmp(argv[1], "-r") == 0) {
12631695Skarels			if (rflag || hflag || fflag) {
12731695Skarels				printf("Other options not allowed with -r\n");
12824712Sbloom				exit(1);
12924712Sbloom			}
130*32313Sbostic			if (argv[2] == 0)
131*32313Sbostic				exit(1);
13224712Sbloom			rflag = 1;
13324712Sbloom			usererr = doremotelogin(argv[2]);
13429992Skarels			if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0)
13529992Skarels				*p = 0;
13612687Ssam			SCPYN(utmp.ut_host, argv[2]);
13724712Sbloom			argc -= 2;
13824712Sbloom			argv += 2;
13924712Sbloom			continue;
1406197Sroot		}
14131695Skarels		if (strcmp(argv[1], "-h") == 0) {
14231695Skarels			if (getuid() == 0) {
14331695Skarels				if (rflag || hflag) {
14431695Skarels				    printf("Only one of -r and -h allowed\n");
14531695Skarels				    exit(1);
14631695Skarels				}
14731695Skarels				hflag = 1;
14831695Skarels				if ((p = index(argv[2], '.')) &&
14931695Skarels				    strcmp(p, domain) == 0)
15031695Skarels					*p = 0;
15131695Skarels				SCPYN(utmp.ut_host, argv[2]);
15231695Skarels			}
15331695Skarels			argc -= 2;
15431695Skarels			argv += 2;
15531695Skarels			continue;
15631695Skarels		}
15731695Skarels		if (strcmp(argv[1], "-f") == 0 && argc > 2) {
15831695Skarels			if (rflag) {
15931695Skarels				printf("Only one of -r and -f allowed\n");
16024712Sbloom				exit(1);
16124712Sbloom			}
16231695Skarels			fflag = 1;
16331695Skarels			SCPYN(utmp.ut_name, argv[2]);
16424712Sbloom			argc -= 2;
16524712Sbloom			argv += 2;
16624712Sbloom			continue;
1676197Sroot		}
16818549Ssam		if (strcmp(argv[1], "-p") == 0) {
16918549Ssam			argc--;
17018549Ssam			argv++;
17118549Ssam			pflag = 1;
17224712Sbloom			continue;
17318549Ssam		}
17424712Sbloom		break;
1756005Swnj	}
17613074Ssam	ioctl(0, TIOCLSET, &zero);
1771547Sbill	ioctl(0, TIOCNXCL, 0);
1786329Swnj	ioctl(0, FIONBIO, &zero);
1796329Swnj	ioctl(0, FIOASYNC, &zero);
18013074Ssam	ioctl(0, TIOCGETP, &ttyb);
18112687Ssam	/*
18212687Ssam	 * If talking to an rlogin process,
18312687Ssam	 * propagate the terminal type and
18412687Ssam	 * baud rate across the network.
18512687Ssam	 */
18612687Ssam	if (rflag)
18712687Ssam		doremoteterm(term, &ttyb);
18826482Skarels	ttyb.sg_erase = CERASE;
18926482Skarels	ttyb.sg_kill = CKILL;
19013074Ssam	ioctl(0, TIOCSLTC, &ltc);
19113074Ssam	ioctl(0, TIOCSETC, &tc);
19213074Ssam	ioctl(0, TIOCSETP, &ttyb);
19324849Smckusick	for (t = getdtablesize(); t > 2; t--)
1941043Sbill		close(t);
1951043Sbill	ttyn = ttyname(0);
19625426Sbloom	if (ttyn == (char *)0 || *ttyn == '\0')
1971043Sbill		ttyn = "/dev/tty??";
19816453Sroot	tty = rindex(ttyn, '/');
19916453Sroot	if (tty == NULL)
20016453Sroot		tty = ttyn;
20116453Sroot	else
20216453Sroot		tty++;
20324852Seric	openlog("login", LOG_ODELAY, LOG_AUTH);
20416453Sroot	t = 0;
20525163Sbloom	invalid = FALSE;
2062822Swnj	do {
2072822Swnj		ldisc = 0;
2082822Swnj		ioctl(0, TIOCSETD, &ldisc);
20931695Skarels		if (fflag == 0)
21031695Skarels			SCPYN(utmp.ut_name, "");
21112687Ssam		/*
21212687Ssam		 * Name specified, take it.
21312687Ssam		 */
21412687Ssam		if (argc > 1) {
2152822Swnj			SCPYN(utmp.ut_name, argv[1]);
2162822Swnj			argc = 0;
2171043Sbill		}
21812687Ssam		/*
21912687Ssam		 * If remote login take given name,
22012687Ssam		 * otherwise prompt user for something.
22112687Ssam		 */
22225163Sbloom		if (rflag && !invalid)
2239867Ssam			SCPYN(utmp.ut_name, lusername);
224*32313Sbostic		else {
22512687Ssam			getloginname(&utmp);
226*32313Sbostic			if (utmp.ut_name[0] == '-') {
227*32313Sbostic				puts("login names may not start with '-'.");
228*32313Sbostic				invalid = TRUE;
229*32313Sbostic				continue;
230*32313Sbostic			}
231*32313Sbostic		}
23225163Sbloom		invalid = FALSE;
2332822Swnj		if (!strcmp(pwd->pw_shell, "/bin/csh")) {
2342822Swnj			ldisc = NTTYDISC;
2352822Swnj			ioctl(0, TIOCSETD, &ldisc);
2362822Swnj		}
23731695Skarels		if (fflag) {
23831695Skarels			int uid = getuid();
23931695Skarels
24031695Skarels			if (uid != 0 && uid != pwd->pw_uid)
24131695Skarels				fflag = 0;
24231695Skarels			/*
24331695Skarels			 * Disallow automatic login for root.
24431695Skarels			 */
24531695Skarels			if (pwd->pw_uid == 0)
24631695Skarels				fflag = 0;
24731695Skarels		}
24812687Ssam		/*
24912687Ssam		 * If no remote login authentication and
25012687Ssam		 * a password exists for this user, prompt
25112687Ssam		 * for one and verify it.
25212687Ssam		 */
25331695Skarels		if (usererr == -1 && fflag == 0 && *pwd->pw_passwd != '\0') {
25412687Ssam			char *pp;
25512687Ssam
25612687Ssam			setpriority(PRIO_PROCESS, 0, -4);
25712687Ssam			pp = getpass("Password:");
25812687Ssam			namep = crypt(pp, pwd->pw_passwd);
25912687Ssam			setpriority(PRIO_PROCESS, 0, 0);
26012687Ssam			if (strcmp(namep, pwd->pw_passwd))
26112687Ssam				invalid = TRUE;
2622822Swnj		}
26312687Ssam		/*
26412687Ssam		 * If user not super-user, check for logins disabled.
26512687Ssam		 */
2662822Swnj		if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) {
2672822Swnj			while ((c = getc(nlfd)) != EOF)
2682822Swnj				putchar(c);
2692822Swnj			fflush(stdout);
2702822Swnj			sleep(5);
2712822Swnj			exit(0);
2722822Swnj		}
27312687Ssam		/*
27412687Ssam		 * If valid so far and root is logging in,
27512687Ssam		 * see if root logins on this terminal are permitted.
27612687Ssam		 */
27716453Sroot		if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) {
27825230Smckusick			if (utmp.ut_host[0])
27925230Smckusick				syslog(LOG_CRIT,
28025230Smckusick				    "ROOT LOGIN REFUSED ON %s FROM %.*s",
28125230Smckusick				    tty, HMAX, utmp.ut_host);
28225230Smckusick			else
28325230Smckusick				syslog(LOG_CRIT,
28425230Smckusick				    "ROOT LOGIN REFUSED ON %s", tty);
2852822Swnj			invalid = TRUE;
2862822Swnj		}
2872822Swnj		if (invalid) {
2881043Sbill			printf("Login incorrect\n");
28916453Sroot			if (++t >= 5) {
29025230Smckusick				if (utmp.ut_host[0])
29131695Skarels					syslog(LOG_ERR,
29231695Skarels			    "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
29325230Smckusick					    tty, HMAX, utmp.ut_host,
29425230Smckusick					    NMAX, utmp.ut_name);
29525230Smckusick				else
29631695Skarels					syslog(LOG_ERR,
29731695Skarels				    "REPEATED LOGIN FAILURES ON %s, %.*s",
29825230Smckusick						tty, NMAX, utmp.ut_name);
29916453Sroot				ioctl(0, TIOCHPCL, (struct sgttyb *) 0);
30018549Ssam				close(0), close(1), close(2);
30116453Sroot				sleep(10);
30216453Sroot				exit(1);
30316453Sroot			}
3041043Sbill		}
3052822Swnj		if (*pwd->pw_shell == '\0')
3062822Swnj			pwd->pw_shell = "/bin/sh";
3072822Swnj		if (chdir(pwd->pw_dir) < 0 && !invalid ) {
3082822Swnj			if (chdir("/") < 0) {
3092822Swnj				printf("No directory!\n");
3102822Swnj				invalid = TRUE;
3112822Swnj			} else {
31212687Ssam				printf("No directory! %s\n",
31312687Ssam				   "Logging in with home=/");
3142822Swnj				pwd->pw_dir = "/";
3152822Swnj			}
3161043Sbill		}
31712687Ssam		/*
31812687Ssam		 * Remote login invalid must have been because
31912687Ssam		 * of a restriction of some sort, no extra chances.
32012687Ssam		 */
32124712Sbloom		if (!usererr && invalid)
3226005Swnj			exit(1);
3232822Swnj	} while (invalid);
32412687Ssam/* committed to login turn off timeout */
32512687Ssam	alarm(0);
3261043Sbill
32721083Smckusick	if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
32812678Ssam		if (errno == EUSERS)
32912678Ssam			printf("%s.\n%s.\n",
33012678Ssam			   "Too many users logged on already",
33112678Ssam			   "Try again later");
33212678Ssam		else if (errno == EPROCLIM)
33312678Ssam			printf("You have too many processes running.\n");
33412678Ssam		else
33517664Sserge			perror("quota (Q_SETUID)");
33612678Ssam		sleep(5);
33712678Ssam		exit(0);
33812678Ssam	}
3391043Sbill	time(&utmp.ut_time);
3401043Sbill	t = ttyslot();
34116453Sroot	if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) {
3421043Sbill		lseek(f, (long)(t*sizeof(utmp)), 0);
34316453Sroot		SCPYN(utmp.ut_line, tty);
3441043Sbill		write(f, (char *)&utmp, sizeof(utmp));
3451043Sbill		close(f);
3461043Sbill	}
34716453Sroot	if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) {
3481043Sbill		write(f, (char *)&utmp, sizeof(utmp));
3491043Sbill		close(f);
3501043Sbill	}
35116453Sroot	quietlog = access(qlog, F_OK) == 0;
35216453Sroot	if ((f = open(lastlog, O_RDWR)) >= 0) {
3532822Swnj		struct lastlog ll;
3542822Swnj
3552822Swnj		lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
3562822Swnj		if (read(f, (char *) &ll, sizeof ll) == sizeof ll &&
35712687Ssam		    ll.ll_time != 0 && !quietlog) {
35812687Ssam			printf("Last login: %.*s ",
35912687Ssam			    24-5, (char *)ctime(&ll.ll_time));
36012687Ssam			if (*ll.ll_host != '\0')
36112687Ssam				printf("from %.*s\n",
36212687Ssam				    sizeof (ll.ll_host), ll.ll_host);
36312687Ssam			else
36412687Ssam				printf("on %.*s\n",
36512687Ssam				    sizeof (ll.ll_line), ll.ll_line);
3662822Swnj		}
3672822Swnj		lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
3682822Swnj		time(&ll.ll_time);
36916453Sroot		SCPYN(ll.ll_line, tty);
37012687Ssam		SCPYN(ll.ll_host, utmp.ut_host);
3712822Swnj		write(f, (char *) &ll, sizeof ll);
3722822Swnj		close(f);
3732822Swnj	}
37427056Skarels	chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid));
37524849Smckusick	if (!hflag && !rflag)					/* XXX */
37618549Ssam		ioctl(0, TIOCSWINSZ, &win);
37726862Smckusick	chmod(ttyn, 0620);
3781043Sbill	setgid(pwd->pw_gid);
3796878Smckusick	strncpy(name, utmp.ut_name, NMAX);
3806878Smckusick	name[NMAX] = '\0';
3819224Ssam	initgroups(name, pwd->pw_gid);
38212678Ssam	quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
3831043Sbill	setuid(pwd->pw_uid);
38430606Sbostic
38518549Ssam	/* destroy environment unless user has asked to preserve it */
38618549Ssam	if (!pflag)
38718549Ssam		environ = envinit;
38830606Sbostic	setenv("HOME", pwd->pw_dir, 1);
38930606Sbostic	setenv("SHELL", pwd->pw_shell, 1);
39018549Ssam	if (term[0] == '\0')
39118549Ssam		strncpy(term, stypeof(tty), sizeof(term));
39230606Sbostic	setenv("TERM", term, 0);
39330606Sbostic	setenv("USER", pwd->pw_name, 1);
39430606Sbostic	setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0);
39518549Ssam
3961043Sbill	if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
3971043Sbill		namep = pwd->pw_shell;
3981043Sbill	else
3991043Sbill		namep++;
4001043Sbill	strcat(minusnam, namep);
40116453Sroot	if (tty[sizeof("tty")-1] == 'd')
40218549Ssam		syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
40318549Ssam	if (pwd->pw_uid == 0)
40425230Smckusick		if (utmp.ut_host[0])
40525230Smckusick			syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
40625230Smckusick			    tty, HMAX, utmp.ut_host);
40725230Smckusick		else
40825230Smckusick			syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
4096329Swnj	if (!quietlog) {
41017664Sserge		struct stat st;
41118549Ssam
4122822Swnj		showmotd();
4132822Swnj		strcat(maildir, pwd->pw_name);
41417664Sserge		if (stat(maildir, &st) == 0 && st.st_size != 0)
41517664Sserge			printf("You have %smail.\n",
41618549Ssam				(st.st_mtime > st.st_atime) ? "new " : "");
4172822Swnj	}
41812687Ssam	signal(SIGALRM, SIG_DFL);
4191043Sbill	signal(SIGQUIT, SIG_DFL);
4201043Sbill	signal(SIGINT, SIG_DFL);
4213935Sroot	signal(SIGTSTP, SIG_IGN);
4221043Sbill	execlp(pwd->pw_shell, minusnam, 0);
4232822Swnj	perror(pwd->pw_shell);
4241043Sbill	printf("No shell\n");
4251043Sbill	exit(0);
4261043Sbill}
4271043Sbill
42812687Ssamgetloginname(up)
42912687Ssam	register struct utmp *up;
43012687Ssam{
43112687Ssam	register char *namep;
43212712Ssam	char c;
43312687Ssam
43412687Ssam	while (up->ut_name[0] == '\0') {
43514897Sedward		namep = up->ut_name;
43612712Ssam		printf("login: ");
43712687Ssam		while ((c = getchar()) != '\n') {
43812687Ssam			if (c == ' ')
43912687Ssam				c = '_';
44012687Ssam			if (c == EOF)
44112687Ssam				exit(0);
44212687Ssam			if (namep < up->ut_name+NMAX)
44312687Ssam				*namep++ = c;
44412687Ssam		}
44512687Ssam	}
44614897Sedward	strncpy(lusername, up->ut_name, NMAX);
44714897Sedward	lusername[NMAX] = 0;
44814897Sedward	if ((pwd = getpwnam(lusername)) == NULL)
44912687Ssam		pwd = &nouser;
45012687Ssam}
45112687Ssam
45212687Ssamtimedout()
45312687Ssam{
45412687Ssam
45512687Ssam	printf("Login timed out after %d seconds\n", timeout);
45612687Ssam	exit(0);
45712687Ssam}
45812687Ssam
4591043Sbillint	stopmotd;
4601043Sbillcatch()
4611043Sbill{
4626466Swnj
4631043Sbill	signal(SIGINT, SIG_IGN);
4641043Sbill	stopmotd++;
4651043Sbill}
4661043Sbill
4672822Swnjrootterm(tty)
4686466Swnj	char *tty;
4692822Swnj{
47016453Sroot	register struct ttyent *t;
4712822Swnj
47216453Sroot	if ((t = getttynam(tty)) != NULL) {
47316453Sroot		if (t->ty_status & TTY_SECURE)
47416453Sroot			return (1);
4752822Swnj	}
47616453Sroot	return (0);
4772822Swnj}
4782822Swnj
4791043Sbillshowmotd()
4801043Sbill{
4811043Sbill	FILE *mf;
4821043Sbill	register c;
4831043Sbill
4841043Sbill	signal(SIGINT, catch);
48516453Sroot	if ((mf = fopen("/etc/motd", "r")) != NULL) {
4862822Swnj		while ((c = getc(mf)) != EOF && stopmotd == 0)
4871043Sbill			putchar(c);
4881043Sbill		fclose(mf);
4891043Sbill	}
4901043Sbill	signal(SIGINT, SIG_IGN);
4911043Sbill}
4921043Sbill
4932822Swnj#undef	UNKNOWN
4941043Sbill#define UNKNOWN "su"
4951043Sbill
4961043Sbillchar *
4971043Sbillstypeof(ttyid)
49812687Ssam	char *ttyid;
4991043Sbill{
50016453Sroot	register struct ttyent *t;
5011043Sbill
50216453Sroot	if (ttyid == NULL || (t = getttynam(ttyid)) == NULL)
5031043Sbill		return (UNKNOWN);
50416453Sroot	return (t->ty_type);
5051043Sbill}
5066005Swnj
50712687Ssamdoremotelogin(host)
50812687Ssam	char *host;
50912687Ssam{
51012687Ssam	getstr(rusername, sizeof (rusername), "remuser");
51112687Ssam	getstr(lusername, sizeof (lusername), "locuser");
51218549Ssam	getstr(term, sizeof(term), "Terminal type");
51313470Ssam	if (getuid()) {
51413470Ssam		pwd = &nouser;
51524712Sbloom		return(-1);
51613470Ssam	}
51712687Ssam	pwd = getpwnam(lusername);
51813470Ssam	if (pwd == NULL) {
51913470Ssam		pwd = &nouser;
52024712Sbloom		return(-1);
52113470Ssam	}
52224712Sbloom	return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername));
52312687Ssam}
52412687Ssam
5256005Swnjgetstr(buf, cnt, err)
5266005Swnj	char *buf;
5276005Swnj	int cnt;
5286005Swnj	char *err;
5296005Swnj{
5306005Swnj	char c;
5316005Swnj
5326005Swnj	do {
5336005Swnj		if (read(0, &c, 1) != 1)
5346005Swnj			exit(1);
5356005Swnj		if (--cnt < 0) {
5366005Swnj			printf("%s too long\r\n", err);
5376005Swnj			exit(1);
5386005Swnj		}
5396005Swnj		*buf++ = c;
5406005Swnj	} while (c != 0);
5416005Swnj}
5426329Swnj
54312687Ssamchar	*speeds[] =
54412687Ssam    { "0", "50", "75", "110", "134", "150", "200", "300",
54512687Ssam      "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
54612687Ssam#define	NSPEEDS	(sizeof (speeds) / sizeof (speeds[0]))
54712687Ssam
54812687Ssamdoremoteterm(term, tp)
54912687Ssam	char *term;
55012687Ssam	struct sgttyb *tp;
55112687Ssam{
55218549Ssam	register char *cp = index(term, '/'), **cpp;
55318549Ssam	char *speed;
55412687Ssam
55512687Ssam	if (cp) {
55618549Ssam		*cp++ = '\0';
55718549Ssam		speed = cp;
55818549Ssam		cp = index(speed, '/');
55918549Ssam		if (cp)
56018549Ssam			*cp++ = '\0';
56118549Ssam		for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
56218549Ssam			if (strcmp(*cpp, speed) == 0) {
56318549Ssam				tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
56412687Ssam				break;
56512687Ssam			}
56612687Ssam	}
56712687Ssam	tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
56812687Ssam}
56918549Ssam
57027056Skarelstty_gid(default_gid)
57126876Smckusick	int default_gid;
57226862Smckusick{
57326862Smckusick	struct group *getgrnam(), *gr;
57426876Smckusick	int gid = default_gid;
57526862Smckusick
57627056Skarels	gr = getgrnam(TTYGRPNAME);
57726862Smckusick	if (gr != (struct group *) 0)
57826862Smckusick		gid = gr->gr_gid;
57926862Smckusick
58026862Smckusick	endgrent();
58126862Smckusick
58226876Smckusick	return (gid);
58326862Smckusick}
584