version 1.29, 2000/07/17 16:43:14 |
version 1.30, 2000/08/20 18:42:39 |
|
|
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <grp.h> |
#include <grp.h> |
|
#include <login_cap.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <setjmp.h> |
#include <setjmp.h> |
#include <signal.h> |
#include <signal.h> |
|
|
/* |
/* |
* This bounds the time given to login. Not a define so it can |
* This bounds the time given to login. Not a define so it can |
* be patched on machines where it's too small. |
* be patched on machines where it's too small. |
|
* XXX - should be a login.conf variable! |
*/ |
*/ |
u_int timeout = 300; |
u_int timeout = 300; |
|
|
#if defined(KERBEROS) || defined(KERBEROS5) |
#if defined(KERBEROS) || defined(KERBEROS5) |
int notickets = 1; |
int notickets = 1; |
char *instance; |
char *instance; |
char *krbtkfile_env; |
char *krbtkfile_env; |
int authok; |
int authok; |
#endif |
#endif |
|
|
struct passwd *pwd; |
struct passwd *pwd; |
int failures; |
login_cap_t *lc = NULL; |
char term[64], *hostname, *tty; |
int failures; |
char *username = NULL, *rusername = NULL; |
char term[64], *hostname, *tty; |
|
char *username = NULL, *rusername = NULL; |
|
|
int |
int |
main(argc, argv) |
main(argc, argv) |
|
|
struct utmp utmp; |
struct utmp utmp; |
int ask, ch, cnt, fflag, hflag, pflag, uflag, quietlog, rootlogin, rval; |
int ask, ch, cnt, fflag, hflag, pflag, uflag, quietlog, rootlogin, rval; |
uid_t uid; |
uid_t uid; |
char *domain, *p, *salt, *ttyn; |
char *domain, *p, *salt, *ttyn, *shell; |
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; |
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; |
char localhost[MAXHOSTNAMELEN]; |
char localhost[MAXHOSTNAMELEN]; |
|
|
|
|
salt = pwd->pw_passwd; |
salt = pwd->pw_passwd; |
else |
else |
salt = "xx"; |
salt = "xx"; |
|
lc = login_getclass(pwd ? pwd->pw_class : LOGIN_DEFCLASS); |
|
if (!lc) |
|
err(1, "unable to get login class"); |
|
|
/* |
/* |
* If we have a valid account name, and it doesn't have a |
* If we have a valid account name, and it doesn't have a |
|
|
|
|
if (chdir(pwd->pw_dir) < 0) { |
if (chdir(pwd->pw_dir) < 0) { |
(void)printf("No home directory %s!\n", pwd->pw_dir); |
(void)printf("No home directory %s!\n", pwd->pw_dir); |
|
if (login_getcapbool(lc, "requirehome", 0)) |
|
exit(1); |
if (chdir("/")) |
if (chdir("/")) |
exit(0); |
exit(0); |
pwd->pw_dir = "/"; |
pwd->pw_dir = "/"; |
(void)printf("Logging in with home = \"/\".\n"); |
(void)printf("Logging in with home = \"/\".\n"); |
} |
} |
|
|
|
shell = login_getcapstr(lc, "shell", pwd->pw_shell, pwd->pw_shell); |
|
if (*shell == '\0') |
|
shell = _PATH_BSHELL; |
|
else if (strlen(shell) >= MAXPATHLEN) { |
|
syslog(LOG_ERR, "shell path too long: %s", shell); |
|
warnx("invalid shell"); |
|
sleepexit(1); |
|
} |
|
|
quietlog = ((strcmp(pwd->pw_shell, "/sbin/nologin") == 0) || |
quietlog = ((strcmp(pwd->pw_shell, "/sbin/nologin") == 0) || |
(access(_PATH_HUSHLOGIN, F_OK) == 0)); |
login_getcapbool(lc, "hushlogin", 0) || |
|
(access(_PATH_HUSHLOGIN, F_OK) == 0)); |
|
|
seteuid(0); |
seteuid(0); |
setegid(0); /* XXX use a saved gid instead? */ |
setegid(0); /* XXX use a saved gid instead? */ |
|
|
if (tp.tv_sec >= pwd->pw_change) { |
if (tp.tv_sec >= pwd->pw_change) { |
(void)printf("Sorry -- your password has expired.\n"); |
(void)printf("Sorry -- your password has expired.\n"); |
sleepexit(1); |
sleepexit(1); |
} else if (pwd->pw_change - tp.tv_sec < |
} else if (!quietlog && pwd->pw_change - tp.tv_sec < |
2 * DAYSPERWEEK * SECSPERDAY && !quietlog) |
login_getcaptime(lc, "password-warn", |
|
2 * DAYSPERWEEK * SECSPERDAY, 2 * DAYSPERWEEK * SECSPERDAY)) |
(void)printf("Warning: your password expires on %s", |
(void)printf("Warning: your password expires on %s", |
ctime(&pwd->pw_change)); |
ctime(&pwd->pw_change)); |
} |
} |
|
|
if (tp.tv_sec >= pwd->pw_expire) { |
if (tp.tv_sec >= pwd->pw_expire) { |
(void)printf("Sorry -- your account has expired.\n"); |
(void)printf("Sorry -- your account has expired.\n"); |
sleepexit(1); |
sleepexit(1); |
} else if (pwd->pw_expire - tp.tv_sec < |
} else if (!quietlog &&pwd->pw_expire - tp.tv_sec < |
2 * DAYSPERWEEK * SECSPERDAY && !quietlog) |
login_getcaptime(lc, "expire-warn", |
|
2 * DAYSPERWEEK * SECSPERDAY, 2 * DAYSPERWEEK * SECSPERDAY)) |
(void)printf("Warning: your account expires on %s", |
(void)printf("Warning: your account expires on %s", |
ctime(&pwd->pw_expire)); |
ctime(&pwd->pw_expire)); |
} |
} |
|
|
if (krbtkfile_env) |
if (krbtkfile_env) |
dofork(); |
dofork(); |
#endif |
#endif |
(void)setegid(pwd->pw_gid); |
|
(void)setgid(pwd->pw_gid); |
|
|
|
initgroups(username, pwd->pw_gid); |
|
|
|
if (*pwd->pw_shell == '\0') |
|
pwd->pw_shell = _PATH_BSHELL; |
|
|
|
/* Destroy environment unless user has requested its preservation. */ |
/* Destroy environment unless user has requested its preservation. */ |
if (!pflag) { |
if (!pflag) { |
if ((environ = calloc(1, sizeof (char *))) == NULL) |
if ((environ = calloc(1, sizeof (char *))) == NULL) |
|
|
} |
} |
*cpp2 = 0; |
*cpp2 = 0; |
} |
} |
|
/* Note: setusercontext(3) will set PATH */ |
(void)setenv("HOME", pwd->pw_dir, 1); |
(void)setenv("HOME", pwd->pw_dir, 1); |
(void)setenv("SHELL", pwd->pw_shell, 1); |
(void)setenv("SHELL", shell, 1); |
if (term[0] == '\0') |
if (term[0] == '\0') |
(void)strlcpy(term, stypeof(tty), sizeof(term)); |
(void)strlcpy(term, stypeof(tty), sizeof(term)); |
(void)setenv("TERM", term, 0); |
(void)setenv("TERM", term, 0); |
(void)setenv("LOGNAME", pwd->pw_name, 1); |
(void)setenv("LOGNAME", pwd->pw_name, 1); |
(void)setenv("USER", pwd->pw_name, 1); |
(void)setenv("USER", pwd->pw_name, 1); |
(void)setenv("PATH", _PATH_DEFPATH, 0); |
|
if (hostname) |
if (hostname) |
(void)setenv("REMOTEHOST", hostname, 1); |
(void)setenv("REMOTEHOST", hostname, 1); |
if (rusername) |
if (rusername) |
|
|
if (krbtkfile_env) |
if (krbtkfile_env) |
(void)setenv("KRB5CCNAME", krbtkfile_env, 1); |
(void)setenv("KRB5CCNAME", krbtkfile_env, 1); |
#endif |
#endif |
|
|
/* If fflag is on, assume caller/authenticator has logged root login. */ |
/* If fflag is on, assume caller/authenticator has logged root login. */ |
if (rootlogin && fflag == 0) { |
if (rootlogin && fflag == 0) { |
if (hostname) |
if (hostname) |
|
|
(void)signal(SIGTSTP, SIG_IGN); |
(void)signal(SIGTSTP, SIG_IGN); |
|
|
tbuf[0] = '-'; |
tbuf[0] = '-'; |
(void)strlcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? |
(void)strlcpy(tbuf + 1, (p = strrchr(shell, '/')) ? |
p + 1 : pwd->pw_shell, sizeof tbuf - 1); |
p + 1 : shell, sizeof tbuf - 1); |
|
|
if (setlogin(pwd->pw_name) < 0) |
|
syslog(LOG_ERR, "setlogin() failure: %m"); |
|
|
|
/* Discard permissions last so can't get killed and drop core. */ |
/* Discard permissions last so can't get killed and drop core. */ |
if (rootlogin) |
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETALL)) { |
(void) setuid(0); |
warn("unable to set user context"); |
else { |
exit(1); |
(void) seteuid(pwd->pw_uid); |
|
(void) setuid(pwd->pw_uid); |
|
} |
} |
|
|
#ifdef KERBEROS |
#ifdef KERBEROS |
kgettokens(pwd->pw_dir); |
kgettokens(pwd->pw_dir); |
#endif |
#endif |
|
|
execlp(pwd->pw_shell, tbuf, 0); |
execlp(shell, tbuf, 0); |
err(1, "%s", pwd->pw_shell); |
err(1, "%s", shell); |
} |
} |
|
|
int |
int |
|
|
int fd, nchars; |
int fd, nchars; |
sig_t oldint; |
sig_t oldint; |
char tbuf[8192]; |
char tbuf[8192]; |
|
char *motd; |
|
|
if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0) |
motd = login_getcapstr(lc, "welcome", _PATH_MOTDFILE, _PATH_MOTDFILE); |
|
|
|
if ((fd = open(motd, O_RDONLY, 0)) < 0) |
return; |
return; |
oldint = signal(SIGINT, sigint); |
oldint = signal(SIGINT, sigint); |
if (setjmp(motdinterrupt) == 0) |
if (setjmp(motdinterrupt) == 0) |
|
|
checknologin() |
checknologin() |
{ |
{ |
int fd, nchars; |
int fd, nchars; |
|
char *nologin; |
char tbuf[8192]; |
char tbuf[8192]; |
|
|
if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) { |
if (!login_getcapbool(lc, "ignorenologin", 0)) { |
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) |
nologin = login_getcapstr(lc, "nologin", _PATH_NOLOGIN, |
(void)write(fileno(stdout), tbuf, nchars); |
_PATH_NOLOGIN); |
sleepexit(0); |
if ((fd = open(nologin, O_RDONLY, 0)) >= 0) { |
|
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) |
|
(void)write(fileno(stdout), tbuf, nchars); |
|
sleepexit(0); |
|
} |
} |
} |
} |
} |
|
|
|
|
{ |
{ |
struct ttyent *t; |
struct ttyent *t; |
|
|
return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); |
return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : |
|
login_getcapstr(lc, "term", UNKNOWN, UNKNOWN)); |
} |
} |
|
|
void |
void |
|
|
{ |
{ |
if (username) |
if (username) |
badlogin(username); |
badlogin(username); |
|
exit(0); |
exit(W_EXITCODE(0, signum)); |
|
} |
} |