diff -ruN postfix-2.1.5/postfix-2.1.5-dovecot-auth.patch postfix-2.1.5-dovecot/postfix-2.1.5-dovecot-auth.patch
--- postfix-2.1.5/postfix-2.1.5-dovecot-auth.patch	1970-01-01 02:00:00.000000000 +0200
+++ postfix-2.1.5-dovecot/postfix-2.1.5-dovecot-auth.patch	2005-01-22 22:01:57.000000000 +0200
@@ -0,0 +1,1039 @@
+diff -ruN postfix-2.1.5/src/global/mail_params.h postfix-2.1.5-dovecot/src/global/mail_params.h
+--- postfix-2.1.5/src/global/mail_params.h	2004-04-21 21:56:04.000000000 +0300
++++ postfix-2.1.5-dovecot/src/global/mail_params.h	2005-01-22 22:00:58.000000000 +0200
+@@ -908,6 +908,10 @@
+ #define DEF_SMTPD_SASL_ENABLE	0
+ extern bool var_smtpd_sasl_enable;
+ 
++#define VAR_SMTPD_SASL_SOCKET	"smtpd_sasl_auth_socket"
++#define DEF_SMTPD_SASL_SOCKET	""
++extern char *var_smtpd_sasl_socket;
++
+ #define VAR_SMTPD_SASL_OPTS	"smtpd_sasl_security_options"
+ #define DEF_SMTPD_SASL_OPTS	"noanonymous"
+ extern char *var_smtpd_sasl_opts;
+diff -ruN postfix-2.1.5/src/lmtp/lmtp.c postfix-2.1.5-dovecot/src/lmtp/lmtp.c
+--- postfix-2.1.5/src/lmtp/lmtp.c	2004-06-20 02:06:39.000000000 +0300
++++ postfix-2.1.5-dovecot/src/lmtp/lmtp.c	2005-01-22 22:00:58.000000000 +0200
+@@ -354,7 +354,7 @@
+ 	    lmtp_quit(state);
+ 	    lmtp_chat_reset(state);
+ 	    state->session = lmtp_session_free(state->session);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    if (var_lmtp_sasl_enable)
+ 		lmtp_sasl_cleanup(state);
+ #endif
+@@ -367,7 +367,7 @@
+ 	else if (lmtp_rset(state) != 0) {
+ 	    lmtp_chat_reset(state);
+ 	    state->session = lmtp_session_free(state->session);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    if (var_lmtp_sasl_enable)
+ 		lmtp_sasl_cleanup(state);
+ #endif
+@@ -405,7 +405,7 @@
+ 	 */
+ 	else if (lmtp_lhlo(state) != 0) {
+ 	    state->session = lmtp_session_free(state->session);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    if (var_lmtp_sasl_enable)
+ 		lmtp_sasl_cleanup(state);
+ #endif
+@@ -501,7 +501,7 @@
+ {
+     debug_peer_init();
+     if (var_lmtp_sasl_enable)
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	lmtp_sasl_initialize();
+ #else
+ 	msg_warn("%s is true, but SASL support is not compiled in",
+@@ -526,7 +526,7 @@
+ 	    msg_info("cleanup: just closed down session");
+     }
+     lmtp_state_free(state);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     if (var_lmtp_sasl_enable)
+ 	sasl_done();
+ #endif
+diff -ruN postfix-2.1.5/src/lmtp/lmtp.h postfix-2.1.5-dovecot/src/lmtp/lmtp.h
+--- postfix-2.1.5/src/lmtp/lmtp.h	2003-12-16 03:21:54.000000000 +0200
++++ postfix-2.1.5-dovecot/src/lmtp/lmtp.h	2005-01-22 22:00:58.000000000 +0200
+@@ -11,7 +11,7 @@
+  /*
+   * SASL library.
+   */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ #include <sasl.h>
+ #include <saslutil.h>
+ #endif
+@@ -43,7 +43,7 @@
+     int     features;			/* server features */
+     ARGV   *history;			/* transaction log */
+     int     error_mask;			/* error classes */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     char   *sasl_mechanism_list;	/* server mechanism list */
+     char   *sasl_username;		/* client username */
+     char   *sasl_passwd;		/* client password */
+diff -ruN postfix-2.1.5/src/lmtp/lmtp_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c
+--- postfix-2.1.5/src/lmtp/lmtp_proto.c	2004-04-14 23:02:37.000000000 +0300
++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c	2005-01-22 22:00:58.000000000 +0200
+@@ -259,7 +259,7 @@
+ 						 NAME_CODE_FLAG_NONE, word);
+ 	    else if (strcasecmp(word, "SIZE") == 0)
+ 		state->features |= LMTP_FEATURE_SIZE;
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
+ 		lmtp_sasl_helo_auth(state, words);
+ #endif
+@@ -293,7 +293,7 @@
+     } else
+ 	state->sndbufsize = 0;
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH))
+ 	return (lmtp_sasl_helo_login(state));
+ #endif
+@@ -444,7 +444,7 @@
+ 	    /*
+ 	     * We authenticate the local MTA only, but not the sender.
+ 	     */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    if (var_lmtp_sasl_enable
+ 		&& (state->features & LMTP_FEATURE_AUTH)
+ 		&& state->sasl_passwd)
+diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c
+--- postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c	2003-09-12 21:46:58.000000000 +0300
++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c	2005-01-22 22:00:58.000000000 +0200
+@@ -108,7 +108,7 @@
+ #include "lmtp.h"
+ #include "lmtp_sasl.h"
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 
+  /*
+   * Authentication security options.
+diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c
+--- postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c	2003-07-07 21:01:17.000000000 +0300
++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c	2005-01-22 22:00:58.000000000 +0200
+@@ -71,7 +71,7 @@
+ #include "lmtp.h"
+ #include "lmtp_sasl.h"
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 
+ /* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */
+ 
+diff -ruN postfix-2.1.5/src/lmtp/lmtp_state.c postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c
+--- postfix-2.1.5/src/lmtp/lmtp_state.c	2003-09-12 21:42:55.000000000 +0300
++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c	2005-01-22 22:00:58.000000000 +0200
+@@ -76,7 +76,7 @@
+     state->features = 0;
+     state->history = 0;
+     state->error_mask = 0;
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     lmtp_sasl_connect(state);
+ #endif
+     state->sndbufsize = 0;
+@@ -91,7 +91,7 @@
+     vstring_free(state->buffer);
+     vstring_free(state->scratch);
+     vstring_free(state->scratch2);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     lmtp_sasl_cleanup(state);
+ #endif
+     myfree((char *) state);
+diff -ruN postfix-2.1.5/src/smtp/smtp.c postfix-2.1.5-dovecot/src/smtp/smtp.c
+--- postfix-2.1.5/src/smtp/smtp.c	2004-04-14 17:25:42.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtp/smtp.c	2005-01-22 22:00:58.000000000 +0200
+@@ -447,7 +447,7 @@
+      * SASL initialization.
+      */
+     if (var_smtp_sasl_enable)
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	smtp_sasl_initialize();
+ #else
+ 	msg_warn("%s is true, but SASL support is not compiled in",
+@@ -476,7 +476,7 @@
+ 
+ static void pre_exit(void)
+ {
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     if (var_smtp_sasl_enable)
+ 	sasl_done();
+ #endif
+diff -ruN postfix-2.1.5/src/smtp/smtp.h postfix-2.1.5-dovecot/src/smtp/smtp.h
+--- postfix-2.1.5/src/smtp/smtp.h	2003-12-26 21:17:29.000000000 +0200
++++ postfix-2.1.5-dovecot/src/smtp/smtp.h	2005-01-22 22:00:58.000000000 +0200
+@@ -11,7 +11,7 @@
+  /*
+   * SASL library.
+   */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ #include <sasl.h>
+ #include <saslutil.h>
+ #endif
+@@ -43,7 +43,7 @@
+     int     features;			/* server features */
+     ARGV   *history;			/* transaction log */
+     int     error_mask;			/* error classes */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     char   *sasl_mechanism_list;	/* server mechanism list */
+     char   *sasl_username;		/* client username */
+     char   *sasl_passwd;		/* client password */
+diff -ruN postfix-2.1.5/src/smtp/smtp_connect.c postfix-2.1.5-dovecot/src/smtp/smtp_connect.c
+--- postfix-2.1.5/src/smtp/smtp_connect.c	2004-06-19 19:23:33.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtp/smtp_connect.c	2005-01-22 22:00:58.000000000 +0200
+@@ -368,7 +368,7 @@
+ 		/* XXX smtp_xfer() may abort in the middle of DATA. */
+ 		smtp_session_free(state->session);
+ 		state->session = 0;
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 		smtp_sasl_cleanup(state);
+ #endif
+ 		debug_peer_restore();
+diff -ruN postfix-2.1.5/src/smtp/smtp_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_proto.c
+--- postfix-2.1.5/src/smtp/smtp_proto.c	2004-04-14 23:02:20.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtp/smtp_proto.c	2005-01-22 22:00:58.000000000 +0200
+@@ -288,7 +288,7 @@
+ 			state->size_limit = off_cvt_string(word);
+ 		}
+ 	    }
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
+ 		smtp_sasl_helo_auth(state, words);
+ #endif
+@@ -307,7 +307,7 @@
+ 	msg_info("server features: 0x%x size %.0f",
+ 		 state->features, (double) state->size_limit);
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH))
+ 	return (smtp_sasl_helo_login(state));
+ #endif
+@@ -610,7 +610,7 @@
+ 	    /*
+ 	     * We authenticate the local MTA only, but not the sender.
+ 	     */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 	    if (var_smtp_sasl_enable
+ 		&& (state->features & SMTP_FEATURE_AUTH)
+ 		&& state->sasl_passwd)
+diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_glue.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c
+--- postfix-2.1.5/src/smtp/smtp_sasl_glue.c	2003-07-14 21:03:20.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c	2005-01-22 22:00:58.000000000 +0200
+@@ -108,7 +108,7 @@
+ #include "smtp.h"
+ #include "smtp_sasl.h"
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 
+  /*
+   * Authentication security options.
+diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c
+--- postfix-2.1.5/src/smtp/smtp_sasl_proto.c	2003-07-07 21:01:32.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c	2005-01-22 22:00:58.000000000 +0200
+@@ -71,7 +71,7 @@
+ #include "smtp.h"
+ #include "smtp_sasl.h"
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+ 
+ /* smtp_sasl_helo_auth - handle AUTH option in EHLO reply */
+ 
+diff -ruN postfix-2.1.5/src/smtp/smtp_state.c postfix-2.1.5-dovecot/src/smtp/smtp_state.c
+--- postfix-2.1.5/src/smtp/smtp_state.c	2003-12-21 04:10:50.000000000 +0200
++++ postfix-2.1.5-dovecot/src/smtp/smtp_state.c	2005-01-22 22:00:58.000000000 +0200
+@@ -66,7 +66,7 @@
+     state->features = 0;
+     state->history = 0;
+     state->error_mask = 0;
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     smtp_sasl_connect(state);
+ #endif
+     state->size_limit = 0;
+@@ -82,7 +82,7 @@
+     vstring_free(state->buffer);
+     vstring_free(state->scratch);
+     vstring_free(state->scratch2);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_CLIENT_AUTH
+     smtp_sasl_cleanup(state);
+ #endif
+     if (state->mime_state)
+diff -ruN postfix-2.1.5/src/smtpd/Makefile.in postfix-2.1.5-dovecot/src/smtpd/Makefile.in
+--- postfix-2.1.5/src/smtpd/Makefile.in	2004-04-22 22:37:39.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/Makefile.in	2005-01-22 22:00:58.000000000 +0200
+@@ -1,10 +1,10 @@
+ SHELL	= /bin/sh
+ SRCS	= smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
+-	smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
+-	smtpd_xforward.c
++	smtpd_peer.c smtpd_sasl.c smtpd_sasl_proto.c smtpd_sasl_glue.c \
++	smtpd_proxy.c smtpd_xforward.c
+ OBJS	= smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
+-	smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
+-	smtpd_xforward.o
++	smtpd_peer.o smtpd_sasl.o smtpd_sasl_proto.o smtpd_sasl_glue.o \
++	smtpd_proxy.o smtpd_xforward.o
+ HDRS	= smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
+ 	smtpd_sasl_glue.h smtpd_proxy.h
+ TESTSRC	= smtpd_token_test.c
+@@ -272,6 +272,26 @@
+ smtpd_proxy.o: ../../include/argv.h
+ smtpd_proxy.o: ../../include/mail_stream.h
+ smtpd_proxy.o: smtpd_proxy.h
++smtpd_sasl.o: smtpd_sasl.c
++smtpd_sasl.o: ../../include/sys_defs.h
++smtpd_sasl.o: ../../include/base64_code.h
++smtpd_sasl.o: ../../include/vstring.h
++smtpd_sasl.o: ../../include/vbuf.h
++smtpd_sasl.o: ../../include/connect.h
++smtpd_sasl.o: ../../include/iostuff.h
++smtpd_sasl.o: ../../include/msg.h
++smtpd_sasl.o: ../../include/mymalloc.h
++smtpd_sasl.o: ../../include/split_at.h
++smtpd_sasl.o: ../../include/stringops.h
++smtpd_sasl.o: ../../include/vstring_vstream.h
++smtpd_sasl.o: ../../include/vstream.h
++smtpd_sasl.o: ../../include/mail_params.h
++smtpd_sasl.o: ../../include/smtp_stream.h
++smtpd_sasl.o: smtpd.h
++smtpd_sasl.o: ../../include/argv.h
++smtpd_sasl.o: ../../include/mail_stream.h
++smtpd_sasl.o: smtpd_sasl_glue.h
++smtpd_sasl.o: smtpd_chat.h
+ smtpd_sasl_glue.o: smtpd_sasl_glue.c
+ smtpd_sasl_glue.o: ../../include/sys_defs.h
+ smtpd_sasl_glue.o: ../../include/msg.h
+diff -ruN postfix-2.1.5/src/smtpd/smtpd.c postfix-2.1.5-dovecot/src/smtpd/smtpd.c
+--- postfix-2.1.5/src/smtpd/smtpd.c	2004-08-14 01:28:41.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd.c	2005-01-22 22:00:58.000000000 +0200
+@@ -717,6 +717,7 @@
+ int     var_smtpd_junk_cmd_limit;
+ int     var_smtpd_rcpt_overlim;
+ bool    var_smtpd_sasl_enable;
++char   *var_smtpd_sasl_socket;
+ char   *var_smtpd_sasl_opts;
+ char   *var_smtpd_sasl_appname;
+ char   *var_smtpd_sasl_realm;
+@@ -816,7 +817,7 @@
+   */
+ #define NEUTER_CHARACTERS " <>()\\\";:@"
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 
+  /*
+   * SASL exceptions.
+@@ -943,7 +944,7 @@
+     if (var_disable_vrfy_cmd == 0)
+ 	smtpd_chat_reply(state, "250-VRFY");
+     smtpd_chat_reply(state, "250-ETRN");
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+     if (var_smtpd_sasl_enable && !sasl_client_exception(state)) {
+ 	smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
+ 	if (var_broken_auth_clients)
+@@ -1246,7 +1247,7 @@
+ 		state->error_mask |= MAIL_ERROR_POLICY;
+ 		return (-1);
+ 	    }
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 	} else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) {
+ 	    if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
+ 		smtpd_chat_reply(state, "%s", err);
+@@ -1354,7 +1355,7 @@
+ 	state->saved_redirect = 0;
+     }
+     state->saved_flags = 0;
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+     if (var_smtpd_sasl_enable)
+ 	smtpd_sasl_mail_reset(state);
+ #endif
+@@ -1455,7 +1456,7 @@
+ 	/*
+ 	 * Log the queue ID with the message origin.
+ 	 */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 	if (var_smtpd_sasl_enable)
+ 	    smtpd_sasl_mail_log(state);
+ 	else
+@@ -2328,7 +2329,7 @@
+     "HELO", helo_cmd, SMTPD_CMD_FLAG_LIMIT,
+     "EHLO", ehlo_cmd, SMTPD_CMD_FLAG_LIMIT,
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+     "AUTH", smtpd_sasl_auth_cmd, 0,
+ #endif
+ 
+@@ -2531,7 +2532,7 @@
+      * dialog.
+      */
+     helo_reset(state);
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+     if (var_smtpd_sasl_enable)
+ 	smtpd_sasl_auth_reset(state);
+ #endif
+@@ -2628,7 +2629,7 @@
+     debug_peer_init();
+ 
+     if (var_smtpd_sasl_enable)
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 	smtpd_sasl_initialize();
+ 
+     if (*var_smtpd_sasl_exceptions_networks)
+@@ -2757,6 +2758,7 @@
+ 	VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0,
+ 	VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
+ 	VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
++	VAR_SMTPD_SASL_SOCKET, DEF_SMTPD_SASL_SOCKET, &var_smtpd_sasl_socket, 0, 0,
+ 	VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
+ 	VAR_SMTPD_SASL_APPNAME, DEF_SMTPD_SASL_APPNAME, &var_smtpd_sasl_appname, 1, 0,
+ 	VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0,
+diff -ruN postfix-2.1.5/src/smtpd/smtpd.h postfix-2.1.5-dovecot/src/smtpd/smtpd.h
+--- postfix-2.1.5/src/smtpd/smtpd.h	2004-04-21 21:23:33.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd.h	2005-01-22 22:00:58.000000000 +0200
+@@ -16,7 +16,7 @@
+  /*
+   * SASL library.
+   */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_CYRUS_SASL
+ #include <sasl.h>
+ #include <saslutil.h>
+ #endif
+@@ -90,7 +90,7 @@
+     /*
+      * SASL specific.
+      */
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ #if SASL_VERSION_MAJOR >= 2
+     const char *sasl_mechanism_list;
+ #else
+@@ -99,10 +99,15 @@
+     char   *sasl_method;
+     char   *sasl_username;
+     char   *sasl_sender;
++    unsigned int sasl_id;
++    VSTRING *sasl_line;
++
++#ifdef USE_CYRUS_SASL
+     sasl_conn_t *sasl_conn;
+     VSTRING *sasl_encoded;
+     VSTRING *sasl_decoded;
+ #endif
++#endif
+ 
+     /*
+      * Specific to smtpd access checks.
+diff -ruN postfix-2.1.5/src/smtpd/smtpd_check.c postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c
+--- postfix-2.1.5/src/smtpd/smtpd_check.c	2004-08-02 00:08:32.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c	2005-01-22 22:00:58.000000000 +0200
+@@ -2762,7 +2762,7 @@
+     return (result);
+ }
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 
+ /* reject_auth_sender_login_mismatch - logged in client must own sender address */
+ 
+@@ -2868,7 +2868,7 @@
+ 			  STR(state->instance),
+ 			  ATTR_TYPE_LONG, MAIL_ATTR_SIZE,
+ 			  (unsigned long) state->msg_size,
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 			  ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD,
+ 			  var_smtpd_sasl_enable && state->sasl_method ?
+ 			  state->sasl_method : "",
+@@ -3162,7 +3162,7 @@
+ 		status = reject_non_fqdn_address(state, state->sender,
+ 					  state->sender, SMTPD_NAME_SENDER);
+ 	} else if (strcasecmp(name, REJECT_AUTH_SENDER_LOGIN_MISMATCH) == 0) {
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 	    if (var_smtpd_sasl_enable) {
+ 		if (state->sender && *state->sender)
+ 		    status = reject_auth_sender_login_mismatch(state, state->sender);
+@@ -3170,7 +3170,7 @@
+ #endif
+ 		msg_warn("restriction `%s' ignored: no SASL support", name);
+ 	} else if (strcasecmp(name, REJECT_UNAUTH_SENDER_LOGIN_MISMATCH) == 0) {
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 	    if (var_smtpd_sasl_enable) {
+ 		if (state->sender && *state->sender)
+ 		    status = reject_unauth_sender_login_mismatch(state, state->sender);
+@@ -3232,7 +3232,7 @@
+ 			 cpp[1], CHECK_RELAY_DOMAINS);
+ 	} else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) {
+ 	    if (var_smtpd_sasl_enable)
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 		status = permit_sasl_auth(state,
+ 					  SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO);
+ #else
+@@ -4209,7 +4209,7 @@
+ 
+ bool    var_smtpd_sasl_enable = 0;
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 
+ /* smtpd_sasl_connect - stub */
+ 
+diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c
+--- postfix-2.1.5/src/smtpd/smtpd_sasl.c	1970-01-01 02:00:00.000000000 +0200
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c	2005-01-22 22:01:20.000000000 +0200
+@@ -0,0 +1,409 @@
++/*++
++/* NAME
++/*	smtpd_sasl_glue 3
++/* SUMMARY
++/*	Postfix SMTP server, SASL support interface
++/* SYNOPSIS
++/*	#include "smtpd_sasl_glue.h"
++/*
++/*	void	smtpd_sasl_initialize()
++/*
++/*	void	smtpd_sasl_connect(state, sasl_opts_name, sasl_opts_val)
++/*	SMTPD_STATE *state;
++/*
++/*	char	*smtpd_sasl_authenticate(state, sasl_method, init_response)
++/*	SMTPD_STATE *state;
++/*	const char *sasl_method;
++/*	const char *init_response;
++/*
++/*	void	smtpd_sasl_logout(state)
++/*	SMTPD_STATE *state;
++/*
++/*	void	smtpd_sasl_disconnect(state)
++/*	SMTPD_STATE *state;
++/* DESCRIPTION
++/*	This module encapsulates most of the detail specific to SASL
++/*	authentication.
++/*
++/*	smtpd_sasl_initialize() initializes the SASL library. This
++/*	routine should be called once at process start-up. It may
++/*	need access to the file system for run-time loading of
++/*	plug-in modules. There is no corresponding cleanup routine.
++/*
++/*	smtpd_sasl_connect() performs per-connection initialization.
++/*	This routine should be called once at the start of every
++/*	connection. The sasl_opts_name and sasl_opts_val parameters
++/*	are the postfix configuration parameters setting the security
++/*	policy of the SASL authentication.
++/*
++/*	smtpd_sasl_authenticate() implements the authentication dialog.
++/*	The result is a null pointer in case of success, an SMTP reply
++/*	in case of failure. smtpd_sasl_authenticate() updates the
++/*	following state structure members:
++/* .IP sasl_method
++/*	The authentication method that was successfully applied.
++/*	This member is a null pointer in the absence of successful
++/*	authentication.
++/* .IP sasl_username
++/*	The username that was successfully authenticated.
++/*	This member is a null pointer in the absence of successful
++/*	authentication.
++/* .PP
++/*	smtpd_sasl_logout() cleans up after smtpd_sasl_authenticate().
++/*	This routine exists for the sake of symmetry.
++/*
++/*	smtpd_sasl_disconnect() performs per-connection cleanup.
++/*	This routine should be called at the end of every connection.
++/*
++/*	Arguments:
++/* .IP state
++/*	SMTP session context.
++/* .IP sasl_method
++/*	A SASL mechanism name
++/* .IP init_reply
++/*	An optional initial client response.
++/* DIAGNOSTICS
++/*	All errors are fatal.
++/* LICENSE
++/* .ad
++/* .fi
++/*	The Secure Mailer license must be distributed with this software.
++/* AUTHOR(S)
++/*	Initial implementation by:
++/*	Till Franke
++/*	SuSE Rhein/Main AG
++/*	65760 Eschborn, Germany
++/*
++/*	Adopted by:
++/*	Wietse Venema
++/*	IBM T.J. Watson Research
++/*	P.O. Box 704
++/*	Yorktown Heights, NY 10598, USA
++/*--*/
++
++/* System library. */
++
++#include <sys_defs.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++/* Utility library. */
++
++#include <base64_code.h>
++#include <connect.h>
++#include <msg.h>
++#include <mymalloc.h>
++#include <split_at.h>
++#include <stringops.h>
++#include <vstring_vstream.h>
++
++/* Global library. */
++
++#include <mail_params.h>
++#include <smtp_stream.h>
++
++/* Application-specific. */
++
++#include "smtpd.h"
++#include "smtpd_sasl_glue.h"
++#include "smtpd_chat.h"
++
++#ifdef USE_SASL_SERVER_AUTH
++
++/* Major version changes are not backwards compatible,
++   minor version numbers can be ignored. */
++#define AUTH_PROTOCOL_MAJOR_VERSION 1
++#define AUTH_PROTOCOL_MINOR_VERSION 0
++
++static unsigned int sasl_id = 0;
++static VSTREAM *sasl_stream = 0;
++static char *sasl_mechanism_list = 0;
++
++/* smtpd_sasl_initialize - per-process initialization */
++
++void    smtpd_sasl_initialize(void)
++{
++#ifdef USE_CYRUS_SASL
++    if (*var_smtpd_sasl_socket == '\0')
++        smtpd_cyrus_sasl_initialize();
++#endif
++}
++
++static void smtpd_sasl_connect_server(void)
++{
++    char   *myname = "smtpd_sasl_connect_server";
++    VSTRING *line_str, *mechanisms_str;
++    char   *line, *cmd, *mech_name;
++    unsigned int major_version, minor_version;
++    int fd;
++
++    if ((fd = unix_connect(var_smtpd_sasl_socket, BLOCKING, 0)) < 0)
++        msg_fatal("SASL: connect failed: %m");
++
++    sasl_stream = vstream_fdopen(fd, O_RDWR);
++    vstream_control(sasl_stream, VSTREAM_CTL_PATH,
++                    var_smtpd_sasl_socket, VSTREAM_CTL_END);
++
++    vstream_fprintf(sasl_stream,
++                    "VERSION\t%u\t%u\n"
++                    "SERVICE\tsmtp\n"
++                    "CPID\t%u\n",
++                    AUTH_PROTOCOL_MAJOR_VERSION,
++                    AUTH_PROTOCOL_MINOR_VERSION,
++                    (unsigned int)getpid());
++    if (vstream_fflush(sasl_stream) == VSTREAM_EOF)
++        msg_fatal("SASL: couldn't send handshake: %m");
++
++    line_str = vstring_alloc(256);
++    mechanisms_str = vstring_alloc(128);
++    while (vstring_get_nonl(line_str, sasl_stream) != VSTREAM_EOF) {
++        line = vstring_str(line_str);
++
++        if (msg_verbose)
++	    msg_info("%s: auth reply: %s", myname, line);
++
++        cmd = line;
++        line = split_at(line, '\t');
++
++        if (strcmp(cmd, "VERSION") == 0) {
++            if (sscanf(line, "%u\t%u", &major_version, &minor_version) != 2)
++                msg_fatal("SASL: Protocol version error");
++
++            if (major_version != AUTH_PROTOCOL_MAJOR_VERSION) {
++                /* Major version is different from ours. */
++                msg_fatal("SASL: Protocol version mismatch (%d vs. %d)",
++                          major_version, AUTH_PROTOCOL_MAJOR_VERSION);
++            }
++	} else if (strcmp(cmd, "MECH") == 0 && line != NULL) {
++            mech_name = line;
++            line = split_at(line, '\t');
++
++            if (VSTRING_LEN(mechanisms_str) > 0)
++                VSTRING_ADDCH(mechanisms_str, ' ');
++            vstring_strcat(mechanisms_str, mech_name);
++        } else if (strcmp(cmd, "DONE") == 0) {
++            /* Handshake finished. */
++            break;
++        } else {
++            /* ignore any unknown commands */
++        }
++    }
++    vstring_free(line_str);
++
++    if (sasl_mechanism_list)
++        myfree(sasl_mechanism_list);
++    sasl_mechanism_list =
++        translit(vstring_export(mechanisms_str), "\t", " ");
++}
++
++static void smtpd_sasl_disconnect_server(void)
++{
++    (void) vstream_fclose(sasl_stream);
++    sasl_stream = 0;
++
++    myfree(sasl_mechanism_list);
++    sasl_mechanism_list = 0;
++}
++
++/* smtpd_sasl_connect - per-connection initialization */
++
++void    smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
++                           const char *sasl_opts_val)
++{
++#ifdef USE_CYRUS_SASL
++    if (*var_smtpd_sasl_socket == '\0') {
++        smtpd_cyrus_sasl_connect(state, sasl_opts_name, sasl_opts_val);
++        return;
++    }
++#endif
++
++    state->sasl_username = 0;
++    state->sasl_method = 0;
++    state->sasl_sender = 0;
++    state->sasl_line = vstring_alloc(512);
++
++    if (!sasl_stream)
++        smtpd_sasl_connect_server();
++    state->sasl_mechanism_list = mystrdup(sasl_mechanism_list);
++}
++
++/* smtpd_sasl_disconnect - per-connection cleanup */
++
++void    smtpd_sasl_disconnect(SMTPD_STATE *state)
++{
++#ifdef USE_CYRUS_SASL
++    if (*var_smtpd_sasl_socket == '\0') {
++        smtpd_cyrus_sasl_disconnect(state);
++        return;
++    }
++#endif
++
++    vstring_free(state->sasl_line);
++    state->sasl_line = 0;
++    myfree(state->sasl_mechanism_list);
++    state->sasl_mechanism_list = 0;
++}
++
++static int smtpd_sasl_parse_reply(SMTPD_STATE *state, char **line)
++{
++    char *id;
++
++    if (*line == NULL)
++        msg_fatal("SASL: Protocol error");
++
++    id = *line;
++    *line = split_at(*line, '\t');
++
++    if (strtoul(id, NULL, 0) != state->sasl_id) {
++        /* reply to another request, shouldn't really happen.. */
++        return 0;
++    }
++
++    return 1;
++}
++
++
++/* smtpd_sasl_authenticate - per-session authentication */
++
++char   *smtpd_sasl_authenticate(SMTPD_STATE *state,
++                                const char *sasl_method,
++                                const char *init_response)
++{
++    char   *myname = "smtpd_sasl_authenticate";
++    char   *line, *cmd;
++    int    i, success;
++
++#ifdef USE_CYRUS_SASL
++    if (*var_smtpd_sasl_socket == '\0')
++        return smtpd_cyrus_sasl_authenticate(state, sasl_method, init_response);
++#endif
++
++#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
++
++    if (msg_verbose)
++	msg_info("%s: sasl_method %s%s%s", myname, sasl_method,
++		 IFELSE(init_response, ", init_response ", ""),
++		 IFELSE(init_response, init_response, ""));
++
++    for (i = 0; i < 2; i++) {
++        state->sasl_id = ++sasl_id;
++        vstream_fprintf(sasl_stream, "AUTH\t%u\t%s",
++                        state->sasl_id, sasl_method);
++        if (init_response)
++            vstream_fprintf(sasl_stream, "\tresp=%s", init_response);
++        VSTREAM_PUTC('\n', sasl_stream);
++
++        if (vstream_fflush(sasl_stream) != VSTREAM_EOF)
++            break;
++
++        if (i == 1)
++            return ("454 Temporary authentication failure");
++
++        /*
++         * Reconnect.
++         */
++        smtpd_sasl_disconnect_server();
++        smtpd_sasl_connect_server();
++    }
++
++    /*
++     * Sanity check.
++     */
++    if (state->sasl_username || state->sasl_method)
++	msg_panic("%s: already authenticated", myname);
++
++    success = 0;
++    while (vstring_get_nonl(state->sasl_line, sasl_stream) != VSTREAM_EOF) {
++        line = vstring_str(state->sasl_line);
++
++	if (msg_verbose)
++	    msg_info("%s: auth reply: %s", myname, line);
++
++        cmd = line;
++        line = split_at(line, '\t');
++
++        if (strcmp(cmd, "OK") == 0) {
++            if (!smtpd_sasl_parse_reply(state, &line))
++                continue;
++
++            /* authentication successful */
++            success = 1;
++            break;
++        } else if (strcmp(cmd, "CONT") == 0) {
++            if (!smtpd_sasl_parse_reply(state, &line))
++                continue;
++
++            /*
++             * Receive the client response. "*" means that the client gives up.
++             * XXX For now we ignore the fact that excessively long responses
++             * will be truncated. To handle such responses, we need to change
++             * smtpd_chat_query() so that it returns an error indication.
++             */
++            smtpd_chat_reply(state, "334 %s", line);
++
++            smtpd_chat_query(state);
++            if (strcmp(vstring_str(state->buffer), "*") == 0)
++                return ("501 Authentication aborted");
++
++            vstream_fprintf(sasl_stream, "CONT\t%u\t", state->sasl_id);
++            vstream_fputs(vstring_str(state->buffer), sasl_stream);
++            VSTREAM_PUTC('\n', sasl_stream);
++
++            if (vstream_fflush(sasl_stream) == VSTREAM_EOF)
++                break;
++        } else if (strcmp(cmd, "FAIL") == 0) {
++            if (!smtpd_sasl_parse_reply(state, &line))
++                continue;
++
++            return ("535 Error: authentication failed");
++	} else {
++	    /* ignore */
++	}
++    }
++
++    if (!success) {
++        /* connection lost to auth server */
++        return ("454 Temporary authentication failure");
++    }
++
++    while (line != NULL && strncmp(line, "user=", 5) != 0)
++        line = split_at(line, '\t');
++
++    if (line == NULL)
++	state->sasl_username = mystrdup("?");
++    else {
++	line += 5;
++	(void) split_at(line, '\t');
++	state->sasl_username = mystrdup(line);
++    }
++    printable(state->sasl_username, '?');
++
++    state->sasl_method = mystrdup(sasl_method);
++    printable(state->sasl_method, '?');
++
++    return (0);
++}
++
++/* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */
++
++void    smtpd_sasl_logout(SMTPD_STATE *state)
++{
++#ifdef USE_CYRUS_SASL
++    if (*var_smtpd_sasl_socket == '\0') {
++        smtpd_cyrus_sasl_logout(state);
++        return;
++    }
++#endif
++
++    if (state->sasl_username) {
++	myfree(state->sasl_username);
++	state->sasl_username = 0;
++    }
++    if (state->sasl_method) {
++	myfree(state->sasl_method);
++	state->sasl_method = 0;
++    }
++}
++
++#endif
+diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c
+--- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c	2004-02-01 20:44:55.000000000 +0200
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c	2005-01-22 22:00:58.000000000 +0200
+@@ -105,7 +105,7 @@
+ #include "smtpd_sasl_glue.h"
+ #include "smtpd_chat.h"
+ 
+-#ifdef USE_SASL_AUTH
++#if defined(USE_SASL_SERVER_AUTH) && defined(USE_CYRUS_SASL)
+ 
+ /*
+  * Silly little macros.
+@@ -205,7 +205,7 @@
+ 
+ /* smtpd_sasl_initialize - per-process initialization */
+ 
+-void    smtpd_sasl_initialize(void)
++void    smtpd_cyrus_sasl_initialize(void)
+ {
+ 
+     /*
+@@ -221,7 +221,7 @@
+ 
+ /* smtpd_sasl_connect - per-connection initialization */
+ 
+-void    smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
++void    smtpd_cyrus_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
+ 			           const char *sasl_opts_val)
+ {
+ #if SASL_VERSION_MAJOR < 2
+@@ -318,7 +318,7 @@
+ 
+ /* smtpd_sasl_disconnect - per-connection cleanup */
+ 
+-void    smtpd_sasl_disconnect(SMTPD_STATE *state)
++void    smtpd_cyrus_sasl_disconnect(SMTPD_STATE *state)
+ {
+     if (state->sasl_mechanism_list) {
+ #if SASL_VERSION_MAJOR < 2
+@@ -337,7 +337,7 @@
+ 
+ /* smtpd_sasl_authenticate - per-session authentication */
+ 
+-char   *smtpd_sasl_authenticate(SMTPD_STATE *state,
++char   *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *state,
+ 				        const char *sasl_method,
+ 				        const char *init_response)
+ {
+@@ -490,7 +490,7 @@
+ 
+ /* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */
+ 
+-void    smtpd_sasl_logout(SMTPD_STATE *state)
++void    smtpd_cyrus_sasl_logout(SMTPD_STATE *state)
+ {
+     if (state->sasl_username) {
+ 	myfree(state->sasl_username);
+diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h
+--- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h	2003-07-07 21:01:45.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h	2005-01-22 22:00:58.000000000 +0200
+@@ -18,6 +18,15 @@
+ extern void smtpd_sasl_logout(SMTPD_STATE *);
+ extern int permit_sasl_auth(SMTPD_STATE *, int, int);
+ 
++#ifdef USE_CYRUS_SASL
++extern void smtpd_cyrus_sasl_initialize(void);
++extern void smtpd_cyrus_sasl_connect(SMTPD_STATE *, const char *, const char *);
++extern void smtpd_cyrus_sasl_disconnect(SMTPD_STATE *);
++extern char *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *, const char *,
++					   const char *);
++extern void smtpd_cyrus_sasl_logout(SMTPD_STATE *);
++#endif
++
+ /* LICENSE
+ /* .ad
+ /* .fi
+diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c
+--- postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c	2004-03-29 22:40:52.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c	2005-01-22 22:00:58.000000000 +0200
+@@ -109,7 +109,7 @@
+ #include "smtpd_sasl_proto.h"
+ #include "smtpd_sasl_glue.h"
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+ 
+ /* smtpd_sasl_auth_cmd - process AUTH command */
+ 
+diff -ruN postfix-2.1.5/src/smtpd/smtpd_state.c postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c
+--- postfix-2.1.5/src/smtpd/smtpd_state.c	2004-04-21 21:23:49.000000000 +0300
++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c	2005-01-22 22:00:58.000000000 +0200
+@@ -112,7 +112,7 @@
+     state->instance = vstring_alloc(10);
+     state->seqno = 0;
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+     if (SMTPD_STAND_ALONE(state))
+ 	var_smtpd_sasl_enable = 0;
+     if (var_smtpd_sasl_enable)
+@@ -166,7 +166,7 @@
+     if (state->instance)
+ 	vstring_free(state->instance);
+ 
+-#ifdef USE_SASL_AUTH
++#ifdef USE_SASL_SERVER_AUTH
+     if (var_smtpd_sasl_enable)
+ 	smtpd_sasl_disconnect(state);
+ #endif
diff -ruN postfix-2.1.5/src/global/mail_params.h postfix-2.1.5-dovecot/src/global/mail_params.h
--- postfix-2.1.5/src/global/mail_params.h	2004-04-21 21:56:04.000000000 +0300
+++ postfix-2.1.5-dovecot/src/global/mail_params.h	2005-03-25 14:12:56.709298387 +0200
@@ -908,6 +908,10 @@
 #define DEF_SMTPD_SASL_ENABLE	0
 extern bool var_smtpd_sasl_enable;
 
+#define VAR_SMTPD_SASL_SOCKET	"smtpd_sasl_auth_socket"
+#define DEF_SMTPD_SASL_SOCKET	""
+extern char *var_smtpd_sasl_socket;
+
 #define VAR_SMTPD_SASL_OPTS	"smtpd_sasl_security_options"
 #define DEF_SMTPD_SASL_OPTS	"noanonymous"
 extern char *var_smtpd_sasl_opts;
diff -ruN postfix-2.1.5/src/lmtp/lmtp.c postfix-2.1.5-dovecot/src/lmtp/lmtp.c
--- postfix-2.1.5/src/lmtp/lmtp.c	2004-06-20 02:06:39.000000000 +0300
+++ postfix-2.1.5-dovecot/src/lmtp/lmtp.c	2005-03-25 14:12:56.710298199 +0200
@@ -354,7 +354,7 @@
 	    lmtp_quit(state);
 	    lmtp_chat_reset(state);
 	    state->session = lmtp_session_free(state->session);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    if (var_lmtp_sasl_enable)
 		lmtp_sasl_cleanup(state);
 #endif
@@ -367,7 +367,7 @@
 	else if (lmtp_rset(state) != 0) {
 	    lmtp_chat_reset(state);
 	    state->session = lmtp_session_free(state->session);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    if (var_lmtp_sasl_enable)
 		lmtp_sasl_cleanup(state);
 #endif
@@ -405,7 +405,7 @@
 	 */
 	else if (lmtp_lhlo(state) != 0) {
 	    state->session = lmtp_session_free(state->session);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    if (var_lmtp_sasl_enable)
 		lmtp_sasl_cleanup(state);
 #endif
@@ -501,7 +501,7 @@
 {
     debug_peer_init();
     if (var_lmtp_sasl_enable)
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	lmtp_sasl_initialize();
 #else
 	msg_warn("%s is true, but SASL support is not compiled in",
@@ -526,7 +526,7 @@
 	    msg_info("cleanup: just closed down session");
     }
     lmtp_state_free(state);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     if (var_lmtp_sasl_enable)
 	sasl_done();
 #endif
diff -ruN postfix-2.1.5/src/lmtp/lmtp.h postfix-2.1.5-dovecot/src/lmtp/lmtp.h
--- postfix-2.1.5/src/lmtp/lmtp.h	2003-12-16 03:21:54.000000000 +0200
+++ postfix-2.1.5-dovecot/src/lmtp/lmtp.h	2005-03-25 14:12:56.710298199 +0200
@@ -11,7 +11,7 @@
  /*
   * SASL library.
   */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 #include <sasl.h>
 #include <saslutil.h>
 #endif
@@ -43,7 +43,7 @@
     int     features;			/* server features */
     ARGV   *history;			/* transaction log */
     int     error_mask;			/* error classes */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     char   *sasl_mechanism_list;	/* server mechanism list */
     char   *sasl_username;		/* client username */
     char   *sasl_passwd;		/* client password */
diff -ruN postfix-2.1.5/src/lmtp/lmtp_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c
--- postfix-2.1.5/src/lmtp/lmtp_proto.c	2004-04-14 23:02:37.000000000 +0300
+++ postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c	2005-03-25 14:12:56.712297822 +0200
@@ -259,7 +259,7 @@
 						 NAME_CODE_FLAG_NONE, word);
 	    else if (strcasecmp(word, "SIZE") == 0)
 		state->features |= LMTP_FEATURE_SIZE;
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
 		lmtp_sasl_helo_auth(state, words);
 #endif
@@ -293,7 +293,7 @@
     } else
 	state->sndbufsize = 0;
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH))
 	return (lmtp_sasl_helo_login(state));
 #endif
@@ -444,7 +444,7 @@
 	    /*
 	     * We authenticate the local MTA only, but not the sender.
 	     */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    if (var_lmtp_sasl_enable
 		&& (state->features & LMTP_FEATURE_AUTH)
 		&& state->sasl_passwd)
diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c
--- postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c	2003-09-12 21:46:58.000000000 +0300
+++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c	2005-03-25 14:12:56.712297822 +0200
@@ -108,7 +108,7 @@
 #include "lmtp.h"
 #include "lmtp_sasl.h"
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 
  /*
   * Authentication security options.
diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c
--- postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c	2003-07-07 21:01:17.000000000 +0300
+++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c	2005-03-25 14:12:56.713297633 +0200
@@ -71,7 +71,7 @@
 #include "lmtp.h"
 #include "lmtp_sasl.h"
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 
 /* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */
 
diff -ruN postfix-2.1.5/src/lmtp/lmtp_state.c postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c
--- postfix-2.1.5/src/lmtp/lmtp_state.c	2003-09-12 21:42:55.000000000 +0300
+++ postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c	2005-03-25 14:12:56.713297633 +0200
@@ -76,7 +76,7 @@
     state->features = 0;
     state->history = 0;
     state->error_mask = 0;
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     lmtp_sasl_connect(state);
 #endif
     state->sndbufsize = 0;
@@ -91,7 +91,7 @@
     vstring_free(state->buffer);
     vstring_free(state->scratch);
     vstring_free(state->scratch2);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     lmtp_sasl_cleanup(state);
 #endif
     myfree((char *) state);
diff -ruN postfix-2.1.5/src/smtp/smtp.c postfix-2.1.5-dovecot/src/smtp/smtp.c
--- postfix-2.1.5/src/smtp/smtp.c	2004-04-14 17:25:42.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtp/smtp.c	2005-03-25 14:12:56.714297445 +0200
@@ -447,7 +447,7 @@
      * SASL initialization.
      */
     if (var_smtp_sasl_enable)
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	smtp_sasl_initialize();
 #else
 	msg_warn("%s is true, but SASL support is not compiled in",
@@ -476,7 +476,7 @@
 
 static void pre_exit(void)
 {
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     if (var_smtp_sasl_enable)
 	sasl_done();
 #endif
diff -ruN postfix-2.1.5/src/smtp/smtp.h postfix-2.1.5-dovecot/src/smtp/smtp.h
--- postfix-2.1.5/src/smtp/smtp.h	2003-12-26 21:17:29.000000000 +0200
+++ postfix-2.1.5-dovecot/src/smtp/smtp.h	2005-03-25 14:12:56.715297256 +0200
@@ -11,7 +11,7 @@
  /*
   * SASL library.
   */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 #include <sasl.h>
 #include <saslutil.h>
 #endif
@@ -43,7 +43,7 @@
     int     features;			/* server features */
     ARGV   *history;			/* transaction log */
     int     error_mask;			/* error classes */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     char   *sasl_mechanism_list;	/* server mechanism list */
     char   *sasl_username;		/* client username */
     char   *sasl_passwd;		/* client password */
diff -ruN postfix-2.1.5/src/smtp/smtp_connect.c postfix-2.1.5-dovecot/src/smtp/smtp_connect.c
--- postfix-2.1.5/src/smtp/smtp_connect.c	2004-06-19 19:23:33.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtp/smtp_connect.c	2005-03-25 14:12:56.717296879 +0200
@@ -368,7 +368,7 @@
 		/* XXX smtp_xfer() may abort in the middle of DATA. */
 		smtp_session_free(state->session);
 		state->session = 0;
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 		smtp_sasl_cleanup(state);
 #endif
 		debug_peer_restore();
diff -ruN postfix-2.1.5/src/smtp/smtp_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_proto.c
--- postfix-2.1.5/src/smtp/smtp_proto.c	2004-04-14 23:02:20.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtp/smtp_proto.c	2005-03-25 14:12:56.719296502 +0200
@@ -288,7 +288,7 @@
 			state->size_limit = off_cvt_string(word);
 		}
 	    }
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
 		smtp_sasl_helo_auth(state, words);
 #endif
@@ -307,7 +307,7 @@
 	msg_info("server features: 0x%x size %.0f",
 		 state->features, (double) state->size_limit);
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH))
 	return (smtp_sasl_helo_login(state));
 #endif
@@ -610,7 +610,7 @@
 	    /*
 	     * We authenticate the local MTA only, but not the sender.
 	     */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 	    if (var_smtp_sasl_enable
 		&& (state->features & SMTP_FEATURE_AUTH)
 		&& state->sasl_passwd)
diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_glue.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c
--- postfix-2.1.5/src/smtp/smtp_sasl_glue.c	2003-07-14 21:03:20.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c	2005-03-25 14:12:56.720296314 +0200
@@ -108,7 +108,7 @@
 #include "smtp.h"
 #include "smtp_sasl.h"
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 
  /*
   * Authentication security options.
diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c
--- postfix-2.1.5/src/smtp/smtp_sasl_proto.c	2003-07-07 21:01:32.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c	2005-03-25 14:12:56.721296126 +0200
@@ -71,7 +71,7 @@
 #include "smtp.h"
 #include "smtp_sasl.h"
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
 
 /* smtp_sasl_helo_auth - handle AUTH option in EHLO reply */
 
diff -ruN postfix-2.1.5/src/smtp/smtp_state.c postfix-2.1.5-dovecot/src/smtp/smtp_state.c
--- postfix-2.1.5/src/smtp/smtp_state.c	2003-12-21 04:10:50.000000000 +0200
+++ postfix-2.1.5-dovecot/src/smtp/smtp_state.c	2005-03-25 14:12:56.723295749 +0200
@@ -66,7 +66,7 @@
     state->features = 0;
     state->history = 0;
     state->error_mask = 0;
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     smtp_sasl_connect(state);
 #endif
     state->size_limit = 0;
@@ -82,7 +82,7 @@
     vstring_free(state->buffer);
     vstring_free(state->scratch);
     vstring_free(state->scratch2);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_CLIENT_AUTH
     smtp_sasl_cleanup(state);
 #endif
     if (state->mime_state)
diff -ruN postfix-2.1.5/src/smtpd/Makefile.in postfix-2.1.5-dovecot/src/smtpd/Makefile.in
--- postfix-2.1.5/src/smtpd/Makefile.in	2004-04-22 22:37:39.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/Makefile.in	2005-03-25 14:12:56.724295560 +0200
@@ -1,10 +1,10 @@
 SHELL	= /bin/sh
 SRCS	= smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
-	smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
-	smtpd_xforward.c
+	smtpd_peer.c smtpd_sasl.c smtpd_sasl_proto.c smtpd_sasl_glue.c \
+	smtpd_proxy.c smtpd_xforward.c
 OBJS	= smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
-	smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
-	smtpd_xforward.o
+	smtpd_peer.o smtpd_sasl.o smtpd_sasl_proto.o smtpd_sasl_glue.o \
+	smtpd_proxy.o smtpd_xforward.o
 HDRS	= smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
 	smtpd_sasl_glue.h smtpd_proxy.h
 TESTSRC	= smtpd_token_test.c
@@ -272,6 +272,26 @@
 smtpd_proxy.o: ../../include/argv.h
 smtpd_proxy.o: ../../include/mail_stream.h
 smtpd_proxy.o: smtpd_proxy.h
+smtpd_sasl.o: smtpd_sasl.c
+smtpd_sasl.o: ../../include/sys_defs.h
+smtpd_sasl.o: ../../include/base64_code.h
+smtpd_sasl.o: ../../include/vstring.h
+smtpd_sasl.o: ../../include/vbuf.h
+smtpd_sasl.o: ../../include/connect.h
+smtpd_sasl.o: ../../include/iostuff.h
+smtpd_sasl.o: ../../include/msg.h
+smtpd_sasl.o: ../../include/mymalloc.h
+smtpd_sasl.o: ../../include/split_at.h
+smtpd_sasl.o: ../../include/stringops.h
+smtpd_sasl.o: ../../include/vstring_vstream.h
+smtpd_sasl.o: ../../include/vstream.h
+smtpd_sasl.o: ../../include/mail_params.h
+smtpd_sasl.o: ../../include/smtp_stream.h
+smtpd_sasl.o: smtpd.h
+smtpd_sasl.o: ../../include/argv.h
+smtpd_sasl.o: ../../include/mail_stream.h
+smtpd_sasl.o: smtpd_sasl_glue.h
+smtpd_sasl.o: smtpd_chat.h
 smtpd_sasl_glue.o: smtpd_sasl_glue.c
 smtpd_sasl_glue.o: ../../include/sys_defs.h
 smtpd_sasl_glue.o: ../../include/msg.h
diff -ruN postfix-2.1.5/src/smtpd/smtpd.c postfix-2.1.5-dovecot/src/smtpd/smtpd.c
--- postfix-2.1.5/src/smtpd/smtpd.c	2004-08-14 01:28:41.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd.c	2005-03-25 14:12:56.727294995 +0200
@@ -717,6 +717,7 @@
 int     var_smtpd_junk_cmd_limit;
 int     var_smtpd_rcpt_overlim;
 bool    var_smtpd_sasl_enable;
+char   *var_smtpd_sasl_socket;
 char   *var_smtpd_sasl_opts;
 char   *var_smtpd_sasl_appname;
 char   *var_smtpd_sasl_realm;
@@ -816,7 +817,7 @@
   */
 #define NEUTER_CHARACTERS " <>()\\\";:@"
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 
  /*
   * SASL exceptions.
@@ -943,7 +944,7 @@
     if (var_disable_vrfy_cmd == 0)
 	smtpd_chat_reply(state, "250-VRFY");
     smtpd_chat_reply(state, "250-ETRN");
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
     if (var_smtpd_sasl_enable && !sasl_client_exception(state)) {
 	smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
 	if (var_broken_auth_clients)
@@ -1246,7 +1247,7 @@
 		state->error_mask |= MAIL_ERROR_POLICY;
 		return (-1);
 	    }
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 	} else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) {
 	    if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
 		smtpd_chat_reply(state, "%s", err);
@@ -1354,7 +1355,7 @@
 	state->saved_redirect = 0;
     }
     state->saved_flags = 0;
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
     if (var_smtpd_sasl_enable)
 	smtpd_sasl_mail_reset(state);
 #endif
@@ -1455,7 +1456,7 @@
 	/*
 	 * Log the queue ID with the message origin.
 	 */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 	if (var_smtpd_sasl_enable)
 	    smtpd_sasl_mail_log(state);
 	else
@@ -2328,7 +2329,7 @@
     "HELO", helo_cmd, SMTPD_CMD_FLAG_LIMIT,
     "EHLO", ehlo_cmd, SMTPD_CMD_FLAG_LIMIT,
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
     "AUTH", smtpd_sasl_auth_cmd, 0,
 #endif
 
@@ -2531,7 +2532,7 @@
      * dialog.
      */
     helo_reset(state);
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
     if (var_smtpd_sasl_enable)
 	smtpd_sasl_auth_reset(state);
 #endif
@@ -2628,7 +2629,7 @@
     debug_peer_init();
 
     if (var_smtpd_sasl_enable)
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 	smtpd_sasl_initialize();
 
     if (*var_smtpd_sasl_exceptions_networks)
@@ -2757,6 +2758,7 @@
 	VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0,
 	VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
 	VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
+	VAR_SMTPD_SASL_SOCKET, DEF_SMTPD_SASL_SOCKET, &var_smtpd_sasl_socket, 0, 0,
 	VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
 	VAR_SMTPD_SASL_APPNAME, DEF_SMTPD_SASL_APPNAME, &var_smtpd_sasl_appname, 1, 0,
 	VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0,
diff -ruN postfix-2.1.5/src/smtpd/smtpd.h postfix-2.1.5-dovecot/src/smtpd/smtpd.h
--- postfix-2.1.5/src/smtpd/smtpd.h	2004-04-21 21:23:33.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd.h	2005-03-25 14:12:56.729294618 +0200
@@ -16,7 +16,7 @@
  /*
   * SASL library.
   */
-#ifdef USE_SASL_AUTH
+#ifdef USE_CYRUS_SASL
 #include <sasl.h>
 #include <saslutil.h>
 #endif
@@ -90,7 +90,7 @@
     /*
      * SASL specific.
      */
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 #if SASL_VERSION_MAJOR >= 2
     const char *sasl_mechanism_list;
 #else
@@ -99,10 +99,15 @@
     char   *sasl_method;
     char   *sasl_username;
     char   *sasl_sender;
+    unsigned int sasl_id;
+    VSTRING *sasl_line;
+
+#ifdef USE_CYRUS_SASL
     sasl_conn_t *sasl_conn;
     VSTRING *sasl_encoded;
     VSTRING *sasl_decoded;
 #endif
+#endif
 
     /*
      * Specific to smtpd access checks.
diff -ruN postfix-2.1.5/src/smtpd/smtpd_check.c postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c
--- postfix-2.1.5/src/smtpd/smtpd_check.c	2004-08-02 00:08:32.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c	2005-03-25 14:12:56.732294052 +0200
@@ -2762,7 +2762,7 @@
     return (result);
 }
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 
 /* reject_auth_sender_login_mismatch - logged in client must own sender address */
 
@@ -2868,7 +2868,7 @@
 			  STR(state->instance),
 			  ATTR_TYPE_LONG, MAIL_ATTR_SIZE,
 			  (unsigned long) state->msg_size,
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 			  ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD,
 			  var_smtpd_sasl_enable && state->sasl_method ?
 			  state->sasl_method : "",
@@ -3162,7 +3162,7 @@
 		status = reject_non_fqdn_address(state, state->sender,
 					  state->sender, SMTPD_NAME_SENDER);
 	} else if (strcasecmp(name, REJECT_AUTH_SENDER_LOGIN_MISMATCH) == 0) {
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 	    if (var_smtpd_sasl_enable) {
 		if (state->sender && *state->sender)
 		    status = reject_auth_sender_login_mismatch(state, state->sender);
@@ -3170,7 +3170,7 @@
 #endif
 		msg_warn("restriction `%s' ignored: no SASL support", name);
 	} else if (strcasecmp(name, REJECT_UNAUTH_SENDER_LOGIN_MISMATCH) == 0) {
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 	    if (var_smtpd_sasl_enable) {
 		if (state->sender && *state->sender)
 		    status = reject_unauth_sender_login_mismatch(state, state->sender);
@@ -3232,7 +3232,7 @@
 			 cpp[1], CHECK_RELAY_DOMAINS);
 	} else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) {
 	    if (var_smtpd_sasl_enable)
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 		status = permit_sasl_auth(state,
 					  SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO);
 #else
@@ -4209,7 +4209,7 @@
 
 bool    var_smtpd_sasl_enable = 0;
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 
 /* smtpd_sasl_connect - stub */
 
diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c
--- postfix-2.1.5/src/smtpd/smtpd_sasl.c	1970-01-01 02:00:00.000000000 +0200
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c	2005-03-25 14:13:16.856500665 +0200
@@ -0,0 +1,408 @@
+/*++
+/* NAME
+/*	smtpd_sasl_glue 3
+/* SUMMARY
+/*	Postfix SMTP server, SASL support interface
+/* SYNOPSIS
+/*	#include "smtpd_sasl_glue.h"
+/*
+/*	void	smtpd_sasl_initialize()
+/*
+/*	void	smtpd_sasl_connect(state, sasl_opts_name, sasl_opts_val)
+/*	SMTPD_STATE *state;
+/*
+/*	char	*smtpd_sasl_authenticate(state, sasl_method, init_response)
+/*	SMTPD_STATE *state;
+/*	const char *sasl_method;
+/*	const char *init_response;
+/*
+/*	void	smtpd_sasl_logout(state)
+/*	SMTPD_STATE *state;
+/*
+/*	void	smtpd_sasl_disconnect(state)
+/*	SMTPD_STATE *state;
+/* DESCRIPTION
+/*	This module encapsulates most of the detail specific to SASL
+/*	authentication.
+/*
+/*	smtpd_sasl_initialize() initializes the SASL library. This
+/*	routine should be called once at process start-up. It may
+/*	need access to the file system for run-time loading of
+/*	plug-in modules. There is no corresponding cleanup routine.
+/*
+/*	smtpd_sasl_connect() performs per-connection initialization.
+/*	This routine should be called once at the start of every
+/*	connection. The sasl_opts_name and sasl_opts_val parameters
+/*	are the postfix configuration parameters setting the security
+/*	policy of the SASL authentication.
+/*
+/*	smtpd_sasl_authenticate() implements the authentication dialog.
+/*	The result is a null pointer in case of success, an SMTP reply
+/*	in case of failure. smtpd_sasl_authenticate() updates the
+/*	following state structure members:
+/* .IP sasl_method
+/*	The authentication method that was successfully applied.
+/*	This member is a null pointer in the absence of successful
+/*	authentication.
+/* .IP sasl_username
+/*	The username that was successfully authenticated.
+/*	This member is a null pointer in the absence of successful
+/*	authentication.
+/* .PP
+/*	smtpd_sasl_logout() cleans up after smtpd_sasl_authenticate().
+/*	This routine exists for the sake of symmetry.
+/*
+/*	smtpd_sasl_disconnect() performs per-connection cleanup.
+/*	This routine should be called at the end of every connection.
+/*
+/*	Arguments:
+/* .IP state
+/*	SMTP session context.
+/* .IP sasl_method
+/*	A SASL mechanism name
+/* .IP init_reply
+/*	An optional initial client response.
+/* DIAGNOSTICS
+/*	All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/*	The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*	Initial implementation by:
+/*	Till Franke
+/*	SuSE Rhein/Main AG
+/*	65760 Eschborn, Germany
+/*
+/*	Adopted by:
+/*	Wietse Venema
+/*	IBM T.J. Watson Research
+/*	P.O. Box 704
+/*	Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <base64_code.h>
+#include <connect.h>
+#include <msg.h>
+#include <mymalloc.h>
+#include <split_at.h>
+#include <stringops.h>
+#include <vstring_vstream.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <smtp_stream.h>
+
+/* Application-specific. */
+
+#include "smtpd.h"
+#include "smtpd_sasl_glue.h"
+#include "smtpd_chat.h"
+
+#ifdef USE_SASL_SERVER_AUTH
+
+/* Major version changes are not backwards compatible,
+   minor version numbers can be ignored. */
+#define AUTH_PROTOCOL_MAJOR_VERSION 1
+#define AUTH_PROTOCOL_MINOR_VERSION 0
+
+static unsigned int sasl_id = 0;
+static VSTREAM *sasl_stream = 0;
+static char *sasl_mechanism_list = 0;
+
+/* smtpd_sasl_initialize - per-process initialization */
+
+void    smtpd_sasl_initialize(void)
+{
+#ifdef USE_CYRUS_SASL
+    if (*var_smtpd_sasl_socket == '\0')
+        smtpd_cyrus_sasl_initialize();
+#endif
+}
+
+static void smtpd_sasl_connect_server(void)
+{
+    char   *myname = "smtpd_sasl_connect_server";
+    VSTRING *line_str, *mechanisms_str;
+    char   *line, *cmd, *mech_name;
+    unsigned int major_version, minor_version;
+    int fd;
+
+    if ((fd = unix_connect(var_smtpd_sasl_socket, BLOCKING, 0)) < 0)
+        msg_fatal("SASL: connect failed: %m");
+
+    sasl_stream = vstream_fdopen(fd, O_RDWR);
+    vstream_control(sasl_stream, VSTREAM_CTL_PATH,
+                    var_smtpd_sasl_socket, VSTREAM_CTL_END);
+
+    vstream_fprintf(sasl_stream,
+                    "VERSION\t%u\t%u\n"
+                    "CPID\t%u\n",
+                    AUTH_PROTOCOL_MAJOR_VERSION,
+                    AUTH_PROTOCOL_MINOR_VERSION,
+                    (unsigned int)getpid());
+    if (vstream_fflush(sasl_stream) == VSTREAM_EOF)
+        msg_fatal("SASL: couldn't send handshake: %m");
+
+    line_str = vstring_alloc(256);
+    mechanisms_str = vstring_alloc(128);
+    while (vstring_get_nonl(line_str, sasl_stream) != VSTREAM_EOF) {
+        line = vstring_str(line_str);
+
+        if (msg_verbose)
+	    msg_info("%s: auth reply: %s", myname, line);
+
+        cmd = line;
+        line = split_at(line, '\t');
+
+        if (strcmp(cmd, "VERSION") == 0) {
+            if (sscanf(line, "%u\t%u", &major_version, &minor_version) != 2)
+                msg_fatal("SASL: Protocol version error");
+
+            if (major_version != AUTH_PROTOCOL_MAJOR_VERSION) {
+                /* Major version is different from ours. */
+                msg_fatal("SASL: Protocol version mismatch (%d vs. %d)",
+                          major_version, AUTH_PROTOCOL_MAJOR_VERSION);
+            }
+	} else if (strcmp(cmd, "MECH") == 0 && line != NULL) {
+            mech_name = line;
+            line = split_at(line, '\t');
+
+            if (VSTRING_LEN(mechanisms_str) > 0)
+                VSTRING_ADDCH(mechanisms_str, ' ');
+            vstring_strcat(mechanisms_str, mech_name);
+        } else if (strcmp(cmd, "DONE") == 0) {
+            /* Handshake finished. */
+            break;
+        } else {
+            /* ignore any unknown commands */
+        }
+    }
+    vstring_free(line_str);
+
+    if (sasl_mechanism_list)
+        myfree(sasl_mechanism_list);
+    sasl_mechanism_list =
+        translit(vstring_export(mechanisms_str), "\t", " ");
+}
+
+static void smtpd_sasl_disconnect_server(void)
+{
+    (void) vstream_fclose(sasl_stream);
+    sasl_stream = 0;
+
+    myfree(sasl_mechanism_list);
+    sasl_mechanism_list = 0;
+}
+
+/* smtpd_sasl_connect - per-connection initialization */
+
+void    smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
+                           const char *sasl_opts_val)
+{
+#ifdef USE_CYRUS_SASL
+    if (*var_smtpd_sasl_socket == '\0') {
+        smtpd_cyrus_sasl_connect(state, sasl_opts_name, sasl_opts_val);
+        return;
+    }
+#endif
+
+    state->sasl_username = 0;
+    state->sasl_method = 0;
+    state->sasl_sender = 0;
+    state->sasl_line = vstring_alloc(512);
+
+    if (!sasl_stream)
+        smtpd_sasl_connect_server();
+    state->sasl_mechanism_list = mystrdup(sasl_mechanism_list);
+}
+
+/* smtpd_sasl_disconnect - per-connection cleanup */
+
+void    smtpd_sasl_disconnect(SMTPD_STATE *state)
+{
+#ifdef USE_CYRUS_SASL
+    if (*var_smtpd_sasl_socket == '\0') {
+        smtpd_cyrus_sasl_disconnect(state);
+        return;
+    }
+#endif
+
+    vstring_free(state->sasl_line);
+    state->sasl_line = 0;
+    myfree(state->sasl_mechanism_list);
+    state->sasl_mechanism_list = 0;
+}
+
+static int smtpd_sasl_parse_reply(SMTPD_STATE *state, char **line)
+{
+    char *id;
+
+    if (*line == NULL)
+        msg_fatal("SASL: Protocol error");
+
+    id = *line;
+    *line = split_at(*line, '\t');
+
+    if (strtoul(id, NULL, 0) != state->sasl_id) {
+        /* reply to another request, shouldn't really happen.. */
+        return 0;
+    }
+
+    return 1;
+}
+
+
+/* smtpd_sasl_authenticate - per-session authentication */
+
+char   *smtpd_sasl_authenticate(SMTPD_STATE *state,
+                                const char *sasl_method,
+                                const char *init_response)
+{
+    char   *myname = "smtpd_sasl_authenticate";
+    char   *line, *cmd;
+    int    i, success;
+
+#ifdef USE_CYRUS_SASL
+    if (*var_smtpd_sasl_socket == '\0')
+        return smtpd_cyrus_sasl_authenticate(state, sasl_method, init_response);
+#endif
+
+#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
+
+    if (msg_verbose)
+	msg_info("%s: sasl_method %s%s%s", myname, sasl_method,
+		 IFELSE(init_response, ", init_response ", ""),
+		 IFELSE(init_response, init_response, ""));
+
+    for (i = 0; i < 2; i++) {
+        state->sasl_id = ++sasl_id;
+        vstream_fprintf(sasl_stream, "AUTH\t%u\t%s\tservice=smtp",
+                        state->sasl_id, sasl_method);
+        if (init_response)
+            vstream_fprintf(sasl_stream, "\tresp=%s", init_response);
+        VSTREAM_PUTC('\n', sasl_stream);
+
+        if (vstream_fflush(sasl_stream) != VSTREAM_EOF)
+            break;
+
+        if (i == 1)
+            return ("454 Temporary authentication failure");
+
+        /*
+         * Reconnect.
+         */
+        smtpd_sasl_disconnect_server();
+        smtpd_sasl_connect_server();
+    }
+
+    /*
+     * Sanity check.
+     */
+    if (state->sasl_username || state->sasl_method)
+	msg_panic("%s: already authenticated", myname);
+
+    success = 0;
+    while (vstring_get_nonl(state->sasl_line, sasl_stream) != VSTREAM_EOF) {
+        line = vstring_str(state->sasl_line);
+
+	if (msg_verbose)
+	    msg_info("%s: auth reply: %s", myname, line);
+
+        cmd = line;
+        line = split_at(line, '\t');
+
+        if (strcmp(cmd, "OK") == 0) {
+            if (!smtpd_sasl_parse_reply(state, &line))
+                continue;
+
+            /* authentication successful */
+            success = 1;
+            break;
+        } else if (strcmp(cmd, "CONT") == 0) {
+            if (!smtpd_sasl_parse_reply(state, &line))
+                continue;
+
+            /*
+             * Receive the client response. "*" means that the client gives up.
+             * XXX For now we ignore the fact that excessively long responses
+             * will be truncated. To handle such responses, we need to change
+             * smtpd_chat_query() so that it returns an error indication.
+             */
+            smtpd_chat_reply(state, "334 %s", line);
+
+            smtpd_chat_query(state);
+            if (strcmp(vstring_str(state->buffer), "*") == 0)
+                return ("501 Authentication aborted");
+
+            vstream_fprintf(sasl_stream, "CONT\t%u\t", state->sasl_id);
+            vstream_fputs(vstring_str(state->buffer), sasl_stream);
+            VSTREAM_PUTC('\n', sasl_stream);
+
+            if (vstream_fflush(sasl_stream) == VSTREAM_EOF)
+                break;
+        } else if (strcmp(cmd, "FAIL") == 0) {
+            if (!smtpd_sasl_parse_reply(state, &line))
+                continue;
+
+            return ("535 Error: authentication failed");
+	} else {
+	    /* ignore */
+	}
+    }
+
+    if (!success) {
+        /* connection lost to auth server */
+        return ("454 Temporary authentication failure");
+    }
+
+    while (line != NULL && strncmp(line, "user=", 5) != 0)
+        line = split_at(line, '\t');
+
+    if (line == NULL)
+	state->sasl_username = mystrdup("?");
+    else {
+	line += 5;
+	(void) split_at(line, '\t');
+	state->sasl_username = mystrdup(line);
+    }
+    printable(state->sasl_username, '?');
+
+    state->sasl_method = mystrdup(sasl_method);
+    printable(state->sasl_method, '?');
+
+    return (0);
+}
+
+/* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */
+
+void    smtpd_sasl_logout(SMTPD_STATE *state)
+{
+#ifdef USE_CYRUS_SASL
+    if (*var_smtpd_sasl_socket == '\0') {
+        smtpd_cyrus_sasl_logout(state);
+        return;
+    }
+#endif
+
+    if (state->sasl_username) {
+	myfree(state->sasl_username);
+	state->sasl_username = 0;
+    }
+    if (state->sasl_method) {
+	myfree(state->sasl_method);
+	state->sasl_method = 0;
+    }
+}
+
+#endif
diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c
--- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c	2004-02-01 20:44:55.000000000 +0200
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c	2005-03-25 14:12:56.736293299 +0200
@@ -105,7 +105,7 @@
 #include "smtpd_sasl_glue.h"
 #include "smtpd_chat.h"
 
-#ifdef USE_SASL_AUTH
+#if defined(USE_SASL_SERVER_AUTH) && defined(USE_CYRUS_SASL)
 
 /*
  * Silly little macros.
@@ -205,7 +205,7 @@
 
 /* smtpd_sasl_initialize - per-process initialization */
 
-void    smtpd_sasl_initialize(void)
+void    smtpd_cyrus_sasl_initialize(void)
 {
 
     /*
@@ -221,7 +221,7 @@
 
 /* smtpd_sasl_connect - per-connection initialization */
 
-void    smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
+void    smtpd_cyrus_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
 			           const char *sasl_opts_val)
 {
 #if SASL_VERSION_MAJOR < 2
@@ -318,7 +318,7 @@
 
 /* smtpd_sasl_disconnect - per-connection cleanup */
 
-void    smtpd_sasl_disconnect(SMTPD_STATE *state)
+void    smtpd_cyrus_sasl_disconnect(SMTPD_STATE *state)
 {
     if (state->sasl_mechanism_list) {
 #if SASL_VERSION_MAJOR < 2
@@ -337,7 +337,7 @@
 
 /* smtpd_sasl_authenticate - per-session authentication */
 
-char   *smtpd_sasl_authenticate(SMTPD_STATE *state,
+char   *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *state,
 				        const char *sasl_method,
 				        const char *init_response)
 {
@@ -490,7 +490,7 @@
 
 /* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */
 
-void    smtpd_sasl_logout(SMTPD_STATE *state)
+void    smtpd_cyrus_sasl_logout(SMTPD_STATE *state)
 {
     if (state->sasl_username) {
 	myfree(state->sasl_username);
diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h
--- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h	2003-07-07 21:01:45.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h	2005-03-25 14:12:56.737293110 +0200
@@ -18,6 +18,15 @@
 extern void smtpd_sasl_logout(SMTPD_STATE *);
 extern int permit_sasl_auth(SMTPD_STATE *, int, int);
 
+#ifdef USE_CYRUS_SASL
+extern void smtpd_cyrus_sasl_initialize(void);
+extern void smtpd_cyrus_sasl_connect(SMTPD_STATE *, const char *, const char *);
+extern void smtpd_cyrus_sasl_disconnect(SMTPD_STATE *);
+extern char *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *, const char *,
+					   const char *);
+extern void smtpd_cyrus_sasl_logout(SMTPD_STATE *);
+#endif
+
 /* LICENSE
 /* .ad
 /* .fi
diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c
--- postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c	2004-03-29 22:40:52.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c	2005-03-25 14:12:56.739292733 +0200
@@ -109,7 +109,7 @@
 #include "smtpd_sasl_proto.h"
 #include "smtpd_sasl_glue.h"
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
 
 /* smtpd_sasl_auth_cmd - process AUTH command */
 
diff -ruN postfix-2.1.5/src/smtpd/smtpd_state.c postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c
--- postfix-2.1.5/src/smtpd/smtpd_state.c	2004-04-21 21:23:49.000000000 +0300
+++ postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c	2005-03-25 14:12:56.740292545 +0200
@@ -112,7 +112,7 @@
     state->instance = vstring_alloc(10);
     state->seqno = 0;
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
     if (SMTPD_STAND_ALONE(state))
 	var_smtpd_sasl_enable = 0;
     if (var_smtpd_sasl_enable)
@@ -166,7 +166,7 @@
     if (state->instance)
 	vstring_free(state->instance);
 
-#ifdef USE_SASL_AUTH
+#ifdef USE_SASL_SERVER_AUTH
     if (var_smtpd_sasl_enable)
 	smtpd_sasl_disconnect(state);
 #endif
