diff options
author | Dirk Meyer <dinoex@FreeBSD.org> | 2002-03-17 20:24:24 +0000 |
---|---|---|
committer | Dirk Meyer <dinoex@FreeBSD.org> | 2002-03-17 20:24:24 +0000 |
commit | 74642142e398b1c92976c1b59a44a53415798dce (patch) | |
tree | 742c57e9fae2b7fc99fc092418eea94ba23b1c48 /security | |
parent | Merge 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/Makefile | 2 | ||||
-rw-r--r-- | security/hpn-ssh/files/patch-auth.c | 6 | ||||
-rw-r--r-- | security/hpn-ssh/files/patch-auth1.c | 56 | ||||
-rw-r--r-- | security/hpn-ssh/files/patch-auth2.c | 60 | ||||
-rw-r--r-- | security/hpn-ssh/files/patch-session.c | 186 | ||||
-rw-r--r-- | security/openssh-portable/Makefile | 2 | ||||
-rw-r--r-- | security/openssh-portable/files/patch-auth.c | 6 | ||||
-rw-r--r-- | security/openssh-portable/files/patch-auth1.c | 56 | ||||
-rw-r--r-- | security/openssh-portable/files/patch-auth2.c | 60 | ||||
-rw-r--r-- | security/openssh-portable/files/patch-session.c | 186 |
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 } |