Index: auth-pam.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.c,v
retrieving revision 1.114
diff -u -p -r1.114 auth-pam.c
--- auth-pam.c	16 Aug 2004 13:12:06 -0000	1.114
+++ auth-pam.c	9 Sep 2004 12:35:58 -0000
@@ -490,6 +490,51 @@ sshpam_null_conv(int n, struct pam_messa
 
 static struct pam_conv null_conv = { sshpam_null_conv, NULL };
 
+static int
+sshpam_store_conv(int n, struct pam_message **msg,
+    struct pam_response **resp, void *data)
+{
+	struct pam_response *reply;
+	int i;
+	size_t len;
+
+	debug3("PAM: %s called with %d messages", __func__, n);
+	*resp = NULL;
+
+	if (n <= 0 || n > PAM_MAX_NUM_MSG)
+		return (PAM_CONV_ERR);
+
+	if ((reply = malloc(n * sizeof(*reply))) == NULL)
+		return (PAM_CONV_ERR);
+	memset(reply, 0, n * sizeof(*reply));
+
+	for (i = 0; i < n; ++i) {
+		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+		case PAM_ERROR_MSG:
+		case PAM_TEXT_INFO:
+			len = strlen(PAM_MSG_MEMBER(msg, i, msg));
+			buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
+			buffer_append(&loginmsg, "\n", 1 );
+			reply[i].resp_retcode = PAM_SUCCESS;
+			break;
+		default:
+			goto fail;
+		}
+	}
+	*resp = reply;
+	return (PAM_SUCCESS);
+
+ fail:
+	for(i = 0; i < n; i++) {
+		if (reply[i].resp != NULL)
+			xfree(reply[i].resp);
+	}
+	xfree(reply);
+	return (PAM_CONV_ERR);
+}
+
+static struct pam_conv store_conv = { sshpam_store_conv, NULL };
+
 void
 sshpam_cleanup(void)
 {
@@ -527,7 +572,7 @@ sshpam_init(Authctxt *authctxt)
 	}
 	debug("PAM: initializing for \"%s\"", user);
 	sshpam_err =
-	    pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle);
+	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
 	sshpam_authctxt = authctxt;
 
 	if (sshpam_err != PAM_SUCCESS) {
@@ -759,11 +804,13 @@ finish_pam(void)
 u_int
 do_pam_account(void)
 {
+	debug("%s: called", __func__);
 	if (sshpam_account_status != -1)
 		return (sshpam_account_status);
 
 	sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
-	debug3("PAM: %s pam_acct_mgmt = %d", __func__, sshpam_err);
+	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
+	    pam_strerror(sshpam_handle, sshpam_err));
 	
 	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
 		sshpam_account_status = 0;
@@ -793,7 +840,7 @@ void
 do_pam_setcred(int init)
 {
 	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
-	    (const void *)&null_conv);
+	    (const void *)&store_conv);
 	if (sshpam_err != PAM_SUCCESS)
 		fatal("PAM: failed to set PAM_CONV: %s",
 		    pam_strerror(sshpam_handle, sshpam_err));
@@ -894,51 +941,6 @@ do_pam_chauthtok(void)
 		    pam_strerror(sshpam_handle, sshpam_err));
 }
 
-static int
-sshpam_store_conv(int n, struct pam_message **msg,
-    struct pam_response **resp, void *data)
-{
-	struct pam_response *reply;
-	int i;
-	size_t len;
-
-	debug3("PAM: %s called with %d messages", __func__, n);
-	*resp = NULL;
-
-	if (n <= 0 || n > PAM_MAX_NUM_MSG)
-		return (PAM_CONV_ERR);
-
-	if ((reply = malloc(n * sizeof(*reply))) == NULL)
-		return (PAM_CONV_ERR);
-	memset(reply, 0, n * sizeof(*reply));
-
-	for (i = 0; i < n; ++i) {
-		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
-		case PAM_ERROR_MSG:
-		case PAM_TEXT_INFO:
-			len = strlen(PAM_MSG_MEMBER(msg, i, msg));
-			buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
-			buffer_append(&loginmsg, "\n", 1 );
-			reply[i].resp_retcode = PAM_SUCCESS;
-			break;
-		default:
-			goto fail;
-		}
-	}
-	*resp = reply;
-	return (PAM_SUCCESS);
-
- fail:
-	for(i = 0; i < n; i++) {
-		if (reply[i].resp != NULL)
-			xfree(reply[i].resp);
-	}
-	xfree(reply);
-	return (PAM_CONV_ERR);
-}
-
-static struct pam_conv store_conv = { sshpam_store_conv, NULL };
-
 void
 do_pam_session(void)
 {
@@ -949,10 +951,20 @@ do_pam_session(void)
 		fatal("PAM: failed to set PAM_CONV: %s",
 		    pam_strerror(sshpam_handle, sshpam_err));
 	sshpam_err = pam_open_session(sshpam_handle, 0);
-	if (sshpam_err != PAM_SUCCESS)
-		fatal("PAM: pam_open_session(): %s",
+	if (sshpam_err == PAM_SUCCESS)
+		sshpam_session_open = 1;
+	else {
+		disable_forwarding();
+		error("PAM: pam_open_session(): %s",
 		    pam_strerror(sshpam_handle, sshpam_err));
-	sshpam_session_open = 1;
+	}
+
+}
+
+int
+is_pam_session_open(void)
+{
+	return sshpam_session_open;
 }
 
 /*
Index: auth-pam.h
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.h,v
retrieving revision 1.26
diff -u -p -r1.26 auth-pam.h
--- auth-pam.h	30 May 2004 10:43:59 -0000	1.26
+++ auth-pam.h	9 Sep 2004 12:35:58 -0000
@@ -45,5 +45,6 @@ void free_pam_environment(char **);
 void sshpam_thread_cleanup(void);
 void sshpam_cleanup(void);
 int sshpam_auth_passwd(Authctxt *, const char *);
+int is_pam_session_open(void);
 
 #endif /* USE_PAM */
Index: auth.h
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth.h,v
retrieving revision 1.62
diff -u -p -r1.62 auth.h
--- auth.h	24 May 2004 00:36:23 -0000	1.62
+++ auth.h	9 Sep 2004 12:35:02 -0000
@@ -137,6 +137,7 @@ void	do_authentication2(Authctxt *);
 
 void	auth_log(Authctxt *, int, char *, char *);
 void	userauth_finish(Authctxt *, int, char *);
+void	userauth_send_banner(const char *);
 int	auth_root_allowed(char *);
 
 char	*auth2_read_banner(void);
Index: auth2-none.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth2-none.c,v
retrieving revision 1.7
diff -u -p -r1.7 auth2-none.c
--- auth2-none.c	13 May 2004 06:39:33 -0000	1.7
+++ auth2-none.c	9 Sep 2004 12:35:02 -0000
@@ -74,6 +74,19 @@ auth2_read_banner(void)
 	return (banner);
 }
 
+void
+userauth_send_banner(const char *msg)
+{
+	if (datafellows & SSH_BUG_BANNER)
+		return;
+
+	packet_start(SSH2_MSG_USERAUTH_BANNER);
+	packet_put_cstring(msg);
+	packet_put_cstring("");		/* language, unused */
+	packet_send();
+	debug("%s: sent", __func__);
+}
+
 static void
 userauth_banner(void)
 {
@@ -84,12 +97,8 @@ userauth_banner(void)
 
 	if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
 		goto done;
+	userauth_send_banner(banner);
 
-	packet_start(SSH2_MSG_USERAUTH_BANNER);
-	packet_put_cstring(banner);
-	packet_put_cstring("");		/* language, unused */
-	packet_send();
-	debug("userauth_banner: sent");
 done:
 	if (banner)
 		xfree(banner);
Index: auth2.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth2.c,v
retrieving revision 1.130
diff -u -p -r1.130 auth2.c
--- auth2.c	12 Aug 2004 12:40:25 -0000	1.130
+++ auth2.c	9 Sep 2004 12:35:02 -0000
@@ -35,6 +35,7 @@ RCSID("$OpenBSD: auth2.c,v 1.107 2004/07
 #include "dispatch.h"
 #include "pathnames.h"
 #include "monitor_wrap.h"
+#include "buffer.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -44,6 +45,7 @@ RCSID("$OpenBSD: auth2.c,v 1.107 2004/07
 extern ServerOptions options;
 extern u_char *session_id2;
 extern u_int session_id2_len;
+extern Buffer loginmsg;
 
 /* methods */
 
@@ -216,8 +218,17 @@ userauth_finish(Authctxt *authctxt, int 
 		authenticated = 0;
 
 #ifdef USE_PAM
-	if (options.use_pam && authenticated && !PRIVSEP(do_pam_account()))
-		authenticated = 0;
+	if (options.use_pam && authenticated) {
+		if (!PRIVSEP(do_pam_account())) {
+			authenticated = 0;
+			/* if PAM returned a message, send it to the user */
+			if (buffer_len(&loginmsg) > 0) {
+				buffer_append(&loginmsg, "\0", 1);
+				userauth_send_banner(buffer_ptr(&loginmsg));
+				buffer_clear(&loginmsg);
+			}
+		}
+	}
 #endif
 
 #ifdef _UNICOS
Index: monitor.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/monitor.c,v
retrieving revision 1.76
diff -u -p -r1.76 monitor.c
--- monitor.c	17 Jul 2004 07:05:14 -0000	1.76
+++ monitor.c	9 Sep 2004 12:35:07 -0000
@@ -810,6 +810,9 @@ mm_answer_pam_account(int sock, Buffer *
 	ret = do_pam_account();
 
 	buffer_put_int(m, ret);
+	buffer_append(&loginmsg, "\0", 1);
+	buffer_put_cstring(m, buffer_ptr(&loginmsg));
+	buffer_clear(&loginmsg);
 
 	mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m);
 
Index: monitor_wrap.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/monitor_wrap.c,v
retrieving revision 1.48
diff -u -p -r1.48 monitor_wrap.c
--- monitor_wrap.c	17 Jul 2004 07:05:14 -0000	1.48
+++ monitor_wrap.c	9 Sep 2004 12:35:07 -0000
@@ -72,6 +72,7 @@ extern struct monitor *pmonitor;
 extern Buffer input, output;
 extern Buffer loginmsg;
 extern ServerOptions options;
+extern Buffer loginmsg;
 
 int
 mm_is_monitor(void)
@@ -716,6 +717,7 @@ mm_do_pam_account(void)
 {
 	Buffer m;
 	u_int ret;
+	char *msg;
 
 	debug3("%s entering", __func__);
 	if (!options.use_pam)
@@ -727,6 +729,9 @@ mm_do_pam_account(void)
 	mm_request_receive_expect(pmonitor->m_recvfd,
 	    MONITOR_ANS_PAM_ACCOUNT, &m);
 	ret = buffer_get_int(&m);
+	msg = buffer_get_string(&m, NULL);
+	buffer_append(&loginmsg, msg, strlen(msg));
+	xfree(msg);
 
 	buffer_free(&m);
 
Index: session.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/session.c,v
retrieving revision 1.288
diff -u -p -r1.288 session.c
--- session.c	30 Aug 2004 10:42:08 -0000	1.288
+++ session.c	9 Sep 2004 12:35:58 -0000
@@ -1439,6 +1439,13 @@ do_child(Session *s, const char *command
 #endif /* HAVE_OSF_SIA */
 	}
 
+#ifdef USE_PAM
+	if (options.use_pam && !is_pam_session_open()) {
+		display_loginmsg();
+		exit(254);
+	}
+#endif
+
 	/*
 	 * Get the shell from the password data.  An empty shell field is
 	 * legal, and means /bin/sh.
