login.c revision 1.35 1 /* $NetBSD: login.c,v 1.35 1998/01/16 00:31:53 hubertf Exp $ */
2
3 /*-
4 * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 __COPYRIGHT(
39 "@(#) Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994\n\
40 The Regents of the University of California. All rights reserved.\n");
41 #endif /* not lint */
42
43 #ifndef lint
44 #if 0
45 static char sccsid[] = "@(#)login.c 8.4 (Berkeley) 4/2/94";
46 #endif
47 __RCSID("$NetBSD: login.c,v 1.35 1998/01/16 00:31:53 hubertf Exp $");
48 #endif /* not lint */
49
50 /*
51 * login [ name ]
52 * login -h hostname (for telnetd, etc.)
53 * login -f name (for pre-authenticated login: datakit, xterm, etc.)
54 */
55
56 #include <sys/param.h>
57 #include <sys/stat.h>
58 #include <sys/time.h>
59 #include <sys/resource.h>
60 #include <sys/file.h>
61
62 #include <err.h>
63 #include <errno.h>
64 #include <grp.h>
65 #include <pwd.h>
66 #include <setjmp.h>
67 #include <signal.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71 #include <syslog.h>
72 #include <ttyent.h>
73 #include <tzfile.h>
74 #include <unistd.h>
75 #include <utmp.h>
76 #include <util.h>
77 #ifdef SKEY
78 #include <skey.h>
79 #endif
80 #ifdef KERBEROS5
81 #include <krb5.h>
82 #endif
83
84 #include "pathnames.h"
85
86 void badlogin __P((char *));
87 void checknologin __P((void));
88 void dolastlog __P((int));
89 void getloginname __P((void));
90 int main __P((int, char *[]));
91 void motd __P((void));
92 int rootterm __P((char *));
93 void sigint __P((int));
94 void sleepexit __P((int));
95 char *stypeof __P((char *));
96 void timedout __P((int));
97 #if defined(KERBEROS) || defined(KERBEROS5)
98 int klogin __P((struct passwd *, char *, char *, char *));
99 void kdestroy __P((void));
100 void dofork __P((void));
101 #endif
102
103 extern void login __P((struct utmp *));
104
105 #define TTYGRPNAME "tty" /* name of group to own ttys */
106
107 /*
108 * This bounds the time given to login. Not a define so it can
109 * be patched on machines where it's too small.
110 */
111 u_int timeout = 300;
112
113 #if defined(KERBEROS) || defined(KERBEROS5)
114 int notickets = 1;
115 char *instance;
116 char *krbtkfile_env;
117 #endif
118 #ifdef KERBEROS5
119 extern krb5_context kcontext;
120 #endif
121
122 struct passwd *pwd;
123 int failures;
124 char term[64], *envinit[1], *hostname, *username, *tty;
125
126 static const char copyrightstr[] = "\
127 Copyright (c) 1996, 1997, 1998
128 \tThe NetBSD Foundation, Inc. All rights reserved.
129 Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
130 \tThe Regents of the University of California. All rights reserved.\n\n";
131
132 int
133 main(argc, argv)
134 int argc;
135 char *argv[];
136 {
137 extern char **environ;
138 struct group *gr;
139 struct stat st;
140 struct timeval tp;
141 struct utmp utmp;
142 int ask, ch, cnt, fflag, hflag, pflag, sflag, quietlog, rootlogin, rval;
143 uid_t uid, saved_uid;
144 gid_t saved_gid, saved_gids[NGROUPS_MAX];
145 int nsaved_gids;
146 char *domain, *p, *salt, *ttyn, *pwprompt;
147 char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
148 char localhost[MAXHOSTNAMELEN];
149 int need_chpass, require_chpass;
150 #ifdef KERBEROS5
151 krb5_error_code kerror;
152 #endif
153
154 tbuf[0] = '\0';
155 rval = 0;
156 pwprompt = NULL;
157 need_chpass = require_chpass = 0;
158
159 (void)signal(SIGALRM, timedout);
160 (void)alarm(timeout);
161 (void)signal(SIGQUIT, SIG_IGN);
162 (void)signal(SIGINT, SIG_IGN);
163 (void)setpriority(PRIO_PROCESS, 0, 0);
164
165 openlog("login", LOG_ODELAY, LOG_AUTH);
166
167 /*
168 * -p is used by getty to tell login not to destroy the environment
169 * -f is used to skip a second login authentication
170 * -h is used by other servers to pass the name of the remote
171 * host to login so that it may be placed in utmp and wtmp
172 * -s is used to force use of S/Key or equivalent.
173 */
174 domain = NULL;
175 if (gethostname(localhost, sizeof(localhost)) < 0)
176 syslog(LOG_ERR, "couldn't get local hostname: %m");
177 else
178 domain = strchr(localhost, '.');
179
180 fflag = hflag = pflag = sflag = 0;
181 uid = getuid();
182 while ((ch = getopt(argc, argv, "fh:ps")) != -1)
183 switch (ch) {
184 case 'f':
185 fflag = 1;
186 break;
187 case 'h':
188 if (uid)
189 errx(1, "-h option: %s", strerror(EPERM));
190 hflag = 1;
191 if (domain && (p = strchr(optarg, '.')) != NULL &&
192 strcasecmp(p, domain) == 0)
193 *p = 0;
194 hostname = optarg;
195 break;
196 case 'p':
197 pflag = 1;
198 break;
199 case 's':
200 sflag = 1;
201 break;
202 default:
203 case '?':
204 (void)fprintf(stderr,
205 "usage: login [-fps] [-h hostname] [username]\n");
206 exit(1);
207 }
208 argc -= optind;
209 argv += optind;
210
211 if (*argv) {
212 username = *argv;
213 ask = 0;
214 } else
215 ask = 1;
216
217 for (cnt = getdtablesize(); cnt > 2; cnt--)
218 (void)close(cnt);
219
220 ttyn = ttyname(STDIN_FILENO);
221 if (ttyn == NULL || *ttyn == '\0') {
222 (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
223 ttyn = tname;
224 }
225 if ((tty = strrchr(ttyn, '/')) != NULL)
226 ++tty;
227 else
228 tty = ttyn;
229
230 #ifdef KERBEROS5
231 kerror = krb5_init_context(&kcontext);
232 if (kerror) {
233 syslog(LOG_NOTICE, "%s when initializing Kerberos context",
234 error_message(kerror));
235 exit(1);
236 }
237 #endif KERBEROS5
238
239 for (cnt = 0;; ask = 1) {
240 #if defined(KERBEROS) || defined(KERBEROS5)
241 kdestroy();
242 #endif
243 if (ask) {
244 fflag = 0;
245 getloginname();
246 }
247 rootlogin = 0;
248 #ifdef KERBEROS
249 if ((instance = strchr(username, '.')) != NULL)
250 *instance++ = '\0';
251 else
252 instance = "";
253 #endif
254 #ifdef KERBEROS5
255 if ((instance = strchr(username, '/')) != NULL)
256 *instance++ = '\0';
257 else
258 instance = "";
259 #endif
260 if (strlen(username) > MAXLOGNAME)
261 username[MAXLOGNAME] = '\0';
262
263 /*
264 * Note if trying multiple user names; log failures for
265 * previous user name, but don't bother logging one failure
266 * for nonexistent name (mistyped username).
267 */
268 if (failures && strcmp(tbuf, username)) {
269 if (failures > (pwd ? 0 : 1))
270 badlogin(tbuf);
271 failures = 0;
272 }
273 (void)strncpy(tbuf, username, sizeof(tbuf) - 1);
274
275 if ((pwd = getpwnam(username)) != NULL)
276 salt = pwd->pw_passwd;
277 else
278 salt = "xx";
279
280 /*
281 * if we have a valid account name, and it doesn't have a
282 * password, or the -f option was specified and the caller
283 * is root or the caller isn't changing their uid, don't
284 * authenticate.
285 */
286 if (pwd) {
287 if (pwd->pw_uid == 0)
288 rootlogin = 1;
289
290 if (fflag && (uid == 0 || uid == pwd->pw_uid)) {
291 /* already authenticated */
292 break;
293 } else if (pwd->pw_passwd[0] == '\0') {
294 /* pretend password okay */
295 rval = 0;
296 goto ttycheck;
297 }
298 }
299
300 fflag = 0;
301
302 (void)setpriority(PRIO_PROCESS, 0, -4);
303
304 #ifdef SKEY
305 if (skey_haskey(username) == 0) {
306 static char skprompt[80];
307 char *skinfo = skey_keyinfo(username);
308
309 (void)snprintf(skprompt, sizeof(skprompt)-1,
310 "Password [%s]:",
311 skinfo ? skinfo : "error getting challenge");
312 pwprompt = skprompt;
313 } else
314 #endif
315 pwprompt = "Password:";
316
317 p = getpass(pwprompt);
318
319 if (pwd == NULL) {
320 rval = 1;
321 goto skip;
322 }
323 #ifdef KERBEROS
324 if (klogin(pwd, instance, localhost, p) == 0) {
325 rval = 0;
326 goto skip;
327 }
328 #endif
329 #ifdef KERBEROS5
330 if (klogin(pwd, instance, localhost, p) == 0) {
331 rval = 0;
332 goto skip;
333 }
334 #endif
335 #ifdef SKEY
336 if (skey_haskey(username) == 0 &&
337 skey_passcheck(username, p) != -1) {
338 rval = 0;
339 goto skip;
340 }
341 #endif
342 if (!sflag && *pwd->pw_passwd != '\0' &&
343 !strcmp(crypt(p, pwd->pw_passwd), pwd->pw_passwd)) {
344 rval = 0;
345 require_chpass = 1;
346 goto skip;
347 }
348 rval = 1;
349
350 skip:
351 memset(p, 0, strlen(p));
352
353 (void)setpriority(PRIO_PROCESS, 0, 0);
354
355 ttycheck:
356 /*
357 * If trying to log in as root without Kerberos,
358 * but with insecure terminal, refuse the login attempt.
359 */
360 if (pwd && !rval && rootlogin && !rootterm(tty)) {
361 (void)fprintf(stderr,
362 "%s login refused on this terminal.\n",
363 pwd->pw_name);
364 if (hostname)
365 syslog(LOG_NOTICE,
366 "LOGIN %s REFUSED FROM %s ON TTY %s",
367 pwd->pw_name, hostname, tty);
368 else
369 syslog(LOG_NOTICE,
370 "LOGIN %s REFUSED ON TTY %s",
371 pwd->pw_name, tty);
372 continue;
373 }
374
375 if (pwd && !rval)
376 break;
377
378 (void)printf("Login incorrect\n");
379 failures++;
380 /* we allow 10 tries, but after 3 we start backing off */
381 if (++cnt > 3) {
382 if (cnt >= 10) {
383 badlogin(username);
384 sleepexit(1);
385 }
386 sleep((u_int)((cnt - 3) * 5));
387 }
388 }
389
390 /* committed to login -- turn off timeout */
391 (void)alarm((u_int)0);
392
393 endpwent();
394
395 /* if user not super-user, check for disabled logins */
396 if (!rootlogin)
397 checknologin();
398
399 /* Temporarily give up special privileges so we can change */
400 /* into NFS-mounted homes that are exported for non-root */
401 /* access and have mode 7x0 */
402 saved_uid = geteuid();
403 saved_gid = getegid();
404 nsaved_gids = getgroups(NGROUPS_MAX, saved_gids);
405
406 (void)setegid(pwd->pw_gid);
407 initgroups(username, pwd->pw_gid);
408 (void)seteuid(pwd->pw_uid);
409
410 if (chdir(pwd->pw_dir) < 0) {
411 (void)printf("No home directory %s!\n", pwd->pw_dir);
412 if (chdir("/"))
413 exit(0);
414 pwd->pw_dir = "/";
415 (void)printf("Logging in with home = \"/\".\n");
416 }
417
418 quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
419
420 /* regain special privileges */
421 (void)seteuid(saved_uid);
422 setgroups(nsaved_gids, saved_gids);
423 (void)setegid(saved_gid);
424
425 if (pwd->pw_change || pwd->pw_expire)
426 (void)gettimeofday(&tp, (struct timezone *)NULL);
427 if (pwd->pw_expire)
428 if (tp.tv_sec >= pwd->pw_expire) {
429 (void)printf("Sorry -- your account has expired.\n");
430 sleepexit(1);
431 } else if (pwd->pw_expire - tp.tv_sec <
432 _PASSWORD_WARNDAYS * SECSPERDAY && !quietlog)
433 (void)printf("Warning: your account expires on %s",
434 ctime(&pwd->pw_expire));
435 if (pwd->pw_change)
436 if (pwd->pw_change == _PASSWORD_CHGNOW)
437 need_chpass = 1;
438 else if (tp.tv_sec >= pwd->pw_change) {
439 (void)printf("Sorry -- your password has expired.\n");
440 sleepexit(1);
441 } else if (pwd->pw_change - tp.tv_sec <
442 _PASSWORD_WARNDAYS * SECSPERDAY && !quietlog)
443 (void)printf("Warning: your password expires on %s",
444 ctime(&pwd->pw_change));
445
446 /* Nothing else left to fail -- really log in. */
447 memset((void *)&utmp, 0, sizeof(utmp));
448 (void)time(&utmp.ut_time);
449 (void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
450 if (hostname)
451 (void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
452 (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
453 login(&utmp);
454
455 dolastlog(quietlog);
456
457 (void)chown(ttyn, pwd->pw_uid,
458 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
459
460 if (ttyaction(ttyn, "login", pwd->pw_name))
461 (void)printf("Warning: ttyaction failed.\n");
462
463 #if defined(KERBEROS) || defined(KERBEROS5)
464 /* Fork so that we can call kdestroy */
465 if (krbtkfile_env)
466 dofork();
467 #endif
468 (void)setgid(pwd->pw_gid);
469
470 initgroups(username, pwd->pw_gid);
471
472 if (*pwd->pw_shell == '\0')
473 pwd->pw_shell = _PATH_BSHELL;
474
475 /* Destroy environment unless user has requested its preservation. */
476 if (!pflag)
477 environ = envinit;
478 (void)setenv("HOME", pwd->pw_dir, 1);
479 (void)setenv("SHELL", pwd->pw_shell, 1);
480 if (term[0] == '\0')
481 (void)strncpy(term, stypeof(tty), sizeof(term));
482 (void)setenv("TERM", term, 0);
483 (void)setenv("LOGNAME", pwd->pw_name, 1);
484 (void)setenv("USER", pwd->pw_name, 1);
485 (void)setenv("PATH", _PATH_DEFPATH, 0);
486 #ifdef KERBEROS
487 if (krbtkfile_env)
488 (void)setenv("KRBTKFILE", krbtkfile_env, 1);
489 #endif
490 #ifdef KERBEROS5
491 if (krbtkfile_env)
492 (void)setenv("KRB5CCNAME", krbtkfile_env, 1);
493 #endif
494
495 if (tty[sizeof("tty")-1] == 'd')
496 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
497
498 /* If fflag is on, assume caller/authenticator has logged root login. */
499 if (rootlogin && fflag == 0)
500 if (hostname)
501 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
502 username, tty, hostname);
503 else
504 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
505
506 #if defined(KERBEROS) || defined(KERBEROS5)
507 if (!quietlog && notickets == 1)
508 (void)printf("Warning: no Kerberos tickets issued.\n");
509 #endif
510
511 if (!quietlog) {
512 (void)printf(copyrightstr);
513 motd();
514 (void)snprintf(tbuf,
515 sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
516 if (stat(tbuf, &st) == 0 && st.st_size != 0)
517 (void)printf("You have %smail.\n",
518 (st.st_mtime > st.st_atime) ? "new " : "");
519 }
520
521 (void)signal(SIGALRM, SIG_DFL);
522 (void)signal(SIGQUIT, SIG_DFL);
523 (void)signal(SIGINT, SIG_DFL);
524 (void)signal(SIGTSTP, SIG_IGN);
525
526 tbuf[0] = '-';
527 (void)strncpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
528 p + 1 : pwd->pw_shell, sizeof(tbuf) - 2);
529
530 if (setlogin(pwd->pw_name) < 0)
531 syslog(LOG_ERR, "setlogin() failure: %m");
532
533 /* Discard permissions last so can't get killed and drop core. */
534 if (rootlogin)
535 (void)setuid(0);
536 else
537 (void)setuid(pwd->pw_uid);
538
539 /* Wait to change password until we're unprivileged */
540 if (need_chpass) {
541 if (!require_chpass)
542 (void)printf(
543 "Warning: your password has expired. Please change it as soon as possible.\n");
544 else {
545 (void)printf(
546 "Your password has expired. Please choose a new one.\n");
547 if (system(_PATH_BINPASSWD) != 0)
548 sleepexit(1);
549 }
550 }
551
552 execlp(pwd->pw_shell, tbuf, 0);
553 err(1, "%s", pwd->pw_shell);
554 }
555
556 #if defined(KERBEROS) || defined(KERBEROS5)
557 #define NBUFSIZ (MAXLOGNAME + 1 + 5) /* .root suffix */
558 #else
559 #define NBUFSIZ (MAXLOGNAME + 1)
560 #endif
561
562 #if defined(KERBEROS) || defined(KERBEROS5)
563 /*
564 * This routine handles cleanup stuff, and the like.
565 * It exists only in the child process.
566 */
567 #include <sys/wait.h>
568 void
569 dofork()
570 {
571 int child;
572
573 if (!(child = fork()))
574 return; /* Child process */
575
576 /* Setup stuff? This would be things we could do in parallel with login */
577 (void) chdir("/"); /* Let's not keep the fs busy... */
578
579 /* If we're the parent, watch the child until it dies */
580 while (wait(0) != child)
581 ;
582
583 /* Cleanup stuff */
584 /* Run kdestroy to destroy tickets */
585 kdestroy();
586
587 /* Leave */
588 exit(0);
589 }
590 #endif
591
592 void
593 getloginname()
594 {
595 int ch;
596 char *p;
597 static char nbuf[NBUFSIZ];
598
599 for (;;) {
600 (void)printf("login: ");
601 for (p = nbuf; (ch = getchar()) != '\n'; ) {
602 if (ch == EOF) {
603 badlogin(username);
604 exit(0);
605 }
606 if (p < nbuf + (NBUFSIZ - 1))
607 *p++ = ch;
608 }
609 if (p > nbuf)
610 if (nbuf[0] == '-')
611 (void)fprintf(stderr,
612 "login names may not start with '-'.\n");
613 else {
614 *p = '\0';
615 username = nbuf;
616 break;
617 }
618 }
619 }
620
621 int
622 rootterm(ttyn)
623 char *ttyn;
624 {
625 struct ttyent *t;
626
627 return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
628 }
629
630 jmp_buf motdinterrupt;
631
632 void
633 motd()
634 {
635 int fd, nchars;
636 sig_t oldint;
637 char tbuf[8192];
638
639 if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
640 return;
641 oldint = signal(SIGINT, sigint);
642 if (setjmp(motdinterrupt) == 0)
643 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
644 (void)write(fileno(stdout), tbuf, nchars);
645 (void)signal(SIGINT, oldint);
646 (void)close(fd);
647 }
648
649 /* ARGSUSED */
650 void
651 sigint(signo)
652 int signo;
653 {
654 longjmp(motdinterrupt, 1);
655 }
656
657 /* ARGSUSED */
658 void
659 timedout(signo)
660 int signo;
661 {
662 (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
663 exit(0);
664 }
665
666 void
667 checknologin()
668 {
669 int fd, nchars;
670 char tbuf[8192];
671
672 if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
673 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
674 (void)write(fileno(stdout), tbuf, nchars);
675 sleepexit(0);
676 }
677 }
678
679 void
680 dolastlog(quiet)
681 int quiet;
682 {
683 struct lastlog ll;
684 int fd;
685
686 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
687 (void)lseek(fd, (off_t)(pwd->pw_uid * sizeof(ll)), SEEK_SET);
688 if (!quiet) {
689 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
690 ll.ll_time != 0) {
691 (void)printf("Last login: %.*s ",
692 24-5, (char *)ctime(&ll.ll_time));
693 if (*ll.ll_host != '\0')
694 (void)printf("from %.*s\n",
695 (int)sizeof(ll.ll_host),
696 ll.ll_host);
697 else
698 (void)printf("on %.*s\n",
699 (int)sizeof(ll.ll_line),
700 ll.ll_line);
701 }
702 (void)lseek(fd, (off_t)(pwd->pw_uid * sizeof(ll)),
703 SEEK_SET);
704 }
705 memset((void *)&ll, 0, sizeof(ll));
706 (void)time(&ll.ll_time);
707 (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
708 if (hostname)
709 (void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
710 (void)write(fd, (char *)&ll, sizeof(ll));
711 (void)close(fd);
712 }
713 }
714
715 void
716 badlogin(name)
717 char *name;
718 {
719 if (failures == 0)
720 return;
721 if (hostname) {
722 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
723 failures, failures > 1 ? "S" : "", hostname);
724 syslog(LOG_AUTHPRIV|LOG_NOTICE,
725 "%d LOGIN FAILURE%s FROM %s, %s",
726 failures, failures > 1 ? "S" : "", hostname, name);
727 } else {
728 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
729 failures, failures > 1 ? "S" : "", tty);
730 syslog(LOG_AUTHPRIV|LOG_NOTICE,
731 "%d LOGIN FAILURE%s ON %s, %s",
732 failures, failures > 1 ? "S" : "", tty, name);
733 }
734 }
735
736 #undef UNKNOWN
737 #define UNKNOWN "su"
738
739 char *
740 stypeof(ttyid)
741 char *ttyid;
742 {
743 struct ttyent *t;
744
745 return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
746 }
747
748 void
749 sleepexit(eval)
750 int eval;
751 {
752 (void)sleep(5);
753 exit(eval);
754 }
755