119843Sdist /* 236515Sbostic * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. 336515Sbostic * All rights reserved. 436515Sbostic * 536515Sbostic * Redistribution and use in source and binary forms are permitted 636515Sbostic * provided that the above copyright notice and this paragraph are 736515Sbostic * duplicated in all such forms and that any documentation, 836515Sbostic * advertising materials, and other materials related to such 936515Sbostic * distribution and use acknowledge that the software was developed 1036515Sbostic * by the University of California, Berkeley. The name of the 1136515Sbostic * University may not be used to endorse or promote products derived 1236515Sbostic * from this software without specific prior written permission. 1336515Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1436515Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536515Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1619843Sdist */ 1719843Sdist 1812678Ssam #ifndef lint 1919843Sdist char copyright[] = 2036515Sbostic "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\ 2119843Sdist All rights reserved.\n"; 2236515Sbostic #endif /* not lint */ 2312678Ssam 2419843Sdist #ifndef lint 25*36608Skfall static char sccsid[] = "@(#)login.c 5.29 (Berkeley) 1/20/89"; 2636515Sbostic #endif /* not lint */ 2719843Sdist 281043Sbill /* 291043Sbill * login [ name ] 3031695Skarels * login -h hostname (for telnetd, etc.) 3131695Skarels * login -f name (for pre-authenticated login: datakit, xterm, etc.) 321043Sbill */ 331043Sbill 3412984Ssam #include <sys/param.h> 3512687Ssam #include <sys/quota.h> 3612687Ssam #include <sys/stat.h> 3712687Ssam #include <sys/time.h> 3812687Ssam #include <sys/resource.h> 3916453Sroot #include <sys/file.h> 4036460Sbostic #include <sys/ioctl.h> 4112687Ssam 421043Sbill #include <utmp.h> 431043Sbill #include <signal.h> 441043Sbill #include <lastlog.h> 4512678Ssam #include <errno.h> 4616453Sroot #include <ttyent.h> 4716453Sroot #include <syslog.h> 4826862Smckusick #include <grp.h> 4936460Sbostic #include <pwd.h> 5036515Sbostic #include <setjmp.h> 5136460Sbostic #include <stdio.h> 5236460Sbostic #include <strings.h> 531043Sbill 54*36608Skfall #ifdef KERBEROS 55*36608Skfall #include <kerberos/krb.h> 56*36608Skfall #include <sys/termios.h> 57*36608Skfall char inst[INST_SZ]; 58*36608Skfall char realm[REALM_SZ]; 59*36608Skfall int kerror = KSUCCESS, notickets = 1; 60*36608Skfall #define LIFE 96 /* ticket lifetime in 5-min units */ 61*36608Skfall #endif 62*36608Skfall 6336460Sbostic #define TTYGRPNAME "tty" /* name of group to own ttys */ 6426862Smckusick 6536460Sbostic #define MOTDFILE "/etc/motd" 6636460Sbostic #define MAILDIR "/usr/spool/mail" 6736460Sbostic #define NOLOGIN "/etc/nologin" 6836460Sbostic #define HUSHLOGIN ".hushlogin" 6936460Sbostic #define LASTLOG "/usr/adm/lastlog" 7036460Sbostic #define BSHELL "/bin/sh" 712822Swnj 7212687Ssam /* 7336460Sbostic * This bounds the time given to login. Not a define so it can 7436460Sbostic * be patched on machines where it's too small. 7512687Ssam */ 7631509Sbostic int timeout = 300; 776005Swnj 7836460Sbostic struct passwd *pwd; 7936549Sbostic int repeatcnt; 8036549Sbostic char term[64], *hostname, *username, *tty; 816005Swnj 8236515Sbostic struct sgttyb sgttyb; 8336460Sbostic struct tchars tc = { 8413074Ssam CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 851365Sbill }; 8636460Sbostic struct ltchars ltc = { 8713074Ssam CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT 8813074Ssam }; 891365Sbill 901043Sbill main(argc, argv) 9136460Sbostic int argc; 9236460Sbostic char **argv; 931043Sbill { 9436460Sbostic extern int errno, optind; 9536460Sbostic extern char *optarg, **environ; 9636460Sbostic struct group *gr; 9736460Sbostic register int ch; 98*36608Skfall register char *p, *pp; 9936549Sbostic int ask, fflag, hflag, pflag, cnt; 10036460Sbostic int quietlog, passwd_req, ioctlval, timedout(); 10136549Sbostic char *domain, *salt, *envinit[1], *ttyn; 10236460Sbostic char tbuf[MAXPATHLEN + 2]; 10336460Sbostic char *ttyname(), *stypeof(), *crypt(), *getpass(); 10436460Sbostic time_t time(); 10536460Sbostic off_t lseek(); 1061043Sbill 10736460Sbostic (void)signal(SIGALRM, timedout); 10836460Sbostic (void)alarm((u_int)timeout); 10936460Sbostic (void)signal(SIGQUIT, SIG_IGN); 11036460Sbostic (void)signal(SIGINT, SIG_IGN); 11136460Sbostic (void)setpriority(PRIO_PROCESS, 0, 0); 11236460Sbostic (void)quota(Q_SETUID, 0, 0, 0); 11336460Sbostic 11412687Ssam /* 11518549Ssam * -p is used by getty to tell login not to destroy the environment 11631695Skarels * -f is used to skip a second login authentication 11736523Skarels * -h is used by other servers to pass the name of the remote 11836523Skarels * host to login so that it may be placed in utmp and wtmp 11912687Ssam */ 12036460Sbostic (void)gethostname(tbuf, sizeof(tbuf)); 12136460Sbostic domain = index(tbuf, '.'); 12236460Sbostic 12336523Skarels fflag = hflag = pflag = 0; 12436460Sbostic passwd_req = 1; 12536523Skarels while ((ch = getopt(argc, argv, "fh:p")) != EOF) 12636515Sbostic switch (ch) { 12736460Sbostic case 'f': 12836460Sbostic fflag = 1; 12936460Sbostic break; 13036460Sbostic case 'h': 13136460Sbostic if (getuid()) { 13236460Sbostic fprintf(stderr, 13336460Sbostic "login: -h for super-user only.\n"); 13432313Sbostic exit(1); 13531695Skarels } 13636460Sbostic hflag = 1; 13736460Sbostic if (domain && (p = index(optarg, '.')) && 13836553Sbostic strcasecmp(p, domain) == 0) 13936460Sbostic *p = 0; 14036460Sbostic hostname = optarg; 14136460Sbostic break; 14236460Sbostic case 'p': 14318549Ssam pflag = 1; 14436460Sbostic break; 14536460Sbostic case '?': 14636460Sbostic default: 14736515Sbostic fprintf(stderr, "usage: login [-fp] [username]\n"); 14836460Sbostic exit(1); 14918549Ssam } 15036460Sbostic argc -= optind; 15136460Sbostic argv += optind; 15236549Sbostic if (*argv) { 15336549Sbostic ask = 0; 15436460Sbostic username = *argv; 15536549Sbostic } 15636549Sbostic else 15736549Sbostic ask = 1; 15836460Sbostic 15936460Sbostic ioctlval = 0; 16036460Sbostic (void)ioctl(0, TIOCLSET, &ioctlval); 16136460Sbostic (void)ioctl(0, TIOCNXCL, 0); 16236515Sbostic (void)fcntl(0, F_SETFL, ioctlval); 16336515Sbostic (void)ioctl(0, TIOCGETP, &sgttyb); 16436515Sbostic sgttyb.sg_erase = CERASE; 16536515Sbostic sgttyb.sg_kill = CKILL; 16636460Sbostic (void)ioctl(0, TIOCSLTC, <c); 16736460Sbostic (void)ioctl(0, TIOCSETC, &tc); 16836515Sbostic (void)ioctl(0, TIOCSETP, &sgttyb); 16936460Sbostic 17036460Sbostic for (cnt = getdtablesize(); cnt > 2; cnt--) 17136460Sbostic close(cnt); 17236460Sbostic 1731043Sbill ttyn = ttyname(0); 17436460Sbostic if (ttyn == NULL || *ttyn == '\0') 1751043Sbill ttyn = "/dev/tty??"; 17636460Sbostic if (tty = rindex(ttyn, '/')) 17736460Sbostic ++tty; 17836460Sbostic else 17916453Sroot tty = ttyn; 18036460Sbostic 18124852Seric openlog("login", LOG_ODELAY, LOG_AUTH); 18236460Sbostic 18336549Sbostic for (cnt = 0;; ask = 1) { 18436460Sbostic ioctlval = 0; 18536460Sbostic (void)ioctl(0, TIOCSETD, &ioctlval); 18636460Sbostic 18736549Sbostic if (ask) { 18836515Sbostic fflag = 0; 18936460Sbostic getloginname(); 19036515Sbostic } 19136549Sbostic /* note if trying multiple login's */ 19236549Sbostic if (repeatcnt) { 19336549Sbostic if (strcmp(tbuf, username)) { 19436549Sbostic badlogin(tbuf); 19536549Sbostic repeatcnt = 1; 19636549Sbostic (void)strcpy(tbuf, username); 19736549Sbostic } 19836549Sbostic else 19936549Sbostic ++repeatcnt; 20036549Sbostic } 20136549Sbostic else { 20236549Sbostic repeatcnt = 1; 20336549Sbostic (void)strcpy(tbuf, username); 20436549Sbostic } 20536515Sbostic if (pwd = getpwnam(username)) 20636515Sbostic salt = pwd->pw_passwd; 20736515Sbostic else 20836515Sbostic salt = "xx"; 20936460Sbostic 21036460Sbostic /* if user not super-user, check for disabled logins */ 21136515Sbostic if (pwd == NULL || pwd->pw_uid) 21236460Sbostic checknologin(); 21336460Sbostic 21412687Ssam /* 21536515Sbostic * Disallow automatic login to root; if not invoked by 21636515Sbostic * root, disallow if the uid's differ. 21712687Ssam */ 21836515Sbostic if (fflag && pwd) { 21931695Skarels int uid = getuid(); 22031695Skarels 22136515Sbostic passwd_req = pwd->pw_uid == 0 || 22236515Sbostic (uid && uid != pwd->pw_uid); 22331695Skarels } 22436460Sbostic 22512687Ssam /* 22636523Skarels * If no pre-authentication and a password exists 22736460Sbostic * for this user, prompt for one and verify it. 22812687Ssam */ 229*36608Skfall if (!passwd_req || (pwd && !*pwd->pw_passwd)) 23036460Sbostic break; 23112687Ssam 23236460Sbostic setpriority(PRIO_PROCESS, 0, -4); 233*36608Skfall pp = getpass("Password:"); 234*36608Skfall p = crypt(pp, salt); 23536460Sbostic setpriority(PRIO_PROCESS, 0, 0); 236*36608Skfall 237*36608Skfall #ifdef KERBEROS 238*36608Skfall 239*36608Skfall /* 240*36608Skfall * If we aren't Kerberos-authenticated, try the normal 241*36608Skfall * pw file for a password. If that's ok, log the user 242*36608Skfall * in without issueing any tickets. 243*36608Skfall */ 244*36608Skfall 245*36608Skfall if(!get_krbrlm(realm,1)) { 246*36608Skfall /* get TGT for local realm */ 247*36608Skfall kerror = get_in_tkt(pwd->pw_name, inst, realm, 248*36608Skfall "krbtgt", realm, LIFE, pp); 249*36608Skfall if(kerror == KSUCCESS) { 250*36608Skfall bzero(pp, strlen(pp)); 251*36608Skfall notickets = 0; /* user got ticket */ 252*36608Skfall break; 253*36608Skfall } 254*36608Skfall } 255*36608Skfall #endif 256*36608Skfall (void) bzero(pp, strlen(pp)); 25736515Sbostic if (pwd && !strcmp(p, pwd->pw_passwd)) 25836460Sbostic break; 25936460Sbostic 26036460Sbostic printf("Login incorrect\n"); 26136549Sbostic /* we allow 10 tries, but after 3 we start backing off */ 26236549Sbostic if (++cnt > 3) { 26336549Sbostic if (cnt >= 10) { 26436549Sbostic badlogin(username); 26536549Sbostic (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL); 26636549Sbostic sleepexit(1); 26736549Sbostic } 26836549Sbostic sleep((u_int)((cnt - 3) * 5)); 2692822Swnj } 27036460Sbostic } 2711043Sbill 27236460Sbostic /* committed to login -- turn off timeout */ 27336460Sbostic (void)alarm((u_int)0); 27436460Sbostic 27536549Sbostic /* log any mistakes -- don't count last one */ 27636549Sbostic --repeatcnt; 27736549Sbostic badlogin(username); 27836549Sbostic 27936460Sbostic /* 28036460Sbostic * If valid so far and root is logging in, see if root logins on 28136460Sbostic * this terminal are permitted. 28236460Sbostic */ 28336549Sbostic if (pwd->pw_uid == 0 && !rootterm()) { 28436460Sbostic if (hostname) 28536549Sbostic syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s", 28636549Sbostic tty, hostname); 28712678Ssam else 28836515Sbostic syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty); 28936460Sbostic printf("Login incorrect\n"); 29036460Sbostic sleepexit(1); 29112678Ssam } 2922822Swnj 29336460Sbostic if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { 29436460Sbostic switch(errno) { 29536460Sbostic case EUSERS: 29636460Sbostic fprintf(stderr, 29736460Sbostic "Too many users logged on already.\nTry again later.\n"); 29836460Sbostic break; 29936460Sbostic case EPROCLIM: 30036460Sbostic fprintf(stderr, 30136460Sbostic "You have too many processes running.\n"); 30236460Sbostic break; 30336460Sbostic default: 30436460Sbostic perror("quota (Q_SETUID)"); 3052822Swnj } 30636460Sbostic sleepexit(0); 3072822Swnj } 30836460Sbostic 30936515Sbostic if (chdir(pwd->pw_dir) < 0) { 31036515Sbostic printf("No directory %s!\n", pwd->pw_dir); 31136515Sbostic if (chdir("/")) 31236515Sbostic exit(0); 31336515Sbostic pwd->pw_dir = "/"; 31436515Sbostic printf("Logging in with home = \"/\".\n"); 31536515Sbostic } 31636515Sbostic 317*36608Skfall #ifdef KERBEROS 318*36608Skfall if(notickets) 319*36608Skfall printf("Warning: no Kerberos tickets issued\n"); 320*36608Skfall #endif 321*36608Skfall 32236515Sbostic /* nothing else left to fail -- really log in */ 32336460Sbostic { 32436460Sbostic struct utmp utmp; 32536460Sbostic 32636460Sbostic (void)time(&utmp.ut_time); 32736460Sbostic strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); 32836591Sbostic if (hostname) 32936591Sbostic strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); 33036591Sbostic else 33136591Sbostic bzero(utmp.ut_host, sizeof(utmp.ut_host)); 33236460Sbostic strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); 33336460Sbostic login(&utmp); 33436460Sbostic } 33536460Sbostic 33636460Sbostic quietlog = access(HUSHLOGIN, F_OK) == 0; 33736549Sbostic dolastlog(quietlog); 33836460Sbostic 33936523Skarels if (!hflag) { /* XXX */ 34036460Sbostic static struct winsize win = { 0, 0, 0, 0 }; 34136460Sbostic 34236460Sbostic (void)ioctl(0, TIOCSWINSZ, &win); 34336460Sbostic } 34436460Sbostic 34536460Sbostic (void)chown(ttyn, pwd->pw_uid, 34636460Sbostic (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); 34736460Sbostic (void)chmod(ttyn, 0620); 34836460Sbostic (void)setgid(pwd->pw_gid); 34936460Sbostic 35036460Sbostic initgroups(username, pwd->pw_gid); 35136460Sbostic 35212678Ssam quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); 35336460Sbostic (void)setuid(pwd->pw_uid); 35430606Sbostic 35536515Sbostic if (*pwd->pw_shell == '\0') 35636515Sbostic pwd->pw_shell = BSHELL; 35736515Sbostic /* turn on new line discipline for the csh */ 35836515Sbostic else if (!strcmp(pwd->pw_shell, "/bin/csh")) { 35936515Sbostic ioctlval = NTTYDISC; 36036515Sbostic (void)ioctl(0, TIOCSETD, &ioctlval); 36136515Sbostic } 36236515Sbostic 36336460Sbostic /* destroy environment unless user has requested preservation */ 36418549Ssam if (!pflag) 36518549Ssam environ = envinit; 36636515Sbostic (void)setenv("HOME", pwd->pw_dir, 1); 36736515Sbostic (void)setenv("SHELL", pwd->pw_shell, 1); 36818549Ssam if (term[0] == '\0') 36936549Sbostic strncpy(term, stypeof(), sizeof(term)); 37036515Sbostic (void)setenv("TERM", term, 0); 37136515Sbostic (void)setenv("USER", pwd->pw_name, 1); 37236515Sbostic (void)setenv("PATH", "/usr/ucb:/bin:/usr/bin:", 0); 37318549Ssam 37416453Sroot if (tty[sizeof("tty")-1] == 'd') 37518549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 37618549Ssam if (pwd->pw_uid == 0) 37736460Sbostic if (hostname) 37836549Sbostic syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s", 37936549Sbostic tty, hostname); 38025230Smckusick else 38125230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); 38236460Sbostic 3836329Swnj if (!quietlog) { 38417664Sserge struct stat st; 38518549Ssam 38636460Sbostic motd(); 38736460Sbostic (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name); 38836460Sbostic if (stat(tbuf, &st) == 0 && st.st_size != 0) 38917664Sserge printf("You have %smail.\n", 39036460Sbostic (st.st_mtime > st.st_atime) ? "new " : ""); 3912822Swnj } 39236460Sbostic 39336460Sbostic (void)signal(SIGALRM, SIG_DFL); 39436460Sbostic (void)signal(SIGQUIT, SIG_DFL); 39536460Sbostic (void)signal(SIGINT, SIG_DFL); 39636460Sbostic (void)signal(SIGTSTP, SIG_IGN); 39736460Sbostic 39836460Sbostic tbuf[0] = '-'; 39936460Sbostic strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ? 40036460Sbostic p + 1 : pwd->pw_shell); 40136460Sbostic execlp(pwd->pw_shell, tbuf, 0); 40236515Sbostic fprintf(stderr, "login: no shell: "); 4032822Swnj perror(pwd->pw_shell); 4041043Sbill exit(0); 4051043Sbill } 4061043Sbill 40736460Sbostic getloginname() 40812687Ssam { 40936460Sbostic register int ch; 41036460Sbostic register char *p; 41136460Sbostic static char nbuf[UT_NAMESIZE + 1]; 41212687Ssam 41336460Sbostic for (;;) { 41412712Ssam printf("login: "); 41536515Sbostic for (p = nbuf; (ch = getchar()) != '\n'; ) { 41636549Sbostic if (ch == EOF) { 41736549Sbostic badlogin(username); 41812687Ssam exit(0); 41936549Sbostic } 42036515Sbostic if (p < nbuf + UT_NAMESIZE) 42136460Sbostic *p++ = ch; 42212687Ssam } 42336460Sbostic if (p > nbuf) 42436460Sbostic if (nbuf[0] == '-') 42536460Sbostic fprintf(stderr, 42636460Sbostic "login names may not start with '-'.\n"); 42736460Sbostic else { 42836460Sbostic *p = '\0'; 42936460Sbostic username = nbuf; 43036515Sbostic break; 43136460Sbostic } 43212687Ssam } 43312687Ssam } 43412687Ssam 43512687Ssam timedout() 43612687Ssam { 43736460Sbostic fprintf(stderr, "Login timed out after %d seconds\n", timeout); 43812687Ssam exit(0); 43912687Ssam } 44012687Ssam 44136549Sbostic rootterm() 4421043Sbill { 44336460Sbostic struct ttyent *t; 4446466Swnj 44536460Sbostic return((t = getttynam(tty)) && t->ty_status&TTY_SECURE); 4461043Sbill } 4471043Sbill 44836515Sbostic jmp_buf motdinterrupt; 44936515Sbostic 45036460Sbostic motd() 4512822Swnj { 45236515Sbostic register int fd, nchars; 45336460Sbostic int (*oldint)(), sigint(); 45436515Sbostic char tbuf[8192]; 4552822Swnj 45636515Sbostic if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0) 45736460Sbostic return; 45836460Sbostic oldint = signal(SIGINT, sigint); 45936515Sbostic if (setjmp(motdinterrupt) == 0) 46036515Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 46136515Sbostic (void)write(fileno(stdout), tbuf, nchars); 46236460Sbostic (void)signal(SIGINT, oldint); 46336515Sbostic (void)close(fd); 46436460Sbostic } 46536460Sbostic 46636460Sbostic sigint() 46736460Sbostic { 46836515Sbostic longjmp(motdinterrupt, 1); 46936460Sbostic } 47036460Sbostic 47136460Sbostic checknologin() 47236460Sbostic { 47336460Sbostic register int fd, nchars; 47436515Sbostic char tbuf[8192]; 47536460Sbostic 47636460Sbostic if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) { 47736460Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 47836460Sbostic (void)write(fileno(stdout), tbuf, nchars); 47936460Sbostic sleepexit(0); 4802822Swnj } 4812822Swnj } 4822822Swnj 48336549Sbostic dolastlog(quiet) 48436460Sbostic int quiet; 4851043Sbill { 48636460Sbostic struct lastlog ll; 48736460Sbostic int fd; 4881043Sbill 48936460Sbostic if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) { 49036515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 49136460Sbostic if (!quiet) { 49236460Sbostic if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && 49336460Sbostic ll.ll_time != 0) { 49436460Sbostic printf("Last login: %.*s ", 49536460Sbostic 24-5, (char *)ctime(&ll.ll_time)); 49636460Sbostic if (*ll.ll_host != '\0') 49736460Sbostic printf("from %.*s\n", 49836460Sbostic sizeof(ll.ll_host), ll.ll_host); 49936460Sbostic else 50036460Sbostic printf("on %.*s\n", 50136460Sbostic sizeof(ll.ll_line), ll.ll_line); 50236460Sbostic } 50336515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 50436460Sbostic } 50536460Sbostic (void)time(&ll.ll_time); 50636460Sbostic strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 50736591Sbostic if (hostname) 50836591Sbostic strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); 50936591Sbostic else 51036591Sbostic bzero(ll.ll_host, sizeof(ll.ll_host)); 51136460Sbostic strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); 51236460Sbostic (void)write(fd, (char *)&ll, sizeof(ll)); 51336460Sbostic (void)close(fd); 5141043Sbill } 5151043Sbill } 5161043Sbill 51736549Sbostic badlogin(name) 51836549Sbostic char *name; 51936549Sbostic { 52036549Sbostic if (!repeatcnt) 52136549Sbostic return; 52236549Sbostic if (hostname) 52336549Sbostic syslog(LOG_ERR, "%d LOGIN FAILURE%s ON %s FROM %s, %s", 52436549Sbostic repeatcnt, repeatcnt > 1 ? "S" : "", tty, hostname, name); 52536549Sbostic else 52636549Sbostic syslog(LOG_ERR, "%d LOGIN FAILURE%s ON %s, %s", 52736549Sbostic repeatcnt, repeatcnt > 1 ? "S" : "", tty, name); 52836549Sbostic } 52936549Sbostic 5302822Swnj #undef UNKNOWN 53136460Sbostic #define UNKNOWN "su" 5321043Sbill 5331043Sbill char * 53436549Sbostic stypeof() 5351043Sbill { 53636460Sbostic struct ttyent *t; 5371043Sbill 53836549Sbostic return(tty && (t = getttynam(tty)) ? t->ty_type : UNKNOWN); 5391043Sbill } 5406005Swnj 5416005Swnj getstr(buf, cnt, err) 54236460Sbostic char *buf, *err; 5436005Swnj int cnt; 5446005Swnj { 54536460Sbostic char ch; 5466005Swnj 5476005Swnj do { 54836460Sbostic if (read(0, &ch, sizeof(ch)) != sizeof(ch)) 5496005Swnj exit(1); 5506005Swnj if (--cnt < 0) { 55136460Sbostic fprintf(stderr, "%s too long\r\n", err); 55236460Sbostic sleepexit(1); 5536005Swnj } 55436460Sbostic *buf++ = ch; 55536460Sbostic } while (ch); 5566005Swnj } 5576329Swnj 55836460Sbostic sleepexit(eval) 55936460Sbostic int eval; 56026862Smckusick { 56136460Sbostic sleep((u_int)5); 56236460Sbostic exit(eval); 56326862Smckusick } 564