X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/abc4056e93f8780d7cafe28754a1f7f211f948d6..9a448eeeeabdfc4bfdb708d7db19bcb936e8c671:/usr/src/usr.bin/login/login.c diff --git a/usr/src/usr.bin/login/login.c b/usr/src/usr.bin/login/login.c index ae1f834611..33baab4718 100644 --- a/usr/src/usr.bin/login/login.c +++ b/usr/src/usr.bin/login/login.c @@ -22,7 +22,7 @@ char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)login.c 5.28 (Berkeley) %G%"; +static char sccsid[] = "@(#)login.c 5.36 (Berkeley) %G%"; #endif /* not lint */ /* @@ -50,48 +50,54 @@ static char sccsid[] = "@(#)login.c 5.28 (Berkeley) %G%"; #include #include #include +#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(); @@ -141,10 +147,9 @@ main(argc, argv) argc -= optind; argv += optind; if (*argv) { - ask = 0; username = *argv; - } - else + ask = 0; + } else ask = 1; ioctlval = 0; @@ -179,20 +184,18 @@ main(argc, argv) 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 @@ -217,16 +220,20 @@ main(argc, argv) * 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) { @@ -241,20 +248,16 @@ main(argc, argv) /* 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); } @@ -283,18 +286,68 @@ main(argc, argv) 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)); - strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); + if (hostname) + strncpy(utmp.ut_host, hostname, 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 */ @@ -314,9 +367,9 @@ main(argc, argv) (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); } @@ -327,7 +380,7 @@ main(argc, argv) (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); @@ -336,16 +389,16 @@ main(argc, argv) 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 " : ""); @@ -399,11 +452,12 @@ timedout() 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; @@ -414,7 +468,7 @@ motd() 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) @@ -434,7 +488,7 @@ checknologin() 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); @@ -446,8 +500,10 @@ dolastlog(quiet) { 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) && @@ -463,9 +519,11 @@ dolastlog(quiet) } (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)); - strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); + if (hostname) + strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); (void)write(fd, (char *)&ll, sizeof(ll)); (void)close(fd); } @@ -474,25 +532,26 @@ dolastlog(quiet) 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)