diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
commit | f9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch) | |
tree | add7e996bac5289cdc55e6935750c352505560a9 /usr.bin/login | |
parent | be22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff) | |
download | FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz |
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/login')
-rw-r--r-- | usr.bin/login/Makefile | 12 | ||||
-rw-r--r-- | usr.bin/login/klogin.c | 190 | ||||
-rw-r--r-- | usr.bin/login/login.1 | 146 | ||||
-rw-r--r-- | usr.bin/login/login.c | 594 | ||||
-rw-r--r-- | usr.bin/login/pathnames.h | 39 |
5 files changed, 981 insertions, 0 deletions
diff --git a/usr.bin/login/Makefile b/usr.bin/login/Makefile new file mode 100644 index 0000000..a11fbc0 --- /dev/null +++ b/usr.bin/login/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 7/19/93 + +CFLAGS+=-DKERBEROS +PROG= login +SRCS= klogin.c login.c +DPADD= ${LIBUTIL} ${LIBKRB} ${LIBDES} +LDADD= -lutil -lkrb -ldes +BINOWN= root +BINMODE=4555 +INSTALLFLAGS=-fschg + +.include <bsd.prog.mk> diff --git a/usr.bin/login/klogin.c b/usr.bin/login/klogin.c new file mode 100644 index 0000000..6601a6e --- /dev/null +++ b/usr.bin/login/klogin.c @@ -0,0 +1,190 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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 +static char sccsid[] = "@(#)klogin.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#ifdef KERBEROS +#include <sys/param.h> +#include <sys/syslog.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> + +#include <err.h> +#include <netdb.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define INITIAL_TICKET "krbtgt" +#define VERIFY_SERVICE "rcmd" + +extern int notickets; +extern char *krbtkfile_env; + +/* + * Attempt to log the user in using Kerberos authentication + * + * return 0 on success (will be logged in) + * 1 if Kerberos failed (try local password in login) + */ +int +klogin(pw, instance, localhost, password) + struct passwd *pw; + char *instance, *localhost, *password; +{ + int kerror; + AUTH_DAT authdata; + KTEXT_ST ticket; + struct hostent *hp; + unsigned long faddr; + char realm[REALM_SZ], savehost[MAXHOSTNAMELEN]; + char tkt_location[MAXPATHLEN]; + char *krb_get_phost(); + + /* + * Root logins don't use Kerberos. + * If we have a realm, try getting a ticket-granting ticket + * and using it to authenticate. Otherwise, return + * failure so that we can try the normal passwd file + * for a password. If that's ok, log the user in + * without issuing any tickets. + */ + if (strcmp(pw->pw_name, "root") == 0 || + krb_get_lrealm(realm, 0) != KSUCCESS) + return (1); + + /* + * get TGT for local realm + * tickets are stored in a file named TKT_ROOT plus uid + * except for user.root tickets. + */ + + if (strcmp(instance, "root") != 0) + (void)sprintf(tkt_location, "%s%d", TKT_ROOT, pw->pw_uid); + else { + (void)sprintf(tkt_location, "%s_root_%d", TKT_ROOT, pw->pw_uid); + krbtkfile_env = tkt_location; + } + (void)krb_set_tkt_string(tkt_location); + + /* + * Set real as well as effective ID to 0 for the moment, + * to make the kerberos library do the right thing. + */ + if (setuid(0) < 0) { + warnx("setuid"); + return (1); + } + kerror = krb_get_pw_in_tkt(pw->pw_name, instance, + realm, INITIAL_TICKET, realm, DEFAULT_TKT_LIFE, password); + /* + * If we got a TGT, get a local "rcmd" ticket and check it so as to + * ensure that we are not talking to a bogus Kerberos server. + * + * There are 2 cases where we still allow a login: + * 1: the VERIFY_SERVICE doesn't exist in the KDC + * 2: local host has no srvtab, as (hopefully) indicated by a + * return value of RD_AP_UNDEC from krb_rd_req(). + */ + if (kerror != INTK_OK) { + if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) { + syslog(LOG_ERR, "Kerberos intkt error: %s", + krb_err_txt[kerror]); + dest_tkt(); + } + return (1); + } + + if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0) + syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE); + + (void)strncpy(savehost, krb_get_phost(localhost), sizeof(savehost)); + savehost[sizeof(savehost)-1] = NULL; + + /* + * if the "VERIFY_SERVICE" doesn't exist in the KDC for this host, + * still allow login with tickets, but log the error condition. + */ + + kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33); + if (kerror == KDC_PR_UNKNOWN) { + syslog(LOG_NOTICE, + "warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?", + krb_err_txt[kerror], VERIFY_SERVICE, savehost); + notickets = 0; + return (0); + } + + if (kerror != KSUCCESS) { + warnx("unable to use TGT: (%s)", krb_err_txt[kerror]); + syslog(LOG_NOTICE, "unable to use TGT: (%s)", + krb_err_txt[kerror]); + dest_tkt(); + return (1); + } + + if (!(hp = gethostbyname(localhost))) { + syslog(LOG_ERR, "couldn't get local host address"); + dest_tkt(); + return (1); + } + + memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); + + kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr, + &authdata, ""); + + if (kerror == KSUCCESS) { + notickets = 0; + return (0); + } + + /* undecipherable: probably didn't have a srvtab on the local host */ + if (kerror = RD_AP_UNDEC) { + syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]); + dest_tkt(); + return (1); + } + /* failed for some other reason */ + warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE, + krb_err_txt[kerror]); + syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE, + krb_err_txt[kerror]); + dest_tkt(); + return (1); +} +#endif diff --git a/usr.bin/login/login.1 b/usr.bin/login/login.1 new file mode 100644 index 0000000..db59c1a --- /dev/null +++ b/usr.bin/login/login.1 @@ -0,0 +1,146 @@ +.\" Copyright (c) 1980, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" 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. +.\" +.\" @(#)login.1 8.1 (Berkeley) 6/9/93 +.\" +.Dd June 9, 1993 +.Dt LOGIN 1 +.Os BSD 4 +.Sh NAME +.Nm login +.Nd log into the computer +.Sh SYNOPSIS +.Nm login +.Op Fl fp +.Op Fl h Ar hostname +.Op Ar user +.Sh DESCRIPTION +The +.Nm login +utility logs users (and pseudo-users) into the computer system. +.Pp +If no user is specified, or if a user is specified and authentication +of the user fails, +.Nm login +prompts for a user name. +Authentication of users is done via passwords. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl f +The +.Fl f +option is used when a user name is specified to indicate that proper +authentication has already been done and that no password need be +requested. +This option may only be used by the super-user or when an already +logged in user is logging in as themselves. +.It Fl h +The +.Fl h +option specifies the host from which the connection was received. +It is used by various daemons such as +.Xr telnetd 8 . +This option may only be used by the super-user. +.It Fl p +By default, +.Nm login +discards any previous environment. +The +.Fl p +option disables this behavior. +.El +.Pp +If the file +.Pa /etc/nologin +exists, +.Nm login +dislays its contents to the user and exits. +This is used by +.Xr shutdown 8 +to prevent users from logging in when the system is about to go down. +.Pp +Immediately after logging a user in, +.Nm login +displays the system copyright notice, the date and time the user last +logged in, the message of the day as well as other information. +If the file +.Dq Pa .hushlogin +exists in the user's home directory, all of these messages are suppressed. +This is to simplify logins for non-human users, such as +.Xr uucp 1 . +.Nm Login +then records an entry in the +.Xr wtmp 5 +and +.Xr utmp 5 +files and executes the user's command interpretor. +.Pp +Login enters information into the environment (see +.Xr environ 7 ) +specifying the user's home directory (HOME), command interpreter (SHELL), +search path (PATH), terminal type (TERM) and user name (both LOGNAME and +USER). +.Pp +The standard shells, +.Xr csh 1 +and +.Xr sh 1 , +do not fork before executing the +.Nm login +utility. +.Sh FILES +.Bl -tag -width /var/mail/userXXX -compact +.It Pa /etc/motd +message-of-the-day +.It Pa /etc/nologin +disallows logins +.It Pa /var/run/utmp +current logins +.It Pa /var/log/wtmp +login account records +.It Pa /var/mail/user +system mailboxes +.It Pa \&.hushlogin +makes login quieter +.El +.Sh SEE ALSO +.Xr chpass 1 , +.Xr passwd 1 , +.Xr rlogin 1 , +.Xr getpass 3 , +.Xr utmp 5 , +.Xr environ 7 , +.Sh HISTORY +A +.Nm login +appeared in +.At v6 . diff --git a/usr.bin/login/login.c b/usr.bin/login/login.c new file mode 100644 index 0000000..ef75733 --- /dev/null +++ b/usr.bin/login/login.c @@ -0,0 +1,594 @@ +/*- + * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * 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 +static char copyright[] = +"@(#) Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)login.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ + +/* + * login [ name ] + * login -h hostname (for telnetd, etc.) + * login -f name (for pre-authenticated login: datakit, xterm, etc.) + */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/file.h> + +#include <err.h> +#include <errno.h> +#include <grp.h> +#include <pwd.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <ttyent.h> +#include <tzfile.h> +#include <unistd.h> +#include <utmp.h> + +#include "pathnames.h" + +void badlogin __P((char *)); +void checknologin __P((void)); +void dolastlog __P((int)); +void getloginname __P((void)); +void motd __P((void)); +int rootterm __P((char *)); +void sigint __P((int)); +void sleepexit __P((int)); +char *stypeof __P((char *)); +void timedout __P((int)); +#ifdef KERBEROS +int klogin __P((struct passwd *, char *, char *, char *)); +#endif + +extern void login __P((struct utmp *)); + +#define TTYGRPNAME "tty" /* name of group to own ttys */ + +/* + * This bounds the time given to login. Not a define so it can + * be patched on machines where it's too small. + */ +u_int timeout = 300; + +#ifdef KERBEROS +int notickets = 1; +char *instance; +char *krbtkfile_env; +int authok; +#endif + +struct passwd *pwd; +int failures; +char term[64], *envinit[1], *hostname, *username, *tty; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char **environ; + struct group *gr; + struct stat st; + struct timeval tp; + struct utmp utmp; + int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval; + uid_t uid; + char *domain, *p, *salt, *ttyn; + char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; + char localhost[MAXHOSTNAMELEN]; + + (void)signal(SIGALRM, timedout); + (void)alarm(timeout); + (void)signal(SIGQUIT, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)setpriority(PRIO_PROCESS, 0, 0); + + openlog("login", LOG_ODELAY, LOG_AUTH); + + /* + * -p is used by getty to tell login not to destroy the environment + * -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 + */ + domain = NULL; + if (gethostname(localhost, sizeof(localhost)) < 0) + syslog(LOG_ERR, "couldn't get local hostname: %m"); + else + domain = strchr(localhost, '.'); + + fflag = hflag = pflag = 0; + uid = getuid(); + while ((ch = getopt(argc, argv, "fh:p")) != EOF) + switch (ch) { + case 'f': + fflag = 1; + break; + case 'h': + if (uid) + errx(1, "-h option: %s", strerror(EPERM)); + hflag = 1; + if (domain && (p = strchr(optarg, '.')) && + strcasecmp(p, domain) == 0) + *p = 0; + hostname = optarg; + break; + case 'p': + pflag = 1; + break; + case '?': + default: + if (!uid) + syslog(LOG_ERR, "invalid flag %c", ch); + (void)fprintf(stderr, + "usage: login [-fp] [-h hostname] [username]\n"); + exit(1); + } + argc -= optind; + argv += optind; + + if (*argv) { + username = *argv; + ask = 0; + } else + ask = 1; + + for (cnt = getdtablesize(); cnt > 2; cnt--) + (void)close(cnt); + + ttyn = ttyname(STDIN_FILENO); + if (ttyn == NULL || *ttyn == '\0') { + (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY); + ttyn = tname; + } + if (tty = strrchr(ttyn, '/')) + ++tty; + else + tty = ttyn; + + for (cnt = 0;; ask = 1) { + if (ask) { + fflag = 0; + getloginname(); + } + rootlogin = 0; +#ifdef KERBEROS + if ((instance = strchr(username, '.')) != NULL) { + if (strncmp(instance, ".root", 5) == 0) + rootlogin = 1; + *instance++ = '\0'; + } else + instance = ""; +#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 + * for nonexistent name (mistyped username). + */ + if (failures && strcmp(tbuf, username)) { + if (failures > (pwd ? 0 : 1)) + badlogin(tbuf); + failures = 0; + } + (void)strcpy(tbuf, username); + + if (pwd = getpwnam(username)) + salt = pwd->pw_passwd; + else + salt = "xx"; + + /* + * 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 (pwd && (*pwd->pw_passwd == '\0' || + 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 && rootlogin && pwd->pw_uid != 0) + rootlogin = 0; + if (rval == 0) + authok = 1; + else if (rval == 1) + rval = strcmp(crypt(p, salt), pwd->pw_passwd); +#else + rval = strcmp(crypt(p, salt), pwd->pw_passwd); +#endif + } + memset(p, 0, strlen(p)); + + (void)setpriority(PRIO_PROCESS, 0, 0); + + /* + * If trying to log in as root without Kerberos, + * but with insecure terminal, refuse the login attempt. + */ +#ifdef KERBEROS + if (authok == 0) +#endif + if (pwd && rootlogin && !rootterm(tty)) { + (void)fprintf(stderr, + "%s login refused on this terminal.\n", + pwd->pw_name); + if (hostname) + syslog(LOG_NOTICE, + "LOGIN %s REFUSED FROM %s ON TTY %s", + pwd->pw_name, hostname, tty); + else + syslog(LOG_NOTICE, + "LOGIN %s REFUSED ON TTY %s", + pwd->pw_name, tty); + continue; + } + + if (pwd && !rval) + break; + + (void)printf("Login incorrect\n"); + failures++; + /* we allow 10 tries, but after 3 we start backing off */ + if (++cnt > 3) { + if (cnt >= 10) { + badlogin(username); + sleepexit(1); + } + sleep((u_int)((cnt - 3) * 5)); + } + } + + /* committed to login -- turn off timeout */ + (void)alarm((u_int)0); + + endpwent(); + + /* if user not super-user, check for disabled logins */ + if (!rootlogin) + checknologin(); + + if (chdir(pwd->pw_dir) < 0) { + (void)printf("No home directory %s!\n", pwd->pw_dir); + if (chdir("/")) + exit(0); + pwd->pw_dir = "/"; + (void)printf("Logging in with home = \"/\".\n"); + } + + quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; + + if (pwd->pw_change || pwd->pw_expire) + (void)gettimeofday(&tp, (struct timezone *)NULL); + if (pwd->pw_change) + 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 < + 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) + (void)printf("Warning: your password expires on %s", + ctime(&pwd->pw_change)); + 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) + (void)printf("Warning: your account expires on %s", + ctime(&pwd->pw_expire)); + + /* Nothing else left to fail -- really log in. */ + memset((void *)&utmp, 0, sizeof(utmp)); + (void)time(&utmp.ut_time); + (void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); + if (hostname) + (void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); + (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); + login(&utmp); + + dolastlog(quietlog); + + (void)chown(ttyn, pwd->pw_uid, + (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : 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. */ + if (!pflag) + environ = envinit; + (void)setenv("HOME", pwd->pw_dir, 1); + (void)setenv("SHELL", pwd->pw_shell, 1); + if (term[0] == '\0') + (void)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 (hostname) + syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s", + username, tty, hostname); + else + syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty); + +#ifdef KERBEROS + if (!quietlog && notickets == 1) + (void)printf("Warning: no Kerberos tickets issued.\n"); +#endif + + if (!quietlog) { + (void)printf("%s\n\t%s %s\n\n", + "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", + "The Regents of the University of California. ", + "All rights reserved."); + motd(); + (void)snprintf(tbuf, + sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name); + if (stat(tbuf, &st) == 0 && st.st_size != 0) + (void)printf("You have %smail.\n", + (st.st_mtime > st.st_atime) ? "new " : ""); + } + + (void)signal(SIGALRM, SIG_DFL); + (void)signal(SIGQUIT, SIG_DFL); + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGTSTP, SIG_IGN); + + tbuf[0] = '-'; + (void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? + p + 1 : pwd->pw_shell); + + if (setlogin(pwd->pw_name) < 0) + syslog(LOG_ERR, "setlogin() failure: %m"); + + /* Discard permissions last so can't get killed and drop core. */ + if (rootlogin) + (void) setuid(0); + else + (void) setuid(pwd->pw_uid); + + execlp(pwd->pw_shell, tbuf, 0); + err(1, "%s", pwd->pw_shell); +} + +#ifdef KERBEROS +#define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */ +#else +#define NBUFSIZ (UT_NAMESIZE + 1) +#endif + +void +getloginname() +{ + int ch; + char *p; + static char nbuf[NBUFSIZ]; + + for (;;) { + (void)printf("login: "); + for (p = nbuf; (ch = getchar()) != '\n'; ) { + if (ch == EOF) { + badlogin(username); + exit(0); + } + if (p < nbuf + (NBUFSIZ - 1)) + *p++ = ch; + } + if (p > nbuf) + if (nbuf[0] == '-') + (void)fprintf(stderr, + "login names may not start with '-'.\n"); + else { + *p = '\0'; + username = nbuf; + break; + } + } +} + +int +rootterm(ttyn) + char *ttyn; +{ + struct ttyent *t; + + return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE); +} + +jmp_buf motdinterrupt; + +void +motd() +{ + int fd, nchars; + sig_t oldint; + char tbuf[8192]; + + if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0) + return; + oldint = signal(SIGINT, sigint); + if (setjmp(motdinterrupt) == 0) + while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) + (void)write(fileno(stdout), tbuf, nchars); + (void)signal(SIGINT, oldint); + (void)close(fd); +} + +/* ARGSUSED */ +void +sigint(signo) + int signo; +{ + + longjmp(motdinterrupt, 1); +} + +/* ARGSUSED */ +void +timedout(signo) + int signo; +{ + + (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout); + exit(0); +} + +void +checknologin() +{ + int fd, nchars; + char tbuf[8192]; + + 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); + } +} + +void +dolastlog(quiet) + int quiet; +{ + struct lastlog ll; + int fd; + + 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) && + ll.ll_time != 0) { + (void)printf("Last login: %.*s ", + 24-5, (char *)ctime(&ll.ll_time)); + if (*ll.ll_host != '\0') + (void)printf("from %.*s\n", + (int)sizeof(ll.ll_host), + ll.ll_host); + else + (void)printf("on %.*s\n", + (int)sizeof(ll.ll_line), + ll.ll_line); + } + (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); + } + memset((void *)&ll, 0, sizeof(ll)); + (void)time(&ll.ll_time); + (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); + if (hostname) + (void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); + (void)write(fd, (char *)&ll, sizeof(ll)); + (void)close(fd); + } +} + +void +badlogin(name) + char *name; +{ + + if (failures == 0) + return; + if (hostname) { + syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s", + failures, failures > 1 ? "S" : "", hostname); + syslog(LOG_AUTHPRIV|LOG_NOTICE, + "%d LOGIN FAILURE%s FROM %s, %s", + failures, failures > 1 ? "S" : "", hostname, name); + } else { + syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s", + failures, failures > 1 ? "S" : "", tty); + syslog(LOG_AUTHPRIV|LOG_NOTICE, + "%d LOGIN FAILURE%s ON %s, %s", + failures, failures > 1 ? "S" : "", tty, name); + } +} + +#undef UNKNOWN +#define UNKNOWN "su" + +char * +stypeof(ttyid) + char *ttyid; +{ + struct ttyent *t; + + return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); +} + +void +sleepexit(eval) + int eval; +{ + + (void)sleep(5); + exit(eval); +} diff --git a/usr.bin/login/pathnames.h b/usr.bin/login/pathnames.h new file mode 100644 index 0000000..a9e1a077 --- /dev/null +++ b/usr.bin/login/pathnames.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/9/93 + */ + +#include <paths.h> + +#define _PATH_HUSHLOGIN ".hushlogin" +#define _PATH_MOTDFILE "/etc/motd" |