143653Sbostic /*- 247437Skarels * Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University 347437Skarels * of California. All rights reserved. 436515Sbostic * 543653Sbostic * %sccs.include.redist.c% 619843Sdist */ 719843Sdist 812678Ssam #ifndef lint 919843Sdist char copyright[] = 1047437Skarels "@(#) Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University of California.\n\ 1119843Sdist All rights reserved.\n"; 1236515Sbostic #endif /* not lint */ 1312678Ssam 1419843Sdist #ifndef lint 15*47685Skfall static char sccsid[] = "@(#)login.c 5.68 (Berkeley) 03/29/91"; 1636515Sbostic #endif /* not lint */ 1719843Sdist 181043Sbill /* 191043Sbill * login [ name ] 2031695Skarels * login -h hostname (for telnetd, etc.) 2131695Skarels * login -f name (for pre-authenticated login: datakit, xterm, etc.) 221043Sbill */ 231043Sbill 2412984Ssam #include <sys/param.h> 2512687Ssam #include <sys/stat.h> 2612687Ssam #include <sys/time.h> 2712687Ssam #include <sys/resource.h> 2816453Sroot #include <sys/file.h> 2912687Ssam 301043Sbill #include <utmp.h> 311043Sbill #include <signal.h> 3212678Ssam #include <errno.h> 3316453Sroot #include <ttyent.h> 3416453Sroot #include <syslog.h> 3526862Smckusick #include <grp.h> 3636460Sbostic #include <pwd.h> 3736515Sbostic #include <setjmp.h> 3836460Sbostic #include <stdio.h> 3942063Sbostic #include <string.h> 4037203Sbostic #include <tzfile.h> 4137203Sbostic #include "pathnames.h" 421043Sbill 4336460Sbostic #define TTYGRPNAME "tty" /* name of group to own ttys */ 4426862Smckusick 4512687Ssam /* 4636460Sbostic * This bounds the time given to login. Not a define so it can 4736460Sbostic * be patched on machines where it's too small. 4812687Ssam */ 4931509Sbostic int timeout = 300; 5043653Sbostic #ifdef KERBEROS 5143653Sbostic int notickets = 1; 52*47685Skfall int rootlogin = 0; 53*47685Skfall #define ROOTLOGIN (rootlogin || (pwd && pwd->pw_uid == 0)) 54*47685Skfall #else 55*47685Skfall #define ROOTLOGIN (pwd && pwd->pw_uid == 0) 5643653Sbostic #endif 576005Swnj 5836647Skarels struct passwd *pwd; 5936647Skarels int failures; 6040490Sbostic char term[64], *envinit[1], *hostname, *username, *tty; 616005Swnj 621043Sbill main(argc, argv) 6336460Sbostic int argc; 6436460Sbostic char **argv; 651043Sbill { 6643653Sbostic extern int optind; 6736460Sbostic extern char *optarg, **environ; 6836880Sbostic struct timeval tp; 6936460Sbostic struct group *gr; 7036460Sbostic register int ch; 7136647Skarels register char *p; 7239271Skfall int ask, fflag, hflag, pflag, cnt, uid; 7344568Smarc int quietlog, rval; 7443653Sbostic char *domain, *salt, *ttyn; 7537692Sbostic char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; 7638034Skfall char localhost[MAXHOSTNAMELEN]; 7736880Sbostic char *ctime(), *ttyname(), *stypeof(), *crypt(), *getpass(); 7836460Sbostic time_t time(); 7936460Sbostic off_t lseek(); 8043653Sbostic void timedout(); 811043Sbill 8236460Sbostic (void)signal(SIGALRM, timedout); 8336460Sbostic (void)alarm((u_int)timeout); 8436460Sbostic (void)signal(SIGQUIT, SIG_IGN); 8536460Sbostic (void)signal(SIGINT, SIG_IGN); 8636460Sbostic (void)setpriority(PRIO_PROCESS, 0, 0); 8736460Sbostic 8842502Sbostic openlog("login", LOG_ODELAY, LOG_AUTH); 8942502Sbostic 9012687Ssam /* 9118549Ssam * -p is used by getty to tell login not to destroy the environment 9231695Skarels * -f is used to skip a second login authentication 9336523Skarels * -h is used by other servers to pass the name of the remote 9436523Skarels * host to login so that it may be placed in utmp and wtmp 9512687Ssam */ 9638034Skfall domain = NULL; 9738034Skfall if (gethostname(localhost, sizeof(localhost)) < 0) 9838034Skfall syslog(LOG_ERR, "couldn't get local hostname: %m"); 9938034Skfall else 10038034Skfall domain = index(localhost, '.'); 10136460Sbostic 10237203Sbostic fflag = hflag = pflag = 0; 10339271Skfall uid = getuid(); 10437203Sbostic while ((ch = getopt(argc, argv, "fh:p")) != EOF) 10536515Sbostic switch (ch) { 10636460Sbostic case 'f': 10736460Sbostic fflag = 1; 10836460Sbostic break; 10936460Sbostic case 'h': 11039271Skfall if (uid) { 11137203Sbostic (void)fprintf(stderr, 11236460Sbostic "login: -h for super-user only.\n"); 11332313Sbostic exit(1); 11431695Skarels } 11536460Sbostic hflag = 1; 11636460Sbostic if (domain && (p = index(optarg, '.')) && 11736553Sbostic strcasecmp(p, domain) == 0) 11836460Sbostic *p = 0; 11936460Sbostic hostname = optarg; 12036460Sbostic break; 12136460Sbostic case 'p': 12218549Ssam pflag = 1; 12336460Sbostic break; 12436460Sbostic case '?': 12536460Sbostic default: 12639271Skfall if (!uid) 12739271Skfall syslog(LOG_ERR, "invalid flag %c", ch); 12837203Sbostic (void)fprintf(stderr, 12937203Sbostic "usage: login [-fp] [username]\n"); 13036460Sbostic exit(1); 13118549Ssam } 13236460Sbostic argc -= optind; 13336460Sbostic argv += optind; 13436549Sbostic if (*argv) { 13536647Skarels username = *argv; 13643653Sbostic if (strlen(username) > UT_NAMESIZE) 13743653Sbostic username[UT_NAMESIZE] = '\0'; 13836549Sbostic ask = 0; 13936647Skarels } else 14036549Sbostic ask = 1; 14136460Sbostic 14236460Sbostic for (cnt = getdtablesize(); cnt > 2; cnt--) 14336460Sbostic close(cnt); 14436460Sbostic 1451043Sbill ttyn = ttyname(0); 14637692Sbostic if (ttyn == NULL || *ttyn == '\0') { 14737692Sbostic (void)sprintf(tname, "%s??", _PATH_TTY); 14837692Sbostic ttyn = tname; 14937692Sbostic } 15036460Sbostic if (tty = rindex(ttyn, '/')) 15136460Sbostic ++tty; 15236460Sbostic else 15316453Sroot tty = ttyn; 15436460Sbostic 15536549Sbostic for (cnt = 0;; ask = 1) { 15636549Sbostic if (ask) { 15736515Sbostic fflag = 0; 15836460Sbostic getloginname(); 15936515Sbostic } 16036647Skarels /* 16139271Skfall * Note if trying multiple user names; log failures for 16239271Skfall * previous user name, but don't bother logging one failure 16336647Skarels * for nonexistent name (mistyped username). 16436647Skarels */ 16536647Skarels if (failures && strcmp(tbuf, username)) { 16636647Skarels if (failures > (pwd ? 0 : 1)) 16736549Sbostic badlogin(tbuf); 16836647Skarels failures = 0; 16936549Sbostic } 17036647Skarels (void)strcpy(tbuf, username); 17143659Sbostic 17236515Sbostic if (pwd = getpwnam(username)) 17336515Sbostic salt = pwd->pw_passwd; 17443659Sbostic else 17543659Sbostic salt = "xx"; 17636460Sbostic 17712687Ssam /* 17843674Sbostic * if we have a valid account name, and it doesn't have a 17943674Sbostic * password, or the -f option was specified and the caller 18043674Sbostic * is root or the caller isn't changing their uid, don't 18143674Sbostic * authenticate. 18212687Ssam */ 18343674Sbostic if (pwd && (*pwd->pw_passwd == '\0' || 18443674Sbostic fflag && (uid == 0 || uid == pwd->pw_uid))) 18536460Sbostic break; 18644348Skarels fflag = 0; 18712687Ssam 18839271Skfall /* 18939271Skfall * If trying to log in as root, but with insecure terminal, 19039271Skfall * refuse the login attempt. 19139271Skfall */ 192*47685Skfall if (ROOTLOGIN && !rootterm(tty)) { 19339271Skfall (void)fprintf(stderr, 19439271Skfall "%s login refused on this terminal.\n", 19539271Skfall pwd->pw_name); 19639271Skfall if (hostname) 19739271Skfall syslog(LOG_NOTICE, 19839271Skfall "LOGIN %s REFUSED FROM %s ON TTY %s", 19939271Skfall pwd->pw_name, hostname, tty); 20039271Skfall else 20139271Skfall syslog(LOG_NOTICE, 20239271Skfall "LOGIN %s REFUSED ON TTY %s", 20339271Skfall pwd->pw_name, tty); 20439271Skfall continue; 20539271Skfall } 20639271Skfall 20743653Sbostic (void)setpriority(PRIO_PROCESS, 0, -4); 20843659Sbostic 20943653Sbostic p = getpass("Password:"); 21036608Skfall 21143659Sbostic if (pwd) { 21243653Sbostic #ifdef KERBEROS 21343659Sbostic rval = klogin(pwd, localhost, p); 21443659Sbostic if (rval == 1) 21543659Sbostic rval = strcmp(crypt(p, salt), pwd->pw_passwd); 21643659Sbostic #else 21743653Sbostic rval = strcmp(crypt(p, salt), pwd->pw_passwd); 21837203Sbostic #endif 21943659Sbostic } 22043653Sbostic bzero(p, strlen(p)); 22143659Sbostic 22243659Sbostic (void)setpriority(PRIO_PROCESS, 0, 0); 22343659Sbostic 22443659Sbostic if (pwd && !rval) 22536460Sbostic break; 22636460Sbostic 22743659Sbostic (void)printf("Login incorrect\n"); 22836647Skarels failures++; 22936549Sbostic /* we allow 10 tries, but after 3 we start backing off */ 23036549Sbostic if (++cnt > 3) { 23136549Sbostic if (cnt >= 10) { 23236549Sbostic badlogin(username); 23336549Sbostic sleepexit(1); 23436549Sbostic } 23536549Sbostic sleep((u_int)((cnt - 3) * 5)); 2362822Swnj } 23736460Sbostic } 2381043Sbill 23936460Sbostic /* committed to login -- turn off timeout */ 24036460Sbostic (void)alarm((u_int)0); 24136460Sbostic 24237692Sbostic /* paranoia... */ 24337692Sbostic endpwent(); 24437692Sbostic 24543663Sbostic /* if user not super-user, check for disabled logins */ 246*47685Skfall if (!(ROOTLOGIN)) 24743663Sbostic checknologin(); 24843663Sbostic 24936515Sbostic if (chdir(pwd->pw_dir) < 0) { 25037203Sbostic (void)printf("No directory %s!\n", pwd->pw_dir); 25136515Sbostic if (chdir("/")) 25236515Sbostic exit(0); 25336515Sbostic pwd->pw_dir = "/"; 25437203Sbostic (void)printf("Logging in with home = \"/\".\n"); 25536515Sbostic } 25636515Sbostic 25737203Sbostic quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; 25837203Sbostic 25936880Sbostic if (pwd->pw_change || pwd->pw_expire) 26036880Sbostic (void)gettimeofday(&tp, (struct timezone *)NULL); 26136880Sbostic if (pwd->pw_change) 26236880Sbostic if (tp.tv_sec >= pwd->pw_change) { 26337203Sbostic (void)printf("Sorry -- your password has expired.\n"); 26436880Sbostic sleepexit(1); 26536880Sbostic } 26638216Sbostic else if (pwd->pw_change - tp.tv_sec < 26743660Sbostic 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) 26843660Sbostic (void)printf("Warning: your password expires on %s", 26943660Sbostic ctime(&pwd->pw_expire)); 27036880Sbostic if (pwd->pw_expire) 27136880Sbostic if (tp.tv_sec >= pwd->pw_expire) { 27237203Sbostic (void)printf("Sorry -- your account has expired.\n"); 27336880Sbostic sleepexit(1); 27436880Sbostic } 27538216Sbostic else if (pwd->pw_expire - tp.tv_sec < 27643660Sbostic 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) 27743660Sbostic (void)printf("Warning: your account expires on %s", 27843660Sbostic ctime(&pwd->pw_expire)); 27936880Sbostic 28036515Sbostic /* nothing else left to fail -- really log in */ 28136460Sbostic { 28236460Sbostic struct utmp utmp; 28336460Sbostic 28443653Sbostic bzero((void *)&utmp, sizeof(utmp)); 28536460Sbostic (void)time(&utmp.ut_time); 28636460Sbostic strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); 28736591Sbostic if (hostname) 28836591Sbostic strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); 28936460Sbostic strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); 29036460Sbostic login(&utmp); 29136460Sbostic } 29236460Sbostic 29336549Sbostic dolastlog(quietlog); 29436460Sbostic 29536460Sbostic (void)chown(ttyn, pwd->pw_uid, 29636460Sbostic (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); 29736460Sbostic (void)chmod(ttyn, 0620); 29836460Sbostic (void)setgid(pwd->pw_gid); 29936460Sbostic 30036460Sbostic initgroups(username, pwd->pw_gid); 30136460Sbostic 30236515Sbostic if (*pwd->pw_shell == '\0') 30337203Sbostic pwd->pw_shell = _PATH_BSHELL; 30436515Sbostic 30536460Sbostic /* destroy environment unless user has requested preservation */ 30618549Ssam if (!pflag) 30718549Ssam environ = envinit; 30836515Sbostic (void)setenv("HOME", pwd->pw_dir, 1); 30936515Sbostic (void)setenv("SHELL", pwd->pw_shell, 1); 31018549Ssam if (term[0] == '\0') 31136647Skarels strncpy(term, stypeof(tty), sizeof(term)); 31236515Sbostic (void)setenv("TERM", term, 0); 31336515Sbostic (void)setenv("USER", pwd->pw_name, 1); 31437252Sbostic (void)setenv("PATH", _PATH_DEFPATH, 0); 31518549Ssam 31616453Sroot if (tty[sizeof("tty")-1] == 'd') 31718549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 31844348Skarels /* if fflag is on, assume caller/authenticator has logged root login */ 319*47685Skfall if (ROOTLOGIN && fflag == 0) 32036460Sbostic if (hostname) 321*47685Skfall syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s", 322*47685Skfall username, tty, hostname); 32325230Smckusick else 324*47685Skfall syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty); 32536460Sbostic 32643653Sbostic #ifdef KERBEROS 32743653Sbostic if (!quietlog && notickets == 1) 32843653Sbostic (void)printf("Warning: no Kerberos tickets issued.\n"); 32943653Sbostic #endif 33043653Sbostic 3316329Swnj if (!quietlog) { 33217664Sserge struct stat st; 33318549Ssam 33447437Skarels printf( 33547437Skarels "Copyright (c) 1980,1983,1986,1988,1990,1991 The Regents of the University\n%s", 33647437Skarels "of California. All rights reserved.\n\n"); 33736460Sbostic motd(); 33837203Sbostic (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name); 33936460Sbostic if (stat(tbuf, &st) == 0 && st.st_size != 0) 34037203Sbostic (void)printf("You have %smail.\n", 34136460Sbostic (st.st_mtime > st.st_atime) ? "new " : ""); 3422822Swnj } 34336460Sbostic 34436460Sbostic (void)signal(SIGALRM, SIG_DFL); 34536460Sbostic (void)signal(SIGQUIT, SIG_DFL); 34636460Sbostic (void)signal(SIGINT, SIG_DFL); 34736460Sbostic (void)signal(SIGTSTP, SIG_IGN); 34836460Sbostic 34936460Sbostic tbuf[0] = '-'; 35036460Sbostic strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ? 35136460Sbostic p + 1 : pwd->pw_shell); 35237203Sbostic 35340009Ssklower if (setlogin(pwd->pw_name) < 0) 35440009Ssklower syslog(LOG_ERR, "setlogin() failure: %m"); 35537692Sbostic 35637203Sbostic /* discard permissions last so can't get killed and drop core */ 357*47685Skfall if (ROOTLOGIN) 358*47685Skfall (void) setuid(0); 359*47685Skfall else 360*47685Skfall (void)setuid(pwd->pw_uid); 36137203Sbostic 36236460Sbostic execlp(pwd->pw_shell, tbuf, 0); 36337203Sbostic (void)fprintf(stderr, "login: no shell: %s.\n", strerror(errno)); 3641043Sbill exit(0); 3651043Sbill } 3661043Sbill 367*47685Skfall #ifdef KERBEROS 368*47685Skfall #define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */ 369*47685Skfall #else 370*47685Skfall #define NBUFSIZ (UT_NAMESIZE + 1) 371*47685Skfall #endif 372*47685Skfall 37336460Sbostic getloginname() 37412687Ssam { 37536460Sbostic register int ch; 376*47685Skfall register char *p, *instance; 377*47685Skfall static char nbuf[NBUFSIZ]; 37812687Ssam 37936460Sbostic for (;;) { 38037203Sbostic (void)printf("login: "); 38136515Sbostic for (p = nbuf; (ch = getchar()) != '\n'; ) { 38236549Sbostic if (ch == EOF) { 38336549Sbostic badlogin(username); 38412687Ssam exit(0); 38536549Sbostic } 386*47685Skfall if (p < nbuf + (NBUFSIZ - 1)) 38736460Sbostic *p++ = ch; 38812687Ssam } 38936460Sbostic if (p > nbuf) 39036460Sbostic if (nbuf[0] == '-') 39137203Sbostic (void)fprintf(stderr, 39236460Sbostic "login names may not start with '-'.\n"); 39336460Sbostic else { 39436460Sbostic *p = '\0'; 39536460Sbostic username = nbuf; 39636515Sbostic break; 39736460Sbostic } 39812687Ssam } 399*47685Skfall #ifdef KERBEROS 400*47685Skfall if ((instance = index(nbuf, '.')) != NULL) { 401*47685Skfall if (strncmp(instance, ".root", 5) == 0) { 402*47685Skfall rootlogin++; 403*47685Skfall } 404*47685Skfall *instance = '\0'; 405*47685Skfall if ((instance - nbuf) > UT_NAMESIZE) 406*47685Skfall nbuf[UT_NAMESIZE] = '\0'; 407*47685Skfall } else 408*47685Skfall rootlogin = 0; 409*47685Skfall #endif 41012687Ssam } 41112687Ssam 41243653Sbostic void 41312687Ssam timedout() 41412687Ssam { 41537203Sbostic (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout); 41612687Ssam exit(0); 41712687Ssam } 41812687Ssam 41936647Skarels rootterm(ttyn) 42036647Skarels char *ttyn; 4211043Sbill { 42236460Sbostic struct ttyent *t; 4236466Swnj 42436647Skarels return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE); 4251043Sbill } 4261043Sbill 42736515Sbostic jmp_buf motdinterrupt; 42836515Sbostic 42936460Sbostic motd() 4302822Swnj { 43136515Sbostic register int fd, nchars; 43238726Skfall sig_t oldint; 43346835Sbostic void sigint(); 43436515Sbostic char tbuf[8192]; 4352822Swnj 43637203Sbostic if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0) 43736460Sbostic return; 43836460Sbostic oldint = signal(SIGINT, sigint); 43936515Sbostic if (setjmp(motdinterrupt) == 0) 44036515Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 44136515Sbostic (void)write(fileno(stdout), tbuf, nchars); 44236460Sbostic (void)signal(SIGINT, oldint); 44336515Sbostic (void)close(fd); 44436460Sbostic } 44536460Sbostic 44646835Sbostic void 44736460Sbostic sigint() 44836460Sbostic { 44936515Sbostic longjmp(motdinterrupt, 1); 45036460Sbostic } 45136460Sbostic 45236460Sbostic checknologin() 45336460Sbostic { 45436460Sbostic register int fd, nchars; 45536515Sbostic char tbuf[8192]; 45636460Sbostic 45737203Sbostic if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) { 45836460Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 45936460Sbostic (void)write(fileno(stdout), tbuf, nchars); 46036460Sbostic sleepexit(0); 4612822Swnj } 4622822Swnj } 4632822Swnj 46436549Sbostic dolastlog(quiet) 46536460Sbostic int quiet; 4661043Sbill { 46736460Sbostic struct lastlog ll; 46836460Sbostic int fd; 46936880Sbostic char *ctime(); 4701043Sbill 47137203Sbostic if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { 47236515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 47336460Sbostic if (!quiet) { 47436460Sbostic if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && 47536460Sbostic ll.ll_time != 0) { 47637203Sbostic (void)printf("Last login: %.*s ", 47736460Sbostic 24-5, (char *)ctime(&ll.ll_time)); 47836460Sbostic if (*ll.ll_host != '\0') 47937203Sbostic (void)printf("from %.*s\n", 48036460Sbostic sizeof(ll.ll_host), ll.ll_host); 48136460Sbostic else 48237203Sbostic (void)printf("on %.*s\n", 48336460Sbostic sizeof(ll.ll_line), ll.ll_line); 48436460Sbostic } 48536515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 48636460Sbostic } 48743653Sbostic bzero((void *)&ll, sizeof(ll)); 48836460Sbostic (void)time(&ll.ll_time); 48936460Sbostic strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 49036591Sbostic if (hostname) 49136591Sbostic strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); 49236460Sbostic (void)write(fd, (char *)&ll, sizeof(ll)); 49336460Sbostic (void)close(fd); 4941043Sbill } 4951043Sbill } 4961043Sbill 49736549Sbostic badlogin(name) 49836549Sbostic char *name; 49936549Sbostic { 50036647Skarels if (failures == 0) 50136549Sbostic return; 50245431Sbostic if (hostname) { 50345431Sbostic syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s", 50445431Sbostic failures, failures > 1 ? "S" : "", hostname); 50545431Sbostic syslog(LOG_AUTHPRIV|LOG_NOTICE, 50645431Sbostic "%d LOGIN FAILURE%s FROM %s, %s", 50736647Skarels failures, failures > 1 ? "S" : "", hostname, name); 50845431Sbostic } else { 50945431Sbostic syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s", 51045431Sbostic failures, failures > 1 ? "S" : "", tty); 51145431Sbostic syslog(LOG_AUTHPRIV|LOG_NOTICE, 51245431Sbostic "%d LOGIN FAILURE%s ON %s, %s", 51336647Skarels failures, failures > 1 ? "S" : "", tty, name); 51445431Sbostic } 51536549Sbostic } 51636549Sbostic 5172822Swnj #undef UNKNOWN 51836460Sbostic #define UNKNOWN "su" 5191043Sbill 5201043Sbill char * 52136647Skarels stypeof(ttyid) 52236647Skarels char *ttyid; 5231043Sbill { 52436460Sbostic struct ttyent *t; 5251043Sbill 52636647Skarels return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); 5271043Sbill } 5286005Swnj 52936460Sbostic sleepexit(eval) 53036460Sbostic int eval; 53126862Smckusick { 53236460Sbostic sleep((u_int)5); 53336460Sbostic exit(eval); 53426862Smckusick } 535