lock.c revision 1590
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1980, 1987, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * This code is derived from software contributed to Berkeley by 61590Srgrimes * Bob Toxen. 71590Srgrimes * 81590Srgrimes * Redistribution and use in source and binary forms, with or without 91590Srgrimes * modification, are permitted provided that the following conditions 101590Srgrimes * are met: 111590Srgrimes * 1. Redistributions of source code must retain the above copyright 121590Srgrimes * notice, this list of conditions and the following disclaimer. 131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer in the 151590Srgrimes * documentation and/or other materials provided with the distribution. 161590Srgrimes * 3. All advertising materials mentioning features or use of this software 171590Srgrimes * must display the following acknowledgement: 181590Srgrimes * This product includes software developed by the University of 191590Srgrimes * California, Berkeley and its contributors. 201590Srgrimes * 4. Neither the name of the University nor the names of its contributors 211590Srgrimes * may be used to endorse or promote products derived from this software 221590Srgrimes * without specific prior written permission. 231590Srgrimes * 241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341590Srgrimes * SUCH DAMAGE. 351590Srgrimes */ 361590Srgrimes 371590Srgrimes#ifndef lint 381590Srgrimesstatic char copyright[] = 391590Srgrimes"@(#) Copyright (c) 1980, 1987, 1993\n\ 401590Srgrimes The Regents of the University of California. All rights reserved.\n"; 411590Srgrimes#endif /* not lint */ 421590Srgrimes 431590Srgrimes#ifndef lint 441590Srgrimesstatic char sccsid[] = "@(#)lock.c 8.1 (Berkeley) 6/6/93"; 451590Srgrimes#endif /* not lint */ 461590Srgrimes 471590Srgrimes/* 481590Srgrimes * Lock a terminal up until the given key is entered, until the root 491590Srgrimes * password is entered, or the given interval times out. 501590Srgrimes * 511590Srgrimes * Timeout interval is by default TIMEOUT, it can be changed with 521590Srgrimes * an argument of the form -time where time is in minutes 531590Srgrimes */ 541590Srgrimes 551590Srgrimes#include <sys/param.h> 561590Srgrimes#include <sys/stat.h> 571590Srgrimes#include <sys/time.h> 581590Srgrimes#include <sys/signal.h> 591590Srgrimes#include <sgtty.h> 601590Srgrimes#include <pwd.h> 611590Srgrimes#include <stdio.h> 621590Srgrimes#include <ctype.h> 631590Srgrimes#include <string.h> 641590Srgrimes 651590Srgrimes#define TIMEOUT 15 661590Srgrimes 671590Srgrimesvoid quit(), bye(), hi(); 681590Srgrimes 691590Srgrimesstruct timeval timeout; 701590Srgrimesstruct timeval zerotime; 711590Srgrimesstruct sgttyb tty, ntty; 721590Srgrimeslong nexttime; /* keep the timeout time */ 731590Srgrimes 741590Srgrimes/*ARGSUSED*/ 751590Srgrimesmain(argc, argv) 761590Srgrimes int argc; 771590Srgrimes char **argv; 781590Srgrimes{ 791590Srgrimes extern char *optarg; 801590Srgrimes extern int errno, optind; 811590Srgrimes struct passwd *pw; 821590Srgrimes struct timeval timval; 831590Srgrimes struct itimerval ntimer, otimer; 841590Srgrimes struct tm *timp; 851590Srgrimes int ch, sectimeout, usemine; 861590Srgrimes char *ap, *mypw, *ttynam, *tzn; 871590Srgrimes char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ]; 881590Srgrimes char *crypt(), *ttyname(); 891590Srgrimes 901590Srgrimes sectimeout = TIMEOUT; 911590Srgrimes mypw = NULL; 921590Srgrimes usemine = 0; 931590Srgrimes while ((ch = getopt(argc, argv, "pt:")) != EOF) 941590Srgrimes switch((char)ch) { 951590Srgrimes case 't': 961590Srgrimes if ((sectimeout = atoi(optarg)) <= 0) { 971590Srgrimes (void)fprintf(stderr, 981590Srgrimes "lock: illegal timeout value.\n"); 991590Srgrimes exit(1); 1001590Srgrimes } 1011590Srgrimes break; 1021590Srgrimes case 'p': 1031590Srgrimes usemine = 1; 1041590Srgrimes if (!(pw = getpwuid(getuid()))) { 1051590Srgrimes (void)fprintf(stderr, 1061590Srgrimes "lock: unknown uid %d.\n", getuid()); 1071590Srgrimes exit(1); 1081590Srgrimes } 1091590Srgrimes mypw = strdup(pw->pw_passwd); 1101590Srgrimes break; 1111590Srgrimes case '?': 1121590Srgrimes default: 1131590Srgrimes (void)fprintf(stderr, 1141590Srgrimes "usage: lock [-p] [-t timeout]\n"); 1151590Srgrimes exit(1); 1161590Srgrimes } 1171590Srgrimes timeout.tv_sec = sectimeout * 60; 1181590Srgrimes 1191590Srgrimes setuid(getuid()); /* discard privs */ 1201590Srgrimes 1211590Srgrimes if (ioctl(0, TIOCGETP, &tty)) /* get information for header */ 1221590Srgrimes exit(1); 1231590Srgrimes gethostname(hostname, sizeof(hostname)); 1241590Srgrimes if (!(ttynam = ttyname(0))) { 1251590Srgrimes (void)printf("lock: not a terminal?\n"); 1261590Srgrimes exit(1); 1271590Srgrimes } 1281590Srgrimes if (gettimeofday(&timval, (struct timezone *)NULL)) { 1291590Srgrimes (void)fprintf(stderr, 1301590Srgrimes "lock: gettimeofday: %s\n", strerror(errno)); 1311590Srgrimes exit(1); 1321590Srgrimes } 1331590Srgrimes nexttime = timval.tv_sec + (sectimeout * 60); 1341590Srgrimes timp = localtime(&timval.tv_sec); 1351590Srgrimes ap = asctime(timp); 1361590Srgrimes tzn = timp->tm_zone; 1371590Srgrimes 1381590Srgrimes (void)signal(SIGINT, quit); 1391590Srgrimes (void)signal(SIGQUIT, quit); 1401590Srgrimes ntty = tty; ntty.sg_flags &= ~ECHO; 1411590Srgrimes (void)ioctl(0, TIOCSETP, &ntty); 1421590Srgrimes 1431590Srgrimes if (!mypw) { 1441590Srgrimes /* get key and check again */ 1451590Srgrimes (void)printf("Key: "); 1461590Srgrimes if (!fgets(s, sizeof(s), stdin) || *s == '\n') 1471590Srgrimes quit(); 1481590Srgrimes (void)printf("\nAgain: "); 1491590Srgrimes /* 1501590Srgrimes * Don't need EOF test here, if we get EOF, then s1 != s 1511590Srgrimes * and the right things will happen. 1521590Srgrimes */ 1531590Srgrimes (void)fgets(s1, sizeof(s1), stdin); 1541590Srgrimes (void)putchar('\n'); 1551590Srgrimes if (strcmp(s1, s)) { 1561590Srgrimes (void)printf("\07lock: passwords didn't match.\n"); 1571590Srgrimes ioctl(0, TIOCSETP, &tty); 1581590Srgrimes exit(1); 1591590Srgrimes } 1601590Srgrimes s[0] = NULL; 1611590Srgrimes mypw = s1; 1621590Srgrimes } 1631590Srgrimes 1641590Srgrimes /* set signal handlers */ 1651590Srgrimes (void)signal(SIGINT, hi); 1661590Srgrimes (void)signal(SIGQUIT, hi); 1671590Srgrimes (void)signal(SIGTSTP, hi); 1681590Srgrimes (void)signal(SIGALRM, bye); 1691590Srgrimes 1701590Srgrimes ntimer.it_interval = zerotime; 1711590Srgrimes ntimer.it_value = timeout; 1721590Srgrimes setitimer(ITIMER_REAL, &ntimer, &otimer); 1731590Srgrimes 1741590Srgrimes /* header info */ 1751590Srgrimes(void)printf("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s", 1761590Srgrimes ttynam, hostname, sectimeout, ap, tzn, ap + 19); 1771590Srgrimes 1781590Srgrimes for (;;) { 1791590Srgrimes (void)printf("Key: "); 1801590Srgrimes if (!fgets(s, sizeof(s), stdin)) { 1811590Srgrimes clearerr(stdin); 1821590Srgrimes hi(); 1831590Srgrimes continue; 1841590Srgrimes } 1851590Srgrimes if (usemine) { 1861590Srgrimes s[strlen(s) - 1] = '\0'; 1871590Srgrimes if (!strcmp(mypw, crypt(s, mypw))) 1881590Srgrimes break; 1891590Srgrimes } 1901590Srgrimes else if (!strcmp(s, s1)) 1911590Srgrimes break; 1921590Srgrimes (void)printf("\07\n"); 1931590Srgrimes if (ioctl(0, TIOCGETP, &ntty)) 1941590Srgrimes exit(1); 1951590Srgrimes } 1961590Srgrimes quit(); 1971590Srgrimes} 1981590Srgrimes 1991590Srgrimesvoid 2001590Srgrimeshi() 2011590Srgrimes{ 2021590Srgrimes struct timeval timval; 2031590Srgrimes 2041590Srgrimes if (!gettimeofday(&timval, (struct timezone *)NULL)) 2051590Srgrimes(void)printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n", 2061590Srgrimes (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60); 2071590Srgrimes} 2081590Srgrimes 2091590Srgrimesvoid 2101590Srgrimesquit() 2111590Srgrimes{ 2121590Srgrimes (void)putchar('\n'); 2131590Srgrimes (void)ioctl(0, TIOCSETP, &tty); 2141590Srgrimes exit(0); 2151590Srgrimes} 2161590Srgrimes 2171590Srgrimesvoid 2181590Srgrimesbye() 2191590Srgrimes{ 2201590Srgrimes (void)ioctl(0, TIOCSETP, &tty); 2211590Srgrimes (void)printf("lock: timeout\n"); 2221590Srgrimes exit(1); 2231590Srgrimes} 224