]> git.saurik.com Git - apple/system_cmds.git/blame - login.tproj/login.c
system_cmds-230.tar.gz
[apple/system_cmds.git] / login.tproj / login.c
CommitLineData
1815bff5
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*-
25 * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57#ifndef lint
58static char copyright[] =
59"@(#) Copyright (c) Apple Computer, Inc. 1997\n\n";
60#endif /* not lint */
61
62/*
63 * login [ name ]
64 * login -h hostname (for telnetd, etc.)
65 * login -f name (for pre-authenticated login: datakit, xterm, etc.)
66 */
67
68#include <sys/param.h>
69#include <sys/stat.h>
70#include <sys/time.h>
71#include <sys/resource.h>
72#include <sys/file.h>
b51d5b5f 73#include <sys/wait.h>
1815bff5
A
74
75#include <err.h>
76#include <errno.h>
77#include <grp.h>
78#include <pwd.h>
79#include <setjmp.h>
80#include <signal.h>
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <syslog.h>
85#include <ttyent.h>
86#include <tzfile.h>
87#include <unistd.h>
88#include <utmp.h>
89
b51d5b5f
A
90#ifdef USE_PAM
91#include <pam/pam_appl.h>
92#include <pam/pam_misc.h>
93#endif
94
1815bff5
A
95#include "pathnames.h"
96
97void badlogin __P((char *));
98void checknologin __P((void));
99void dolastlog __P((int));
100void getloginname __P((void));
101void motd __P((void));
102int rootterm __P((char *));
103void sigint __P((int));
104void sleepexit __P((int));
105char *stypeof __P((char *));
106void timedout __P((int));
107#ifdef KERBEROS
108int klogin __P((struct passwd *, char *, char *, char *));
109#endif
110
111extern void login __P((struct utmp *));
112
113#define TTYGRPNAME "tty" /* name of group to own ttys */
114
115/*
116 * This bounds the time given to login. Not a define so it can
117 * be patched on machines where it's too small.
118 */
119u_int timeout = 300;
120
121#ifdef KERBEROS
122int notickets = 1;
123char *instance;
124char *krbtkfile_env;
125int authok;
126#endif
127
128struct passwd *pwd;
129int failures;
b51d5b5f 130char term[64], *hostname, *username = NULL, *tty;
1815bff5
A
131
132int
133main(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;
b51d5b5f 142 int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin = 0, rval;
1815bff5 143 uid_t uid;
b51d5b5f
A
144 uid_t euid;
145 gid_t egid;
1815bff5
A
146 char *domain, *p, *salt, *ttyn;
147 char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
148 char localhost[MAXHOSTNAMELEN];
b51d5b5f
A
149#ifdef USE_PAM
150 pam_handle_t *pamh = NULL;
151 struct pam_conv conv = { misc_conv, NULL };
152 char **pmenv;
153 pid_t pid;
154#endif
1815bff5
A
155
156 (void)signal(SIGALRM, timedout);
157 (void)alarm(timeout);
158 (void)signal(SIGQUIT, SIG_IGN);
159 (void)signal(SIGINT, SIG_IGN);
160 (void)setpriority(PRIO_PROCESS, 0, 0);
161
162 openlog("login", LOG_ODELAY, LOG_AUTH);
163
164 /*
165 * -p is used by getty to tell login not to destroy the environment
166 * -f is used to skip a second login authentication
167 * -h is used by other servers to pass the name of the remote
168 * host to login so that it may be placed in utmp and wtmp
169 */
170 domain = NULL;
171 if (gethostname(localhost, sizeof(localhost)) < 0)
172 syslog(LOG_ERR, "couldn't get local hostname: %m");
173 else
174 domain = strchr(localhost, '.');
b51d5b5f
A
175
176 euid = geteuid();
177 egid = getegid();
1815bff5
A
178
179 fflag = hflag = pflag = 0;
180 uid = getuid();
181 while ((ch = getopt(argc, argv, "fh:p")) != EOF)
182 switch (ch) {
183 case 'f':
184 fflag = 1;
185 break;
186 case 'h':
187 if (uid)
188 errx(1, "-h option: %s", strerror(EPERM));
189 hflag = 1;
190 if (domain && (p = strchr(optarg, '.')) &&
191 strcasecmp(p, domain) == 0)
192 *p = 0;
193 hostname = optarg;
194 break;
195 case 'p':
196 pflag = 1;
197 break;
198 case '?':
199 default:
200 if (!uid)
201 syslog(LOG_ERR, "invalid flag %c", ch);
202 (void)fprintf(stderr,
203 "usage: login [-fp] [-h hostname] [username]\n");
204 exit(1);
205 }
206 argc -= optind;
207 argv += optind;
208
209 if (*argv) {
210 username = *argv;
211 ask = 0;
212 } else
213 ask = 1;
214
215 for (cnt = getdtablesize(); cnt > 2; cnt--)
216 (void)close(cnt);
217
218 ttyn = ttyname(STDIN_FILENO);
219 if (ttyn == NULL || *ttyn == '\0') {
220 (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
221 ttyn = tname;
222 }
223 if (tty = strrchr(ttyn, '/'))
224 ++tty;
225 else
226 tty = ttyn;
227
b51d5b5f
A
228#ifdef USE_PAM
229 rval = pam_start("login", username, &conv, &pamh);
230 if( rval != PAM_SUCCESS ) {
231 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
232 exit(1);
233 }
234 rval = pam_set_item(pamh, PAM_TTY, tty);
235 if( rval != PAM_SUCCESS ) {
236 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
237 exit(1);
238 }
239
240 rval = pam_set_item(pamh, PAM_RHOST, hostname);
241 if( rval != PAM_SUCCESS ) {
242 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
243 exit(1);
244 }
245
246 rval = pam_set_item(pamh, PAM_USER_PROMPT, "login: ");
247 if( rval != PAM_SUCCESS ) {
248 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
249 exit(1);
250 }
251
252 if( !username )
253 getloginname();
254 pam_set_item(pamh, PAM_USER, username);
255 pwd = getpwnam(username);
256 if( (pwd != NULL) && (pwd->pw_uid == 0) )
257 rootlogin = 1;
258
259 if( (pwd != NULL) && fflag && ((uid == 0) || (uid == pwd->pw_uid)) ){
260 rval = 0;
261 } else {
262
263 rval = pam_authenticate(pamh, 0);
264 while( (cnt++ < 10) && ((rval == PAM_AUTH_ERR) ||
265 (rval == PAM_USER_UNKNOWN) ||
266 (rval == PAM_CRED_INSUFFICIENT) ||
267 (rval == PAM_AUTHINFO_UNAVAIL))) {
268 badlogin(username);
269 printf("Login incorrect\n");
270 rootlogin = 0;
271 getloginname();
272 pwd = getpwnam(username);
273 if( (pwd != NULL) && (pwd->pw_uid == 0) )
274 rootlogin = 1;
275 pam_set_item(pamh, PAM_USER, username);
276 rval = pam_authenticate(pamh, 0);
277 }
278
279 if( rval != PAM_SUCCESS ) {
280 pam_get_item(pamh, PAM_USER, (void *)&username);
281 badlogin(username);
282 printf("Login incorrect\n");
283 exit(1);
284 }
285
286 rval = pam_acct_mgmt(pamh, 0);
287 if( rval == PAM_NEW_AUTHTOK_REQD ) {
288 rval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
289 }
290 if( rval != PAM_SUCCESS ) {
291 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
292 exit(1);
293 }
294 }
295
296 rval = pam_get_item(pamh, PAM_USER, (void *)&username);
297 if( (rval == PAM_SUCCESS) && username && *username)
298 pwd = getpwnam(username);
299
300 rval = pam_open_session(pamh, 0);
301 if( rval != PAM_SUCCESS ) {
302 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
303 exit(1);
304 }
305
306 rval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
307 if( rval != PAM_SUCCESS ) {
308 fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
309 exit(1);
310 }
311
312#else /* USE_PAM */
1815bff5
A
313 for (cnt = 0;; ask = 1) {
314 if (ask) {
315 fflag = 0;
316 getloginname();
317 }
318 rootlogin = 0;
319#ifdef KERBEROS
320 if ((instance = strchr(username, '.')) != NULL) {
321 if (strncmp(instance, ".root", 5) == 0)
322 rootlogin = 1;
323 *instance++ = '\0';
324 } else
325 instance = "";
326#endif
327 if (strlen(username) > UT_NAMESIZE)
328 username[UT_NAMESIZE] = '\0';
329
330 /*
331 * Note if trying multiple user names; log failures for
332 * previous user name, but don't bother logging one failure
333 * for nonexistent name (mistyped username).
334 */
335 if (failures && strcmp(tbuf, username)) {
336 if (failures > (pwd ? 0 : 1))
337 badlogin(tbuf);
338 failures = 0;
339 }
340 (void)strcpy(tbuf, username);
341
342 if (pwd = getpwnam(username))
343 salt = pwd->pw_passwd;
344 else
345 salt = "xx";
346
347 /*
348 * if we have a valid account name, and it doesn't have a
349 * password, or the -f option was specified and the caller
350 * is root or the caller isn't changing their uid, don't
351 * authenticate.
352 */
353 if (pwd && (*pwd->pw_passwd == '\0' ||
354 fflag && (uid == 0 || uid == pwd->pw_uid)))
355 break;
356 fflag = 0;
357 if (pwd && pwd->pw_uid == 0)
358 rootlogin = 1;
359
360 (void)setpriority(PRIO_PROCESS, 0, -4);
361
362 p = getpass("Password:");
363
364 if (pwd) {
365#ifdef KERBEROS
366 rval = klogin(pwd, instance, localhost, p);
367 if (rval != 0 && rootlogin && pwd->pw_uid != 0)
368 rootlogin = 0;
369 if (rval == 0)
370 authok = 1;
371 else if (rval == 1)
372 rval = strcmp(crypt(p, salt), pwd->pw_passwd);
373#else
374 rval = strcmp(crypt(p, salt), pwd->pw_passwd);
375#endif
376 }
377 memset(p, 0, strlen(p));
378
379 (void)setpriority(PRIO_PROCESS, 0, 0);
380
381 /*
382 * If trying to log in as root without Kerberos,
383 * but with insecure terminal, refuse the login attempt.
384 */
385#ifdef KERBEROS
386 if (authok == 0)
387#endif
388 if (pwd && rootlogin && !rootterm(tty)) {
389 (void)fprintf(stderr,
390 "%s login refused on this terminal.\n",
391 pwd->pw_name);
392 if (hostname)
393 syslog(LOG_NOTICE,
394 "LOGIN %s REFUSED FROM %s ON TTY %s",
395 pwd->pw_name, hostname, tty);
396 else
397 syslog(LOG_NOTICE,
398 "LOGIN %s REFUSED ON TTY %s",
399 pwd->pw_name, tty);
400 continue;
401 }
402
403 if (pwd && !rval)
404 break;
405
406 (void)printf("Login incorrect\n");
407 failures++;
408 /* we allow 10 tries, but after 3 we start backing off */
409 if (++cnt > 3) {
410 if (cnt >= 10) {
411 badlogin(username);
412 sleepexit(1);
413 }
414 sleep((u_int)((cnt - 3) * 5));
415 }
416 }
b51d5b5f 417#endif
1815bff5
A
418
419 /* committed to login -- turn off timeout */
420 (void)alarm((u_int)0);
421
422 endpwent();
423
424 /* if user not super-user, check for disabled logins */
425 if (!rootlogin)
426 checknologin();
427
b51d5b5f
A
428 setegid(pwd->pw_gid);
429 seteuid(rootlogin ? 0 : pwd->pw_uid);
430
431 /* First do a stat in case the homedir is automounted */
432\r stat(pwd->pw_dir,&st);
433
1815bff5
A
434 if (chdir(pwd->pw_dir) < 0) {
435 (void)printf("No home directory %s!\n", pwd->pw_dir);
436 if (chdir("/"))
437 exit(0);
438 pwd->pw_dir = "/";
439 (void)printf("Logging in with home = \"/\".\n");
440 }
b51d5b5f
A
441 seteuid(euid);
442 setegid(egid);
1815bff5
A
443
444 quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
445
1815bff5
A
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);
1c51fdde 459 (void)chmod(ttyn, 0620);
1815bff5
A
460 (void)setgid(pwd->pw_gid);
461
462 initgroups(username, pwd->pw_gid);
463
464 if (*pwd->pw_shell == '\0')
465 pwd->pw_shell = _PATH_BSHELL;
466
467 /* Destroy environment unless user has requested its preservation. */
b51d5b5f
A
468 if (!pflag) {
469 environ = malloc(sizeof(char *));
470 *environ = NULL;
471 }
1815bff5
A
472 (void)setenv("HOME", pwd->pw_dir, 1);
473 (void)setenv("SHELL", pwd->pw_shell, 1);
474 if (term[0] == '\0')
475 (void)strncpy(term, stypeof(tty), sizeof(term));
476 (void)setenv("TERM", term, 0);
477 (void)setenv("LOGNAME", pwd->pw_name, 1);
478 (void)setenv("USER", pwd->pw_name, 1);
479 (void)setenv("PATH", _PATH_DEFPATH, 0);
480#ifdef KERBEROS
481 if (krbtkfile_env)
482 (void)setenv("KRBTKFILE", krbtkfile_env, 1);
483#endif
484
b51d5b5f
A
485#ifdef USE_PAM
486 pmenv = pam_getenvlist(pamh);
487 for( cnt = 0; pmenv && pmenv[cnt]; cnt++ )
488 putenv(pmenv[cnt]);
489
490 pid = fork();
491 if ( pid < 0 ) {
492 err(1, "fork");
493 } else if( pid != 0 ) {
494 waitpid(pid, NULL, 0);
495 pam_setcred(pamh, PAM_DELETE_CRED);
496 rval = pam_close_session(pamh, 0);
497 pam_end(pamh,rval);
498 exit(0);
499 }
500
501#endif
502
1815bff5
A
503 if (tty[sizeof("tty")-1] == 'd')
504 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
505
506 /* If fflag is on, assume caller/authenticator has logged root login. */
507 if (rootlogin && fflag == 0)
508 if (hostname)
509 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
510 username, tty, hostname);
511 else
512 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
513
514#ifdef KERBEROS
515 if (!quietlog && notickets == 1)
516 (void)printf("Warning: no Kerberos tickets issued.\n");
517#endif
518
519 if (!quietlog) {
520 motd();
521 (void)snprintf(tbuf,
522 sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
523 if (stat(tbuf, &st) == 0 && st.st_size != 0)
524 (void)printf("You have %smail.\n",
525 (st.st_mtime > st.st_atime) ? "new " : "");
526 }
527
528 (void)signal(SIGALRM, SIG_DFL);
529 (void)signal(SIGQUIT, SIG_DFL);
530 (void)signal(SIGINT, SIG_DFL);
531 (void)signal(SIGTSTP, SIG_IGN);
532
533 tbuf[0] = '-';
534 (void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
535 p + 1 : pwd->pw_shell);
536
537 if (setlogin(pwd->pw_name) < 0)
538 syslog(LOG_ERR, "setlogin() failure: %m");
539
540 /* Discard permissions last so can't get killed and drop core. */
541 if (rootlogin)
542 (void) setuid(0);
543 else
544 (void) setuid(pwd->pw_uid);
545
546 execlp(pwd->pw_shell, tbuf, 0);
547 err(1, "%s", pwd->pw_shell);
548}
549
550#ifdef KERBEROS
b51d5b5f 551#define NBUFSIZ (MAXLOGNAME + 1 + 5) /* .root suffix */
1815bff5 552#else
b51d5b5f 553#define NBUFSIZ (MAXLOGNAME + 1)
1815bff5
A
554#endif
555
556void
557getloginname()
558{
559 int ch;
560 char *p;
561 static char nbuf[NBUFSIZ];
562
563 for (;;) {
564 (void)printf("login: ");
565 for (p = nbuf; (ch = getchar()) != '\n'; ) {
566 if (ch == EOF) {
567 badlogin(username);
568 exit(0);
569 }
570 if (p < nbuf + (NBUFSIZ - 1))
571 *p++ = ch;
572 }
b51d5b5f 573 if (p > nbuf) {
1815bff5
A
574 if (nbuf[0] == '-')
575 (void)fprintf(stderr,
576 "login names may not start with '-'.\n");
577 else {
578 *p = '\0';
579 username = nbuf;
580 break;
581 }
b51d5b5f 582 }
1815bff5
A
583 }
584}
585
586int
587rootterm(ttyn)
588 char *ttyn;
589{
590 struct ttyent *t;
591
592 return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
593}
594
595jmp_buf motdinterrupt;
596
597void
598motd()
599{
600 int fd, nchars;
601 sig_t oldint;
602 char tbuf[8192];
603
604 if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
605 return;
606 oldint = signal(SIGINT, sigint);
607 if (setjmp(motdinterrupt) == 0)
608 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
609 (void)write(fileno(stdout), tbuf, nchars);
610 (void)signal(SIGINT, oldint);
611 (void)close(fd);
612}
613
614/* ARGSUSED */
615void
616sigint(signo)
617 int signo;
618{
619
620 longjmp(motdinterrupt, 1);
621}
622
623/* ARGSUSED */
624void
625timedout(signo)
626 int signo;
627{
628
629 (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
630 exit(0);
631}
632
633void
634checknologin()
635{
636 int fd, nchars;
637 char tbuf[8192];
638
639 if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
640 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
641 (void)write(fileno(stdout), tbuf, nchars);
642 sleepexit(0);
643 }
644}
645
646void
647dolastlog(quiet)
648 int quiet;
649{
650 struct lastlog ll;
651 int fd;
652
653 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
654 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
655 if (!quiet) {
656 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
657 ll.ll_time != 0) {
658 (void)printf("Last login: %.*s ",
659 24-5, (char *)ctime(&ll.ll_time));
660 if (*ll.ll_host != '\0')
661 (void)printf("from %.*s\n",
662 (int)sizeof(ll.ll_host),
663 ll.ll_host);
664 else
665 (void)printf("on %.*s\n",
666 (int)sizeof(ll.ll_line),
667 ll.ll_line);
668 }
669 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
670 }
671 memset((void *)&ll, 0, sizeof(ll));
672 (void)time(&ll.ll_time);
673 (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
674 if (hostname)
675 (void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
676 (void)write(fd, (char *)&ll, sizeof(ll));
677 (void)close(fd);
678 }
679}
680
681void
682badlogin(name)
683 char *name;
684{
685
686 if (failures == 0)
687 return;
688 if (hostname) {
689 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
690 failures, failures > 1 ? "S" : "", hostname);
691 syslog(LOG_AUTHPRIV|LOG_NOTICE,
692 "%d LOGIN FAILURE%s FROM %s, %s",
693 failures, failures > 1 ? "S" : "", hostname, name);
694 } else {
695 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
696 failures, failures > 1 ? "S" : "", tty);
697 syslog(LOG_AUTHPRIV|LOG_NOTICE,
698 "%d LOGIN FAILURE%s ON %s, %s",
699 failures, failures > 1 ? "S" : "", tty, name);
700 }
701}
702
703#undef UNKNOWN
704#define UNKNOWN "su"
705
706char *
707stypeof(ttyid)
708 char *ttyid;
709{
710 struct ttyent *t;
711
712 return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
713}
714
715void
716sleepexit(eval)
717 int eval;
718{
719
720 (void)sleep(5);
721 exit(eval);
722}