- (dtucker) [auth-pam.c auth.h auth2-none.c auth2.c monitor.c monitor_wrap.c]
   Bug #892: Send messages from failing PAM account modules to the client via
   SSH2_MSG_USERAUTH_BANNER messages.  Note that this will not happen with
   SSH2 kbdint authentication, which need to be dealt with separately.  ok djm@
diff --git a/ChangeLog b/ChangeLog
index 85366cb..0c0d2c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
  - (dtucker) [auth-pam.c] Relocate sshpam_store_conv(), no code change.
  - (djm) [auth2-kbdint.c auth2-none.c  auth2-passwd.c auth2-pubkey.c] 
    Make cygwin code more consistent with that which surrounds it
+ - (dtucker) [auth-pam.c auth.h auth2-none.c auth2.c monitor.c monitor_wrap.c]
+   Bug #892: Send messages from failing PAM account modules to the client via
+   SSH2_MSG_USERAUTH_BANNER messages.  Note that this will not happen with
+   SSH2 kbdint authentication, which need to be dealt with separately.  ok djm@
 
 20040830
  - (dtucker) [session.c openbsd-compat/bsd-cygwin_util.{c,h}] Bug #915: only
@@ -1725,4 +1729,4 @@
    - (djm) Trim deprecated options from INSTALL. Mention UsePAM
    - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
 
-$Id: ChangeLog,v 1.3543 2004/09/11 12:42:09 djm Exp $
+$Id: ChangeLog,v 1.3544 2004/09/11 13:07:03 dtucker Exp $
diff --git a/auth-pam.c b/auth-pam.c
index 4ad86de..0a6817d 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -47,7 +47,7 @@
 
 /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
 #include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.116 2004/09/11 12:28:02 dtucker Exp $");
+RCSID("$Id: auth-pam.c,v 1.117 2004/09/11 13:07:03 dtucker Exp $");
 
 #ifdef USE_PAM
 #if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -572,7 +572,7 @@
 	}
 	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) {
@@ -804,11 +804,13 @@
 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;
@@ -838,7 +840,7 @@
 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));
diff --git a/auth.h b/auth.h
index 2f09440..760337b 100644
--- a/auth.h
+++ b/auth.h
@@ -137,6 +137,7 @@
 
 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);
diff --git a/auth2-none.c b/auth2-none.c
index 787458d..1c30a32 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -74,6 +74,19 @@
 	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 @@
 
 	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);
diff --git a/auth2.c b/auth2.c
index b983095..57e6db4 100644
--- a/auth2.c
+++ b/auth2.c
@@ -35,6 +35,7 @@
 #include "dispatch.h"
 #include "pathnames.h"
 #include "monitor_wrap.h"
+#include "buffer.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -44,6 +45,7 @@
 extern ServerOptions options;
 extern u_char *session_id2;
 extern u_int session_id2_len;
+extern Buffer loginmsg;
 
 /* methods */
 
@@ -216,8 +218,17 @@
 		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
diff --git a/monitor.c b/monitor.c
index b746340..00d4a78 100644
--- a/monitor.c
+++ b/monitor.c
@@ -810,6 +810,9 @@
 	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);
 
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 0d7a0e3..2385763 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -72,6 +72,7 @@
 extern Buffer input, output;
 extern Buffer loginmsg;
 extern ServerOptions options;
+extern Buffer loginmsg;
 
 int
 mm_is_monitor(void)
@@ -716,6 +717,7 @@
 {
 	Buffer m;
 	u_int ret;
+	char *msg;
 
 	debug3("%s entering", __func__);
 	if (!options.use_pam)
@@ -727,6 +729,9 @@
 	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);