summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorDirk Meyer <dinoex@FreeBSD.org>2002-03-17 20:24:24 +0000
committerDirk Meyer <dinoex@FreeBSD.org>2002-03-17 20:24:24 +0000
commit74642142e398b1c92976c1b59a44a53415798dce (patch)
tree742c57e9fae2b7fc99fc092418eea94ba23b1c48 /security
parentMerge patches from -stable with USE_PAM and HAVE_LOGIN_CAP (diff)
Merged patches for HAVE_LOGIN_CAP from stable
PR: 35904
Notes
Notes: svn path=/head/; revision=56266
Diffstat (limited to 'security')
-rw-r--r--security/hpn-ssh/Makefile2
-rw-r--r--security/hpn-ssh/files/patch-auth.c6
-rw-r--r--security/hpn-ssh/files/patch-auth1.c56
-rw-r--r--security/hpn-ssh/files/patch-auth2.c60
-rw-r--r--security/hpn-ssh/files/patch-session.c186
-rw-r--r--security/openssh-portable/Makefile2
-rw-r--r--security/openssh-portable/files/patch-auth.c6
-rw-r--r--security/openssh-portable/files/patch-auth1.c56
-rw-r--r--security/openssh-portable/files/patch-auth2.c60
-rw-r--r--security/openssh-portable/files/patch-session.c186
10 files changed, 594 insertions, 26 deletions
diff --git a/security/hpn-ssh/Makefile b/security/hpn-ssh/Makefile
index cfe8163d7664..26a10c695fa6 100644
--- a/security/hpn-ssh/Makefile
+++ b/security/hpn-ssh/Makefile
@@ -7,7 +7,7 @@
PORTNAME= openssh
PORTVERSION= 3.1p1
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= security ipv6
MASTER_SITES= ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/ \
ftp://ftp.op.net/pub/OpenBSD/OpenSSH/portable/ \
diff --git a/security/hpn-ssh/files/patch-auth.c b/security/hpn-ssh/files/patch-auth.c
index 99c9d0c1550e..20cef648ab71 100644
--- a/security/hpn-ssh/files/patch-auth.c
+++ b/security/hpn-ssh/files/patch-auth.c
@@ -1,6 +1,6 @@
---- auth.c.orig Mon Mar 19 23:15:57 2001
-+++ auth.c Fri Jun 1 07:59:43 2001
-@@ -158,6 +158,17 @@
+--- auth.c.orig Tue Mar 5 02:42:43 2002
++++ auth.c Sun Mar 17 20:53:15 2002
+@@ -193,6 +193,17 @@
}
#endif /* WITH_AIXAUTHENTICATE */
diff --git a/security/hpn-ssh/files/patch-auth1.c b/security/hpn-ssh/files/patch-auth1.c
new file mode 100644
index 000000000000..43e0d0d4a29b
--- /dev/null
+++ b/security/hpn-ssh/files/patch-auth1.c
@@ -0,0 +1,56 @@
+--- auth1.c.orig Thu Feb 14 10:39:50 2002
++++ auth1.c Sun Mar 17 20:53:15 2002
+@@ -75,6 +75,18 @@
+ u_int ulen;
+ int type = 0;
+ struct passwd *pw = authctxt->pw;
++#ifdef HAVE_LOGIN_CAP
++ login_cap_t *lc;
++#endif
++#ifdef USE_PAM
++ struct inverted_pam_cookie *pam_cookie;
++#endif /* USE_PAM */
++#if defined(HAVE_LOGIN_CAP) || defined(LOGIN_ACCESS)
++ const char *from_host, *from_ip;
++
++ from_host = get_canonical_hostname(options.verify_reverse_mapping);
++ from_ip = get_remote_ipaddr();
++#endif /* HAVE_LOGIN_CAP || LOGIN_ACCESS */
+
+ debug("Attempting authentication for %s%.100s.",
+ authctxt->valid ? "" : "illegal user ", authctxt->user);
+@@ -297,6 +309,34 @@
+ log("Unknown message during authentication: type %d", type);
+ break;
+ }
++
++#ifdef HAVE_LOGIN_CAP
++ if (pw != NULL) {
++ lc = login_getpwclass(pw);
++ if (lc == NULL)
++ lc = login_getclassbyname(NULL, pw);
++ if (!auth_hostok(lc, from_host, from_ip)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++ if (!auth_timeok(lc, time(NULL))) {
++ log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
++ pw->pw_name, from_host);
++ packet_disconnect("Logins not available right now.");
++ }
++ login_close(lc);
++ lc = NULL;
++ }
++#endif /* HAVE_LOGIN_CAP */
++#ifdef LOGIN_ACCESS
++ if (pw != NULL && !login_access(pw->pw_name, from_host)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++#endif /* LOGIN_ACCESS */
++
+ #ifdef BSD_AUTH
+ if (authctxt->as) {
+ auth_close(authctxt->as);
diff --git a/security/hpn-ssh/files/patch-auth2.c b/security/hpn-ssh/files/patch-auth2.c
new file mode 100644
index 000000000000..46fa0f40f6e8
--- /dev/null
+++ b/security/hpn-ssh/files/patch-auth2.c
@@ -0,0 +1,60 @@
+--- auth2.c.orig Tue Feb 26 19:09:43 2002
++++ auth2.c Sun Mar 17 20:53:15 2002
+@@ -168,6 +168,15 @@
+ Authmethod *m = NULL;
+ char *user, *service, *method, *style = NULL;
+ int authenticated = 0;
++#ifdef HAVE_LOGIN_CAP
++ login_cap_t *lc;
++#endif /* HAVE_LOGIN_CAP */
++#if defined(HAVE_LOGIN_CAP) || defined(LOGIN_ACCESS)
++ const char *from_host, *from_ip;
++
++ from_host = get_canonical_hostname(options.verify_reverse_mapping);
++ from_ip = get_remote_ipaddr();
++#endif /* HAVE_LOGIN_CAP || LOGIN_ACCESS */
+
+ if (authctxt == NULL)
+ fatal("input_userauth_request: no authctxt");
+@@ -208,6 +217,41 @@
+ "(%s,%s) -> (%s,%s)",
+ authctxt->user, authctxt->service, user, service);
+ }
++
++#ifdef HAVE_LOGIN_CAP
++ if (authctxt->pw != NULL) {
++ lc = login_getpwclass(authctxt->pw);
++ if (lc == NULL)
++ lc = login_getclassbyname(NULL, authctxt->pw);
++ if (!auth_hostok(lc, from_host, from_ip)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ authctxt->pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++ if (!auth_timeok(lc, time(NULL))) {
++ log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
++ authctxt->pw->pw_name, from_host);
++ packet_disconnect("Logins not available right now.");
++ }
++ login_close(lc);
++ lc = NULL;
++ }
++#endif /* HAVE_LOGIN_CAP */
++#ifdef LOGIN_ACCESS
++ if (authctxt->pw != NULL &&
++ !login_access(authctxt->pw->pw_name, from_host)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ authctxt->pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++#endif /* LOGIN_ACCESS */
++#ifdef BSD_AUTH
++ if (authctxt->as) {
++ auth_close(authctxt->as);
++ authctxt->as = NULL;
++ }
++#endif
++
+ /* reset state */
+ auth2_challenge_stop(authctxt);
+ authctxt->postponed = 0;
diff --git a/security/hpn-ssh/files/patch-session.c b/security/hpn-ssh/files/patch-session.c
index 211addbf8b13..c2a9faf6201d 100644
--- a/security/hpn-ssh/files/patch-session.c
+++ b/security/hpn-ssh/files/patch-session.c
@@ -1,6 +1,20 @@
--- session.c.orig Mon Feb 25 16:48:03 2002
-+++ session.c Fri Mar 8 06:28:38 2002
-@@ -423,6 +423,13 @@
++++ session.c Sun Mar 17 21:05:03 2002
+@@ -63,6 +63,13 @@
+ #define is_winnt (GetVersion() < 0x80000000)
+ #endif
+
++#ifdef __FreeBSD__
++#include <libutil.h>
++#include <syslog.h>
++#include <time.h>
++#define _PATH_CHPASS "/usr/bin/passwd"
++#endif /* __FreeBSD__ */
++
+ /* types */
+
+ #define TTYSZ 64
+@@ -423,6 +430,13 @@
log_init(__progname, options.log_level, options.log_facility, log_stderr);
/*
@@ -14,7 +28,7 @@
* Create a new session and process group since the 4.4BSD
* setlogin() affects the entire process group.
*/
-@@ -537,6 +544,14 @@
+@@ -537,6 +551,14 @@
/* Child. Reinitialize the log because the pid has changed. */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -29,7 +43,14 @@
/* Close the master side of the pseudo tty. */
close(ptyfd);
-@@ -665,6 +680,11 @@
+@@ -659,12 +681,23 @@
+ do_login(Session *s, const char *command)
+ {
+ char *time_string;
++ char *newcommand;
+ char hostname[MAXHOSTNAMELEN];
+ socklen_t fromlen;
+ struct sockaddr_storage from;
time_t last_login_time;
struct passwd * pw = s->pw;
pid_t pid = getpid();
@@ -38,15 +59,105 @@
+ char buf[256];
+ char *fname;
+#endif /* HAVE_LOGIN_CAP */
++#ifdef __FreeBSD__
++#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
++ struct timeval tv;
++ time_t warntime = DEFAULT_WARN;
++#endif /* __FreeBSD__ */
/*
* Get IP address of client. If the connection is not a socket, let
-@@ -725,6 +745,21 @@
+@@ -703,6 +736,63 @@
+ }
+ #endif
+
++#ifdef __FreeBSD__
++ if (pw->pw_change || pw->pw_expire)
++ (void)gettimeofday(&tv, NULL);
++#ifdef HAVE_LOGIN_CAP
++ warntime = login_getcaptime(lc, "warnpassword",
++ DEFAULT_WARN, DEFAULT_WARN);
++#endif /* HAVE_LOGIN_CAP */
++ /*
++ * If the password change time is set and has passed, give the
++ * user a password expiry notice and chance to change it.
++ */
++ if (pw->pw_change != 0) {
++ if (tv.tv_sec >= pw->pw_change) {
++ (void)printf(
++ "Sorry -- your password has expired.\n");
++ log("%s Password expired - forcing change",
++ pw->pw_name);
++ if (newcommand != NULL)
++ xfree(newcommand);
++ newcommand = xstrdup(_PATH_CHPASS);
++ } else if (pw->pw_change - tv.tv_sec < warntime &&
++ !check_quietlogin(s, command))
++ (void)printf(
++ "Warning: your password expires on %s",
++ ctime(&pw->pw_change));
++ }
++
++#ifndef USE_PAM
++ if (pw->pw_expire) {
++ if (tv.tv_sec >= pw->pw_expire) {
++ (void)printf(
++ "Sorry -- your account has expired.\n");
++ log(
++ "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
++ pw->pw_name, get_remote_name_or_ip(utmp_len,
++ options.verify_reverse_mapping), s->tty);
++ exit(254);
++ } else if (pw->pw_expire - tv.tv_sec < warntime &&
++ !check_quietlogin(s, command))
++ (void)printf(
++ "Warning: your account expires on %s",
++ ctime(&pw->pw_expire));
++ }
++#endif /* !USE_PAM */
++#endif /* __FreeBSD__ */
++
++#ifdef HAVE_LOGIN_CAP
++ if (!auth_ttyok(lc, s->tty)) {
++ (void)printf("Permission denied.\n");
++ log(
++ "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s",
++ pw->pw_name, get_remote_name_or_ip(utmp_len,
++ options.verify_reverse_mapping), s->tty);
++ exit(254);
++ }
++#endif /* HAVE_LOGIN_CAP */
++
+ if (check_quietlogin(s, command))
+ return;
+
+@@ -715,7 +805,17 @@
+ printf("%s\n", aixloginmsg);
+ #endif /* WITH_AIXAUTHENTICATE */
+
+- if (options.print_lastlog && last_login_time != 0) {
++ /*
++ * If the user has logged in before, display the time of last
++ * login. However, don't display anything extra if a command
++ * has been specified (so that ssh can be used to execute
++ * commands on a remote machine without users knowing they
++ * are going to another machine). Login(1) will do this for
++ * us as well, so check if login(1) is used
++ */
++ if (command == NULL && options.print_lastlog &&
++ last_login_time != 0 &&
++ !options.use_login) {
+ time_string = ctime(&last_login_time);
+ if (strchr(time_string, '\n'))
+ *strchr(time_string, '\n') = 0;
+@@ -725,7 +825,30 @@
printf("Last login: %s from %s\r\n", time_string, hostname);
}
+- do_motd();
+#ifdef HAVE_LOGIN_CAP
-+ if (!options.use_login) {
++ if (command == NULL &&
++ !options.use_login) {
+ fname = login_getcapstr(lc, "copyright", NULL, NULL);
+ if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
+ while (fgets(buf, sizeof(buf), f) != NULL)
@@ -60,10 +171,67 @@
+ }
+#endif /* HAVE_LOGIN_CAP */
+
- do_motd();
++ /*
++ * Print /etc/motd unless a command was specified or printing
++ * it was disabled in server options or login(1) will be
++ * used. Note that some machines appear to print it in
++ * /etc/profile or similar.
++ */
++ if (command == NULL && !options.use_login)
++ do_motd();
}
-@@ -1241,7 +1276,7 @@
+ /*
+@@ -741,9 +864,9 @@
+ #ifdef HAVE_LOGIN_CAP
+ f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
+ "/etc/motd"), "r");
+-#else
++#else /* !HAVE_LOGIN_CAP */
+ f = fopen("/etc/motd", "r");
+-#endif
++#endif /* HAVE_LOGIN_CAP */
+ if (f) {
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stdout);
+@@ -770,10 +893,10 @@
+ #ifdef HAVE_LOGIN_CAP
+ if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
+ return 1;
+-#else
++#else /* HAVE_LOGIN_CAP */
+ if (stat(buf, &st) >= 0)
+ return 1;
+-#endif
++#endif /* HAVE_LOGIN_CAP */
+ return 0;
+ }
+
+@@ -902,6 +1025,10 @@
+ #endif
+
+ if (!options.use_login) {
++#ifdef HAVE_LOGIN_CAP
++ char *var;
++#endif /* HAVE_LOGIN_CAP */
++
+ /* Set basic environment. */
+ child_set_env(&env, &envsize, "USER", pw->pw_name);
+ child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
+@@ -909,6 +1036,12 @@
+ #ifdef HAVE_LOGIN_CAP
+ (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
+ child_set_env(&env, &envsize, "PATH", getenv("PATH"));
++ var= login_getcapstr(lc, "lang", NULL, NULL);
++ if ( var ) child_set_env(&env, &envsize, "LANG", var);
++ var= login_getcapstr(lc, "charset", NULL, NULL);
++ if ( var ) child_set_env(&env, &envsize, "MM_CHARSET", var);
++ var= login_getcapstr(lc, "timezone", NULL, NULL);
++ if ( var ) child_set_env(&env, &envsize, "TZ", var);
+ #else /* HAVE_LOGIN_CAP */
+ # ifndef HAVE_CYGWIN
+ /*
+@@ -1241,7 +1374,7 @@
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
*/
@@ -72,7 +240,7 @@
close(i);
/*
-@@ -1271,6 +1306,31 @@
+@@ -1271,6 +1404,31 @@
exit(1);
#endif
}
diff --git a/security/openssh-portable/Makefile b/security/openssh-portable/Makefile
index cfe8163d7664..26a10c695fa6 100644
--- a/security/openssh-portable/Makefile
+++ b/security/openssh-portable/Makefile
@@ -7,7 +7,7 @@
PORTNAME= openssh
PORTVERSION= 3.1p1
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= security ipv6
MASTER_SITES= ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/ \
ftp://ftp.op.net/pub/OpenBSD/OpenSSH/portable/ \
diff --git a/security/openssh-portable/files/patch-auth.c b/security/openssh-portable/files/patch-auth.c
index 99c9d0c1550e..20cef648ab71 100644
--- a/security/openssh-portable/files/patch-auth.c
+++ b/security/openssh-portable/files/patch-auth.c
@@ -1,6 +1,6 @@
---- auth.c.orig Mon Mar 19 23:15:57 2001
-+++ auth.c Fri Jun 1 07:59:43 2001
-@@ -158,6 +158,17 @@
+--- auth.c.orig Tue Mar 5 02:42:43 2002
++++ auth.c Sun Mar 17 20:53:15 2002
+@@ -193,6 +193,17 @@
}
#endif /* WITH_AIXAUTHENTICATE */
diff --git a/security/openssh-portable/files/patch-auth1.c b/security/openssh-portable/files/patch-auth1.c
new file mode 100644
index 000000000000..43e0d0d4a29b
--- /dev/null
+++ b/security/openssh-portable/files/patch-auth1.c
@@ -0,0 +1,56 @@
+--- auth1.c.orig Thu Feb 14 10:39:50 2002
++++ auth1.c Sun Mar 17 20:53:15 2002
+@@ -75,6 +75,18 @@
+ u_int ulen;
+ int type = 0;
+ struct passwd *pw = authctxt->pw;
++#ifdef HAVE_LOGIN_CAP
++ login_cap_t *lc;
++#endif
++#ifdef USE_PAM
++ struct inverted_pam_cookie *pam_cookie;
++#endif /* USE_PAM */
++#if defined(HAVE_LOGIN_CAP) || defined(LOGIN_ACCESS)
++ const char *from_host, *from_ip;
++
++ from_host = get_canonical_hostname(options.verify_reverse_mapping);
++ from_ip = get_remote_ipaddr();
++#endif /* HAVE_LOGIN_CAP || LOGIN_ACCESS */
+
+ debug("Attempting authentication for %s%.100s.",
+ authctxt->valid ? "" : "illegal user ", authctxt->user);
+@@ -297,6 +309,34 @@
+ log("Unknown message during authentication: type %d", type);
+ break;
+ }
++
++#ifdef HAVE_LOGIN_CAP
++ if (pw != NULL) {
++ lc = login_getpwclass(pw);
++ if (lc == NULL)
++ lc = login_getclassbyname(NULL, pw);
++ if (!auth_hostok(lc, from_host, from_ip)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++ if (!auth_timeok(lc, time(NULL))) {
++ log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
++ pw->pw_name, from_host);
++ packet_disconnect("Logins not available right now.");
++ }
++ login_close(lc);
++ lc = NULL;
++ }
++#endif /* HAVE_LOGIN_CAP */
++#ifdef LOGIN_ACCESS
++ if (pw != NULL && !login_access(pw->pw_name, from_host)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++#endif /* LOGIN_ACCESS */
++
+ #ifdef BSD_AUTH
+ if (authctxt->as) {
+ auth_close(authctxt->as);
diff --git a/security/openssh-portable/files/patch-auth2.c b/security/openssh-portable/files/patch-auth2.c
new file mode 100644
index 000000000000..46fa0f40f6e8
--- /dev/null
+++ b/security/openssh-portable/files/patch-auth2.c
@@ -0,0 +1,60 @@
+--- auth2.c.orig Tue Feb 26 19:09:43 2002
++++ auth2.c Sun Mar 17 20:53:15 2002
+@@ -168,6 +168,15 @@
+ Authmethod *m = NULL;
+ char *user, *service, *method, *style = NULL;
+ int authenticated = 0;
++#ifdef HAVE_LOGIN_CAP
++ login_cap_t *lc;
++#endif /* HAVE_LOGIN_CAP */
++#if defined(HAVE_LOGIN_CAP) || defined(LOGIN_ACCESS)
++ const char *from_host, *from_ip;
++
++ from_host = get_canonical_hostname(options.verify_reverse_mapping);
++ from_ip = get_remote_ipaddr();
++#endif /* HAVE_LOGIN_CAP || LOGIN_ACCESS */
+
+ if (authctxt == NULL)
+ fatal("input_userauth_request: no authctxt");
+@@ -208,6 +217,41 @@
+ "(%s,%s) -> (%s,%s)",
+ authctxt->user, authctxt->service, user, service);
+ }
++
++#ifdef HAVE_LOGIN_CAP
++ if (authctxt->pw != NULL) {
++ lc = login_getpwclass(authctxt->pw);
++ if (lc == NULL)
++ lc = login_getclassbyname(NULL, authctxt->pw);
++ if (!auth_hostok(lc, from_host, from_ip)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ authctxt->pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++ if (!auth_timeok(lc, time(NULL))) {
++ log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
++ authctxt->pw->pw_name, from_host);
++ packet_disconnect("Logins not available right now.");
++ }
++ login_close(lc);
++ lc = NULL;
++ }
++#endif /* HAVE_LOGIN_CAP */
++#ifdef LOGIN_ACCESS
++ if (authctxt->pw != NULL &&
++ !login_access(authctxt->pw->pw_name, from_host)) {
++ log("Denied connection for %.200s from %.200s [%.200s].",
++ authctxt->pw->pw_name, from_host, from_ip);
++ packet_disconnect("Sorry, you are not allowed to connect.");
++ }
++#endif /* LOGIN_ACCESS */
++#ifdef BSD_AUTH
++ if (authctxt->as) {
++ auth_close(authctxt->as);
++ authctxt->as = NULL;
++ }
++#endif
++
+ /* reset state */
+ auth2_challenge_stop(authctxt);
+ authctxt->postponed = 0;
diff --git a/security/openssh-portable/files/patch-session.c b/security/openssh-portable/files/patch-session.c
index 211addbf8b13..c2a9faf6201d 100644
--- a/security/openssh-portable/files/patch-session.c
+++ b/security/openssh-portable/files/patch-session.c
@@ -1,6 +1,20 @@
--- session.c.orig Mon Feb 25 16:48:03 2002
-+++ session.c Fri Mar 8 06:28:38 2002
-@@ -423,6 +423,13 @@
++++ session.c Sun Mar 17 21:05:03 2002
+@@ -63,6 +63,13 @@
+ #define is_winnt (GetVersion() < 0x80000000)
+ #endif
+
++#ifdef __FreeBSD__
++#include <libutil.h>
++#include <syslog.h>
++#include <time.h>
++#define _PATH_CHPASS "/usr/bin/passwd"
++#endif /* __FreeBSD__ */
++
+ /* types */
+
+ #define TTYSZ 64
+@@ -423,6 +430,13 @@
log_init(__progname, options.log_level, options.log_facility, log_stderr);
/*
@@ -14,7 +28,7 @@
* Create a new session and process group since the 4.4BSD
* setlogin() affects the entire process group.
*/
-@@ -537,6 +544,14 @@
+@@ -537,6 +551,14 @@
/* Child. Reinitialize the log because the pid has changed. */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -29,7 +43,14 @@
/* Close the master side of the pseudo tty. */
close(ptyfd);
-@@ -665,6 +680,11 @@
+@@ -659,12 +681,23 @@
+ do_login(Session *s, const char *command)
+ {
+ char *time_string;
++ char *newcommand;
+ char hostname[MAXHOSTNAMELEN];
+ socklen_t fromlen;
+ struct sockaddr_storage from;
time_t last_login_time;
struct passwd * pw = s->pw;
pid_t pid = getpid();
@@ -38,15 +59,105 @@
+ char buf[256];
+ char *fname;
+#endif /* HAVE_LOGIN_CAP */
++#ifdef __FreeBSD__
++#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
++ struct timeval tv;
++ time_t warntime = DEFAULT_WARN;
++#endif /* __FreeBSD__ */
/*
* Get IP address of client. If the connection is not a socket, let
-@@ -725,6 +745,21 @@
+@@ -703,6 +736,63 @@
+ }
+ #endif
+
++#ifdef __FreeBSD__
++ if (pw->pw_change || pw->pw_expire)
++ (void)gettimeofday(&tv, NULL);
++#ifdef HAVE_LOGIN_CAP
++ warntime = login_getcaptime(lc, "warnpassword",
++ DEFAULT_WARN, DEFAULT_WARN);
++#endif /* HAVE_LOGIN_CAP */
++ /*
++ * If the password change time is set and has passed, give the
++ * user a password expiry notice and chance to change it.
++ */
++ if (pw->pw_change != 0) {
++ if (tv.tv_sec >= pw->pw_change) {
++ (void)printf(
++ "Sorry -- your password has expired.\n");
++ log("%s Password expired - forcing change",
++ pw->pw_name);
++ if (newcommand != NULL)
++ xfree(newcommand);
++ newcommand = xstrdup(_PATH_CHPASS);
++ } else if (pw->pw_change - tv.tv_sec < warntime &&
++ !check_quietlogin(s, command))
++ (void)printf(
++ "Warning: your password expires on %s",
++ ctime(&pw->pw_change));
++ }
++
++#ifndef USE_PAM
++ if (pw->pw_expire) {
++ if (tv.tv_sec >= pw->pw_expire) {
++ (void)printf(
++ "Sorry -- your account has expired.\n");
++ log(
++ "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
++ pw->pw_name, get_remote_name_or_ip(utmp_len,
++ options.verify_reverse_mapping), s->tty);
++ exit(254);
++ } else if (pw->pw_expire - tv.tv_sec < warntime &&
++ !check_quietlogin(s, command))
++ (void)printf(
++ "Warning: your account expires on %s",
++ ctime(&pw->pw_expire));
++ }
++#endif /* !USE_PAM */
++#endif /* __FreeBSD__ */
++
++#ifdef HAVE_LOGIN_CAP
++ if (!auth_ttyok(lc, s->tty)) {
++ (void)printf("Permission denied.\n");
++ log(
++ "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s",
++ pw->pw_name, get_remote_name_or_ip(utmp_len,
++ options.verify_reverse_mapping), s->tty);
++ exit(254);
++ }
++#endif /* HAVE_LOGIN_CAP */
++
+ if (check_quietlogin(s, command))
+ return;
+
+@@ -715,7 +805,17 @@
+ printf("%s\n", aixloginmsg);
+ #endif /* WITH_AIXAUTHENTICATE */
+
+- if (options.print_lastlog && last_login_time != 0) {
++ /*
++ * If the user has logged in before, display the time of last
++ * login. However, don't display anything extra if a command
++ * has been specified (so that ssh can be used to execute
++ * commands on a remote machine without users knowing they
++ * are going to another machine). Login(1) will do this for
++ * us as well, so check if login(1) is used
++ */
++ if (command == NULL && options.print_lastlog &&
++ last_login_time != 0 &&
++ !options.use_login) {
+ time_string = ctime(&last_login_time);
+ if (strchr(time_string, '\n'))
+ *strchr(time_string, '\n') = 0;
+@@ -725,7 +825,30 @@
printf("Last login: %s from %s\r\n", time_string, hostname);
}
+- do_motd();
+#ifdef HAVE_LOGIN_CAP
-+ if (!options.use_login) {
++ if (command == NULL &&
++ !options.use_login) {
+ fname = login_getcapstr(lc, "copyright", NULL, NULL);
+ if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
+ while (fgets(buf, sizeof(buf), f) != NULL)
@@ -60,10 +171,67 @@
+ }
+#endif /* HAVE_LOGIN_CAP */
+
- do_motd();
++ /*
++ * Print /etc/motd unless a command was specified or printing
++ * it was disabled in server options or login(1) will be
++ * used. Note that some machines appear to print it in
++ * /etc/profile or similar.
++ */
++ if (command == NULL && !options.use_login)
++ do_motd();
}
-@@ -1241,7 +1276,7 @@
+ /*
+@@ -741,9 +864,9 @@
+ #ifdef HAVE_LOGIN_CAP
+ f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
+ "/etc/motd"), "r");
+-#else
++#else /* !HAVE_LOGIN_CAP */
+ f = fopen("/etc/motd", "r");
+-#endif
++#endif /* HAVE_LOGIN_CAP */
+ if (f) {
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stdout);
+@@ -770,10 +893,10 @@
+ #ifdef HAVE_LOGIN_CAP
+ if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
+ return 1;
+-#else
++#else /* HAVE_LOGIN_CAP */
+ if (stat(buf, &st) >= 0)
+ return 1;
+-#endif
++#endif /* HAVE_LOGIN_CAP */
+ return 0;
+ }
+
+@@ -902,6 +1025,10 @@
+ #endif
+
+ if (!options.use_login) {
++#ifdef HAVE_LOGIN_CAP
++ char *var;
++#endif /* HAVE_LOGIN_CAP */
++
+ /* Set basic environment. */
+ child_set_env(&env, &envsize, "USER", pw->pw_name);
+ child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
+@@ -909,6 +1036,12 @@
+ #ifdef HAVE_LOGIN_CAP
+ (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
+ child_set_env(&env, &envsize, "PATH", getenv("PATH"));
++ var= login_getcapstr(lc, "lang", NULL, NULL);
++ if ( var ) child_set_env(&env, &envsize, "LANG", var);
++ var= login_getcapstr(lc, "charset", NULL, NULL);
++ if ( var ) child_set_env(&env, &envsize, "MM_CHARSET", var);
++ var= login_getcapstr(lc, "timezone", NULL, NULL);
++ if ( var ) child_set_env(&env, &envsize, "TZ", var);
+ #else /* HAVE_LOGIN_CAP */
+ # ifndef HAVE_CYGWIN
+ /*
+@@ -1241,7 +1374,7 @@
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
*/
@@ -72,7 +240,7 @@
close(i);
/*
-@@ -1271,6 +1306,31 @@
+@@ -1271,6 +1404,31 @@
exit(1);
#endif
}