#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)login.c 5.29 (Berkeley) %G%";
+static char sccsid[] = "@(#)login.c 5.36 (Berkeley) %G%";
#endif /* not lint */
/*
#include <setjmp.h>
#include <stdio.h>
#include <strings.h>
+#include "pathnames.h"
#define TTYGRPNAME "tty" /* name of group to own ttys */
-#define MOTDFILE "/etc/motd"
-#define MAILDIR "/usr/spool/mail"
-#define NOLOGIN "/etc/nologin"
-#define HUSHLOGIN ".hushlogin"
-#define LASTLOG "/usr/adm/lastlog"
-#define BSHELL "/bin/sh"
-
/*
* This bounds the time given to login. Not a define so it can
* be patched on machines where it's too small.
*/
int timeout = 300;
-struct passwd *pwd;
-int repeatcnt;
-char term[64], *hostname, *username, *tty;
+struct passwd *pwd;
+int failures;
+char term[64], *hostname, *username, *tty;
-struct sgttyb sgttyb;
-struct tchars tc = {
+struct sgttyb sgttyb;
+struct tchars tc = {
CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
};
-struct ltchars ltc = {
+struct ltchars ltc = {
CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
};
+char *months[] =
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
+ "Sep", "Oct", "Nov", "Dec" };
+
+char *months[] =
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
+ "Sep", "Oct", "Nov", "Dec" };
+
main(argc, argv)
int argc;
char **argv;
{
extern int errno, optind;
extern char *optarg, **environ;
+ struct timeval tp;
+ struct tm *ttp;
+ struct timeval tp;
+ struct tm *ttp;
struct group *gr;
register int ch;
register char *p;
int ask, fflag, hflag, pflag, cnt;
int quietlog, passwd_req, ioctlval, timedout();
- char *domain, *salt, *envinit[1], *ttyn;
+ char *domain, *salt, *envinit[1], *ttyn, *pp;
char tbuf[MAXPATHLEN + 2];
- char *ttyname(), *stypeof(), *crypt(), *getpass();
+ char *ctime(), *ttyname(), *stypeof(), *crypt(), *getpass();
time_t time();
off_t lseek();
argc -= optind;
argv += optind;
if (*argv) {
- ask = 0;
username = *argv;
- }
- else
+ ask = 0;
+ } else
ask = 1;
ioctlval = 0;
fflag = 0;
getloginname();
}
- /* note if trying multiple login's */
- if (repeatcnt) {
- if (strcmp(tbuf, username)) {
+ /*
+ * Note if trying multiple user names;
+ * log failures for previous user name,
+ * but don't bother logging one failure
+ * for nonexistent name (mistyped username).
+ */
+ if (failures && strcmp(tbuf, username)) {
+ if (failures > (pwd ? 0 : 1))
badlogin(tbuf);
- repeatcnt = 1;
- (void)strcpy(tbuf, username);
- }
- else
- ++repeatcnt;
- }
- else {
- repeatcnt = 1;
- (void)strcpy(tbuf, username);
+ failures = 0;
}
+ (void)strcpy(tbuf, username);
if (pwd = getpwnam(username))
salt = pwd->pw_passwd;
else
* If no pre-authentication and a password exists
* for this user, prompt for one and verify it.
*/
- if (!passwd_req || pwd && !*pwd->pw_passwd)
+ if (!passwd_req || (pwd && !*pwd->pw_passwd))
break;
setpriority(PRIO_PROCESS, 0, -4);
- p = crypt(getpass("Password:"), salt);
+ pp = getpass("Password:");
+ p = crypt(pp, salt);
setpriority(PRIO_PROCESS, 0, 0);
+
+ (void) bzero(pp, strlen(pp));
if (pwd && !strcmp(p, pwd->pw_passwd))
break;
printf("Login incorrect\n");
+ failures++;
/* we allow 10 tries, but after 3 we start backing off */
if (++cnt > 3) {
if (cnt >= 10) {
/* committed to login -- turn off timeout */
(void)alarm((u_int)0);
- /* log any mistakes -- don't count last one */
- --repeatcnt;
- badlogin(username);
-
/*
* If valid so far and root is logging in, see if root logins on
* this terminal are permitted.
*/
- if (pwd->pw_uid == 0 && !rootterm()) {
+ if (pwd->pw_uid == 0 && !rootterm(tty)) {
if (hostname)
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s",
- tty, hostname);
+ syslog(LOG_NOTICE, "ROOT LOGIN REFUSED FROM %s",
+ hostname);
else
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty);
+ syslog(LOG_NOTICE, "ROOT LOGIN REFUSED ON %s", tty);
printf("Login incorrect\n");
sleepexit(1);
}
printf("Logging in with home = \"/\".\n");
}
+#define TWOWEEKS (14*24*60*60)
+ if (pwd->pw_change || pwd->pw_expire)
+ (void)gettimeofday(&tp, (struct timezone *)NULL);
+ if (pwd->pw_change)
+ if (tp.tv_sec >= pwd->pw_change) {
+ printf("Sorry -- your password has expired.\n");
+ sleepexit(1);
+ }
+ else if (tp.tv_sec - pwd->pw_change < TWOWEEKS) {
+ ttp = localtime(&pwd->pw_change);
+ printf("Warning: your password expires on %s %d, 19%d\n",
+ months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
+ }
+ if (pwd->pw_expire)
+ if (tp.tv_sec >= pwd->pw_expire) {
+ printf("Sorry -- your account has expired.\n");
+ sleepexit(1);
+ }
+ else if (tp.tv_sec - pwd->pw_expire < TWOWEEKS) {
+ ttp = localtime(&pwd->pw_expire);
+ printf("Warning: your account expires on %s %d, 19%d\n",
+ months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
+ }
+
+#define TWOWEEKS (14*24*60*60)
+ if (pwd->pw_change || pwd->pw_expire)
+ (void)gettimeofday(&tp, (struct timezone *)NULL);
+ if (pwd->pw_change)
+ if (tp.tv_sec >= pwd->pw_change) {
+ printf("Sorry -- your password has expired.\n");
+ sleepexit(1);
+ }
+ else if (tp.tv_sec - pwd->pw_change < TWOWEEKS) {
+ ttp = localtime(&pwd->pw_change);
+ printf("Warning: your password expires on %s %d, 19%d\n",
+ months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
+ }
+ if (pwd->pw_expire)
+ if (tp.tv_sec >= pwd->pw_expire) {
+ printf("Sorry -- your account has expired.\n");
+ sleepexit(1);
+ }
+ else if (tp.tv_sec - pwd->pw_expire < TWOWEEKS) {
+ ttp = localtime(&pwd->pw_expire);
+ printf("Warning: your account expires on %s %d, 19%d\n",
+ months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
+ }
+
/* nothing else left to fail -- really log in */
{
struct utmp utmp;
+ bzero((char *)&utmp, sizeof(utmp));
(void)time(&utmp.ut_time);
strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
if (hostname)
strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
- else
- bzero(utmp.ut_host, sizeof(utmp.ut_host));
strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
login(&utmp);
}
- quietlog = access(HUSHLOGIN, F_OK) == 0;
+ quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
dolastlog(quietlog);
if (!hflag) { /* XXX */
(void)setuid(pwd->pw_uid);
if (*pwd->pw_shell == '\0')
- pwd->pw_shell = BSHELL;
+ pwd->pw_shell = _PATH_BSHELL;
/* turn on new line discipline for the csh */
- else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
+ else if (!strcmp(pwd->pw_shell, _PATH_CSHELL)) {
ioctlval = NTTYDISC;
(void)ioctl(0, TIOCSETD, &ioctlval);
}
(void)setenv("HOME", pwd->pw_dir, 1);
(void)setenv("SHELL", pwd->pw_shell, 1);
if (term[0] == '\0')
- strncpy(term, stypeof(), sizeof(term));
+ strncpy(term, stypeof(tty), sizeof(term));
(void)setenv("TERM", term, 0);
(void)setenv("USER", pwd->pw_name, 1);
(void)setenv("PATH", "/usr/ucb:/bin:/usr/bin:", 0);
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
if (pwd->pw_uid == 0)
if (hostname)
- syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s",
+ syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s",
tty, hostname);
else
- syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
+ syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty);
if (!quietlog) {
struct stat st;
motd();
- (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
+ (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
if (stat(tbuf, &st) == 0 && st.st_size != 0)
printf("You have %smail.\n",
(st.st_mtime > st.st_atime) ? "new " : "");
exit(0);
}
-rootterm()
+rootterm(ttyn)
+ char *ttyn;
{
struct ttyent *t;
- return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
+ return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE);
}
jmp_buf motdinterrupt;
int (*oldint)(), sigint();
char tbuf[8192];
- if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
+ if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
return;
oldint = signal(SIGINT, sigint);
if (setjmp(motdinterrupt) == 0)
register int fd, nchars;
char tbuf[8192];
- if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
+ if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
(void)write(fileno(stdout), tbuf, nchars);
sleepexit(0);
{
struct lastlog ll;
int fd;
+ char *ctime();
+ char *ctime();
- if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
+ if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
if (!quiet) {
if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
}
(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
}
+ bzero((char *)&ll, sizeof(ll));
(void)time(&ll.ll_time);
strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
if (hostname)
strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
- else
- bzero(ll.ll_host, sizeof(ll.ll_host));
- strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
(void)write(fd, (char *)&ll, sizeof(ll));
(void)close(fd);
}
badlogin(name)
char *name;
{
- if (!repeatcnt)
+ if (failures == 0)
return;
if (hostname)
- syslog(LOG_ERR, "%d LOGIN FAILURE%s ON %s FROM %s, %s",
- repeatcnt, repeatcnt > 1 ? "S" : "", tty, hostname, name);
+ syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s",
+ failures, failures > 1 ? "S" : "", hostname, name);
else
- syslog(LOG_ERR, "%d LOGIN FAILURE%s ON %s, %s",
- repeatcnt, repeatcnt > 1 ? "S" : "", tty, name);
+ syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s",
+ failures, failures > 1 ? "S" : "", tty, name);
}
#undef UNKNOWN
#define UNKNOWN "su"
char *
-stypeof()
+stypeof(ttyid)
+ char *ttyid;
{
struct ttyent *t;
- return(tty && (t = getttynam(tty)) ? t->ty_type : UNKNOWN);
+ return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
}
getstr(buf, cnt, err)