Subject: PAM credential cleanup

From: Fredrik Tolf <[email-masked]>
Date: Sun, 18 Apr 2004 15:32:53 +0200

Hi!

I'm using the UW IMAP imapd in my network on a GNU/Linux host, along
with Kerberos authentication, and plaintext passwords using PAM and
the pam_krb5 module.

The pam_krb5 module saves the user's decoded ticket in /tmp upon a
call to pam_setcred. However, imapd deliberately doesn't clean up
these tickets when the user logs out, which leaves /tmp on the mail
server filled up with users' tickets. To remedy this, I patched imapd
and ipop3d to fix this, and so I thought I'd send you a patch in case
you want it. The problem is that I don't really know much about the
portability issues in the UW IMAP suite, so the patch isn't really
complete because of that. I would fix it, but I don't know exactly
how.

Fredrik Tolf

--- ./src/c-client/env.h~	2001-11-20 22:56:35.000000000 +0100
+++ ./src/c-client/env.h	2004-04-18 15:11:48.000000000 +0200
@@ -30,6 +30,7 @@ long server_input_wait (long seconds);
 void server_init (char *server,char *service,char *sasl,
 		  void *clkint,void *kodint,void *hupint,void *trmint);
 long server_login (char *user,char *pass,char *authuser,int argc,char *argv[]);
+void server_logout (void);
 long authserver_login (char *user,char *authuser,int argc,char *argv[]);
 long anonymous_login (int argc,char *argv[]);
 char *mylocalhost (void);
--- ./src/imapd/imapd.c~	2003-07-08 05:21:50.000000000 +0200
+++ ./src/imapd/imapd.c	2004-04-18 15:05:19.068400584 +0200
@@ -1163,6 +1163,7 @@ int main (int argc,char *argv[])
   }
   syslog (LOG_INFO,"Logout user=%.80s host=%.80s",user ? user : "???",
 	  tcp_clienthost ());
+  server_logout();
   exit (0);			/* all done */
   return 0;			/* stupid compilers */
 }
--- ./src/ipopd/ipop3d.c~	2003-01-17 17:49:31.000000000 +0100
+++ ./src/ipopd/ipop3d.c	2004-04-18 15:05:06.451318672 +0200
@@ -463,6 +463,7 @@ int main (int argc,char *argv[])
 	       tcp_clienthost ());
   PSOUT (sayonara);		/* "now it's time to say sayonara..." */
   PFLUSH ();			/* make sure output finished */
+  server_logout();
   exit (0);			/* all done */
   return 0;			/* stupid compilers */
 }
--- ./src/osdep/unix/env_unix.c~	2003-07-15 03:30:00.000000000 +0200
+++ ./src/osdep/unix/env_unix.c	2004-04-18 15:06:34.414946168 +0200
@@ -561,6 +561,11 @@ long server_login (char *user,char *pwd,
   sleep (3);			/* slow down possible cracker */
   return NIL;
 }
+
+void server_logout (void)
+{
+  destroy_cred();
+}
 
 /* Authenticated server log in
  * Accepts: user name string
--- ./src/osdep/unix/env_unix.h~	2002-02-23 05:03:45.000000000 +0100
+++ ./src/osdep/unix/env_unix.h	2004-04-18 15:13:01.000000000 +0200
@@ -91,6 +91,7 @@ void grim_pid_reap_status (int pid,int k
 long safe_write (int fd,char *buf,long nbytes);
 void *arm_signal (int sig,void *action);
 struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[]);
+void destroy_cred (void);
 long loginpw (struct passwd *pw,int argc,char *argv[]);
 long pw_login (struct passwd *pw,char *auser,char *user,char *home,int argc,
 	       char *argv[]);
--- ./src/osdep/unix/ckp_pam.c~	2002-04-30 04:32:27.000000000 +0200
+++ ./src/osdep/unix/ckp_pam.c	2004-04-18 15:08:37.545227520 +0200
@@ -25,6 +25,8 @@ struct checkpw_cred {
   char *pass;			/* password */
 };
 
+static pam_handle_t *hdl = NULL;
+
 /* PAM conversation function
  * Accepts: number of messages
  *	    vector of messages
@@ -69,7 +71,6 @@ static int checkpw_conv (int num_msg,con
 
 struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
 {
-  pam_handle_t *hdl;
   struct pam_conv conv;
   struct checkpw_cred cred;
   conv.conv = &checkpw_conv;
@@ -100,15 +101,14 @@ struct passwd *checkpw (struct passwd *p
    */
   pam_open_session (hdl,NIL);	/* make sure account doesn't go inactive */
 #endif
-#if 0
-  /*
-   * This is also a problem.  Apparently doing this breaks access to DFS home
-   * space (hence the #if 0), but there is a report that not doing it causes
-   * the credentials to stick around long after the server process is gone.
-   */
-				/* clean up */
-  pam_setcred (hdl,PAM_DELETE_CRED);
-#endif
-  pam_end (hdl,PAM_SUCCESS);	/* return success */
   return pw;
 }
+
+void destroy_cred (void)
+{
+  if(hdl == NULL)
+    return;
+  pam_close_session (hdl,NIL);
+  pam_setcred (hdl,PAM_DELETE_CRED);
+  pam_end (hdl,PAM_SUCCESS);
+}

---

From: David Lee <[email-masked]>
Date: Mon, 19 Apr 2004 09:38:27 +0100 (BST)

> complete because of that. I would fix it, but I don't know exactly

Could I add my (e-)voice in support of addressing this?  Some months ago,
we, too, had this problem of "/tmp" filling up with literally millions of
orphaned krb5 credentials files.  (imap-2002e but I think the problem has
been around for longer: a copy of "imap-2001a" also has this same code.)

My own work around (fudge) was a simpler version than that of Fredrik
Tolf: I simply re-enabled the code that had been '#if 0'd out.  (I cannot
judge on which is "better": his may well be more thorough.)

==================== snip ===================
--- src/osdep/unix/ckp_pam.c.orig       Tue Apr 30 03:32:27 2002
+++ src/osdep/unix/ckp_pam.c    Sat Jan 17 12:26:31 2004
@@ -100,7 +100,7 @@
    */
   pam_open_session (hdl,NIL);  /* make sure account doesn't go inactive */
 #endif
-#if 0
+#if 1
   /*
    * This is also a problem.  Apparently doing this breaks access to DFS home
    * space (hence the #if 0), but there is a report that not doing it causes
==================== snip ===================

The code that should be removing the credentials has been '#if 0'd (i.e.
commented out) because of a problem in one particular operating
environment, DFS.  If that environment needs special treatment, then
wouldn't it be much cleaner make the "#if ..." target only that system or
feature.  (If c-client were using autoconf, I would volunteer to assist a
DFS person to code the relevant autoconf test, but we're not so I can't.)

Somehow, could this be addressed, please  Many thanks.

Sorry for not reporting it earlier: I considered it, but thought that I
would have been a lone voice, pleading a minority interest corner.  It is
at least reassuring to know that there are more of us.

Thanks again, Mark, for a great product!

-- 

:  David Lee                                I.T. Service          :
:  Systems Programmer                       Computer Centre       :
:                                           University of Durham  :
:  http://www.dur.ac.uk/t.d.lee/            South Road            :
:                                           Durham                :
:  Phone: +44 191 334 2752                  U.K.                  :