-/*
+/*-
* Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
* All rights reserved.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
*/
#ifndef lint
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)login.c 5.50 (Berkeley) %G%";
+static char sccsid[] = "@(#)login.c 5.64 (Berkeley) %G%";
#endif /* not lint */
/*
*/
#include <sys/param.h>
-#include <ufs/quota.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <pwd.h>
#include <setjmp.h>
#include <stdio.h>
-#include <strings.h>
+#include <string.h>
#include <tzfile.h>
#include "pathnames.h"
* be patched on machines where it's too small.
*/
int timeout = 300;
+#ifdef KERBEROS
+int notickets = 1;
+#endif
struct passwd *pwd;
int failures;
char term[64], *envinit[1], *hostname, *username, *tty;
-struct sgttyb sgttyb;
-struct tchars tc = {
- CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
-};
-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" };
int argc;
char **argv;
{
- extern int errno, optind;
+ extern int 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, rflag, cnt;
- int quietlog, passwd_req, ioctlval, timedout();
- char *domain, *salt, *ttyn, *pp;
+ int quietlog, rval;
+ char *domain, *salt, *ttyn;
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
char localhost[MAXHOSTNAMELEN];
char *ctime(), *ttyname(), *stypeof(), *crypt(), *getpass();
time_t time();
off_t lseek();
+ void timedout();
(void)signal(SIGALRM, timedout);
(void)alarm((u_int)timeout);
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
(void)setpriority(PRIO_PROCESS, 0, 0);
- (void)quota(Q_SETUID, 0, 0, 0);
+
+ openlog("login", LOG_ODELAY, LOG_AUTH);
/*
* -p is used by getty to tell login not to destroy the environment
else
domain = index(localhost, '.');
- openlog("login", LOG_ODELAY, LOG_AUTH);
-
fflag = hflag = pflag = rflag = 0;
- passwd_req = 1;
uid = getuid();
while ((ch = getopt(argc, argv, "fh:pr:")) != EOF)
switch (ch) {
argv += optind;
if (*argv) {
username = *argv;
+ if (strlen(username) > UT_NAMESIZE)
+ username[UT_NAMESIZE] = '\0';
ask = 0;
} else
ask = 1;
if (rflag)
ask = 0;
- ioctlval = 0;
- (void)ioctl(0, TIOCLSET, &ioctlval);
- (void)ioctl(0, TIOCNXCL, 0);
- (void)fcntl(0, F_SETFL, ioctlval);
- (void)ioctl(0, TIOCGETP, &sgttyb);
-
- /*
- * If talking to an rlogin process, propagate the terminal type and
- * baud rate across the network.
- */
- if (rflag)
- doremoteterm(&sgttyb);
- sgttyb.sg_erase = CERASE;
- sgttyb.sg_kill = CKILL;
- (void)ioctl(0, TIOCSLTC, <c);
- (void)ioctl(0, TIOCSETC, &tc);
- (void)ioctl(0, TIOCSETP, &sgttyb);
-
for (cnt = getdtablesize(); cnt > 2; cnt--)
close(cnt);
tty = ttyn;
for (cnt = 0;; ask = 1) {
- ioctlval = TTYDISC;
- (void)ioctl(0, TIOCSETD, &ioctlval);
-
if (ask) {
fflag = 0;
getloginname();
failures = 0;
}
(void)strcpy(tbuf, username);
+
if (pwd = getpwnam(username))
salt = pwd->pw_passwd;
else
salt = "xx";
- /* if user not super-user, check for disabled logins */
- if (pwd == NULL || pwd->pw_uid)
- checknologin();
-
/*
- * Disallow automatic login to root; if not invoked by
- * root, disallow if the uid's differ.
+ * if we have a valid account name, and it doesn't have a
+ * password, or the -f option was specified and the caller
+ * is root or the caller isn't changing their uid, don't
+ * authenticate.
*/
- if (fflag && pwd) {
- passwd_req =
-#ifndef KERBEROS
- pwd->pw_uid == 0 ||
-#endif
- (uid && uid != pwd->pw_uid);
- }
-
- /*
- * 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 (pwd && (*pwd->pw_passwd == '\0' ||
+ fflag && (uid == 0 || uid == pwd->pw_uid)))
break;
+ fflag = 0;
/*
* If trying to log in as root, but with insecure terminal,
* refuse the login attempt.
*/
- if (pwd->pw_uid == 0 && !rootterm(tty)) {
+ if (pwd && pwd->pw_uid == 0 && !rootterm(tty)) {
(void)fprintf(stderr,
"%s login refused on this terminal.\n",
pwd->pw_name);
continue;
}
- setpriority(PRIO_PROCESS, 0, -4);
- pp = getpass("Password:");
- p = crypt(pp, salt);
- setpriority(PRIO_PROCESS, 0, 0);
+ (void)setpriority(PRIO_PROCESS, 0, -4);
+
+ p = getpass("Password:");
- (void) bzero(pp, strlen(pp));
- if (pwd && !strcmp(p, pwd->pw_passwd))
+ if (pwd) {
+ bzero(p, strlen(p));
+
+ (void)setpriority(PRIO_PROCESS, 0, 0);
+
+ if (pwd && !rval)
break;
(void)printf("Login incorrect\n");
if (++cnt > 3) {
if (cnt >= 10) {
badlogin(username);
- (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL);
sleepexit(1);
}
sleep((u_int)((cnt - 3) * 5));
/* paranoia... */
endpwent();
- if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
- switch(errno) {
- case EUSERS:
- (void)fprintf(stderr,
- "Too many users logged on already.\nTry again later.\n");
- break;
- case EPROCLIM:
- (void)fprintf(stderr,
- "You have too many processes running.\n");
- break;
- default:
- perror("quota (Q_SETUID)");
- }
- sleepexit(0);
- }
+ /* if user not super-user, check for disabled logins */
+ if (pwd->pw_uid)
+ checknologin();
if (chdir(pwd->pw_dir) < 0) {
(void)printf("No directory %s!\n", pwd->pw_dir);
pwd->pw_dir = "/";
(void)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);
sleepexit(1);
}
else if (pwd->pw_change - tp.tv_sec <
- 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) {
- ttp = localtime(&pwd->pw_change);
- (void)printf("Warning: your password expires on %s %d, %d\n",
- months[ttp->tm_mon], ttp->tm_mday,
- TM_YEAR_BASE + ttp->tm_year);
- }
+ 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
+ (void)printf("Warning: your password expires on %s",
+ ctime(&pwd->pw_expire));
if (pwd->pw_expire)
if (tp.tv_sec >= pwd->pw_expire) {
(void)printf("Sorry -- your account has expired.\n");
sleepexit(1);
}
else if (pwd->pw_expire - tp.tv_sec <
- 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) {
- ttp = localtime(&pwd->pw_expire);
- (void)printf("Warning: your account expires on %s %d, %d\n",
- months[ttp->tm_mon], ttp->tm_mday,
- TM_YEAR_BASE + ttp->tm_year);
- }
+ 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
+ (void)printf("Warning: your account expires on %s",
+ ctime(&pwd->pw_expire));
/* nothing else left to fail -- really log in */
{
struct utmp utmp;
- bzero((char *)&utmp, sizeof(utmp));
+ bzero((void *)&utmp, sizeof(utmp));
(void)time(&utmp.ut_time);
strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
if (hostname)
dolastlog(quietlog);
- if (!hflag && !rflag) { /* XXX */
- static struct winsize win = { 0, 0, 0, 0 };
-
- (void)ioctl(0, TIOCSWINSZ, &win);
- }
-
(void)chown(ttyn, pwd->pw_uid,
(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
(void)chmod(ttyn, 0620);
initgroups(username, pwd->pw_gid);
- quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
-
if (*pwd->pw_shell == '\0')
pwd->pw_shell = _PATH_BSHELL;
if (tty[sizeof("tty")-1] == 'd')
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
- if (pwd->pw_uid == 0)
+ /* if fflag is on, assume caller/authenticator has logged root login */
+ if (pwd->pw_uid == 0 && fflag == 0)
if (hostname)
syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s",
tty, hostname);
else
syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty);
+#ifdef KERBEROS
+ if (!quietlog && notickets == 1)
+ (void)printf("Warning: no Kerberos tickets issued.\n");
+#endif
+
if (!quietlog) {
struct stat st;
}
}
+void
timedout()
{
(void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
}
(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
}
- bzero((char *)&ll, sizeof(ll));
+ bzero((void *)&ll, sizeof(ll));
(void)time(&ll.ll_time);
strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
if (hostname)
return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
}
-getstr(buf, cnt, err)
- char *buf, *err;
- int cnt;
-{
- char ch;
-
- do {
- if (read(0, &ch, sizeof(ch)) != sizeof(ch))
- exit(1);
- if (--cnt < 0) {
- (void)fprintf(stderr, "%s too long\r\n", err);
- sleepexit(1);
- }
- *buf++ = ch;
- } while (ch);
-}
-
sleepexit(eval)
int eval;
{