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.8 (Berkeley) 02/22/89"; 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 <strings.h> 45 46 #define TIMEOUT 15 47 48 int 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, *rootpw, *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 exit(1); 79 break; 80 case 'p': 81 usemine = 1; 82 if (!(pw = getpwuid(getuid()))) { 83 fprintf(stderr, "lock: unknown uid %d.\n", 84 getuid()); 85 exit(1); 86 } 87 mypw = strdup(pw->pw_passwd); 88 break; 89 case '?': 90 default: 91 fprintf(stderr, "usage: lock [-p] [-t timeout]\n"); 92 exit(1); 93 } 94 timeout.tv_sec = sectimeout * 60; 95 96 rootpw = (pw = getpwnam("root")) ? strdup(pw->pw_passwd) : NULL; 97 98 setuid(getuid()); /* discard privs */ 99 100 if (ioctl(0, TIOCGETP, &tty)) /* get information for header */ 101 exit(1); 102 gethostname(hostname, sizeof(hostname)); 103 if (!(ttynam = ttyname(0))) { 104 printf("lock: not a terminal?\n"); 105 exit(1); 106 } 107 if (gettimeofday(&timval, (struct timezone *)NULL)) { 108 fprintf(stderr, "lock: gettimeofday: %s\n", strerror(errno)); 109 exit(1); 110 } 111 nexttime = timval.tv_sec + (sectimeout * 60); 112 timp = localtime(&timval.tv_sec); 113 ap = asctime(timp); 114 tzn = timp->tm_zone; 115 116 (void)signal(SIGINT, quit); 117 (void)signal(SIGQUIT, quit); 118 ntty = tty; ntty.sg_flags &= ~ECHO; 119 (void)ioctl(0, TIOCSETP, &ntty); 120 121 if (!mypw) { 122 /* get key and check again */ 123 printf("Key: "); 124 if (!fgets(s, sizeof(s), stdin) || *s == '\n') 125 quit(); 126 printf("\nAgain: "); 127 /* 128 * Don't need EOF test here, if we get EOF, then s1 != s 129 * and the right things will happen. 130 */ 131 (void)fgets(s1, sizeof(s1), stdin); 132 putchar('\n'); 133 if (strcmp(s1, s)) { 134 printf("\07lock: passwords didn't match.\n"); 135 ioctl(0, TIOCSETP, &tty); 136 exit(1); 137 } 138 s[0] = NULL; 139 mypw = s1; 140 } 141 142 /* set signal handlers */ 143 (void)signal(SIGINT, hi); 144 (void)signal(SIGQUIT, hi); 145 (void)signal(SIGTSTP, hi); 146 (void)signal(SIGALRM, bye); 147 148 ntimer.it_interval = zerotime; 149 ntimer.it_value = timeout; 150 setitimer(ITIMER_REAL, &ntimer, &otimer); 151 152 /* header info */ 153 printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s", 154 ttynam, hostname, sectimeout, ap, tzn, ap + 19); 155 156 for (;;) { 157 printf("Key: "); 158 if (!fgets(s, sizeof(s), stdin)) { 159 clearerr(stdin); 160 hi(); 161 continue; 162 } 163 if (usemine) { 164 if (!strcmp(mypw, crypt(s, mypw))) 165 break; 166 } 167 else if (!strcmp(s, s1)) 168 break; 169 if (rootpw && !strcmp(rootpw, crypt(s, rootpw))) 170 break; 171 printf("\07\n"); 172 if (ioctl(0, TIOCGETP, &ntty)) 173 exit(1); 174 } 175 quit(); 176 } 177 178 static 179 hi() 180 { 181 struct timeval timval; 182 183 if (!gettimeofday(&timval, (struct timezone *)NULL)) 184 printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n", 185 (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60); 186 } 187 188 static 189 quit() 190 { 191 putchar('\n'); 192 (void)ioctl(0, TIOCSETP, &tty); 193 exit(0); 194 } 195 196 static 197 bye() 198 { 199 (void)ioctl(0, TIOCSETP, &tty); 200 printf("lock: timeout\n"); 201 exit(1); 202 } 203