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