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