* Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University
* of California. All rights reserved.
*
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#ifndef lint
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)login.c 5.68 (Berkeley) %G%";
+static char sccsid[] = "@(#)login.c 5.73 (Berkeley) 6/29/91";
#endif /* not lint */
/*
* login [ name ]
- * login -r hostname (for rlogind)
* login -h hostname (for telnetd, etc.)
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
*/
* be patched on machines where it's too small.
*/
int timeout = 300;
+int rootlogin;
#ifdef KERBEROS
int notickets = 1;
-int rootlogin = 0;
-#define ROOTLOGIN (rootlogin || (pwd && pwd->pw_uid == 0))
-#else
-#define ROOTLOGIN (pwd && pwd->pw_uid == 0)
+char *instance;
+char *krbtkfile_env;
+int authok;
#endif
struct passwd *pwd;
int failures;
char term[64], *envinit[1], *hostname, *username, *tty;
-char *months[] =
- { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
- "Sep", "Oct", "Nov", "Dec" };
-
main(argc, argv)
int argc;
char **argv;
extern int optind;
extern char *optarg, **environ;
struct timeval tp;
- struct tm *ttp;
- struct timeval tp;
struct group *gr;
register int ch;
register char *p;
- int ask, fflag, hflag, pflag, rflag, cnt;
+ int ask, fflag, hflag, pflag, cnt, uid;
int quietlog, rval;
char *domain, *salt, *ttyn;
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
/*
* -p is used by getty to tell login not to destroy the environment
- * -r is used by rlogind to cause the autologin protocol;
* -f is used to skip a second login authentication
* -h is used by other servers to pass the name of the remote
* host to login so that it may be placed in utmp and wtmp
else
domain = index(localhost, '.');
- fflag = hflag = pflag = rflag = 0;
+ fflag = hflag = pflag = 0;
uid = getuid();
- while ((ch = getopt(argc, argv, "fh:pr:")) != EOF)
+ while ((ch = getopt(argc, argv, "fh:p")) != EOF)
switch (ch) {
case 'f':
- if (rflag) {
- fprintf(stderr,
- "login: only one of -r and -f allowed.\n");
- exit(1);
- }
fflag = 1;
break;
case 'h':
if (uid) {
(void)fprintf(stderr,
- "login: -h for super-user only.\n");
- exit(1);
- }
- if (rflag) {
- fprintf(stderr,
- "login: only one of -r and -h allowed.\n");
+ "login: -h option: %s\n", strerror(EPERM));
exit(1);
}
hflag = 1;
case 'p':
pflag = 1;
break;
- case 'r':
- if (hflag || fflag) {
- fprintf(stderr,
- "login: -f and -h not allowed with -r.\n");
- exit(1);
- }
- if (getuid()) {
- fprintf(stderr,
- "login: -r for super-user only.\n");
- exit(1);
- }
- /* "-r hostname" must be last args */
- if (optind != argc) {
- fprintf(stderr, "Syntax error.\n");
- exit(1);
- }
- rflag = 1;
- passwd_req = (doremotelogin(optarg) == -1);
- if (domain && (p = index(optarg, '.')) &&
- !strcmp(p, domain))
- *p = '\0';
- hostname = optarg;
- break;
case '?':
default:
if (!uid)
syslog(LOG_ERR, "invalid flag %c", ch);
(void)fprintf(stderr,
- "usage: login [-fp] [username]\n");
+ "usage: login [-fp] [-h hostname] [username]\n");
exit(1);
}
argc -= optind;
argv += optind;
if (*argv) {
username = *argv;
- if (strlen(username) > UT_NAMESIZE)
- username[UT_NAMESIZE] = '\0';
ask = 0;
} else
ask = 1;
- if (rflag)
- ask = 0;
for (cnt = getdtablesize(); cnt > 2; cnt--)
close(cnt);
fflag = 0;
getloginname();
}
+#ifdef KERBEROS
+ if ((instance = index(username, '.')) != NULL) {
+ if (strncmp(instance, ".root", 5) == 0)
+ rootlogin++;
+ *instance++ = '\0';
+ } else {
+ rootlogin = 0;
+ instance = "";
+ }
+#else
+ rootlogin = 0;
+#endif
+ if (strlen(username) > UT_NAMESIZE)
+ username[UT_NAMESIZE] = '\0';
+
/*
* Note if trying multiple user names; log failures for
* previous user name, but don't bother logging one failure
fflag && (uid == 0 || uid == pwd->pw_uid)))
break;
fflag = 0;
+ if (pwd && pwd->pw_uid == 0)
+ rootlogin = 1;
+
+ (void)setpriority(PRIO_PROCESS, 0, -4);
+
+ p = getpass("Password:");
+
+ if (pwd) {
+#ifdef KERBEROS
+ rval = klogin(pwd, instance, localhost, p);
+ if (rval == 0)
+ authok = 1;
+ else if (rval == 1) {
+ if (pwd->pw_uid != 0)
+ rootlogin = 0;
+ rval = strcmp(crypt(p, salt), pwd->pw_passwd);
+ }
+#else
+ if (pwd->pw_uid != 0)
+ rootlogin = 0;
+#ifdef DES
+ rval = strcmp(crypt(p, salt), pwd->pw_passwd);
+#else
+ rval = strcmp(p, pwd->pw_passwd);
+#endif
+#endif
+ }
+ bzero(p, strlen(p));
+
+ (void)setpriority(PRIO_PROCESS, 0, 0);
/*
- * If trying to log in as root, but with insecure terminal,
- * refuse the login attempt.
+ * If trying to log in as root without Kerberos,
+ * but with insecure terminal, refuse the login attempt.
*/
- if (ROOTLOGIN && !rootterm(tty)) {
+#ifdef KERBEROS
+ if (authok == 0)
+#endif
+ if (pwd && rootlogin && !rootterm(tty)) {
(void)fprintf(stderr,
"%s login refused on this terminal.\n",
pwd->pw_name);
continue;
}
- (void)setpriority(PRIO_PROCESS, 0, -4);
-
- p = getpass("Password:");
-
- if (pwd) {
- bzero(p, strlen(p));
-
- (void)setpriority(PRIO_PROCESS, 0, 0);
-
if (pwd && !rval)
break;
/* committed to login -- turn off timeout */
(void)alarm((u_int)0);
- /* paranoia... */
endpwent();
/* if user not super-user, check for disabled logins */
- if (!(ROOTLOGIN))
+ if (!rootlogin)
checknologin();
if (chdir(pwd->pw_dir) < 0) {
- (void)printf("No directory %s!\n", pwd->pw_dir);
+ (void)printf("No home directory %s!\n", pwd->pw_dir);
if (chdir("/"))
exit(0);
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);
- 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);
- }
+
+ quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
if (pwd->pw_change || pwd->pw_expire)
(void)gettimeofday(&tp, (struct timezone *)NULL);
if (tp.tv_sec >= pwd->pw_change) {
(void)printf("Sorry -- your password has expired.\n");
sleepexit(1);
- }
- else if (pwd->pw_change - tp.tv_sec <
+ } else if (pwd->pw_change - tp.tv_sec <
2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
(void)printf("Warning: your password expires on %s",
ctime(&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 <
+ } else if (pwd->pw_expire - tp.tv_sec <
2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
(void)printf("Warning: your account expires on %s",
ctime(&pwd->pw_expire));
(void)chown(ttyn, pwd->pw_uid,
(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
- (void)chmod(ttyn, 0620);
(void)setgid(pwd->pw_gid);
initgroups(username, pwd->pw_gid);
if (term[0] == '\0')
strncpy(term, stypeof(tty), sizeof(term));
(void)setenv("TERM", term, 0);
+ (void)setenv("LOGNAME", pwd->pw_name, 1);
(void)setenv("USER", pwd->pw_name, 1);
(void)setenv("PATH", _PATH_DEFPATH, 0);
+#ifdef KERBEROS
+ if (krbtkfile_env)
+ (void)setenv("KRBTKFILE", krbtkfile_env, 1);
+#endif
if (tty[sizeof("tty")-1] == 'd')
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)
+ if (rootlogin && fflag == 0)
if (hostname)
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
username, tty, hostname);
if (!quietlog) {
struct stat st;
- printf(
-"Copyright (c) 1980,1983,1986,1988,1990,1991 The Regents of the University\n%s",
-"of California. All rights reserved.\n\n");
+ printf("%s%s",
+ "386BSD Release 0.1 by William and Lynne Jolitz.\n",
+"Copyright (c) 1989,1990,1991,1992 William F. Jolitz. All rights reserved.\n\
+Based in part on work by the 386BSD User Community and the\n\
+BSD Networking Software, Release 2 by UCB EECS Department.\n");
+
motd();
(void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
if (stat(tbuf, &st) == 0 && st.st_size != 0)
syslog(LOG_ERR, "setlogin() failure: %m");
/* discard permissions last so can't get killed and drop core */
- if (ROOTLOGIN)
+ if (rootlogin)
(void) setuid(0);
else
- (void)setuid(pwd->pw_uid);
+ (void) setuid(pwd->pw_uid);
execlp(pwd->pw_shell, tbuf, 0);
- (void)fprintf(stderr, "login: no shell: %s.\n", strerror(errno));
- exit(0);
+ (void)fprintf(stderr, "%s: %s\n", pwd->pw_shell, strerror(errno));
+ exit(1);
}
#ifdef KERBEROS
getloginname()
{
register int ch;
- register char *p, *instance;
+ register char *p;
static char nbuf[NBUFSIZ];
for (;;) {
break;
}
}
-#ifdef KERBEROS
- if ((instance = index(nbuf, '.')) != NULL) {
- if (strncmp(instance, ".root", 5) == 0) {
- rootlogin++;
- }
- *instance = '\0';
- if ((instance - nbuf) > UT_NAMESIZE)
- nbuf[UT_NAMESIZE] = '\0';
- } else
- rootlogin = 0;
-#endif
}
void
struct lastlog ll;
int fd;
char *ctime();
- char *ctime();
if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
sleep((u_int)5);
exit(eval);
}
-
-doremotelogin(host)
- char *host;
-{
- static char lusername[UT_NAMESIZE+1];
- char rusername[UT_NAMESIZE+1];
-
- getstr(rusername, sizeof(rusername), "remuser");
- getstr(lusername, sizeof(lusername), "locuser");
- getstr(term, sizeof(term), "Terminal type");
- username = lusername;
- pwd = getpwnam(username);
- if (pwd == NULL)
- return(-1);
- return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
-}
-
-char *speeds[] = {
- "0", "50", "75", "110", "134", "150", "200", "300", "600",
- "1200", "1800", "2400", "4800", "9600", "19200", "38400",
-};
-#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
-
-doremoteterm(tp)
- struct sgttyb *tp;
-{
- register char *cp = index(term, '/'), **cpp;
- char *speed;
-
- if (cp) {
- *cp++ = '\0';
- speed = cp;
- cp = index(speed, '/');
- if (cp)
- *cp++ = '\0';
- for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
- if (strcmp(*cpp, speed) == 0) {
- tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
- break;
- }
- }
- tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
-}