Submitted by: Paul Traina <root@shockwave.com> (partially)
Cleanup of #ifdef's for LOGIN_CAP. Fixed bug in empty shell (closes PR#2550). Refused root logins now displays standard "Login incorrect" and exhibits identical backoff behaviour to a failed login. Cleaned up logging of refused logins. Use #defines for login retries and backoff. Also implemented definable variables if LOGIN_CAP is defined, with "login-retries" and "login-backoff" as capabilities in the default class (closes PR#2805). TERM from previous environment is no longer truncated.
This commit is contained in:
parent
43ec585267
commit
a52c1be6ff
@ -77,7 +77,8 @@ static char sccsid[] = "@(#)login.c 8.4 (Berkeley) 4/2/94";
|
||||
#undef LOGIN_CAP_AUTH
|
||||
#endif
|
||||
|
||||
/* If LOGIN_CAP_AUTH is activated:
|
||||
/*
|
||||
* If LOGIN_CAP_AUTH is activated:
|
||||
* kerberose & skey logins are runtime selected via login
|
||||
* login_getstyle() and authentication types for login classes
|
||||
* The actual login itself is handled via /usr/libexec/login_<style>
|
||||
@ -87,11 +88,11 @@ static char sccsid[] = "@(#)login.c 8.4 (Berkeley) 4/2/94";
|
||||
#ifdef LOGIN_CAP_AUTH
|
||||
#undef KERBEROS
|
||||
#undef SKEY
|
||||
#else
|
||||
#endif /* LOGIN_CAP_AUTH */
|
||||
|
||||
#ifdef SKEY
|
||||
#include <skey.h>
|
||||
#endif /* SKEY */
|
||||
#endif /* LOGIN_CAP_AUTH */
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
@ -103,6 +104,7 @@ void motd __P((char *));
|
||||
int rootterm __P((char *));
|
||||
void sigint __P((int));
|
||||
void sleepexit __P((int));
|
||||
void refused __P((char *,char *,int));
|
||||
char *stypeof __P((char *));
|
||||
void timedout __P((int));
|
||||
void login_fbtab __P((char *, uid_t, gid_t));
|
||||
@ -113,6 +115,8 @@ int klogin __P((struct passwd *, char *, char *, char *));
|
||||
extern void login __P((struct utmp *));
|
||||
|
||||
#define TTYGRPNAME "tty" /* name of group to own ttys */
|
||||
#define DEFAULT_BACKOFF 3
|
||||
#define DEFAULT_RETRIES 10
|
||||
|
||||
/*
|
||||
* This bounds the time given to login. Not a define so it can
|
||||
@ -130,7 +134,7 @@ int authok;
|
||||
|
||||
struct passwd *pwd;
|
||||
int failures;
|
||||
char term[64], *envinit[1], *hostname, *username, *tty;
|
||||
char *term, *envinit[1], *hostname, *username, *tty;
|
||||
char full_hostname[MAXHOSTNAMELEN];
|
||||
|
||||
int
|
||||
@ -143,14 +147,15 @@ main(argc, argv)
|
||||
struct stat st;
|
||||
struct timeval tp;
|
||||
struct utmp utmp;
|
||||
int rootok;
|
||||
int rootok, retries, backoff;
|
||||
int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
|
||||
int changepass;
|
||||
time_t warntime;
|
||||
uid_t uid;
|
||||
char *domain, *p, *ep, *salt, *ttyn;
|
||||
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
|
||||
char localhost[MAXHOSTNAMELEN];
|
||||
char shell[MAXPATHLEN];
|
||||
char *shell = NULL;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc = NULL;
|
||||
#ifdef LOGIN_CAP_AUTH
|
||||
@ -158,12 +163,11 @@ main(argc, argv)
|
||||
char *auth_method = NULL;
|
||||
char *instance = NULL;
|
||||
int authok;
|
||||
#else /* !LOGIN_CAP_AUTH */
|
||||
#endif /* LOGIN_CAP_AUTH */
|
||||
#endif /* LOGIN_CAP */
|
||||
#ifdef SKEY
|
||||
int permit_passwd = 0;
|
||||
#endif /* SKEY */
|
||||
#endif /* LOGIN_CAP_AUTH */
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
(void)signal(SIGALRM, timedout);
|
||||
(void)alarm(timeout);
|
||||
@ -181,6 +185,7 @@ main(argc, argv)
|
||||
*/
|
||||
*full_hostname = '\0';
|
||||
domain = NULL;
|
||||
term = NULL;
|
||||
if (gethostname(localhost, sizeof(localhost)) < 0)
|
||||
syslog(LOG_ERR, "couldn't get local hostname: %m");
|
||||
else
|
||||
@ -242,7 +247,7 @@ main(argc, argv)
|
||||
(void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
|
||||
ttyn = tname;
|
||||
}
|
||||
if (tty = strrchr(ttyn, '/'))
|
||||
if ((tty = strrchr(ttyn, '/')) != NULL)
|
||||
++tty;
|
||||
else
|
||||
tty = ttyn;
|
||||
@ -250,6 +255,19 @@ main(argc, argv)
|
||||
#ifdef LOGIN_CAP_AUTH
|
||||
authtype = hostname ? "rlogin" : "login";
|
||||
#endif
|
||||
#ifdef LOGIN_CAP
|
||||
/*
|
||||
* Get "login-retries" & "login-backoff" from default class
|
||||
*/
|
||||
lc = login_getclass(NULL);
|
||||
retries = login_getcapnum(lc, "login-retries", DEFAULT_RETRIES, DEFAULT_RETRIES);
|
||||
backoff = login_getcapnum(lc, "login-backoff", DEFAULT_BACKOFF, DEFAULT_BACKOFF);
|
||||
login_close(lc);
|
||||
lc = NULL;
|
||||
#else
|
||||
retries = DEFAULT_RETRIES;
|
||||
backoff = DEFAULT_BACKOFF;
|
||||
#endif
|
||||
|
||||
for (cnt = 0;; ask = 1) {
|
||||
if (ask) {
|
||||
@ -302,9 +320,14 @@ main(argc, argv)
|
||||
}
|
||||
(void)strcpy(tbuf, username);
|
||||
|
||||
pwd = getpwnam(username);
|
||||
if ((pwd = getpwnam(username)) != NULL)
|
||||
salt = pwd->pw_passwd;
|
||||
else
|
||||
salt = "xx";
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
/* Establish the class now, before we might goto
|
||||
/*
|
||||
* Establish the class now, before we might goto
|
||||
* within the next block. pwd can be NULL since it
|
||||
* falls back to the "default" class if it is.
|
||||
*/
|
||||
@ -317,12 +340,13 @@ main(argc, argv)
|
||||
* is root or the caller isn't changing their uid, don't
|
||||
* authenticate.
|
||||
*/
|
||||
rval = 1;
|
||||
if (pwd != NULL) {
|
||||
salt = pwd->pw_passwd;
|
||||
if (pwd->pw_uid == 0)
|
||||
rootlogin = 1;
|
||||
|
||||
if (fflag && (uid == 0 || uid == pwd->pw_uid)) {
|
||||
if (fflag && (uid == (uid_t)0 ||
|
||||
uid == (uid_t)pwd->pw_uid)) {
|
||||
/* already authenticated */
|
||||
break;
|
||||
} else if (pwd->pw_passwd[0] == '\0') {
|
||||
@ -331,8 +355,6 @@ main(argc, argv)
|
||||
goto ttycheck;
|
||||
}
|
||||
}
|
||||
else
|
||||
salt = "xx";
|
||||
|
||||
fflag = 0;
|
||||
|
||||
@ -340,19 +362,26 @@ main(argc, argv)
|
||||
|
||||
#ifdef LOGIN_CAP_AUTH
|
||||
/*
|
||||
* This hands off authorisation to an authorisation program,
|
||||
* This hands off authorization to an authorization program,
|
||||
* depending on the styles available for the "auth-login",
|
||||
* auth-rlogin (or default) authorisation styles.
|
||||
* auth-rlogin (or default) authorization styles.
|
||||
* We do this regardless of whether an account exists so that
|
||||
* the remote user cannot tell a "real" from an invented
|
||||
* account name. If we don't have an account we just fall
|
||||
* back to the first method for the "default" class.
|
||||
*/
|
||||
if ((style = login_getstyle(lc, auth_method, authtype)) == NULL) {
|
||||
rval = 1; /* No available authorisation method */
|
||||
(void)printf("No auth method available for %s.\n", authtype);
|
||||
if (!(style = login_getstyle(lc, auth_method, authtype))) {
|
||||
|
||||
/*
|
||||
* No available authorization method
|
||||
*/
|
||||
rval = 1;
|
||||
(void)printf("No auth method available for %s.\n",
|
||||
authtype);
|
||||
} else {
|
||||
/* Put back the kerberos instance, if any was given.
|
||||
|
||||
/*
|
||||
* Put back the kerberos instance, if any was given.
|
||||
* Don't worry about the non-kerberos case here, since
|
||||
* if kerberos is not available or not selected and an
|
||||
* instance is given at the login prompt, su or rlogin -l,
|
||||
@ -360,27 +389,42 @@ main(argc, argv)
|
||||
*/
|
||||
if (*instance)
|
||||
*(instance - 1) = '.';
|
||||
rval = authenticate(username, lc ? lc->lc_class : "default", style, authtype);
|
||||
|
||||
rval = authenticate(username,
|
||||
lc ? lc->lc_class : "default",
|
||||
style, authtype);
|
||||
/* Junk it again */
|
||||
if (*instance)
|
||||
*(instance - 1) = '\0';
|
||||
}
|
||||
|
||||
if (!rval) {
|
||||
char * approvp;
|
||||
|
||||
/*
|
||||
* If authentication succeeds, run any approval
|
||||
* program, if applicable for this class.
|
||||
*/
|
||||
char *approvep = login_getcapstr(lc, "approve", NULL, NULL);
|
||||
approvep = login_getcapstr(lc, "approve", NULL, NULL);
|
||||
rval = 1; /* Assume bad login again */
|
||||
if (approvep==NULL || auth_script(approvep, approvep, username, lc->lc_class, 0) == 0) {
|
||||
int r = auth_scan(AUTH_OKAY);
|
||||
/* See what the authorise program says */
|
||||
|
||||
if (approvep==NULL ||
|
||||
auth_script(approvep, approvep, username,
|
||||
lc->lc_class, 0) == 0) {
|
||||
int r;
|
||||
|
||||
r = auth_scan(AUTH_OKAY);
|
||||
/*
|
||||
* See what the authorize program says
|
||||
*/
|
||||
if (r != AUTH_NONE) {
|
||||
rval = 0;
|
||||
|
||||
if (!rootok && (r & AUTH_ROOTOKAY))
|
||||
rootok = 1; /* root approved */
|
||||
else rootlogin = 0;
|
||||
else
|
||||
rootlogin = 0;
|
||||
|
||||
if (!authok && (r & AUTH_SECURE))
|
||||
authok = 1; /* secure */
|
||||
}
|
||||
@ -388,23 +432,27 @@ main(argc, argv)
|
||||
}
|
||||
#else /* !LOGIN_CAP_AUTH */
|
||||
#ifdef SKEY
|
||||
permit_passwd = skeyaccess(username, tty, hostname ? full_hostname : NULL, NULL);
|
||||
permit_passwd = skeyaccess(username, tty,
|
||||
hostname ? full_hostname : NULL,
|
||||
NULL);
|
||||
p = skey_getpass("Password:", pwd, permit_passwd);
|
||||
ep = skey_crypt(p, salt, pwd, permit_passwd);
|
||||
#else /* !SKEY */
|
||||
p = getpass("Password:");
|
||||
ep = crypt(p, salt);
|
||||
#endif/* SKEY */
|
||||
|
||||
if (pwd) {
|
||||
#ifdef KERBEROS
|
||||
#ifdef SKEY
|
||||
if (pwd) {
|
||||
/* Do not allow user to type in kerberos password
|
||||
/*
|
||||
* Do not allow user to type in kerberos password
|
||||
* over the net (actually, this is ok for encrypted
|
||||
* links, but we have no way of determining if the
|
||||
* link is encrypted.
|
||||
*/
|
||||
if (!permit_passwd) {
|
||||
rval = 1; /* force failure */
|
||||
rval = 1; /* failed */
|
||||
} else
|
||||
#endif /* SKEY */
|
||||
rval = klogin(pwd, instance, localhost, p);
|
||||
@ -414,18 +462,17 @@ main(argc, argv)
|
||||
authok = 1; /* kerberos authenticated ok */
|
||||
else if (rval == 1) /* fallback to unix passwd */
|
||||
rval = strcmp(ep, pwd->pw_passwd);
|
||||
#ifdef SKEY
|
||||
}
|
||||
#endif /* SKEY */
|
||||
#else /* !KERBEROS */
|
||||
if (pwd)
|
||||
rval = strcmp(ep, pwd->pw_passwd);
|
||||
rval = strcmp(ep, pwd->pw_passwd);
|
||||
#endif /* KERBEROS */
|
||||
}
|
||||
|
||||
/* clear entered password */
|
||||
memset(p, 0, strlen(p));
|
||||
#endif /* LOGIN_CAP_AUTH */
|
||||
|
||||
(void)setpriority(PRIO_PROCESS, 0, 0);
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if (rval)
|
||||
auth_rmfiles();
|
||||
@ -439,22 +486,25 @@ main(argc, argv)
|
||||
if (authok == 0)
|
||||
#endif
|
||||
if (pwd && !rval && rootlogin && !rootok) {
|
||||
(void)fprintf(stderr, "%s login refused on this terminal.\n", pwd->pw_name);
|
||||
if (hostname)
|
||||
syslog(LOG_NOTICE, "LOGIN %s REFUSED FROM %s ON TTY %s", pwd->pw_name, full_hostname, tty);
|
||||
else
|
||||
syslog(LOG_NOTICE, "LOGIN %s REFUSED ON TTY %s", pwd->pw_name, tty);
|
||||
continue;
|
||||
/* use same message as for authentication failure */
|
||||
/* (void)fprintf(stderr, "%s login refused on this terminal.\n", pwd->pw_name); */
|
||||
refused(NULL, "NOROOT", 0);
|
||||
/* preserve backoff behaviour even for failed root */
|
||||
/* continue; */
|
||||
}
|
||||
|
||||
if (pwd && !rval) /* valid password & authenticated */
|
||||
/* valid password & authenticated */
|
||||
else if (pwd && !rval)
|
||||
break;
|
||||
|
||||
(void)printf("Login incorrect\n");
|
||||
failures++;
|
||||
/* we allow 10 tries, but after 3 we start backing off */
|
||||
if (++cnt > 3) {
|
||||
if (cnt >= 10) {
|
||||
|
||||
/*
|
||||
* we allow up to 'retry' (10) tries,
|
||||
* but after 'backoff' (3) we start backing off
|
||||
*/
|
||||
if (++cnt > backoff) {
|
||||
if (cnt >= retries) {
|
||||
badlogin(username);
|
||||
sleepexit(1);
|
||||
}
|
||||
@ -483,19 +533,14 @@ main(argc, argv)
|
||||
#endif
|
||||
if (!*pwd->pw_dir || chdir(pwd->pw_dir) < 0) {
|
||||
#ifdef LOGIN_CAP
|
||||
if (login_getcapbool(lc, "requirehome", !rootlogin) || chdir("/") < 0) {
|
||||
(void)printf("No home directory %s!\n", pwd->pw_dir);
|
||||
sleepexit(1);
|
||||
}
|
||||
#else
|
||||
if (chdir("/") < 0) {
|
||||
(void)printf("No home directory %s!\n", pwd->pw_dir);
|
||||
sleepexit(1);
|
||||
}
|
||||
if (login_getcapbool(lc, "requirehome", !rootlogin))
|
||||
refused("Home directory not available", "HOMEDIR", 1);
|
||||
#endif
|
||||
if (chdir("/") < 0) {
|
||||
refused("Cannot find root directory", "ROOTDIR", 1);
|
||||
pwd->pw_dir = "/";
|
||||
if (!quietlog)
|
||||
(void)printf("No home directory.\nLogging in with home = \"/\".\n");
|
||||
if (!quietlog || *pwd->pw_dir)
|
||||
printf("No home directory.\nLogging in with home = \"/\".\n");
|
||||
}
|
||||
if (!quietlog)
|
||||
quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
|
||||
@ -505,48 +550,45 @@ main(argc, argv)
|
||||
|
||||
#define DEFAULT_WARN (2L * 7L & 86400L) /* Two weeks */
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
warntime = login_getcaptime(lc, "warnpassword",
|
||||
DEFAULT_WARN, DEFAULT_WARN);
|
||||
#else
|
||||
warntime = DEFAULT_WARN;
|
||||
#endif
|
||||
|
||||
changepass=0;
|
||||
if (pwd->pw_change) {
|
||||
if (tp.tv_sec >= pwd->pw_change) {
|
||||
(void)printf("Sorry -- your password has expired.\n");
|
||||
syslog(LOG_NOTICE, "%s Password expired - forcing change", pwd->pw_name);
|
||||
changepass=1;
|
||||
#ifdef LOGIN_CAP
|
||||
} else {
|
||||
time_t warntime = (time_t)login_getcaptime(lc, "warnpassword", DEFAULT_WARN, DEFAULT_WARN);
|
||||
if (pwd->pw_change - tp.tv_sec < warntime && !quietlog)
|
||||
(void)printf("Warning: your password expires on %s", ctime(&pwd->pw_change));
|
||||
syslog(LOG_INFO,
|
||||
"%s Password expired - forcing change",
|
||||
pwd->pw_name);
|
||||
} else if (pwd->pw_change - tp.tv_sec < warntime && !quietlog)
|
||||
(void)printf("Warning: your password expires on %s",
|
||||
ctime(&pwd->pw_change));
|
||||
}
|
||||
#else
|
||||
} else if (pwd->pw_change - tp.tv_sec < DEFAULT_WARN && !quietlog) {
|
||||
(void)printf("Warning: your password expires on %s", ctime(&pwd->pw_change));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
warntime = login_getcaptime(lc, "warnexpire",
|
||||
DEFAULT_WARN, DEFAULT_WARN);
|
||||
#else
|
||||
warntime = DEFAULT_WARN;
|
||||
#endif
|
||||
|
||||
if (pwd->pw_expire) {
|
||||
if (tp.tv_sec >= pwd->pw_expire) {
|
||||
(void)printf("Sorry -- your account has expired.\n");
|
||||
syslog(LOG_NOTICE, "%s Account expired - login refused", pwd->pw_name);
|
||||
sleepexit(1);
|
||||
#ifdef LOGIN_CAP
|
||||
} else {
|
||||
time_t warntime = (time_t)login_getcaptime(lc, "warnexpire", DEFAULT_WARN, DEFAULT_WARN);
|
||||
if (pwd->pw_expire - tp.tv_sec < warntime && !quietlog)
|
||||
(void)printf("Warning: your account expires on %s",
|
||||
ctime(&pwd->pw_expire));
|
||||
}
|
||||
#else
|
||||
} else if (pwd->pw_expire - tp.tv_sec < DEFAULT_WARN && !quietlog) {
|
||||
(void)printf("Warning: your account expires on %s",
|
||||
ctime(&pwd->pw_expire));
|
||||
}
|
||||
#endif
|
||||
refused("Sorry -- your account has expired",
|
||||
"EXPIRED", 1);
|
||||
} else if (pwd->pw_expire - tp.tv_sec < warntime && !quietlog)
|
||||
(void)printf("Warning: your account expires on %s",
|
||||
ctime(&pwd->pw_expire));
|
||||
}
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if (lc != NULL) {
|
||||
char *msg = NULL;
|
||||
|
||||
if (hostname) {
|
||||
struct hostent *hp = gethostbyname(full_hostname);
|
||||
|
||||
@ -557,39 +599,32 @@ main(argc, argv)
|
||||
memmove(&in, hp->h_addr, sizeof(in));
|
||||
optarg = strdup(inet_ntoa(in));
|
||||
}
|
||||
if (!auth_hostok(lc, full_hostname, optarg)) {
|
||||
syslog(LOG_NOTICE, "%s LOGIN REFUSED (HOST) FROM %s", pwd->pw_name, full_hostname);
|
||||
msg = "Permission denied";
|
||||
}
|
||||
if (!auth_hostok(lc, full_hostname, optarg))
|
||||
refused("Permission denied", "HOST", 1);
|
||||
}
|
||||
|
||||
if (msg == NULL && !auth_ttyok(lc, tty)) {
|
||||
syslog(LOG_NOTICE, "%s LOGIN REFUSED (TTY) ON %s", pwd->pw_name, tty);
|
||||
msg = "Permission denied";
|
||||
}
|
||||
if (!auth_ttyok(lc, tty))
|
||||
refused("Permission denied", "TTY", 1);
|
||||
|
||||
if (msg == NULL && !auth_timeok(lc, time(NULL))) {
|
||||
syslog(LOG_NOTICE, "%s LOGIN REFUSED (TIME) %s %s", pwd->pw_name, hostname?"FROM":"ON", hostname?full_hostname:tty);
|
||||
msg = "Logins not available right now";
|
||||
}
|
||||
|
||||
if (msg != NULL) {
|
||||
printf("%s.\n", msg);
|
||||
sleepexit(1);
|
||||
}
|
||||
if (!auth_timeok(lc, time(NULL)))
|
||||
refused("Logins not available right now", "TIME", 1);
|
||||
}
|
||||
strncpy(shell, login_getcapstr(lc, "shell", pwd->pw_shell, pwd->pw_shell), sizeof shell);
|
||||
shell=login_getcapstr(lc, "shell", pwd->pw_shell, pwd->pw_shell);
|
||||
#else /* !LOGIN_CAP */
|
||||
strncpy(shell, pwd->pw_shell, sizeof shell);
|
||||
shell=pwd->pw_shell;
|
||||
#endif /* LOGIN_CAP */
|
||||
shell[sizeof shell - 1] = '\0';
|
||||
|
||||
#ifdef LOGIN_ACCESS
|
||||
if (login_access(pwd->pw_name, hostname ? full_hostname : tty) == 0) {
|
||||
printf("Permission denied\n");
|
||||
syslog(LOG_NOTICE, "%s LOGIN REFUSED (ACCESS) %s %s", pwd->pw_name, hostname?"FROM":"ON", hostname?full_hostname:tty);
|
||||
if (*pwd->pw_shell == '\0')
|
||||
pwd->pw_shell = _PATH_BSHELL;
|
||||
if (*shell == '\0') /* Not overridden */
|
||||
shell = pwd->pw_shell;
|
||||
if ((shell = strdup(shell)) == NULL) {
|
||||
syslog(LOG_NOTICE, "memory allocation error");
|
||||
sleepexit(1);
|
||||
}
|
||||
|
||||
#ifdef LOGIN_ACCESS
|
||||
if (login_access(pwd->pw_name, hostname ? full_hostname : tty) == 0)
|
||||
refused("Permission denied", "ACCESS", 1);
|
||||
#endif /* LOGIN_ACCESS */
|
||||
|
||||
/* Nothing else left to fail -- really log in. */
|
||||
@ -610,22 +645,22 @@ main(argc, argv)
|
||||
*/
|
||||
login_fbtab(tty, pwd->pw_uid, pwd->pw_gid);
|
||||
|
||||
(void)chown(ttyn, pwd->pw_uid, (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
|
||||
(void)chown(ttyn, pwd->pw_uid,
|
||||
(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
|
||||
|
||||
/* Preserve TERM if it happens to be already set */
|
||||
if ((p = getenv("TERM")) != NULL) {
|
||||
(void)strncpy(term, p, sizeof(term));
|
||||
term[sizeof(term)-1] = '\0';
|
||||
}
|
||||
/*
|
||||
* Preserve TERM if it happens to be already set.
|
||||
*/
|
||||
term = getenv("TERM");
|
||||
|
||||
/* Exclude cons/vt/ptys only, assume dialup otherwise */
|
||||
/*
|
||||
* Exclude cons/vt/ptys only, assume dialup otherwise
|
||||
* TODO: Make dialup tty determination a library call
|
||||
* for consistency (finger etc.)
|
||||
*/
|
||||
if (hostname==NULL && strchr("vpqstPQST", tty[sizeof("tty")-1]) == NULL)
|
||||
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
|
||||
|
||||
/* If fflag is on, assume caller/authenticator has logged root login. */
|
||||
if (rootlogin && fflag == 0)
|
||||
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s%s%s", username, tty, hostname?" FROM ":"", hostname?full_hostname:"");
|
||||
|
||||
#ifdef KERBEROS
|
||||
if (!quietlog && notickets == 1 && !noticketsdontcomplain)
|
||||
(void)printf("Warning: no Kerberos tickets issued.\n");
|
||||
@ -636,14 +671,37 @@ main(argc, argv)
|
||||
* Syslog each successful login, so we don't have to watch hundreds
|
||||
* of wtmp or lastlogin files.
|
||||
*/
|
||||
syslog(LOG_INFO, "login %s %s as %s", hostname?"from":"on", hostname?full_hostname:tty, pwd->pw_name);
|
||||
if (hostname)
|
||||
syslog(LOG_INFO, "login from %s on %s as %s",
|
||||
full_hostname, tty, pwd->pw_name);
|
||||
else
|
||||
syslog(LOG_INFO, "login on %s as %s",
|
||||
tty, pwd->pw_name);
|
||||
#endif
|
||||
|
||||
/* Destroy environment unless user has requested its preservation. */
|
||||
/*
|
||||
* If fflag is on, assume caller/authenticator has logged root login.
|
||||
*/
|
||||
if (rootlogin && fflag == 0)
|
||||
{
|
||||
if (hostname)
|
||||
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
|
||||
username, tty, full_hostname);
|
||||
else
|
||||
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s",
|
||||
username, tty);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy environment unless user has requested its preservation.
|
||||
* We need to do this before setusercontext() because that may
|
||||
* set or reset some environment variables.
|
||||
*/
|
||||
if (!pflag)
|
||||
environ = envinit;
|
||||
|
||||
/* We don't need to be root anymore, so
|
||||
/*
|
||||
* We don't need to be root anymore, so
|
||||
* set the user and session context
|
||||
*/
|
||||
#ifdef LOGIN_CAP
|
||||
@ -660,63 +718,66 @@ main(argc, argv)
|
||||
(void)setuid(rootlogin ? 0 : pwd->pw_uid);
|
||||
#endif
|
||||
|
||||
if (*pwd->pw_shell == '\0') {
|
||||
pwd->pw_shell = _PATH_BSHELL;
|
||||
if (*shell == '\0') /* Not overridden */
|
||||
strcpy(shell, pwd->pw_shell);
|
||||
}
|
||||
(void)setenv("SHELL", pwd->pw_shell, 1);
|
||||
(void)setenv("HOME", pwd->pw_dir, 1);
|
||||
if (term[0] != '\0')
|
||||
if (term != NULL && *term != '\0')
|
||||
(void)setenv("TERM", term, 1); /* Preset overrides */
|
||||
else {
|
||||
(void)strncpy(term, stypeof(tty), sizeof(term));
|
||||
term[sizeof(term)-1] = '\0';
|
||||
(void)setenv("TERM", term, 0); /* Fallback doesn't */
|
||||
(void)setenv("TERM", stypeof(tty), 0); /* Fallback doesn't */
|
||||
}
|
||||
(void)setenv("LOGNAME", pwd->pw_name, 1);
|
||||
(void)setenv("USER", pwd->pw_name, 1);
|
||||
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
|
||||
#if LOGIN_CAP_AUTH
|
||||
auth_env();
|
||||
#else
|
||||
#ifdef KERBEROS
|
||||
if (krbtkfile_env)
|
||||
(void)setenv("KRBTKFILE", krbtkfile_env, 1);
|
||||
#endif
|
||||
#if LOGIN_CAP_AUTH
|
||||
auth_env();
|
||||
#endif
|
||||
|
||||
if (!quietlog) {
|
||||
#ifdef LOGIN_CAP
|
||||
char *cw = login_getcapstr(lc, "copyright", NULL, NULL);
|
||||
if (!quietlog) {
|
||||
char *cw;
|
||||
|
||||
cw = login_getcapstr(lc, "copyright", NULL, NULL);
|
||||
if (cw != NULL && access(cw, F_OK) == 0)
|
||||
motd(cw);
|
||||
else
|
||||
#endif
|
||||
(void)printf("%s\n", copyright);
|
||||
#ifdef LOGIN_CAP
|
||||
(void)printf("%s\n\t%s %s\n",
|
||||
"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
|
||||
"The Regents of the University of California. ",
|
||||
"All rights reserved.");
|
||||
|
||||
(void)printf("\n");
|
||||
|
||||
cw = login_getcapstr(lc, "welcome", NULL, NULL);
|
||||
if (cw == NULL || access(cw, F_OK) != 0)
|
||||
cw = _PATH_MOTDFILE;
|
||||
motd(cw);
|
||||
|
||||
cw = getenv("MAIL"); /* $MAIL may have been set by class */
|
||||
if (cw != NULL) {
|
||||
strncpy(tbuf, cw, sizeof(tbuf));
|
||||
tbuf[sizeof(tbuf)-1] = '\0';
|
||||
} else
|
||||
snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
|
||||
snprintf(tbuf, sizeof(tbuf), "%s/%s",
|
||||
_PATH_MAILDIR, pwd->pw_name);
|
||||
#else
|
||||
if (!quietlog) {
|
||||
(void)printf("%s\n\t%s %s\n",
|
||||
"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
|
||||
"The Regents of the University of California. ",
|
||||
"All rights reserved.");
|
||||
motd(_PATH_MOTDFILE);
|
||||
snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
|
||||
snprintf(tbuf, sizeof(tbuf), "%s/%s",
|
||||
_PATH_MAILDIR, pwd->pw_name);
|
||||
#endif
|
||||
if (stat(tbuf, &st) == 0 && st.st_size != 0)
|
||||
(void)printf("You have %smail.\n", (st.st_mtime > st.st_atime) ? "new " : "");
|
||||
(void)printf("You have %smail.\n",
|
||||
(st.st_mtime > st.st_atime) ? "new " : "");
|
||||
}
|
||||
|
||||
/* Login shells have a leading '-' in front of argv[0] */
|
||||
tbuf[0] = '-';
|
||||
(void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell);
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
login_close(lc);
|
||||
#endif
|
||||
@ -731,12 +792,20 @@ main(argc, argv)
|
||||
sleepexit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Login shells have a leading '-' in front of argv[0]
|
||||
*/
|
||||
tbuf[0] = '-';
|
||||
(void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell);
|
||||
|
||||
execlp(shell, tbuf, 0);
|
||||
err(1, "%s", shell);
|
||||
}
|
||||
|
||||
|
||||
/* Allow for authentication style and/or kerberos instance */
|
||||
/*
|
||||
* Allow for authentication style and/or kerberos instance
|
||||
* */
|
||||
|
||||
#define NBUFSIZ UT_NAMESIZE + 64
|
||||
|
||||
@ -774,6 +843,7 @@ rootterm(ttyn)
|
||||
char *ttyn;
|
||||
{
|
||||
struct ttyent *t;
|
||||
|
||||
return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
|
||||
}
|
||||
|
||||
@ -893,16 +963,36 @@ char *
|
||||
stypeof(ttyid)
|
||||
char *ttyid;
|
||||
{
|
||||
|
||||
struct ttyent *t;
|
||||
|
||||
return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
|
||||
}
|
||||
|
||||
void
|
||||
refused(msg, rtype, lout)
|
||||
char *msg;
|
||||
char *rtype;
|
||||
int lout;
|
||||
{
|
||||
|
||||
if (msg != NULL)
|
||||
printf("%s.\n", msg);
|
||||
if (hostname)
|
||||
syslog(LOG_NOTICE, "LOGIN %s REFUSED (%s) FROM %s ON TTY %s",
|
||||
pwd->pw_name, rtype, full_hostname, tty);
|
||||
else
|
||||
syslog(LOG_NOTICE, "LOGIN %s REFUSED (%s) ON TTY %s",
|
||||
pwd->pw_name, rtype, tty);
|
||||
if (lout)
|
||||
sleepexit(1);
|
||||
}
|
||||
|
||||
void
|
||||
sleepexit(eval)
|
||||
int eval;
|
||||
{
|
||||
|
||||
(void)sleep(5);
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user