- (djm) Bug #564: Perform PAM account checks for all authentications when
   UsePAM=yes; ok dtucker
diff --git a/monitor.c b/monitor.c
index 95fd0cf..80b1a8f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -118,6 +118,7 @@
 
 #ifdef USE_PAM
 int mm_answer_pam_start(int, Buffer *);
+int mm_answer_pam_account(int, Buffer *);
 int mm_answer_pam_init_ctx(int, Buffer *);
 int mm_answer_pam_query(int, Buffer *);
 int mm_answer_pam_respond(int, Buffer *);
@@ -165,6 +166,7 @@
     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
 #ifdef USE_PAM
     {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
+    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
     {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
     {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
     {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
@@ -214,6 +216,7 @@
 #endif
 #ifdef USE_PAM
     {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
+    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
     {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
     {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
     {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
@@ -295,6 +298,18 @@
 			if (authctxt->pw->pw_uid == 0 &&
 			    !auth_root_allowed(auth_method))
 				authenticated = 0;
+#ifdef USE_PAM
+			/* PAM needs to perform account checks after auth */
+			if (options.use_pam) {
+				Buffer m;
+
+				buffer_init(&m);
+				mm_request_receive_expect(pmonitor->m_sendfd, 
+				    MONITOR_REQ_PAM_ACCOUNT, &m);
+				authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);
+				buffer_free(&m);
+			}
+#endif
 		}
 
 		if (ent->flags & MON_AUTHDECIDE) {
@@ -771,9 +786,28 @@
 
 	xfree(user);
 
+	monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1);
+
 	return (0);
 }
 
+int
+mm_answer_pam_account(int socket, Buffer *m)
+{
+	u_int ret;
+	
+	if (!options.use_pam)
+		fatal("UsePAM not set, but ended up in %s anyway", __func__);
+
+	ret = do_pam_account();
+
+	buffer_put_int(m, ret);
+
+	mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m);
+
+	return (ret);
+}
+
 static void *sshpam_ctxt, *sshpam_authok;
 extern KbdintDevice sshpam_device;