login.c revision 38374
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 3423246Swosch#if 0 351590Srgrimesstatic char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 3823246Swosch#endif 391590Srgrimes 401590Srgrimes#ifndef lint 4127605Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)login.c 8.4 (Berkeley) 4/2/94"; 4327605Scharnier#endif 4427605Scharnierstatic const char rcsid[] = 4538374Sjkoshy "$Id: login.c,v 1.37 1998/07/31 07:22:31 bde Exp $"; 461590Srgrimes#endif /* not lint */ 471590Srgrimes 481590Srgrimes/* 491590Srgrimes * login [ name ] 501590Srgrimes * login -h hostname (for telnetd, etc.) 511590Srgrimes * login -f name (for pre-authenticated login: datakit, xterm, etc.) 521590Srgrimes */ 531590Srgrimes 5423246Swosch#include <sys/copyright.h> 551590Srgrimes#include <sys/param.h> 561590Srgrimes#include <sys/stat.h> 571590Srgrimes#include <sys/time.h> 581590Srgrimes#include <sys/resource.h> 591590Srgrimes#include <sys/file.h> 6016423Sache#include <netinet/in.h> 6116423Sache#include <arpa/inet.h> 621590Srgrimes 631590Srgrimes#include <err.h> 641590Srgrimes#include <errno.h> 651590Srgrimes#include <grp.h> 6616423Sache#include <netdb.h> 671590Srgrimes#include <pwd.h> 681590Srgrimes#include <setjmp.h> 691590Srgrimes#include <signal.h> 701590Srgrimes#include <stdio.h> 711590Srgrimes#include <stdlib.h> 721590Srgrimes#include <string.h> 731590Srgrimes#include <syslog.h> 741590Srgrimes#include <ttyent.h> 751590Srgrimes#include <unistd.h> 761590Srgrimes#include <utmp.h> 771590Srgrimes 7821528Sdavidn#ifdef LOGIN_CAP 7921528Sdavidn#include <login_cap.h> 8021528Sdavidn#else /* Undef AUTH as well */ 8121528Sdavidn#undef LOGIN_CAP_AUTH 8221528Sdavidn#endif 8321528Sdavidn 8423985Sdavidn/* 8523985Sdavidn * If LOGIN_CAP_AUTH is activated: 8621528Sdavidn * kerberose & skey logins are runtime selected via login 8721528Sdavidn * login_getstyle() and authentication types for login classes 8821528Sdavidn * The actual login itself is handled via /usr/libexec/login_<style> 8921528Sdavidn * Valid styles are determined by the auth-type=style,style entries 9021528Sdavidn * in the login class. 9121528Sdavidn */ 9221528Sdavidn#ifdef LOGIN_CAP_AUTH 9321528Sdavidn#undef KERBEROS 9421528Sdavidn#undef SKEY 9523985Sdavidn#endif /* LOGIN_CAP_AUTH */ 9623985Sdavidn 973702Spst#ifdef SKEY 983702Spst#include <skey.h> 9921528Sdavidn#endif /* SKEY */ 1003702Spst 1011590Srgrimes#include "pathnames.h" 1021590Srgrimes 1031590Srgrimesvoid badlogin __P((char *)); 1041590Srgrimesvoid checknologin __P((void)); 1051590Srgrimesvoid dolastlog __P((int)); 1061590Srgrimesvoid getloginname __P((void)); 10721528Sdavidnvoid motd __P((char *)); 1081590Srgrimesint rootterm __P((char *)); 1091590Srgrimesvoid sigint __P((int)); 1101590Srgrimesvoid sleepexit __P((int)); 11123985Sdavidnvoid refused __P((char *,char *,int)); 1121590Srgrimeschar *stypeof __P((char *)); 1131590Srgrimesvoid timedout __P((int)); 11429922Smarkmint login_access __P((char *, char *)); 1152224Sguidovoid login_fbtab __P((char *, uid_t, gid_t)); 1161590Srgrimes#ifdef KERBEROS 1171590Srgrimesint klogin __P((struct passwd *, char *, char *, char *)); 1181590Srgrimes#endif 1191590Srgrimes 1201590Srgrimesextern void login __P((struct utmp *)); 12136559Samuraiextern void trimdomain __P((char *, int)); 12227605Scharnierstatic void usage __P((void)); 1231590Srgrimes 1241590Srgrimes#define TTYGRPNAME "tty" /* name of group to own ttys */ 12523985Sdavidn#define DEFAULT_BACKOFF 3 12623985Sdavidn#define DEFAULT_RETRIES 10 1271590Srgrimes 1281590Srgrimes/* 1291590Srgrimes * This bounds the time given to login. Not a define so it can 1301590Srgrimes * be patched on machines where it's too small. 1311590Srgrimes */ 1321590Srgrimesu_int timeout = 300; 1331590Srgrimes 1341590Srgrimes#ifdef KERBEROS 1351590Srgrimesint notickets = 1; 1365627Swollmanint noticketsdontcomplain = 1; 1371590Srgrimeschar *instance; 1381590Srgrimeschar *krbtkfile_env; 1391590Srgrimesint authok; 1401590Srgrimes#endif 1411590Srgrimes 1421590Srgrimesstruct passwd *pwd; 1431590Srgrimesint failures; 14423985Sdavidnchar *term, *envinit[1], *hostname, *username, *tty; 14516423Sachechar full_hostname[MAXHOSTNAMELEN]; 1461590Srgrimes 1471590Srgrimesint 1481590Srgrimesmain(argc, argv) 1491590Srgrimes int argc; 1501590Srgrimes char *argv[]; 1511590Srgrimes{ 1521590Srgrimes extern char **environ; 1531590Srgrimes struct group *gr; 1541590Srgrimes struct stat st; 1551590Srgrimes struct timeval tp; 1561590Srgrimes struct utmp utmp; 15723985Sdavidn int rootok, retries, backoff; 1581590Srgrimes int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval; 1594878Sugen int changepass; 16023985Sdavidn time_t warntime; 16135559Speter uid_t uid, euid; 1623205Spst char *domain, *p, *ep, *salt, *ttyn; 1631590Srgrimes char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; 1641590Srgrimes char localhost[MAXHOSTNAMELEN]; 16523985Sdavidn char *shell = NULL; 16621528Sdavidn#ifdef LOGIN_CAP 16721528Sdavidn login_cap_t *lc = NULL; 16821528Sdavidn#ifdef LOGIN_CAP_AUTH 16921528Sdavidn char *style, *authtype; 17021528Sdavidn char *auth_method = NULL; 17121528Sdavidn char *instance = NULL; 17221528Sdavidn int authok; 17323985Sdavidn#endif /* LOGIN_CAP_AUTH */ 17423985Sdavidn#endif /* LOGIN_CAP */ 17521528Sdavidn#ifdef SKEY 1763205Spst int permit_passwd = 0; 17721528Sdavidn#endif /* SKEY */ 1781590Srgrimes 1791590Srgrimes (void)signal(SIGALRM, timedout); 1801590Srgrimes (void)alarm(timeout); 1811590Srgrimes (void)signal(SIGQUIT, SIG_IGN); 1821590Srgrimes (void)signal(SIGINT, SIG_IGN); 1831590Srgrimes (void)setpriority(PRIO_PROCESS, 0, 0); 1841590Srgrimes 1851590Srgrimes openlog("login", LOG_ODELAY, LOG_AUTH); 1861590Srgrimes 1871590Srgrimes /* 1881590Srgrimes * -p is used by getty to tell login not to destroy the environment 1891590Srgrimes * -f is used to skip a second login authentication 1901590Srgrimes * -h is used by other servers to pass the name of the remote 1911590Srgrimes * host to login so that it may be placed in utmp and wtmp 1921590Srgrimes */ 1933205Spst *full_hostname = '\0'; 1941590Srgrimes domain = NULL; 19523985Sdavidn term = NULL; 1961590Srgrimes if (gethostname(localhost, sizeof(localhost)) < 0) 1971590Srgrimes syslog(LOG_ERR, "couldn't get local hostname: %m"); 1981590Srgrimes else 1991590Srgrimes domain = strchr(localhost, '.'); 2001590Srgrimes 2011590Srgrimes fflag = hflag = pflag = 0; 2021590Srgrimes uid = getuid(); 20335557Speter euid = geteuid(); 20424360Simp while ((ch = getopt(argc, argv, "fh:p")) != -1) 2051590Srgrimes switch (ch) { 2061590Srgrimes case 'f': 2071590Srgrimes fflag = 1; 2081590Srgrimes break; 2091590Srgrimes case 'h': 2101590Srgrimes if (uid) 2111590Srgrimes errx(1, "-h option: %s", strerror(EPERM)); 2121590Srgrimes hflag = 1; 2133205Spst strncpy(full_hostname, optarg, sizeof(full_hostname)-1); 2141590Srgrimes if (domain && (p = strchr(optarg, '.')) && 2151590Srgrimes strcasecmp(p, domain) == 0) 2161590Srgrimes *p = 0; 21736559Samurai 21836559Samurai trimdomain(optarg, UT_HOSTSIZE ); 21936559Samurai 22016423Sache if (strlen(optarg) > UT_HOSTSIZE) { 22116423Sache struct hostent *hp = gethostbyname(optarg); 22216423Sache 22316423Sache if (hp != NULL) { 22416423Sache struct in_addr in; 22516423Sache 22616423Sache memmove(&in, hp->h_addr, sizeof(in)); 22716423Sache optarg = strdup(inet_ntoa(in)); 22816423Sache } else 22916423Sache optarg = "invalid hostname"; 23016423Sache } 2311590Srgrimes hostname = optarg; 2321590Srgrimes break; 2331590Srgrimes case 'p': 2341590Srgrimes pflag = 1; 2351590Srgrimes break; 2361590Srgrimes case '?': 2371590Srgrimes default: 2381590Srgrimes if (!uid) 2391590Srgrimes syslog(LOG_ERR, "invalid flag %c", ch); 24027605Scharnier usage(); 2411590Srgrimes } 2421590Srgrimes argc -= optind; 2431590Srgrimes argv += optind; 2441590Srgrimes 2451590Srgrimes if (*argv) { 2461590Srgrimes username = *argv; 2471590Srgrimes ask = 0; 2481590Srgrimes } else 2491590Srgrimes ask = 1; 2501590Srgrimes 2511590Srgrimes for (cnt = getdtablesize(); cnt > 2; cnt--) 2521590Srgrimes (void)close(cnt); 2531590Srgrimes 2541590Srgrimes ttyn = ttyname(STDIN_FILENO); 2551590Srgrimes if (ttyn == NULL || *ttyn == '\0') { 2561590Srgrimes (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY); 2571590Srgrimes ttyn = tname; 2581590Srgrimes } 25923985Sdavidn if ((tty = strrchr(ttyn, '/')) != NULL) 2601590Srgrimes ++tty; 2611590Srgrimes else 2621590Srgrimes tty = ttyn; 2631590Srgrimes 26421528Sdavidn#ifdef LOGIN_CAP_AUTH 26521528Sdavidn authtype = hostname ? "rlogin" : "login"; 26621528Sdavidn#endif 26723985Sdavidn#ifdef LOGIN_CAP 26823985Sdavidn /* 26923985Sdavidn * Get "login-retries" & "login-backoff" from default class 27023985Sdavidn */ 27123985Sdavidn lc = login_getclass(NULL); 27223985Sdavidn retries = login_getcapnum(lc, "login-retries", DEFAULT_RETRIES, DEFAULT_RETRIES); 27323985Sdavidn backoff = login_getcapnum(lc, "login-backoff", DEFAULT_BACKOFF, DEFAULT_BACKOFF); 27423985Sdavidn login_close(lc); 27523985Sdavidn lc = NULL; 27623985Sdavidn#else 27723985Sdavidn retries = DEFAULT_RETRIES; 27823985Sdavidn backoff = DEFAULT_BACKOFF; 27923985Sdavidn#endif 28021528Sdavidn 2811590Srgrimes for (cnt = 0;; ask = 1) { 2821590Srgrimes if (ask) { 2831590Srgrimes fflag = 0; 2841590Srgrimes getloginname(); 2851590Srgrimes } 2861590Srgrimes rootlogin = 0; 28721528Sdavidn rootok = rootterm(tty); /* Default (auth may change) */ 28821528Sdavidn#ifdef LOGIN_CAP_AUTH 28921528Sdavidn authok = 0; 29021528Sdavidn if (auth_method = strchr(username, ':')) { 29121528Sdavidn *auth_method = '\0'; 29221528Sdavidn auth_method++; 29321528Sdavidn if (*auth_method == '\0') 29421528Sdavidn auth_method = NULL; 29521528Sdavidn } 29621528Sdavidn /* 29721528Sdavidn * We need to do this regardless of whether 29821528Sdavidn * kerberos is available. 29921528Sdavidn */ 3001590Srgrimes if ((instance = strchr(username, '.')) != NULL) { 3011590Srgrimes if (strncmp(instance, ".root", 5) == 0) 3021590Srgrimes rootlogin = 1; 3031590Srgrimes *instance++ = '\0'; 3041590Srgrimes } else 3051590Srgrimes instance = ""; 30621528Sdavidn#else /* !LOGIN_CAP_AUTH */ 30721528Sdavidn#ifdef KERBEROS 30821528Sdavidn if ((instance = strchr(username, '.')) != NULL) { 30921528Sdavidn if (strncmp(instance, ".root", 5) == 0) 31021528Sdavidn rootlogin = 1; 31121528Sdavidn *instance++ = '\0'; 31221528Sdavidn } else 31321528Sdavidn instance = ""; 31421528Sdavidn#endif /* KERBEROS */ 31521528Sdavidn#endif /* LOGIN_CAP_AUTH */ 31621528Sdavidn 3171590Srgrimes if (strlen(username) > UT_NAMESIZE) 3181590Srgrimes username[UT_NAMESIZE] = '\0'; 3191590Srgrimes 3201590Srgrimes /* 3211590Srgrimes * Note if trying multiple user names; log failures for 3221590Srgrimes * previous user name, but don't bother logging one failure 3231590Srgrimes * for nonexistent name (mistyped username). 3241590Srgrimes */ 3251590Srgrimes if (failures && strcmp(tbuf, username)) { 3261590Srgrimes if (failures > (pwd ? 0 : 1)) 3271590Srgrimes badlogin(tbuf); 3281590Srgrimes failures = 0; 3291590Srgrimes } 33027605Scharnier (void)strncpy(tbuf, username, sizeof tbuf-1); 33127605Scharnier tbuf[sizeof tbuf-1] = '\0'; 3321590Srgrimes 33323985Sdavidn if ((pwd = getpwnam(username)) != NULL) 33423985Sdavidn salt = pwd->pw_passwd; 33523985Sdavidn else 33623985Sdavidn salt = "xx"; 33723985Sdavidn 33821528Sdavidn#ifdef LOGIN_CAP 33923985Sdavidn /* 34023985Sdavidn * Establish the class now, before we might goto 34121528Sdavidn * within the next block. pwd can be NULL since it 34221528Sdavidn * falls back to the "default" class if it is. 34321528Sdavidn */ 34435557Speter if (pwd != NULL) 34535557Speter (void)seteuid(rootlogin ? 0 : pwd->pw_uid); 34625671Sdavidn lc = login_getpwclass(pwd); 34735557Speter seteuid(euid); 34821528Sdavidn#endif /* LOGIN_CAP */ 3491590Srgrimes 3501590Srgrimes /* 3511590Srgrimes * if we have a valid account name, and it doesn't have a 3521590Srgrimes * password, or the -f option was specified and the caller 3531590Srgrimes * is root or the caller isn't changing their uid, don't 3541590Srgrimes * authenticate. 3551590Srgrimes */ 35623985Sdavidn rval = 1; 35721528Sdavidn if (pwd != NULL) { 3583205Spst if (pwd->pw_uid == 0) 3593205Spst rootlogin = 1; 3603205Spst 36123985Sdavidn if (fflag && (uid == (uid_t)0 || 36223985Sdavidn uid == (uid_t)pwd->pw_uid)) { 3633205Spst /* already authenticated */ 3643205Spst break; 3653205Spst } else if (pwd->pw_passwd[0] == '\0') { 36624321Sdavidn if (!rootlogin || rootok) { 36724251Sdavidn /* pretend password okay */ 36824251Sdavidn rval = 0; 36924251Sdavidn goto ttycheck; 37024251Sdavidn } 3713205Spst } 3723205Spst } 3733205Spst 3741590Srgrimes fflag = 0; 3751590Srgrimes 3761590Srgrimes (void)setpriority(PRIO_PROCESS, 0, -4); 3771590Srgrimes 37821528Sdavidn#ifdef LOGIN_CAP_AUTH 37921528Sdavidn /* 38023985Sdavidn * This hands off authorization to an authorization program, 38121528Sdavidn * depending on the styles available for the "auth-login", 38223985Sdavidn * auth-rlogin (or default) authorization styles. 38321528Sdavidn * We do this regardless of whether an account exists so that 38421528Sdavidn * the remote user cannot tell a "real" from an invented 38521528Sdavidn * account name. If we don't have an account we just fall 38621528Sdavidn * back to the first method for the "default" class. 38721528Sdavidn */ 38823985Sdavidn if (!(style = login_getstyle(lc, auth_method, authtype))) { 38923985Sdavidn 39023985Sdavidn /* 39123985Sdavidn * No available authorization method 39223985Sdavidn */ 39323985Sdavidn rval = 1; 39423985Sdavidn (void)printf("No auth method available for %s.\n", 39523985Sdavidn authtype); 39621528Sdavidn } else { 39723985Sdavidn 39823985Sdavidn /* 39923985Sdavidn * Put back the kerberos instance, if any was given. 40021528Sdavidn * Don't worry about the non-kerberos case here, since 40121528Sdavidn * if kerberos is not available or not selected and an 40221528Sdavidn * instance is given at the login prompt, su or rlogin -l, 40321528Sdavidn * then anything else should fail as well. 40421528Sdavidn */ 40521528Sdavidn if (*instance) 40621528Sdavidn *(instance - 1) = '.'; 40723985Sdavidn 40823985Sdavidn rval = authenticate(username, 40923985Sdavidn lc ? lc->lc_class : "default", 41023985Sdavidn style, authtype); 41121528Sdavidn /* Junk it again */ 41221528Sdavidn if (*instance) 41321528Sdavidn *(instance - 1) = '\0'; 41421528Sdavidn } 41521528Sdavidn 41621528Sdavidn if (!rval) { 41737812Sjdp char * approvep; 41823985Sdavidn 41921528Sdavidn /* 42021528Sdavidn * If authentication succeeds, run any approval 42121528Sdavidn * program, if applicable for this class. 42221528Sdavidn */ 42323985Sdavidn approvep = login_getcapstr(lc, "approve", NULL, NULL); 42421528Sdavidn rval = 1; /* Assume bad login again */ 42523985Sdavidn 42623985Sdavidn if (approvep==NULL || 42723985Sdavidn auth_script(approvep, approvep, username, 42823985Sdavidn lc->lc_class, 0) == 0) { 42923985Sdavidn int r; 43023985Sdavidn 43123985Sdavidn r = auth_scan(AUTH_OKAY); 43223985Sdavidn /* 43323985Sdavidn * See what the authorize program says 43423985Sdavidn */ 43537812Sjdp if (r != 0) { 43621528Sdavidn rval = 0; 43723985Sdavidn 43821528Sdavidn if (!rootok && (r & AUTH_ROOTOKAY)) 43921528Sdavidn rootok = 1; /* root approved */ 44023985Sdavidn else 44123985Sdavidn rootlogin = 0; 44223985Sdavidn 44321528Sdavidn if (!authok && (r & AUTH_SECURE)) 44421528Sdavidn authok = 1; /* secure */ 44521528Sdavidn } 44621528Sdavidn } 44721528Sdavidn } 44821528Sdavidn#else /* !LOGIN_CAP_AUTH */ 44921528Sdavidn#ifdef SKEY 45023985Sdavidn permit_passwd = skeyaccess(username, tty, 45123985Sdavidn hostname ? full_hostname : NULL, 45223985Sdavidn NULL); 4533205Spst p = skey_getpass("Password:", pwd, permit_passwd); 4543205Spst ep = skey_crypt(p, salt, pwd, permit_passwd); 45521528Sdavidn#else /* !SKEY */ 4561590Srgrimes p = getpass("Password:"); 4573205Spst ep = crypt(p, salt); 45821528Sdavidn#endif/* SKEY */ 45923985Sdavidn 46023985Sdavidn if (pwd) { 46133332Sache if (!p[0] && pwd->pw_passwd[0]) 46233332Sache ep = ":"; 4631590Srgrimes#ifdef KERBEROS 4647800Swollman#ifdef SKEY 46523985Sdavidn /* 46623985Sdavidn * Do not allow user to type in kerberos password 4677800Swollman * over the net (actually, this is ok for encrypted 4687800Swollman * links, but we have no way of determining if the 4697800Swollman * link is encrypted. 4707800Swollman */ 4717893Srgrimes if (!permit_passwd) { 47223985Sdavidn rval = 1; /* failed */ 4737800Swollman } else 47421528Sdavidn#endif /* SKEY */ 4751590Srgrimes rval = klogin(pwd, instance, localhost, p); 4761590Srgrimes if (rval != 0 && rootlogin && pwd->pw_uid != 0) 4771590Srgrimes rootlogin = 0; 4781590Srgrimes if (rval == 0) 47921528Sdavidn authok = 1; /* kerberos authenticated ok */ 48021528Sdavidn else if (rval == 1) /* fallback to unix passwd */ 4813205Spst rval = strcmp(ep, pwd->pw_passwd); 48221528Sdavidn#else /* !KERBEROS */ 48323985Sdavidn rval = strcmp(ep, pwd->pw_passwd); 48421528Sdavidn#endif /* KERBEROS */ 48523985Sdavidn } 48623985Sdavidn 48721528Sdavidn /* clear entered password */ 4881590Srgrimes memset(p, 0, strlen(p)); 48921528Sdavidn#endif /* LOGIN_CAP_AUTH */ 4901590Srgrimes 4911590Srgrimes (void)setpriority(PRIO_PROCESS, 0, 0); 49223985Sdavidn 49325671Sdavidn#ifdef LOGIN_CAP_AUTH 49421528Sdavidn if (rval) 49521528Sdavidn auth_rmfiles(); 49621528Sdavidn#endif 4973205Spst ttycheck: 4981590Srgrimes /* 4991590Srgrimes * If trying to log in as root without Kerberos, 5001590Srgrimes * but with insecure terminal, refuse the login attempt. 5011590Srgrimes */ 50224222Sdavidn if (pwd && !rval) { 50321528Sdavidn#if defined(KERBEROS) || defined(LOGIN_CAP_AUTH) 50424222Sdavidn if (authok == 0 && rootlogin && !rootok) 50524222Sdavidn#else 50624222Sdavidn if (rootlogin && !rootok) 5071590Srgrimes#endif 50824222Sdavidn refused(NULL, "NOROOT", 0); 50924222Sdavidn else /* valid password & authenticated */ 51024222Sdavidn break; 5111590Srgrimes } 5121590Srgrimes 5131590Srgrimes (void)printf("Login incorrect\n"); 5141590Srgrimes failures++; 51523985Sdavidn 51623985Sdavidn /* 51723985Sdavidn * we allow up to 'retry' (10) tries, 51823985Sdavidn * but after 'backoff' (3) we start backing off 51923985Sdavidn */ 52023985Sdavidn if (++cnt > backoff) { 52123985Sdavidn if (cnt >= retries) { 5221590Srgrimes badlogin(username); 5231590Srgrimes sleepexit(1); 5241590Srgrimes } 52538374Sjkoshy sleep((u_int)((cnt - backoff) * 5)); 5261590Srgrimes } 5271590Srgrimes } 5281590Srgrimes 5291590Srgrimes /* committed to login -- turn off timeout */ 5301590Srgrimes (void)alarm((u_int)0); 5311590Srgrimes 5321590Srgrimes endpwent(); 5331590Srgrimes 5341590Srgrimes /* if user not super-user, check for disabled logins */ 53521528Sdavidn#ifdef LOGIN_CAP 5361590Srgrimes if (!rootlogin) 53721528Sdavidn auth_checknologin(lc); 53821528Sdavidn#else 53921528Sdavidn if (!rootlogin) 5401590Srgrimes checknologin(); 54121528Sdavidn#endif 5421590Srgrimes 54321528Sdavidn#ifdef LOGIN_CAP 54421528Sdavidn quietlog = login_getcapbool(lc, "hushlogin", 0); 54521528Sdavidn#else 54621528Sdavidn quietlog = 0; 54721528Sdavidn#endif 54835557Speter (void)seteuid(rootlogin ? 0 : pwd->pw_uid); 54921528Sdavidn if (!*pwd->pw_dir || chdir(pwd->pw_dir) < 0) { 55021528Sdavidn#ifdef LOGIN_CAP 55126021Spst if (login_getcapbool(lc, "requirehome", 0)) 55223985Sdavidn refused("Home directory not available", "HOMEDIR", 1); 55323985Sdavidn#endif 55424485Sdavidn if (chdir("/") < 0) 55523985Sdavidn refused("Cannot find root directory", "ROOTDIR", 1); 5561590Srgrimes pwd->pw_dir = "/"; 55723985Sdavidn if (!quietlog || *pwd->pw_dir) 55823985Sdavidn printf("No home directory.\nLogging in with home = \"/\".\n"); 5591590Srgrimes } 56035557Speter (void)seteuid(euid); 56121528Sdavidn if (!quietlog) 56221528Sdavidn quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; 5631590Srgrimes 5641590Srgrimes if (pwd->pw_change || pwd->pw_expire) 5651590Srgrimes (void)gettimeofday(&tp, (struct timezone *)NULL); 5662532Sjkh 56730564Sjoerg#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ 56821528Sdavidn 56923985Sdavidn#ifdef LOGIN_CAP 57023985Sdavidn warntime = login_getcaptime(lc, "warnpassword", 57123985Sdavidn DEFAULT_WARN, DEFAULT_WARN); 57223985Sdavidn#else 57323985Sdavidn warntime = DEFAULT_WARN; 57423985Sdavidn#endif 57523985Sdavidn 5764878Sugen changepass=0; 57721528Sdavidn if (pwd->pw_change) { 5781590Srgrimes if (tp.tv_sec >= pwd->pw_change) { 5791590Srgrimes (void)printf("Sorry -- your password has expired.\n"); 5804878Sugen changepass=1; 58123985Sdavidn syslog(LOG_INFO, 58223985Sdavidn "%s Password expired - forcing change", 58323985Sdavidn pwd->pw_name); 58423985Sdavidn } else if (pwd->pw_change - tp.tv_sec < warntime && !quietlog) 58523985Sdavidn (void)printf("Warning: your password expires on %s", 58623985Sdavidn ctime(&pwd->pw_change)); 58723985Sdavidn } 58823985Sdavidn 58921528Sdavidn#ifdef LOGIN_CAP 59023985Sdavidn warntime = login_getcaptime(lc, "warnexpire", 59123985Sdavidn DEFAULT_WARN, DEFAULT_WARN); 59221528Sdavidn#else 59323985Sdavidn warntime = DEFAULT_WARN; 59421528Sdavidn#endif 59523985Sdavidn 59621528Sdavidn if (pwd->pw_expire) { 5971590Srgrimes if (tp.tv_sec >= pwd->pw_expire) { 59823985Sdavidn refused("Sorry -- your account has expired", 59923985Sdavidn "EXPIRED", 1); 60023985Sdavidn } else if (pwd->pw_expire - tp.tv_sec < warntime && !quietlog) 60123985Sdavidn (void)printf("Warning: your account expires on %s", 60223985Sdavidn ctime(&pwd->pw_expire)); 60321528Sdavidn } 6041590Srgrimes 60521528Sdavidn#ifdef LOGIN_CAP 60621528Sdavidn if (lc != NULL) { 60721528Sdavidn if (hostname) { 60821528Sdavidn struct hostent *hp = gethostbyname(full_hostname); 60921528Sdavidn 61021528Sdavidn if (hp == NULL) 61121528Sdavidn optarg = NULL; 61221528Sdavidn else { 61321528Sdavidn struct in_addr in; 61421528Sdavidn memmove(&in, hp->h_addr, sizeof(in)); 61521528Sdavidn optarg = strdup(inet_ntoa(in)); 61621528Sdavidn } 61723985Sdavidn if (!auth_hostok(lc, full_hostname, optarg)) 61823985Sdavidn refused("Permission denied", "HOST", 1); 61921528Sdavidn } 62021528Sdavidn 62123985Sdavidn if (!auth_ttyok(lc, tty)) 62223985Sdavidn refused("Permission denied", "TTY", 1); 62321528Sdavidn 62423985Sdavidn if (!auth_timeok(lc, time(NULL))) 62523985Sdavidn refused("Logins not available right now", "TIME", 1); 62621528Sdavidn } 62723985Sdavidn shell=login_getcapstr(lc, "shell", pwd->pw_shell, pwd->pw_shell); 62821528Sdavidn#else /* !LOGIN_CAP */ 62923985Sdavidn shell=pwd->pw_shell; 63021528Sdavidn#endif /* LOGIN_CAP */ 63123985Sdavidn if (*pwd->pw_shell == '\0') 63223985Sdavidn pwd->pw_shell = _PATH_BSHELL; 63323985Sdavidn if (*shell == '\0') /* Not overridden */ 63423985Sdavidn shell = pwd->pw_shell; 63523985Sdavidn if ((shell = strdup(shell)) == NULL) { 63623985Sdavidn syslog(LOG_NOTICE, "memory allocation error"); 63723985Sdavidn sleepexit(1); 63823985Sdavidn } 63921528Sdavidn 64021528Sdavidn#ifdef LOGIN_ACCESS 64123985Sdavidn if (login_access(pwd->pw_name, hostname ? full_hostname : tty) == 0) 64223985Sdavidn refused("Permission denied", "ACCESS", 1); 64321528Sdavidn#endif /* LOGIN_ACCESS */ 64421528Sdavidn 6451590Srgrimes /* Nothing else left to fail -- really log in. */ 6461590Srgrimes memset((void *)&utmp, 0, sizeof(utmp)); 6471590Srgrimes (void)time(&utmp.ut_time); 6481590Srgrimes (void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); 6491590Srgrimes if (hostname) 6501590Srgrimes (void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); 6511590Srgrimes (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); 6521590Srgrimes login(&utmp); 6531590Srgrimes 6541590Srgrimes dolastlog(quietlog); 6551590Srgrimes 6562224Sguido /* 6572224Sguido * Set device protections, depending on what terminal the 6582224Sguido * user is logged in. This feature is used on Suns to give 6592224Sguido * console users better privacy. 6602224Sguido */ 6612224Sguido login_fbtab(tty, pwd->pw_uid, pwd->pw_gid); 6622224Sguido 66323985Sdavidn (void)chown(ttyn, pwd->pw_uid, 66423985Sdavidn (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); 6651590Srgrimes 66623985Sdavidn /* 66723985Sdavidn * Preserve TERM if it happens to be already set. 66823985Sdavidn */ 66924222Sdavidn if ((term = getenv("TERM")) != NULL) 67024222Sdavidn term = strdup(term); 6711590Srgrimes 67223985Sdavidn /* 67323985Sdavidn * Exclude cons/vt/ptys only, assume dialup otherwise 67423985Sdavidn * TODO: Make dialup tty determination a library call 67523985Sdavidn * for consistency (finger etc.) 67623985Sdavidn */ 67724894Sdavidn if (hostname==NULL && isdialuptty(tty)) 6781590Srgrimes syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 6791590Srgrimes 6801590Srgrimes#ifdef KERBEROS 6815627Swollman if (!quietlog && notickets == 1 && !noticketsdontcomplain) 6821590Srgrimes (void)printf("Warning: no Kerberos tickets issued.\n"); 6831590Srgrimes#endif 6841590Srgrimes 6853205Spst#ifdef LOGALL 6863205Spst /* 6873205Spst * Syslog each successful login, so we don't have to watch hundreds 6883205Spst * of wtmp or lastlogin files. 6893205Spst */ 69023985Sdavidn if (hostname) 69123985Sdavidn syslog(LOG_INFO, "login from %s on %s as %s", 69223985Sdavidn full_hostname, tty, pwd->pw_name); 69323985Sdavidn else 69423985Sdavidn syslog(LOG_INFO, "login on %s as %s", 69523985Sdavidn tty, pwd->pw_name); 69621528Sdavidn#endif 69721528Sdavidn 69823985Sdavidn /* 69923985Sdavidn * If fflag is on, assume caller/authenticator has logged root login. 70023985Sdavidn */ 70123985Sdavidn if (rootlogin && fflag == 0) 70223985Sdavidn { 70323985Sdavidn if (hostname) 70423985Sdavidn syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s", 70523985Sdavidn username, tty, full_hostname); 70623985Sdavidn else 70723985Sdavidn syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", 70823985Sdavidn username, tty); 70923985Sdavidn } 71023985Sdavidn 71123985Sdavidn /* 71223985Sdavidn * Destroy environment unless user has requested its preservation. 71323985Sdavidn * We need to do this before setusercontext() because that may 71423985Sdavidn * set or reset some environment variables. 71523985Sdavidn */ 71621528Sdavidn if (!pflag) 71721528Sdavidn environ = envinit; 71821528Sdavidn 71923985Sdavidn /* 72023985Sdavidn * We don't need to be root anymore, so 72121528Sdavidn * set the user and session context 72221528Sdavidn */ 72321528Sdavidn#ifdef LOGIN_CAP 72421528Sdavidn if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETALL) != 0) { 72521528Sdavidn syslog(LOG_ERR, "setusercontext() failed - exiting"); 72621528Sdavidn exit(1); 7273205Spst } 72821528Sdavidn#else 72921528Sdavidn if (setlogin(pwd->pw_name) < 0) 73021528Sdavidn syslog(LOG_ERR, "setlogin() failure: %m"); 73121528Sdavidn 73221528Sdavidn (void)setgid(pwd->pw_gid); 73321528Sdavidn initgroups(username, pwd->pw_gid); 73421528Sdavidn (void)setuid(rootlogin ? 0 : pwd->pw_uid); 7353205Spst#endif 7363205Spst 73723148Sache (void)setenv("SHELL", pwd->pw_shell, 1); 73821528Sdavidn (void)setenv("HOME", pwd->pw_dir, 1); 73923985Sdavidn if (term != NULL && *term != '\0') 74021528Sdavidn (void)setenv("TERM", term, 1); /* Preset overrides */ 74121528Sdavidn else { 74223985Sdavidn (void)setenv("TERM", stypeof(tty), 0); /* Fallback doesn't */ 74321528Sdavidn } 74421528Sdavidn (void)setenv("LOGNAME", pwd->pw_name, 1); 74521528Sdavidn (void)setenv("USER", pwd->pw_name, 1); 74621528Sdavidn (void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0); 74721528Sdavidn#ifdef KERBEROS 74821528Sdavidn if (krbtkfile_env) 74921528Sdavidn (void)setenv("KRBTKFILE", krbtkfile_env, 1); 75021528Sdavidn#endif 75123985Sdavidn#if LOGIN_CAP_AUTH 75223985Sdavidn auth_env(); 75321528Sdavidn#endif 75421528Sdavidn 75523985Sdavidn#ifdef LOGIN_CAP 7561590Srgrimes if (!quietlog) { 75723985Sdavidn char *cw; 75823985Sdavidn 75923985Sdavidn cw = login_getcapstr(lc, "copyright", NULL, NULL); 76021528Sdavidn if (cw != NULL && access(cw, F_OK) == 0) 76121528Sdavidn motd(cw); 76221528Sdavidn else 76323985Sdavidn (void)printf("%s\n\t%s %s\n", 76423985Sdavidn "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", 76523985Sdavidn "The Regents of the University of California. ", 76623985Sdavidn "All rights reserved."); 76723985Sdavidn 76823985Sdavidn (void)printf("\n"); 76923985Sdavidn 77021528Sdavidn cw = login_getcapstr(lc, "welcome", NULL, NULL); 77121528Sdavidn if (cw == NULL || access(cw, F_OK) != 0) 77221528Sdavidn cw = _PATH_MOTDFILE; 77321528Sdavidn motd(cw); 77423985Sdavidn 77521528Sdavidn cw = getenv("MAIL"); /* $MAIL may have been set by class */ 77621528Sdavidn if (cw != NULL) { 77721528Sdavidn strncpy(tbuf, cw, sizeof(tbuf)); 77821528Sdavidn tbuf[sizeof(tbuf)-1] = '\0'; 77921528Sdavidn } else 78023985Sdavidn snprintf(tbuf, sizeof(tbuf), "%s/%s", 78123985Sdavidn _PATH_MAILDIR, pwd->pw_name); 78221528Sdavidn#else 78323985Sdavidn if (!quietlog) { 78423985Sdavidn (void)printf("%s\n\t%s %s\n", 78523985Sdavidn "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", 78623985Sdavidn "The Regents of the University of California. ", 78723985Sdavidn "All rights reserved."); 78821528Sdavidn motd(_PATH_MOTDFILE); 78923985Sdavidn snprintf(tbuf, sizeof(tbuf), "%s/%s", 79023985Sdavidn _PATH_MAILDIR, pwd->pw_name); 79121528Sdavidn#endif 7921590Srgrimes if (stat(tbuf, &st) == 0 && st.st_size != 0) 79323985Sdavidn (void)printf("You have %smail.\n", 79423985Sdavidn (st.st_mtime > st.st_atime) ? "new " : ""); 7951590Srgrimes } 7961590Srgrimes 79721528Sdavidn#ifdef LOGIN_CAP 79821528Sdavidn login_close(lc); 7993205Spst#endif 8003205Spst 8011590Srgrimes (void)signal(SIGALRM, SIG_DFL); 8021590Srgrimes (void)signal(SIGQUIT, SIG_DFL); 8031590Srgrimes (void)signal(SIGINT, SIG_DFL); 8041590Srgrimes (void)signal(SIGTSTP, SIG_IGN); 8051590Srgrimes 8064878Sugen if (changepass) { 80721528Sdavidn if (system(_PATH_CHPASS) != 0) 8084878Sugen sleepexit(1); 8094878Sugen } 8104878Sugen 81123985Sdavidn /* 81223985Sdavidn * Login shells have a leading '-' in front of argv[0] 81323985Sdavidn */ 81423985Sdavidn tbuf[0] = '-'; 81523985Sdavidn (void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell); 81623985Sdavidn 81721528Sdavidn execlp(shell, tbuf, 0); 81821528Sdavidn err(1, "%s", shell); 8191590Srgrimes} 8201590Srgrimes 82127605Scharnierstatic void 82227605Scharnierusage() 82327605Scharnier{ 82427605Scharnier (void)fprintf(stderr, "usage: login [-fp] [-h hostname] [username]\n"); 82527605Scharnier exit(1); 82627605Scharnier} 8271590Srgrimes 82823985Sdavidn/* 82923985Sdavidn * Allow for authentication style and/or kerberos instance 83023985Sdavidn * */ 83121528Sdavidn 83221528Sdavidn#define NBUFSIZ UT_NAMESIZE + 64 83321528Sdavidn 8341590Srgrimesvoid 8351590Srgrimesgetloginname() 8361590Srgrimes{ 8371590Srgrimes int ch; 8381590Srgrimes char *p; 8391590Srgrimes static char nbuf[NBUFSIZ]; 8401590Srgrimes 8411590Srgrimes for (;;) { 8421590Srgrimes (void)printf("login: "); 8431590Srgrimes for (p = nbuf; (ch = getchar()) != '\n'; ) { 8441590Srgrimes if (ch == EOF) { 8451590Srgrimes badlogin(username); 8461590Srgrimes exit(0); 8471590Srgrimes } 8481590Srgrimes if (p < nbuf + (NBUFSIZ - 1)) 8491590Srgrimes *p++ = ch; 8501590Srgrimes } 8511590Srgrimes if (p > nbuf) 8521590Srgrimes if (nbuf[0] == '-') 8531590Srgrimes (void)fprintf(stderr, 8541590Srgrimes "login names may not start with '-'.\n"); 8551590Srgrimes else { 8561590Srgrimes *p = '\0'; 8571590Srgrimes username = nbuf; 8581590Srgrimes break; 8591590Srgrimes } 8601590Srgrimes } 8611590Srgrimes} 8621590Srgrimes 8631590Srgrimesint 8641590Srgrimesrootterm(ttyn) 8651590Srgrimes char *ttyn; 8661590Srgrimes{ 8671590Srgrimes struct ttyent *t; 86823985Sdavidn 8691590Srgrimes return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE); 8701590Srgrimes} 8711590Srgrimes 87221528Sdavidnvolatile int motdinterrupt; 8731590Srgrimes 87421528Sdavidn/* ARGSUSED */ 8751590Srgrimesvoid 87621528Sdavidnsigint(signo) 87721528Sdavidn int signo; 8781590Srgrimes{ 87921528Sdavidn motdinterrupt = 1; 88021528Sdavidn} 88121528Sdavidn 88221528Sdavidnvoid 88321528Sdavidnmotd(motdfile) 88421528Sdavidn char *motdfile; 88521528Sdavidn{ 8861590Srgrimes int fd, nchars; 8871590Srgrimes sig_t oldint; 88821528Sdavidn char tbuf[256]; 8891590Srgrimes 89021528Sdavidn if ((fd = open(motdfile, O_RDONLY, 0)) < 0) 8911590Srgrimes return; 89221528Sdavidn motdinterrupt = 0; 8931590Srgrimes oldint = signal(SIGINT, sigint); 89421528Sdavidn while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0 && !motdinterrupt) 89521528Sdavidn (void)write(fileno(stdout), tbuf, nchars); 8961590Srgrimes (void)signal(SIGINT, oldint); 8971590Srgrimes (void)close(fd); 8981590Srgrimes} 8991590Srgrimes 9001590Srgrimes/* ARGSUSED */ 9011590Srgrimesvoid 9021590Srgrimestimedout(signo) 9031590Srgrimes int signo; 9041590Srgrimes{ 9051590Srgrimes (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout); 9061590Srgrimes exit(0); 9071590Srgrimes} 9081590Srgrimes 90921528Sdavidn#ifndef LOGIN_CAP 9101590Srgrimesvoid 9111590Srgrimeschecknologin() 9121590Srgrimes{ 9131590Srgrimes int fd, nchars; 9141590Srgrimes char tbuf[8192]; 9151590Srgrimes 9161590Srgrimes if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) { 9171590Srgrimes while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 9181590Srgrimes (void)write(fileno(stdout), tbuf, nchars); 9191590Srgrimes sleepexit(0); 9201590Srgrimes } 9211590Srgrimes} 92221528Sdavidn#endif 9231590Srgrimes 9241590Srgrimesvoid 9251590Srgrimesdolastlog(quiet) 9261590Srgrimes int quiet; 9271590Srgrimes{ 9281590Srgrimes struct lastlog ll; 9291590Srgrimes int fd; 9301590Srgrimes 9311590Srgrimes if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { 9321590Srgrimes (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 9331590Srgrimes if (!quiet) { 9341590Srgrimes if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && 9351590Srgrimes ll.ll_time != 0) { 9361590Srgrimes (void)printf("Last login: %.*s ", 9371590Srgrimes 24-5, (char *)ctime(&ll.ll_time)); 9381590Srgrimes if (*ll.ll_host != '\0') 9391590Srgrimes (void)printf("from %.*s\n", 9401590Srgrimes (int)sizeof(ll.ll_host), 9411590Srgrimes ll.ll_host); 9421590Srgrimes else 9431590Srgrimes (void)printf("on %.*s\n", 9441590Srgrimes (int)sizeof(ll.ll_line), 9451590Srgrimes ll.ll_line); 9461590Srgrimes } 9471590Srgrimes (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 9481590Srgrimes } 9491590Srgrimes memset((void *)&ll, 0, sizeof(ll)); 9501590Srgrimes (void)time(&ll.ll_time); 9511590Srgrimes (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 9521590Srgrimes if (hostname) 9531590Srgrimes (void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); 9541590Srgrimes (void)write(fd, (char *)&ll, sizeof(ll)); 9551590Srgrimes (void)close(fd); 9561590Srgrimes } 9571590Srgrimes} 9581590Srgrimes 9591590Srgrimesvoid 9601590Srgrimesbadlogin(name) 9611590Srgrimes char *name; 9621590Srgrimes{ 9631590Srgrimes 9641590Srgrimes if (failures == 0) 9651590Srgrimes return; 9661590Srgrimes if (hostname) { 9671590Srgrimes syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s", 96816423Sache failures, failures > 1 ? "S" : "", full_hostname); 9691590Srgrimes syslog(LOG_AUTHPRIV|LOG_NOTICE, 9701590Srgrimes "%d LOGIN FAILURE%s FROM %s, %s", 97116423Sache failures, failures > 1 ? "S" : "", full_hostname, name); 9721590Srgrimes } else { 9731590Srgrimes syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s", 9741590Srgrimes failures, failures > 1 ? "S" : "", tty); 9751590Srgrimes syslog(LOG_AUTHPRIV|LOG_NOTICE, 9761590Srgrimes "%d LOGIN FAILURE%s ON %s, %s", 9771590Srgrimes failures, failures > 1 ? "S" : "", tty, name); 9781590Srgrimes } 9791590Srgrimes} 9801590Srgrimes 9811590Srgrimes#undef UNKNOWN 9821590Srgrimes#define UNKNOWN "su" 9831590Srgrimes 9841590Srgrimeschar * 9851590Srgrimesstypeof(ttyid) 9861590Srgrimes char *ttyid; 9871590Srgrimes{ 98823985Sdavidn 9891590Srgrimes struct ttyent *t; 99023985Sdavidn 9911590Srgrimes return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); 9921590Srgrimes} 9931590Srgrimes 9941590Srgrimesvoid 99523985Sdavidnrefused(msg, rtype, lout) 99623985Sdavidn char *msg; 99723985Sdavidn char *rtype; 99823985Sdavidn int lout; 99923985Sdavidn{ 100023985Sdavidn 100123985Sdavidn if (msg != NULL) 100223985Sdavidn printf("%s.\n", msg); 100323985Sdavidn if (hostname) 100423985Sdavidn syslog(LOG_NOTICE, "LOGIN %s REFUSED (%s) FROM %s ON TTY %s", 100523985Sdavidn pwd->pw_name, rtype, full_hostname, tty); 100623985Sdavidn else 100723985Sdavidn syslog(LOG_NOTICE, "LOGIN %s REFUSED (%s) ON TTY %s", 100823985Sdavidn pwd->pw_name, rtype, tty); 100923985Sdavidn if (lout) 101023985Sdavidn sleepexit(1); 101123985Sdavidn} 101223985Sdavidn 101323985Sdavidnvoid 10141590Srgrimessleepexit(eval) 10151590Srgrimes int eval; 10161590Srgrimes{ 101723985Sdavidn 10181590Srgrimes (void)sleep(5); 10191590Srgrimes exit(eval); 10201590Srgrimes} 1021