+++ /dev/null
-diff -urP exim-4.20.orig/doc/README.saslauthd.txt exim-4.20/doc/README.saslauthd.txt
---- exim-4.20.orig/doc/README.saslauthd.txt 1970-01-01 01:00:00.000000000 +0100
-+++ exim-4.20/doc/README.saslauthd.txt 2003-07-09 02:46:14.000000000 +0200
-@@ -0,0 +1,31 @@
-+This is sample configuration for enabling authorization mechanism in
-+Exim-4.20 using saslauthd from pacakge cyrus-sasl-saslauthd-2.x (note:
-+not from cyrus-sasl-saslauthd-1.5.27, that provides *pwcheck* daemon):
-+
-+-8<-cut-here---------------------------------------------------------
-+
-+begin authenticators
-+
-+plain:
-+ driver = plaintext
-+ public_name = PLAIN
-+ server_condition = ${if saslauthd{$1:$3:smtp}{1}{0}}
-+ server_set_id = $2
-+
-+login:
-+ driver = plaintext
-+ public_name = LOGIN
-+ server_prompts = "Username:: : Password::"
-+ server_condition = ${if saslauthd{$1:$2:smtp}{1}{0}}
-+ server_set_id = $1
-+
-+-8<-cut-here---------------------------------------------------------
-+
-+Orginal patch has been developed by Alexander Sabourenkov <lists at lxnt.info>
-+and can be find on <http://lxnt.info/stuff/saslauthd.diff>. The syntax of
-+of saslauthd condition is simmilar to pwcheck:
-+
-+${if saslauthd{{<username>}{<password>}[{<servicename>}[{<realm>}]]}{1}{0}}
-+
-+Baseciq <baseciq@pld-linux.org>
-+
-diff -urP exim-4.20.orig/doc/README.saslauthd.txt~ exim-4.20/doc/README.saslauthd.txt~
---- exim-4.20.orig/doc/README.saslauthd.txt~ 1970-01-01 01:00:00.000000000 +0100
-+++ exim-4.20/doc/README.saslauthd.txt~ 2003-07-09 02:34:46.000000000 +0200
-@@ -0,0 +1,31 @@
-+This is sample configuration for enabling authorization mechanism in
-+Exim-4.20 using saslauthd (not pwcheck!) from pacakge
-+cyrus-sasl-saslauthd-2.x:
-+
-+-8<-cut-here---------------------------------------------------------
-+
-+begin authenticators
-+
-+plain:
-+ driver = plaintext
-+ public_name = PLAIN
-+ server_condition = ${if saslauthd{$1:$3:smtp}{1}{0}}
-+ server_set_id = $2
-+
-+login:
-+ driver = plaintext
-+ public_name = LOGIN
-+ server_prompts = "Username:: : Password::"
-+ server_condition = ${if saslauthd{$1:$2:smtp}{1}{0}}
-+ server_set_id = $1
-+
-+-8<-cut-here---------------------------------------------------------
-+
-+Orginal patch has been developed by Alexander Sabourenkov <lists at lxnt.info>
-+and can be find on <http://lxnt.info/stuff/saslauthd.diff>. The syntax of
-+of saslauthd condition is simmilar to pwcheck:
-+
-+${if saslauthd{{<username>}{<password>}[{<servicename>}[{<realm>}]]}{1}{0}}
-+
-+Baseciq <baseciq@pld-linux.org>
-+
-diff -urP exim-4.20.orig/src/auths/call_pwcheck.c exim-4.20/src/auths/call_pwcheck.c
---- exim-4.20.orig/src/auths/call_pwcheck.c 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/auths/call_pwcheck.c 2003-07-09 02:04:37.000000000 +0200
-@@ -13,7 +13,7 @@
- * External entry point *
- *************************************************/
-
--/* This function calls the Cyrus-SASL authentication daemon, passing over a
-+/* This function calls a Cyrus-SASL authentication daemon, pwcheck, passing over a
- colon-separated user name and password. As this is called from the string
- expander, the string will always be in dynamic store and can be overwritten.
-
-@@ -50,7 +50,7 @@
- DEBUG(D_auth) debug_printf("pwcheck: success (%s)\n", reply);
- return OK;
-
-- case PWCHECK_BAD:
-+ case PWCHECK_NO:
- DEBUG(D_auth) debug_printf("pwcheck: access denied (%s)\n", reply);
- return FAIL;
-
-@@ -61,4 +61,75 @@
- }
- }
-
-+/*************************************************
-+* External entry point *
-+*************************************************/
-+
-+/* This function calls a Cyrus-SASL authentication daemon, saslauthd,
-+passing over a colon-separated user name and password. As this is called
-+from the string expander, the string will always be in dynamic store and
-+can be overwritten.
-+
-+Arguments:
-+ s a colon-separated username:password[:servicename[:realm]] string
-+ errptr where to point an error message
-+
-+Returns: OK if authentication succeeded
-+ FAIL if authentication failed
-+ ERROR some other error condition
-+*/
-+
-+
-+int
-+auth_call_saslauthd(uschar *s, uschar **errptr)
-+{
-+uschar *reply = NULL;
-+uschar *pw = Ustrchr(s, ':');
-+uschar *service, *realm;
-+
-+if (pw == NULL)
-+ {
-+ *errptr = US"saslauthd: malformed input - missing colon";
-+ return ERROR;
-+ }
-+
-+*pw++ = 0; /* Separate user and password */
-+service = Ustrchr(pw, ':');
-+if (service != NULL )
-+ {
-+ *service++ = 0;
-+ realm = Ustrchr(service, ':');
-+ if ( realm != NULL )
-+ *realm++ = 0;
-+ else
-+ realm = "";
-+ }
-+else
-+ {
-+ service = "";
-+ realm = "";
-+ }
-+
-+
-+DEBUG(D_auth)
-+ debug_printf("Running saslauthd authentication for user \"%s\"\n", s);
-+
-+switch (saslauthd_verify_password(CS s, CS pw, CS service, CS realm, (const char **)(&reply)))
-+ {
-+ case PWCHECK_OK:
-+ DEBUG(D_auth) debug_printf("saslauthd: success (%s)\n", reply);
-+ return OK;
-+
-+ case PWCHECK_NO:
-+ DEBUG(D_auth) debug_printf("saslauthd: access denied (%s)\n", reply);
-+ return FAIL;
-+
-+ default:
-+ DEBUG(D_auth) debug_printf("saslauthd: query failed (%s)\n", reply);
-+ *errptr = reply;
-+ return ERROR;
-+ }
-+}
-+
-+
- /* End of call_pwcheck.c */
-diff -urP exim-4.20.orig/src/auths/pwcheck.c exim-4.20/src/auths/pwcheck.c
---- exim-4.20.orig/src/auths/pwcheck.c 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/auths/pwcheck.c 2003-07-09 02:04:37.000000000 +0200
-@@ -45,7 +45,7 @@
-
- /*
- * Taken from Cyrus-SASL library and adapted by Alexander S. Sabourenkov
-- * Oct 2001 - Apr 2002. Slightly modified by Philip Hazel.
-+ * Oct 2001 - Apr 2003. Slightly modified by Philip Hazel.
- *
- * screwdriver@lxnt.info
- *
-@@ -55,6 +55,17 @@
- #include "../exim.h"
- #include "pwcheck.h"
-
-+#if defined(CYRUS_PWCHECK_SOCKET) || defined(CYRUS_SASLAUTHD_SOCKET)
-+
-+#include <sys/uio.h>
-+
-+static int retry_read(int, void *, unsigned );
-+static int retry_writev(int, struct iovec *, int );
-+static int read_string(int, uschar **);
-+static int write_string(int, const uschar *, int);
-+
-+#endif
-+
- /* A dummy function that always fails if pwcheck support is not
- wanted. */
-
-@@ -73,65 +84,6 @@
- /* This is the real function */
-
- #else
--#include <sys/uio.h>
--
--
-- /* taken from cyrus-sasl file checkpw.c */
-- /*
-- * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt'
-- * until all the data is written out or an error occurs.
-- */
-- static int retry_writev(int fd, struct iovec *iov, int iovcnt)
-- {
-- int n;
-- int i;
-- int written = 0;
-- static int iov_max =
-- #ifdef MAXIOV
-- MAXIOV
-- #else
-- #ifdef IOV_MAX
-- IOV_MAX
-- #else
-- 8192
-- #endif
-- #endif
-- ;
--
-- for (;;) {
-- while (iovcnt && iov[0].iov_len == 0) {
-- iov++;
-- iovcnt--;
-- }
--
-- if (!iovcnt) return written;
--
-- n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
-- if (n == -1) {
-- if (errno == EINVAL && iov_max > 10) {
-- iov_max /= 2;
-- continue;
-- }
-- if (errno == EINTR) continue;
-- return -1;
-- }
--
-- written += n;
--
-- for (i = 0; i < iovcnt; i++) {
-- if (iov[i].iov_len > n) {
-- iov[i].iov_base = (char *)iov[i].iov_base + n;
-- iov[i].iov_len -= n;
-- break;
-- }
-- n -= iov[i].iov_len;
-- iov[i].iov_len = 0;
-- }
--
-- if (i == iovcnt) return written;
-- }
-- }
--
-
- /* taken from cyrus-sasl file checkpw.c */
- /* pwcheck daemon-authenticated login */
-@@ -139,18 +91,15 @@
- const char *passwd,
- const char **reply)
- {
-- int s;
-+ int s, start, r, n;
- struct sockaddr_un srvaddr;
-- int r;
-- struct iovec iov[10];
-+ struct iovec iov[2];
- static char response[1024];
-- int start, n;
-- /* char pwpath[1024]; is not used - PH */
-
- if (reply) { *reply = NULL; }
-
- s = socket(AF_UNIX, SOCK_STREAM, 0);
-- if (s == -1) return errno;
-+ if (s == -1) { return PWCHECK_FAIL; }
-
- memset((char *)&srvaddr, 0, sizeof(srvaddr));
- srvaddr.sun_family = AF_UNIX;
-@@ -185,9 +134,307 @@
-
- response[start] = '\0';
- if (reply) { *reply = response; }
-- return PWCHECK_BAD;
-+ return PWCHECK_NO;
- }
-
- #endif
-
-+
-+ /* A dummy function that always fails if saslauthd support is not
-+wanted. */
-+
-+#ifndef CYRUS_SASLAUTHD_SOCKET
-+int saslauthd_verify_password(const char *userid,
-+ const char *passwd,
-+ const char *service,
-+ const char *realm,
-+ const char **reply)
-+{
-+userid = userid; /* Keep picky compilers happy */
-+passwd = passwd;
-+service = service;
-+realm = realm;
-+*reply = "saslauthd support is not included in this Exim binary";
-+return PWCHECK_FAIL;
-+}
-+
-+
-+/* This is the real function */
-+
-+#else
-+ /* written from scratch */
-+ /* saslauthd daemon-authenticated login */
-+
-+int saslauthd_verify_password(const char *userid,
-+ const char *password,
-+ const char *service,
-+ const char *realm,
-+ const char **reply)
-+{
-+ uschar *daemon_reply;
-+ int s, r;
-+ struct sockaddr_un srvaddr;
-+
-+ DEBUG(D_auth)
-+ debug_printf("saslauthd userid='%s' password='%s' servicename='%s'"
-+ " realm='%s'\n", userid, password, service, realm );
-+
-+ if (reply)
-+ *reply = NULL;
-+
-+ s = socket(AF_UNIX, SOCK_STREAM, 0);
-+ if (s == -1) {
-+ if (reply)
-+ *reply = strerror(errno);
-+ return PWCHECK_FAIL;
-+ }
-+
-+ memset((char *)&srvaddr, 0, sizeof(srvaddr));
-+ srvaddr.sun_family = AF_UNIX;
-+ strncpy(srvaddr.sun_path, CYRUS_SASLAUTHD_SOCKET,
-+ sizeof(srvaddr.sun_path));
-+ r = connect(s, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
-+ if (r == -1) {
-+ DEBUG(D_auth)
-+ debug_printf("Cannot connect to saslauthd daemon (at '%s'): %s\n",
-+ CYRUS_SASLAUTHD_SOCKET, strerror(errno));
-+ if (reply)
-+ *reply = string_sprintf("cannot connect to saslauthd daemon at "
-+ "%s: %s", strerror(errno));
-+ return PWCHECK_FAIL;
-+ }
-+
-+ if ( write_string(s, userid, strlen(userid)) < 0) {
-+ DEBUG(D_auth)
-+ debug_printf("Failed to send userid to saslauthd daemon \n");
-+ close(s);
-+ return PWCHECK_FAIL;
-+ }
-+
-+ if ( write_string(s, password, strlen(password)) < 0) {
-+ DEBUG(D_auth)
-+ debug_printf("Failed to send password to saslauthd daemon \n");
-+ close(s);
-+ return PWCHECK_FAIL;
-+ }
-+
-+ memset(password, 0, strlen(password));
-+
-+ if ( write_string(s, service, strlen(service)) < 0) {
-+ DEBUG(D_auth)
-+ debug_printf("Failed to send service name to saslauthd daemon \n");
-+ close(s);
-+ return PWCHECK_FAIL;
-+ }
-+
-+ if ( write_string(s, realm, strlen(realm)) < 0) {
-+ DEBUG(D_auth)
-+ debug_printf("Failed to send realm to saslauthd daemon \n");
-+ close(s);
-+ return PWCHECK_FAIL;
-+ }
-+
-+ if ( read_string(s, &daemon_reply ) < 2) {
-+ DEBUG(D_auth)
-+ debug_printf("Corrupted answer '%s' received. \n", daemon_reply);
-+ close(s);
-+ return PWCHECK_FAIL;
-+ }
-+
-+ close(s);
-+
-+ DEBUG(D_auth)
-+ debug_printf("Answer '%s' received. \n", daemon_reply);
-+
-+ *reply = daemon_reply;
-+
-+ if ( (daemon_reply[0] == 'O') && (daemon_reply[1] == 'K') )
-+ return PWCHECK_OK;
-+
-+ if ( (daemon_reply[0] == 'N') && (daemon_reply[1] == 'O') )
-+ return PWCHECK_NO;
-+
-+ return PWCHECK_FAIL;
-+}
-+
-+#endif
-+
-+
-+/* helper functions */
-+#if defined(CYRUS_PWCHECK_SOCKET) || defined(CYRUS_SASLAUTHD_SOCKET)
-+
-+#define MAX_REQ_LEN 1024
-+
-+/* written from scratch */
-+
-+/* FUNCTION: read_string */
-+
-+/* SYNOPSIS
-+ * read a sasld-style counted string into
-+ * store-allocated buffer, set pointer to the buffer,
-+ * return number of bytes read or -1 on failure.
-+ * END SYNOPSIS */
-+
-+static int read_string(int fd, uschar **retval) {
-+ unsigned short count;
-+ int rc;
-+
-+ rc = (retry_read(fd, &count, sizeof(count)) < (int) sizeof(count));
-+ if (!rc) {
-+ count = ntohs(count);
-+ if (count > MAX_REQ_LEN) {
-+ return -1;
-+ } else {
-+ *retval = store_get(count + 1);
-+ rc = (retry_read(fd, *retval, count) < (int) count);
-+ (*retval)[count] = '\0';
-+ return count;
-+ }
-+ }
-+}
-+
-+
-+/* FUNCTION: write_string */
-+
-+/* SYNOPSIS
-+ * write a sasld-style counted string into given fd
-+ * written bytes on success, -1 on failure.
-+ * END SYNOPSIS */
-+
-+static int write_string(int fd, const uschar *string, int len) {
-+ unsigned short count;
-+ int rc;
-+ struct iovec iov[2];
-+
-+ count = htons(len);
-+
-+ iov[0].iov_base = (void *) &count;
-+ iov[0].iov_len = sizeof(count);
-+ iov[1].iov_base = (void *) string;
-+ iov[1].iov_len = len;
-+
-+ rc = retry_writev(fd, iov, 2);
-+
-+ return rc;
-+}
-+
-+
-+/* taken from cyrus-sasl file saslauthd/saslauthd-unix.c */
-+
-+/* FUNCTION: retry_read */
-+
-+/* SYNOPSIS
-+ * Keep calling the read() system call with 'fd', 'buf', and 'nbyte'
-+ * until all the data is read in or an error occurs.
-+ * END SYNOPSIS */
-+static int retry_read(int fd, void *inbuf, unsigned nbyte)
-+{
-+ int n;
-+ int nread = 0;
-+ char *buf = (char *)inbuf;
-+
-+ if (nbyte == 0) return 0;
-+
-+ for (;;) {
-+ n = read(fd, buf, nbyte);
-+ if (n == 0) {
-+ /* end of file */
-+ return -1;
-+ }
-+ if (n == -1) {
-+ if (errno == EINTR) continue;
-+ return -1;
-+ }
-+
-+ nread += n;
-+
-+ if (n >= (int) nbyte) return nread;
-+
-+ buf += n;
-+ nbyte -= n;
-+ }
-+}
-+
-+/* END FUNCTION: retry_read */
-+
-+/* FUNCTION: retry_writev */
-+
-+/* SYNOPSIS
-+ * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt'
-+ * until all the data is written out or an error occurs.
-+ * END SYNOPSIS */
-+
-+static int /* R: bytes written, or -1 on error */
-+retry_writev (
-+ /* PARAMETERS */
-+ int fd, /* I: fd to write on */
-+ struct iovec *iov, /* U: iovec array base
-+ * modified as data written */
-+ int iovcnt /* I: number of iovec entries */
-+ /* END PARAMETERS */
-+ )
-+{
-+ /* VARIABLES */
-+ int n; /* return value from writev() */
-+ int i; /* loop counter */
-+ int written; /* bytes written so far */
-+ static int iov_max; /* max number of iovec entries */
-+ /* END VARIABLES */
-+
-+ /* initialization */
-+#ifdef MAXIOV
-+ iov_max = MAXIOV;
-+#else /* ! MAXIOV */
-+# ifdef IOV_MAX
-+ iov_max = IOV_MAX;
-+# else /* ! IOV_MAX */
-+ iov_max = 8192;
-+# endif /* ! IOV_MAX */
-+#endif /* ! MAXIOV */
-+ written = 0;
-+
-+ for (;;) {
-+
-+ while (iovcnt && iov[0].iov_len == 0) {
-+ iov++;
-+ iovcnt--;
-+ }
-+
-+ if (!iovcnt) {
-+ return written;
-+ }
-+
-+ n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
-+ if (n == -1) {
-+ if (errno == EINVAL && iov_max > 10) {
-+ iov_max /= 2;
-+ continue;
-+ }
-+ if (errno == EINTR) {
-+ continue;
-+ }
-+ return -1;
-+ } else {
-+ written += n;
-+ }
-+
-+ for (i = 0; i < iovcnt; i++) {
-+ if (iov[i].iov_len > (unsigned) n) {
-+ iov[i].iov_base = (char *)iov[i].iov_base + n;
-+ iov[i].iov_len -= n;
-+ break;
-+ }
-+ n -= iov[i].iov_len;
-+ iov[i].iov_len = 0;
-+ }
-+
-+ if (i == iovcnt) {
-+ return written;
-+ }
-+ }
-+ /* NOTREACHED */
-+}
-+
-+/* END FUNCTION: retry_writev */
-+#endif
- /* End of auths/pwcheck.c */
-diff -urP exim-4.20.orig/src/auths/pwcheck.h exim-4.20/src/auths/pwcheck.h
---- exim-4.20.orig/src/auths/pwcheck.h 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/auths/pwcheck.h 2003-07-09 02:04:37.000000000 +0200
-@@ -9,13 +9,18 @@
- daemon. */
-
- /* Error codes */
-+/* OK - auth successful
-+ NO - access denied
-+ FAIL - [temporary] failure */
-+
-
- #define PWCHECK_OK 0
--#define PWCHECK_BAD 1
-+#define PWCHECK_NO 1
- #define PWCHECK_FAIL 2
-
--/* Cyrus function for doing the business */
-+/* Cyrus functions for doing the business */
-
- extern int pwcheck_verify_password(const char *, const char *, const char **);
-+extern int saslauthd_verify_password(const char *, const char *, const char *, const char *, const char **);
-
- /* End of pwcheck.h */
-diff -urP exim-4.20.orig/src/config.h.defaults exim-4.20/src/config.h.defaults
---- exim-4.20.orig/src/config.h.defaults 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/config.h.defaults 2003-07-09 02:04:37.000000000 +0200
-@@ -23,6 +23,7 @@
- #define CONFIGURE_FILE_USE_EUID
- #define CONFIGURE_FILE_USE_NODE
- #define CYRUS_PWCHECK_SOCKET
-+#define CYRUS_SASLAUTHD_SOCKET
-
- #define DEFAULT_CRYPT crypt
- #define DELIVER_IN_BUFFER_SIZE 8192
-diff -urP exim-4.20.orig/src/EDITME exim-4.20/src/EDITME
---- exim-4.20.orig/src/EDITME 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/EDITME 2003-07-09 02:04:37.000000000 +0200
-@@ -523,6 +523,20 @@
-
-
- #------------------------------------------------------------------------------
-+# Support for authentication via the Cyrus SASL saslauthd daemon is available.
-+# The Exim support, which is intented for use in conjunction with the SMTP AUTH
-+# facilities, is included only when requested by setting the following
-+# parameter to the location of the saslauthd daemon's socket directory.
-+#
-+# There is no need to install all of SASL on your system. You just need to run
-+# ./configure --with-saslauthd, cd to the saslauthd directory with sources, make
-+# and make install. You must create the socket directory (default /var/saslauthd)
-+# and chown it to exim's user and group. Once you have installed saslauthd, you
-+# should arrange for it to be started by root at boot time.
-+
-+CYRUS_SASLAUTHD_SOCKET=/var/lib/sasl2/mux
-+
-+#------------------------------------------------------------------------------
- # TCP wrappers: If you want to use tcpwrappers from within Exim, uncomment
- # this setting. See the manual section entitled "Use of tcpwrappers" in the
- # chapter on building and installing Exim.
-diff -urP exim-4.20.orig/src/expand.c exim-4.20/src/expand.c
---- exim-4.20.orig/src/expand.c 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/expand.c 2003-07-09 02:04:37.000000000 +0200
-@@ -1264,6 +1264,7 @@
- radius: does RADIUS authentication
- ldapauth: does LDAP authentication
- pwcheck: does Cyrus SASL pwcheck authentication
-+ saslauthd: does Cyrus SASL saslauthd authentication
- */
-
- else if (Ustrcmp(name, "exists") == 0
-@@ -1271,14 +1272,17 @@
- || Ustrcmp(name, "pam") == 0
- #endif /* SUPPORT_PAM */
- #ifdef RADIUS_CONFIG_FILE
-- || Ustrcmp(name, "radius") == 0
-- #endif /* RADIUS_CONFIG_FILE */
-+ || Ustrcmp(name, "radius") == 0
-+ #endif /* RADIUS_CONFIG_FILE */
- #ifdef LOOKUP_LDAP
- || Ustrcmp(name, "ldapauth") == 0
- #endif
- #ifdef CYRUS_PWCHECK_SOCKET
-- || Ustrcmp(name, "pwcheck") == 0
-- #endif
-+ || Ustrcmp(name, "pwcheck") == 0
-+ #endif
-+ #ifdef CYRUS_SASLAUTHD_SOCKET
-+ | Ustrcmp(name, "saslauthd") == 0
-+ #endif
- )
- {
- uschar *sub;
-@@ -1306,7 +1310,7 @@
- if (name[0] == 'p' && name[1] == 'a')
- rc = auth_call_pam(sub, &expand_string_message);
- #if defined(RADIUS_CONFIG_FILE) || defined(LOOKUP_LDAP) ||\
-- defined(CYRUS_PWCHECK_SOCKET)
-+ defined(CYRUS_PWCHECK_SOCKET) || defined(CYRUS_SASLAUTHD_SOCKET)
- else
- #endif
- #endif /* SUPPORT_PAM */
-@@ -1314,7 +1318,7 @@
- #ifdef RADIUS_CONFIG_FILE
- if (name[0] == 'r')
- rc = auth_call_radius(sub, &expand_string_message);
-- #if defined(LOOKUP_LDAP) || defined(CYRUS_PWCHECK_SOCKET)
-+ #if defined(LOOKUP_LDAP) || defined(CYRUS_PWCHECK_SOCKET) || defined(CYRUS_SASLAUTHD_SOCKET)
- else
- #endif
- #endif /* RADIUS_CONFIG_FILE */
-@@ -1323,16 +1327,24 @@
- if (name[0] == 'l')
- rc = eldapauth_find((void *)(-1), NULL, sub, Ustrlen(sub), NULL,
- &expand_string_message);
-- #if defined(CYRUS_PWCHECK_SOCKET)
-+ #if defined(CYRUS_PWCHECK_SOCKET) || defined(CYRUS_SASLAUTHD_SOCKET)
- else
- #endif
- #endif /* LOOKUP_LDAP */
-
- #ifdef CYRUS_PWCHECK_SOCKET
- if (name[0] == 'p')
-- rc = auth_call_pwcheck(sub, &expand_string_message);
-+ rc = auth_call_pwcheck(sub, &expand_string_message);
-+ #if defined(CYRUS_SASLAUTHD_SOCKET)
-+ else
-+ #endif
- #endif /* CYRUS_PWCHECK_SOCKET */
-
-+ #ifdef CYRUS_SASLAUTHD_SOCKET
-+ if (name[0] == 's')
-+ rc = auth_call_saslauthd(sub, &expand_string_message);
-+ #endif /* CYRUS_SASLAUTHD_SOCKET */
-+
- if (rc == ERROR || rc == DEFER) return NULL;
- *yield = (rc == OK) == testfor;
- }
-diff -urP exim-4.20.orig/src/functions.h exim-4.20/src/functions.h
---- exim-4.20.orig/src/functions.h 2003-07-09 02:04:25.000000000 +0200
-+++ exim-4.20/src/functions.h 2003-07-09 02:04:37.000000000 +0200
-@@ -42,6 +42,7 @@
- extern int auth_b64decode(uschar *, uschar **);
- extern int auth_call_pam(uschar *, uschar **);
- extern int auth_call_pwcheck(uschar *, uschar **);
-+extern int auth_call_saslauthd(uschar *, uschar **);
- extern int auth_call_radius(uschar *, uschar **);
- extern int auth_get_data(uschar **, uschar *);
- extern int auth_get_no64_data(uschar **, uschar *);