9f2fb5f
Index: modules/mod_auth_pam.c
9f2fb5f
===================================================================
9f2fb5f
RCS file: /cvsroot/proftp/proftpd/modules/mod_auth_pam.c,v
9f2fb5f
retrieving revision 1.27
9f2fb5f
diff -u -r1.27 mod_auth_pam.c
9f2fb5f
--- modules/mod_auth_pam.c	26 Feb 2013 23:12:31 -0000	1.27
9f2fb5f
+++ modules/mod_auth_pam.c	16 Apr 2013 16:53:54 -0000
9f2fb5f
@@ -171,7 +171,7 @@
9f2fb5f
 };
9f2fb5f
 
9f2fb5f
 static void auth_pam_exit_ev(const void *event_data, void *user_data) {
9f2fb5f
-  int pam_error = 0;
9f2fb5f
+  int pam_error = 0, disable_id_switching;
9f2fb5f
 
9f2fb5f
   /* Sanity check.
9f2fb5f
    */
9f2fb5f
@@ -182,6 +182,16 @@
9f2fb5f
    * friends.
9f2fb5f
    */
9f2fb5f
   pr_signals_block();
9f2fb5f
+
9f2fb5f
+  /* If ID switching has been disabled, we need to re-enable it; some
9f2fb5f
+   * (spurious, IMHO) PAM errors can happen if pam_close_session(3) is called
9f2fb5f
+   * without proper root privs (Bug#3929).
9f2fb5f
+   */
9f2fb5f
+  disable_id_switching = session.disable_id_switching;
9f2fb5f
+  if (disable_id_switching) {
9f2fb5f
+    session.disable_id_switching = FALSE;
9f2fb5f
+  }
9f2fb5f
+
9f2fb5f
   PRIVS_ROOT
9f2fb5f
 
9f2fb5f
   /* Give up our credentials, close our session, and finally close out this
9f2fb5f
@@ -209,6 +219,12 @@
9f2fb5f
   pamh = NULL;
9f2fb5f
 #endif
9f2fb5f
 
9f2fb5f
+  PRIVS_RELINQUISH
9f2fb5f
+  pr_signals_unblock();
9f2fb5f
+
9f2fb5f
+  /* Restore any "ID switching disabled" setting. */
9f2fb5f
+  session.disable_id_switching = disable_id_switching;
9f2fb5f
+
9f2fb5f
   if (pam_user != NULL) {
9f2fb5f
     memset(pam_user, '\0', pam_user_len);
9f2fb5f
     free(pam_user);
9f2fb5f
@@ -216,8 +232,6 @@
9f2fb5f
     pam_user_len = 0;
9f2fb5f
   }
9f2fb5f
 
9f2fb5f
-  PRIVS_RELINQUISH
9f2fb5f
-  pr_signals_unblock();
9f2fb5f
 }
9f2fb5f
 
9f2fb5f
 MODRET pam_auth(cmd_rec *cmd) {