diff -urN ../courier-imap-2.2.2.20040207-unpatched/authlib/Makefile.in ./authlib/Makefile.in
--- ../courier-imap-2.2.2.20040207-unpatched/authlib/Makefile.in	2004-02-08 05:11:20.000000000 +0100
+++ ./authlib/Makefile.in	2004-03-03 17:46:10.000000000 +0100
@@ -400,7 +400,7 @@
 
 authvchkpw_SOURCES = mod.h modauthvchkpw.c
 authvchkpw_DEPENDENCIES = libauthmod.a libauth.a @MD5LIB@ @SHA1LIB@
-authvchkpw_LDADD = libauthmod.a libauth.a ../numlib/libnumlib.a @MD5LIB@ @SHA1LIB@ @VPOPMAILLIBS@ @LIBM@ $(CRYPTLIBS)
+authvchkpw_LDADD = libauthmod.a libauth.a ../numlib/libnumlib.a @HMACLIB@ @MD5LIB@ @SHA1LIB@ @VPOPMAILLIBS@ @LIBM@ $(CRYPTLIBS)
 
 authcram_SOURCES = mod.h modauthcram.c
 authcram_DEPENDENCIES = libauthmod.a libauth.a @HMACLIB@ ../userdb/libuserdb.a \
diff -urN ../courier-imap-2.2.2.20040207-unpatched/authlib/authvchkpw.c ./authlib/authvchkpw.c
--- ../courier-imap-2.2.2.20040207-unpatched/authlib/authvchkpw.c	2004-01-15 04:17:01.000000000 +0100
+++ ./authlib/authvchkpw.c	2004-03-03 19:46:15.000000000 +0100
@@ -70,8 +70,8 @@
         return (0);
 }
 
-char *auth_vchkpw(const char *service, const char *authtype, char *authdata,
-	int issession,
+static char *auth_vchkpw_login(const char *service, const char *authtype,
+	char *authdata, int issession,
 	void (*callback_func)(struct authinfo *, void *), void *callback_arg)
 {
 char *user, *pass;
@@ -147,6 +147,161 @@
 	return (ci.userret);
 }
 
+#if HAVE_HMACLIB
+
+#include	"../libhmac/hmac.h"
+#include	"cramlib.h"
+
+struct vchkpw_cram_callback_info {
+	struct hmac_hashinfo *h;
+	char *user;
+	char *challenge;
+	char *response;
+	char *userret;
+	int issession;
+	void (*callback_func)(struct authinfo *, void *);
+	void *callback_arg;
+	};
+
+static int callback_cram(struct authinfo *a, void *vp)
+{
+struct vchkpw_cram_callback_info *cci=(struct vchkpw_cram_callback_info *)vp;
+unsigned char *hashbuf;
+unsigned char *p;
+unsigned i;
+static const char hex[]="0123456789abcdef";
+int	rc;
+
+	if (!a->clearpasswd)
+		return (-1);
+
+	/*
+		hmac->hh_L*2 will be the size of the binary hash.
+
+		hmac->hh_L*4+1 will therefore be size of the binary hash,
+		as a hexadecimal string.
+	*/
+
+	if ((hashbuf=malloc(cci->h->hh_L*6+1)) == 0)
+		return (1);
+
+	hmac_hashkey(cci->h, a->clearpasswd, strlen(a->clearpasswd),
+		hashbuf, hashbuf+cci->h->hh_L);
+
+	p=hashbuf+cci->h->hh_L*2;
+
+	for (i=0; i<cci->h->hh_L*2; i++)
+	{
+	char	c;
+
+		c = hex[ (hashbuf[i] >> 4) & 0x0F];
+		*p++=c;
+
+		c = hex[ hashbuf[i] & 0x0F];
+		*p++=c;
+
+		*p=0;
+	}
+
+	rc=auth_verify_cram(cci->h, cci->challenge, cci->response,
+		(const char *)hashbuf+cci->h->hh_L*2);
+	free(hashbuf);
+
+	if (rc)	return (rc);
+
+	if ((cci->userret=strdup(a->address)) == 0)
+	{
+		perror("malloc");
+		return (1);
+	}
+
+	if (cci->callback_func)
+		(*cci->callback_func)(a, cci->callback_arg);
+	else
+	{
+		authsuccess(a->homedir, 0, a->sysuserid,
+			&a->sysgroupid,
+			a->address,
+			a->quota);
+
+		if (a->maildir && a->maildir[0])
+		{
+		static char *maildir=0;
+
+			if (maildir)	free(maildir);
+			maildir=malloc(sizeof("MAILDIR=")+strlen(a->maildir));
+			if (!maildir)
+			{
+				perror("malloc");
+				exit(1);
+			}
+			strcat(strcpy(maildir, "MAILDIR="), a->maildir);
+			putenv(maildir);
+		}
+		else
+		{
+			putenv("MAILDIR=");
+		}
+	}
+
+	return (0);
+}
+
+static char *auth_vchkpw_cram(const char *service,
+	const char *authtype, char *authdata, int issession,
+	void (*callback_func)(struct authinfo *, void *), void *callback_arg)
+{
+struct	vchkpw_cram_callback_info	cci;
+int	rc;
+
+	if (auth_get_cram(authtype, authdata,
+		&cci.h, &cci.user, &cci.challenge, &cci.response))
+		return (0);
+
+	cci.issession=issession;
+	cci.callback_func=callback_func;
+	cci.callback_arg=callback_arg;
+
+	rc=auth_vchkpw_pre(cci.user, service, &callback_cram, &cci);
+
+	if (rc < 0)
+	{
+		errno=EPERM;
+		return (0);
+	}
+	if (rc > 0)
+	{
+		errno=EACCES;
+		return (0);
+	}
+#ifdef HAVE_OPEN_SMTP_RELAY
+        if ( (strcmp("pop3", service)==0) || (strcmp("imap", service)==0) ) {
+               open_smtp_relay();
+        }
+#endif
+
+	return (cci.userret);
+}
+#endif
+
+char *auth_vchkpw(const char *service, const char *authtype, char *authdata,
+	int issession,
+	void (*callback_func)(struct authinfo *, void *), void *callback_arg)
+{
+	if (strcmp(authtype, AUTHTYPE_LOGIN) == 0)
+		return (auth_vchkpw_login(service, authtype, authdata,
+			issession, callback_func, callback_arg));
+
+#if HAVE_HMACLIB
+	return (auth_vchkpw_cram(service, authtype, authdata, issession,
+			callback_func, callback_arg));
+#else
+	errno=EPERM;
+	return (0);
+#endif
+
+}
+
 static void authvchkpwclose()
 {
 }
diff -urN ../courier-imap-2.2.2.20040207-unpatched/authlib/preauthvchkpw.c ./authlib/preauthvchkpw.c
--- ../courier-imap-2.2.2.20040207-unpatched/authlib/preauthvchkpw.c	2004-01-15 04:17:01.000000000 +0100
+++ ./authlib/preauthvchkpw.c	2004-03-03 19:39:05.000000000 +0100
@@ -156,7 +156,9 @@
 	auth.homedir		= vpw->pw_dir;
 	auth.address		= userid;
 	auth.fullname		= vpw->pw_gecos;
+        auth.quota              = vpw->pw_shell;
 	auth.passwd		= vpw->pw_passwd;
+        auth.clearpasswd        = vpw->pw_clear_passwd;
 
 	return ((*callback)(&auth, arg));
 }
