xref: /csrg-svn/usr.bin/lock/lock.c (revision 33161)
121565Sdist /*
2*33161Sbostic  * Copyright (c) 1980, 1987 Regents of the University of California.
3*33161Sbostic  * All rights reserved.
4*33161Sbostic  *
5*33161Sbostic  * Redistribution and use in source and binary forms are permitted
6*33161Sbostic  * provided that this notice is preserved and that due credit is given
7*33161Sbostic  * to the University of California at Berkeley. The name of the University
8*33161Sbostic  * may not be used to endorse or promote products derived from this
9*33161Sbostic  * software without specific prior written permission. This software
10*33161Sbostic  * is provided ``as is'' without express or implied warranty.
1121565Sdist  */
1221565Sdist 
1312989Ssam #ifndef lint
1421565Sdist char copyright[] =
15*33161Sbostic "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
1621565Sdist  All rights reserved.\n";
17*33161Sbostic #endif /* not lint */
1812989Ssam 
1921565Sdist #ifndef lint
20*33161Sbostic static char sccsid[] = "@(#)lock.c	5.5 (Berkeley) 12/26/87";
21*33161Sbostic #endif /* not lint */
2221565Sdist 
2312989Ssam /*
2430956Sbostic  * Lock a terminal up until the given key is entered, until the root
2530956Sbostic  * password is entered, or the given interval times out.
2616239Sralph  *
2716239Sralph  * Timeout interval is by default TIMEOUT, it can be changed with
2816239Sralph  * an argument of the form -time where time is in minutes
2912989Ssam  */
3016239Sralph 
3130652Sbostic #include <sys/param.h>
325748Sroot #include <sys/stat.h>
3316239Sralph #include <sys/time.h>
3430652Sbostic #include <sys/signal.h>
3530652Sbostic #include <pwd.h>
361041Sbill #include <sgtty.h>
3730652Sbostic #include <stdio.h>
3832615Sbostic #include <ctype.h>
391041Sbill 
4030956Sbostic #define	TIMEOUT	15
4130956Sbostic #define	YES	1
4230956Sbostic #define	NO	0
431041Sbill 
4430652Sbostic int	quit(), bye(), hi();
4516239Sralph 
4630652Sbostic struct timeval	timeout;
4730652Sbostic struct timeval	zerotime;
4816239Sralph struct sgttyb	tty, ntty;
4930956Sbostic long	nexttime;			/* keep the timeout time */
5016239Sralph 
5130956Sbostic /*ARGSUSED*/
5230956Sbostic main(argc, argv)
5330652Sbostic 	int	argc;
5430652Sbostic 	char	**argv;
551041Sbill {
5630956Sbostic 	struct passwd	*root_pwd, *my_pwd;
5716239Sralph 	struct timeval	timval;
5816239Sralph 	struct itimerval	ntimer, otimer;
5916239Sralph 	struct tm	*timp;
6030956Sbostic 	int	sectimeout = TIMEOUT,
6130956Sbostic 		use_mine;
6230652Sbostic 	char	*ttynam, *ap, *tzn,
6330956Sbostic 		hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ],
6430652Sbostic 		*crypt(), *index(), *ttyname();
651041Sbill 
6630956Sbostic 	use_mine = NO;
6730956Sbostic 	for (++argv; *argv; ++argv) {
6830956Sbostic 		if (argv[0][0] != '-')
6930956Sbostic 			usage();
7030956Sbostic 		if (argv[0][1] == 'p')
7130956Sbostic 			use_mine = YES;
7232615Sbostic 		else if (!isdigit(argv[0][1])) {
7332615Sbostic 			fprintf(stderr, "lock: illegal option -- %c\n", argv[0][1]);
7432615Sbostic 			usage();
7532615Sbostic 		}
7630956Sbostic 		else if ((sectimeout = atoi(*argv + 1)) <= 0)
7730956Sbostic 			usage();
7816239Sralph 	}
7916239Sralph 	timeout.tv_sec = sectimeout * 60;
8016239Sralph 
8116239Sralph 	/* get information for header */
8212989Ssam 	if (ioctl(0, TIOCGETP, &tty))
831041Sbill 		exit(1);
8416239Sralph 	gethostname(hostname, sizeof(hostname));
8530652Sbostic 	if (!(ttynam = ttyname(0))) {
8630652Sbostic 		puts("lock: not a terminal?");
8730956Sbostic 		exit(1);
8816239Sralph 	}
8930652Sbostic 	if (gettimeofday(&timval, (struct timezone *)NULL)) {
9030652Sbostic 		perror("gettimeofday");
9130956Sbostic 		exit(1);
9230652Sbostic 	}
9316239Sralph 	nexttime = timval.tv_sec + (sectimeout * 60);
9416239Sralph 	timp = localtime(&timval.tv_sec);
9516239Sralph 	ap = asctime(timp);
9630652Sbostic 	tzn = timp->tm_zone;
9716239Sralph 
9830652Sbostic 	(void)signal(SIGINT, quit);
9930652Sbostic 	(void)signal(SIGQUIT, quit);
1001041Sbill 	ntty = tty; ntty.sg_flags &= ~ECHO;
10130652Sbostic 	(void)ioctl(0, TIOCSETP, &ntty);
10230652Sbostic 
10330956Sbostic 	if (!use_mine) {
10430956Sbostic 		/* get key and check again */
10530956Sbostic 		fputs("Key: ", stdout);
10630956Sbostic 		if (!gets(s, sizeof(s)))
10730956Sbostic 			quit();
10830956Sbostic 		fputs("\nAgain: ", stdout);
10930956Sbostic 		/*
11030956Sbostic 		 * Don't need EOF test here, if we get EOF, then s1 != s
11130956Sbostic 		 * and the right things will happen.
11230956Sbostic 		 */
11330956Sbostic 		(void)gets(s1, sizeof(s1));
11430956Sbostic 		putchar('\n');
11530956Sbostic 		if (strcmp(s1, s)) {
11630956Sbostic 			puts("\07lock: passwords didn't match.");
11730956Sbostic 			ioctl(0, TIOCSETP, &tty);
11830956Sbostic 			exit(1);
11930956Sbostic 		}
12030956Sbostic 		s[0] = NULL;
1211041Sbill 	}
12216239Sralph 
12330956Sbostic 	/* set signal handlers */
12430652Sbostic 	(void)signal(SIGINT, hi);
12530652Sbostic 	(void)signal(SIGQUIT, hi);
12630652Sbostic 	(void)signal(SIGTSTP, hi);
12730652Sbostic 	(void)signal(SIGALRM, bye);
12830652Sbostic 
12916239Sralph 	ntimer.it_interval = zerotime;
13016239Sralph 	ntimer.it_value = timeout;
13116239Sralph 	setitimer(ITIMER_REAL, &ntimer, &otimer);
13216239Sralph 
13330956Sbostic 	/* header info */
13430652Sbostic 	printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
13530956Sbostic 		ttynam, hostname, sectimeout, ap, tzn, ap + 19);
13616239Sralph 
13716239Sralph 	/* wait */
13830956Sbostic 	root_pwd = getpwuid(0);
13930956Sbostic 	if (use_mine)
14030956Sbostic 		my_pwd = getpwuid(getuid());
14130956Sbostic 	for (;;) {
14230956Sbostic 		fputs("Key: ", stdout);
14330956Sbostic 		if (!gets(s, sizeof(s))) {
14416599Skre 			clearerr(stdin);
14516599Skre 			hi();
14616599Skre 			continue;
14716599Skre 		}
14830956Sbostic 		if (use_mine) {
14930956Sbostic 			if (!my_pwd || !*my_pwd->pw_passwd || !strcmp(my_pwd->pw_passwd, crypt(s, my_pwd->pw_passwd)))
15030956Sbostic 				break;
15130956Sbostic 		}
15230956Sbostic 		else if (!strcmp(s1, s))
1531041Sbill 			break;
15430956Sbostic 		if (!root_pwd || !*root_pwd->pw_passwd || !strcmp(root_pwd->pw_passwd, crypt(s, root_pwd->pw_passwd)))
15530956Sbostic 			break;
15630652Sbostic 		puts("\07");
15712989Ssam 		if (ioctl(0, TIOCGETP, &ntty))
1581041Sbill 			exit(1);
1591041Sbill 	}
16016239Sralph 	putchar('\n');
16130652Sbostic 	quit();
1621041Sbill }
16316239Sralph 
16430652Sbostic static
16530652Sbostic hi()
16630652Sbostic {
16730652Sbostic 	struct timeval	timval;
16830652Sbostic 
16930652Sbostic 	if (!gettimeofday(&timval, (struct timezone *)NULL))
17030956Sbostic 	    printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n",
17130956Sbostic 	    (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60);
17230652Sbostic }
17330652Sbostic 
17430652Sbostic static
17516239Sralph quit()
17616239Sralph {
17730652Sbostic 	(void)ioctl(0, TIOCSETP, &tty);
17830956Sbostic 	exit(0);
17916239Sralph }
18016239Sralph 
18130652Sbostic static
18216239Sralph bye()
18316239Sralph {
18430652Sbostic 	(void)ioctl(0, TIOCSETP, &tty);
18530652Sbostic 	puts("lock: timeout");
18630956Sbostic 	exit(1);
18716239Sralph }
18830956Sbostic 
18930956Sbostic static
19030956Sbostic usage()
19130956Sbostic {
19232615Sbostic 	fputs("usage: lock [-p] [-timeout]\n", stderr);
19330956Sbostic 	exit(1);
19430956Sbostic }
195