1 /* 2 * Copyright (c) 1980, 1987 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)lock.c 5.12 (Berkeley) 05/15/90"; 26 #endif /* not lint */ 27 28 /* 29 * Lock a terminal up until the given key is entered, until the root 30 * password is entered, or the given interval times out. 31 * 32 * Timeout interval is by default TIMEOUT, it can be changed with 33 * an argument of the form -time where time is in minutes 34 */ 35 36 #include <sys/param.h> 37 #include <sys/stat.h> 38 #include <sys/time.h> 39 #include <sys/signal.h> 40 #include <sgtty.h> 41 #include <pwd.h> 42 #include <stdio.h> 43 #include <ctype.h> 44 #include <string.h> 45 46 #define TIMEOUT 15 47 48 void quit(), bye(), hi(); 49 50 struct timeval timeout; 51 struct timeval zerotime; 52 struct sgttyb tty, ntty; 53 long nexttime; /* keep the timeout time */ 54 55 /*ARGSUSED*/ 56 main(argc, argv) 57 int argc; 58 char **argv; 59 { 60 extern char *optarg; 61 extern int errno, optind; 62 struct passwd *pw; 63 struct timeval timval; 64 struct itimerval ntimer, otimer; 65 struct tm *timp; 66 int ch, sectimeout, usemine; 67 char *ap, *mypw, *ttynam, *tzn; 68 char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ]; 69 char *crypt(), *ttyname(); 70 71 sectimeout = TIMEOUT; 72 mypw = NULL; 73 usemine = 0; 74 while ((ch = getopt(argc, argv, "pt:")) != EOF) 75 switch((char)ch) { 76 case 't': 77 if ((sectimeout = atoi(optarg)) <= 0) { 78 (void)fprintf(stderr, 79 "lock: illegal timeout value.\n"); 80 exit(1); 81 } 82 break; 83 case 'p': 84 usemine = 1; 85 if (!(pw = getpwuid(getuid()))) { 86 (void)fprintf(stderr, 87 "lock: unknown uid %d.\n", getuid()); 88 exit(1); 89 } 90 mypw = strdup(pw->pw_passwd); 91 break; 92 case '?': 93 default: 94 (void)fprintf(stderr, 95 "usage: lock [-p] [-t timeout]\n"); 96 exit(1); 97 } 98 timeout.tv_sec = sectimeout * 60; 99 100 setuid(getuid()); /* discard privs */ 101 102 if (ioctl(0, TIOCGETP, &tty)) /* get information for header */ 103 exit(1); 104 gethostname(hostname, sizeof(hostname)); 105 if (!(ttynam = ttyname(0))) { 106 (void)printf("lock: not a terminal?\n"); 107 exit(1); 108 } 109 if (gettimeofday(&timval, (struct timezone *)NULL)) { 110 (void)fprintf(stderr, 111 "lock: gettimeofday: %s\n", strerror(errno)); 112 exit(1); 113 } 114 nexttime = timval.tv_sec + (sectimeout * 60); 115 timp = localtime(&timval.tv_sec); 116 ap = asctime(timp); 117 tzn = timp->tm_zone; 118 119 (void)signal(SIGINT, quit); 120 (void)signal(SIGQUIT, quit); 121 ntty = tty; ntty.sg_flags &= ~ECHO; 122 (void)ioctl(0, TIOCSETP, &ntty); 123 124 if (!mypw) { 125 /* get key and check again */ 126 (void)printf("Key: "); 127 if (!fgets(s, sizeof(s), stdin) || *s == '\n') 128 quit(); 129 (void)printf("\nAgain: "); 130 /* 131 * Don't need EOF test here, if we get EOF, then s1 != s 132 * and the right things will happen. 133 */ 134 (void)fgets(s1, sizeof(s1), stdin); 135 (void)putchar('\n'); 136 if (strcmp(s1, s)) { 137 (void)printf("\07lock: passwords didn't match.\n"); 138 ioctl(0, TIOCSETP, &tty); 139 exit(1); 140 } 141 s[0] = NULL; 142 mypw = s1; 143 } 144 145 /* set signal handlers */ 146 (void)signal(SIGINT, hi); 147 (void)signal(SIGQUIT, hi); 148 (void)signal(SIGTSTP, hi); 149 (void)signal(SIGALRM, bye); 150 151 ntimer.it_interval = zerotime; 152 ntimer.it_value = timeout; 153 setitimer(ITIMER_REAL, &ntimer, &otimer); 154 155 /* header info */ 156 (void)printf("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s", 157 ttynam, hostname, sectimeout, ap, tzn, ap + 19); 158 159 for (;;) { 160 (void)printf("Key: "); 161 if (!fgets(s, sizeof(s), stdin)) { 162 clearerr(stdin); 163 hi(); 164 continue; 165 } 166 if (usemine) { 167 s[strlen(s) - 1] = '\0'; 168 if (!strcmp(mypw, crypt(s, mypw))) 169 break; 170 } 171 else if (!strcmp(s, s1)) 172 break; 173 (void)printf("\07\n"); 174 if (ioctl(0, TIOCGETP, &ntty)) 175 exit(1); 176 } 177 quit(); 178 } 179 180 void 181 hi() 182 { 183 struct timeval timval; 184 185 if (!gettimeofday(&timval, (struct timezone *)NULL)) 186 (void)printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n", 187 (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60); 188 } 189 190 void 191 quit() 192 { 193 (void)putchar('\n'); 194 (void)ioctl(0, TIOCSETP, &tty); 195 exit(0); 196 } 197 198 void 199 bye() 200 { 201 (void)ioctl(0, TIOCSETP, &tty); 202 (void)printf("lock: timeout\n"); 203 exit(1); 204 } 205