diff options
Diffstat (limited to 'unmaintained/maildrop/maildrop-2.3.0-dovecotauth.patch')
-rw-r--r-- | unmaintained/maildrop/maildrop-2.3.0-dovecotauth.patch | 820 |
1 files changed, 820 insertions, 0 deletions
diff --git a/unmaintained/maildrop/maildrop-2.3.0-dovecotauth.patch b/unmaintained/maildrop/maildrop-2.3.0-dovecotauth.patch new file mode 100644 index 0000000000..1b9319c51e --- /dev/null +++ b/unmaintained/maildrop/maildrop-2.3.0-dovecotauth.patch @@ -0,0 +1,820 @@ +diff -Naur maildrop-2.3.0/maildrop/dovecotauth.c maildrop-2.3.0-dovecotauth/maildrop/dovecotauth.c
+--- maildrop-2.3.0/maildrop/dovecotauth.c 1970-01-01 01:00:00.000000000 +0100
++++ maildrop-2.3.0-dovecotauth/maildrop/dovecotauth.c 2010-01-31 15:01:38.000000000 +0100
+@@ -0,0 +1,480 @@
++/*
++** Copyright 2009 Marko Njezic
++** Licensed under the same terms as Courier Authlib AND/OR Courier Maildrop.
++**
++** Partially based on authdaemonlib.c from Courier Authlib, which had the following statement:
++**
++** Copyright 2000-2006 Double Precision, Inc. See COPYING for
++** distribution information.
++**
++** Code that was taken from authdaemonlib.c is as follows:
++** - s_connect() function
++** - opensock() function with modification to accept socket address
++** - writeauth() function
++** - readline() function with related support functions (with modification
++** to time-out after TIMEOUT_READ seconds)
++*/
++
++#include "dovecotauth.h"
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <pwd.h>
++#include <time.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <sys/select.h>
++
++static const char rcsid[]="$Id$";
++
++static int TIMEOUT_SOCK=10,
++ TIMEOUT_WRITE=10,
++ TIMEOUT_READ=30;
++
++static int s_connect(int sockfd,
++ const struct sockaddr *addr,
++ size_t addr_s,
++ time_t connect_timeout)
++{
++ fd_set fdr;
++ struct timeval tv;
++ int rc;
++
++#ifdef SOL_KEEPALIVE
++ setsockopt(sockfd, SOL_SOCKET, SOL_KEEPALIVE,
++ (const char *)&dummy, sizeof(dummy));
++#endif
++
++#ifdef SOL_LINGER
++ {
++ struct linger l;
++
++ l.l_onoff=0;
++ l.l_linger=0;
++
++ setsockopt(sockfd, SOL_SOCKET, SOL_LINGER,
++ (const char *)&l, sizeof(l));
++ }
++#endif
++
++ /*
++ ** If configuration says to use the kernel's timeout settings,
++ ** just call connect, and be done with it.
++ */
++
++ if (connect_timeout == 0)
++ return ( connect(sockfd, addr, addr_s));
++
++ /* Asynchronous connect with timeout. */
++
++ if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) return (-1);
++
++ if ( connect(sockfd, addr, addr_s) == 0)
++ {
++ /* That was easy, we're done. */
++
++ if (fcntl(sockfd, F_SETFL, 0) < 0) return (-1);
++ return (0);
++ }
++
++ if (errno != EINPROGRESS)
++ return -1;
++
++ /* Wait for the connection to go through, until the timeout expires */
++
++ FD_ZERO(&fdr);
++ FD_SET(sockfd, &fdr);
++ tv.tv_sec=connect_timeout;
++ tv.tv_usec=0;
++
++ rc=select(sockfd+1, 0, &fdr, 0, &tv);
++ if (rc < 0) return (-1);
++
++ if (!FD_ISSET(sockfd, &fdr))
++ {
++ errno=ETIMEDOUT;
++ return (-1);
++ }
++
++ {
++ int gserr;
++ socklen_t gslen = sizeof(gserr);
++
++ if (getsockopt(sockfd, SOL_SOCKET,
++ SO_ERROR,
++ (char *)&gserr, &gslen)==0)
++ {
++ if (gserr == 0)
++ return 0;
++
++ errno=gserr;
++ }
++ }
++ return (-1);
++}
++
++static int opensock(const char *addr)
++{
++ int s=socket(PF_UNIX, SOCK_STREAM, 0);
++ struct sockaddr_un skun;
++
++ skun.sun_family=AF_UNIX;
++ strncpy(skun.sun_path, addr, sizeof(skun.sun_path));
++
++ if (s < 0)
++ {
++ perror("CRIT: dovecotauth: socket() failed");
++ return (-1);
++ }
++
++ {
++ const char *p=getenv("TIMEOUT_SOCK");
++ int n=atoi(p ? p:"0");
++
++ if (n > 0)
++ TIMEOUT_SOCK=n;
++ }
++
++ {
++ const char *p=getenv("TIMEOUT_READ");
++ int n=atoi(p ? p:"0");
++
++ if (n > 0)
++ TIMEOUT_READ=n;
++ }
++
++ {
++ const char *p=getenv("TIMEOUT_WRITE");
++ int n=atoi(p ? p:"0");
++
++ if (n > 0)
++ TIMEOUT_WRITE=n;
++ }
++
++ if (s_connect(s, (const struct sockaddr *)&skun, sizeof(skun),
++ TIMEOUT_SOCK))
++ {
++ perror("ERR: dovecotauth: s_connect() failed");
++ if (errno == ETIMEDOUT || errno == ECONNREFUSED)
++ fprintf(stderr, "ERR: [Hint: perhaps dovecot-auth daemon is not running?]\n");
++ close(s);
++ return (-1);
++ }
++ return (s);
++}
++
++static int writeauth(int fd, const char *p, unsigned pl)
++{
++fd_set fds;
++struct timeval tv;
++
++ while (pl)
++ {
++ int n;
++
++ FD_ZERO(&fds);
++ FD_SET(fd, &fds);
++ tv.tv_sec=TIMEOUT_WRITE;
++ tv.tv_usec=0;
++ if (select(fd+1, 0, &fds, 0, &tv) <= 0 || !FD_ISSET(fd, &fds))
++ return (-1);
++ n=write(fd, p, pl);
++ if (n <= 0) return (-1);
++ p += n;
++ pl -= n;
++ }
++ return (0);
++}
++
++struct enum_getch {
++ char buffer[BUFSIZ];
++ char *buf_ptr;
++ size_t buf_left;
++};
++
++#define getauthc(fd,eg) ((eg)->buf_left-- ? \
++ (unsigned char)*((eg)->buf_ptr)++:\
++ fillgetauthc((fd),(eg)))
++
++static int fillgetauthc(int fd, struct enum_getch *eg)
++{
++ time_t end_time, curtime;
++
++ time(&end_time);
++ end_time += TIMEOUT_READ;
++
++ for (;;)
++ {
++ int n;
++ fd_set fds;
++ struct timeval tv;
++
++ time(&curtime);
++ if (curtime >= end_time)
++ break;
++
++ FD_ZERO(&fds);
++ FD_SET(fd, &fds);
++ tv.tv_sec=end_time - curtime;
++ tv.tv_usec=0;
++ if (select(fd+1, &fds, 0, 0, &tv) <= 0 || !FD_ISSET(fd, &fds))
++ break;
++
++ n=read(fd, eg->buffer, sizeof(eg->buffer));
++ if (n <= 0)
++ break;
++
++ eg->buf_ptr=eg->buffer;
++ eg->buf_left=n;
++
++ --eg->buf_left;
++ return (unsigned char)*(eg->buf_ptr)++;
++ }
++ return EOF;
++}
++
++static int readline(int fd, struct enum_getch *eg,
++ char *buf,
++ size_t bufsize)
++{
++ if (bufsize == 0)
++ return EOF;
++
++ while (--bufsize)
++ {
++ int ch=getauthc(fd, eg);
++
++ if (ch == EOF)
++ return -1;
++ if (ch == '\n')
++ break;
++
++ *buf++=ch;
++ }
++ *buf=0;
++ return 0;
++}
++
++/*
++** The actual implementation of Dovecot authentication protocol handling follows.
++** Full specification of the protocol can be found at: http://wiki.dovecot.org/Authentication%20Protocol
++** We are only interested in the "master" type requests for user information.
++*/
++
++int parse_userinfo(const char *user, const char *linebuf,
++ int (*func)(struct dovecotauthinfo *, void *), void *arg)
++{
++ int return_value=1;
++ struct dovecotauthinfo a;
++ char *buf, *p;
++ uid_t u;
++
++ /* Validate input arguments */
++ if (!user || !linebuf)
++ return (1);
++
++ /* Try to allocate buffer */
++ buf = (char *)malloc(strlen(linebuf)+1);
++ if (!buf)
++ return (1);
++ strcpy(buf, linebuf);
++
++ memset(&a, 0, sizeof(a));
++ a.homedir="";
++
++ p = strtok(buf, "\t");
++ if (p)
++ a.address=p;
++ else
++ a.address=user;
++
++ /* Parse any additional parameters */
++ while ((p = strtok(0, "\t")) != 0)
++ {
++ if (strncmp(p, "uid=", 4) == 0)
++ {
++ u=atol(p+4);
++ a.sysuserid = &u;
++ if (u == 0)
++ {
++ fprintf(stderr, "ERR: dovecotauth: Received invalid uid from auth socket\n");
++ return_value=1;
++ goto cleanup_parse_userinfo;
++ }
++ }
++ else if (strncmp(p, "gid=", 4) == 0)
++ {
++ a.sysgroupid=atol(p+4);
++ if (a.sysgroupid == 0)
++ {
++ fprintf(stderr, "ERR: dovecotauth: Received invalid gid from auth socket\n");
++ return_value=1;
++ goto cleanup_parse_userinfo;
++ }
++ }
++ else if (strncmp(p, "system_user=", 12) == 0)
++ {
++ a.sysusername=p+12;
++ if (a.sysusername)
++ {
++ struct passwd *q=getpwnam(a.sysusername);
++
++ if (q && q->pw_uid == 0)
++ {
++ fprintf(stderr, "ERR: dovecotauth: Received invalid system user from auth socket\n");
++ return_value=1;
++ goto cleanup_parse_userinfo;
++ }
++ }
++ }
++ else if (strncmp(p, "home=", 5) == 0)
++ {
++ a.homedir=p+5;
++ }
++ else if (strncmp(p, "mail=", 5) == 0)
++ {
++ a.maildir=p+5;
++ }
++ }
++
++ return_value = (*func)(&a, arg);
++
++cleanup_parse_userinfo:
++ free(buf);
++ return return_value;
++}
++
++#define DOVECOTAUTH_LINEBUFSIZE 8192
++
++int _dovecotauth_getuserinfo(int wrfd, int rdfd, const char *user,
++ int (*func)(struct dovecotauthinfo *, void *), void *arg)
++{
++ static char cmdpart1[]="VERSION\t1\t0\nUSER\t1\t";
++ static char cmdpart2[]="\tservice=maildrop\n";
++ int return_value=1, handshake=0;
++ struct enum_getch eg;
++ char *cmdbuf, *linebuf;
++
++ /* Validate input arguments */
++ if (!user)
++ return (1);
++
++ /* Try to allocate buffers */
++ cmdbuf=(char *)malloc(strlen(cmdpart1)+strlen(cmdpart2)+strlen(user)+20);
++ if (!cmdbuf)
++ return (1);
++
++ linebuf=(char *)malloc(DOVECOTAUTH_LINEBUFSIZE);
++ if (!linebuf)
++ return (1);
++
++ /* Initial handshake */
++ eg.buf_left=0;
++ while (readline(rdfd, &eg, linebuf, DOVECOTAUTH_LINEBUFSIZE) == 0)
++ {
++ if (strncmp(linebuf, "VERSION\t", 8) == 0)
++ {
++ if (strncmp(linebuf+8, "1\t", 2) != 0)
++ {
++ fprintf(stderr, "ERR: dovecotauth: Authentication protocol version mismatch\n");
++ return_value=1;
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++ }
++ else if (strncmp(linebuf, "SPID\t", 5) == 0)
++ {
++ /* End of server side handshake */
++ handshake=1;
++ break;
++ }
++ }
++
++ if (!handshake)
++ {
++ fprintf(stderr, "ERR: dovecotauth: Did not receive proper server handshake from auth socket\n");
++ return_value=1;
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++
++ /*
++ ** Try to be helpful in case that user tries to connect to the wrong auth socket.
++ ** There's a slight chance that this won't execute in case that the previously
++ ** returned line ends exactly at the buffer end, but we won't handle that case,
++ ** since this is just a hint to the user, and not really neccessary.
++ ** Normally, if user tries to communicate with wrong auth socket,
++ ** we would simply time-out, while waiting for information.
++ */
++ if (eg.buf_left > 0 && readline(rdfd, &eg, linebuf, DOVECOTAUTH_LINEBUFSIZE) == 0)
++ {
++ if (strncmp(linebuf, "CUID\t", 5) == 0)
++ {
++ fprintf(stderr, "ERR: dovecotauth: Trying to connect to what appears to be a client auth socket, instead of a master auth socket\n");
++ return_value=1;
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++ }
++
++ /* Generate our part of communication */
++ strcat(strcat(strcpy(cmdbuf, cmdpart1), user), cmdpart2);
++
++ /* Send our part of communication */
++ if (writeauth(wrfd, cmdbuf, strlen(cmdbuf)))
++ {
++ return_value=1;
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++
++ /* Parse returned information */
++ eg.buf_left=0;
++ if (readline(rdfd, &eg, linebuf, DOVECOTAUTH_LINEBUFSIZE) == 0)
++ {
++ if (strncmp(linebuf, "USER\t1\t", 7) == 0)
++ {
++ /* User was found in the database and we now parse returned information */
++ return_value=parse_userinfo(user, linebuf+7, func, arg);
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++ else if (strcmp(linebuf, "NOTFOUND\t1") == 0)
++ {
++ /* User was not found in the database */
++ return_value=-1; /* Negative return value means that user is not found! */
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++ else if (strncmp(linebuf, "FAIL\t1", 6) == 0)
++ {
++ /* An internal error has occurred on Dovecot's end */
++ return_value=1;
++ goto cleanup_dovecotauth_getuserinfo;
++ }
++ else
++ {
++ fprintf(stderr, "ERR: dovecotauth: Received unknown input from auth socket\n");
++ }
++ }
++ else
++ fprintf(stderr, "ERR: dovecotauth: Did not receive proper input from auth socket\n");
++
++cleanup_dovecotauth_getuserinfo:
++ free(cmdbuf);
++ free(linebuf);
++ return return_value;
++}
++
++int dovecotauth_getuserinfo(const char *addr, const char *user,
++ int (*func)(struct dovecotauthinfo *, void *), void *arg)
++{
++ int s=opensock(addr);
++ int rc;
++
++ if (s < 0)
++ {
++ return (1);
++ }
++ rc = _dovecotauth_getuserinfo(s, s, user, func, arg);
++ close(s);
++ return rc;
++}
+diff -Naur maildrop-2.3.0/maildrop/dovecotauth.h maildrop-2.3.0-dovecotauth/maildrop/dovecotauth.h
+--- maildrop-2.3.0/maildrop/dovecotauth.h 1970-01-01 01:00:00.000000000 +0100
++++ maildrop-2.3.0-dovecotauth/maildrop/dovecotauth.h 2010-01-31 15:01:38.000000000 +0100
+@@ -0,0 +1,59 @@
++#ifndef dovecotauth_h
++#define dovecotauth_h
++
++/*
++** Copyright 2009 Marko Njezic
++** Licensed under the same terms as Courier Authlib AND/OR Courier Maildrop.
++**
++** Partially based on courierauth.h from Courier Authlib, which had the following statement:
++**
++** Copyright 2004 Double Precision, Inc. See COPYING for
++** distribution information.
++*/
++
++#include <sys/types.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++static const char dovecotauth_h_rcsid[]="$Id$";
++
++struct dovecotauthinfo {
++ const char *address;
++ const char *sysusername;
++ const uid_t *sysuserid;
++ gid_t sysgroupid;
++ const char *homedir;
++ const char *maildir;
++ } ;
++
++/*
++ This structure is modeled after authinfo structure from Courier Authlib.
++
++ Either sysusername or sysuserid may be NULL, but not both of them.
++ They, and sysgroupid, specify the authenticated user's system
++ userid and groupid. homedir points to the authenticated user's
++ home directory. address and maildir, are obvious.
++
++ After populating this tructure, the lookup function calls the
++ callback function that's specified in its second argument. The
++ callback function receives a pointer to the authinfo structure.
++
++ The callback function also receives a context pointer, which is
++ the third argument to the lookup function.
++
++ The lookup function should return a negative value if the userid
++ does not exist, a positive value if there was a temporary error
++ looking up the userid, or whatever is the return code from the
++ callback function, if the user exists.
++*/
++
++int dovecotauth_getuserinfo(const char *addr, const char *user,
++ int (*func)(struct dovecotauthinfo *, void *), void *arg);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+diff -Naur maildrop-2.3.0/maildrop/main.C maildrop-2.3.0-dovecotauth/maildrop/main.C
+--- maildrop-2.3.0/maildrop/main.C 2009-09-06 01:12:45.000000000 +0200
++++ maildrop-2.3.0-dovecotauth/maildrop/main.C 2010-01-31 15:11:08.000000000 +0100
+@@ -32,6 +32,16 @@
+ #include <pwd.h>
+ #include <grp.h>
+ #include "../dbobj.h"
++
++/*
++** This switch can later be moved to config.h file with appropriate
++** configure option like --with-dovecotauth or something similar
++*/
++#define DOVECOTAUTH 1
++#if DOVECOTAUTH
++#include "dovecotauth.h"
++#endif
++
+ #if AUTHLIB
+ #include <courierauth.h>
+ #endif
+@@ -171,6 +181,14 @@
+ "\n"
+ #endif
+ #endif
++#if DOVECOTAUTH
++ "Dovecot Authentication extension enabled."
++#if CRLF_TERM
++ "\r\n"
++#else
++ "\n"
++#endif
++#endif
+ #if AUTHLIB
+ "Courier Authentication Library extension enabled."
+ #if CRLF_TERM
+@@ -337,6 +355,98 @@
+ }
+ #endif
+
++#if DOVECOTAUTH
++static int callback_dovecotauth(struct dovecotauthinfo *auth,
++ void *void_arg)
++{
++ Maildrop &maildrop=*(Maildrop *)void_arg;
++
++ if (VerboseLevel() > 1)
++ {
++ Buffer b;
++
++ b.set(auth->sysgroupid);
++ b.push(0);
++
++ merr << "maildrop: dovecotauth: groupid="
++ << b << "\n";
++ }
++
++ setgroupid(auth->sysgroupid);
++
++ uid_t u;
++ if (auth->sysusername)
++ {
++ struct passwd *q=getpwnam(auth->sysusername);
++
++ if (q == NULL)
++ {
++ merr << "Cannot find system user "
++ << auth->sysusername
++ << "\n";
++
++ nochangeuidgid();
++ }
++
++ u=q->pw_uid;
++ }
++ else
++ u=*auth->sysuserid;
++
++ if (VerboseLevel() > 1)
++ {
++ Buffer b;
++
++ b.set(u);
++ b.push(0);
++
++ merr << "maildrop: dovecotauth: userid="
++ << b << "\n";
++ }
++
++ setuid(u);
++
++ if ( getuid() != u)
++ nochangeuidgid();
++
++ if (VerboseLevel() > 1)
++ {
++ merr << "maildrop: dovecotauth: logname="
++ << auth->address
++ << ", home="
++ << auth->homedir
++ << ", mail="
++ << (auth->maildir ? auth->maildir:"(default)")
++ << "\n";
++ }
++
++ maildrop.init_home=auth->homedir;
++ maildrop.init_logname=auth->address;
++ maildrop.init_shell="/bin/sh";
++ maildrop.init_default=auth->maildir ? auth->maildir:
++ GetDefaultMailbox(auth->address);
++
++ return 0;
++}
++
++int find_in_dovecotauth(const char *addr, Maildrop *maildrop, const char* user)
++{
++ int rc=dovecotauth_getuserinfo(addr,
++ user, callback_dovecotauth, maildrop);
++
++ if (rc == 0)
++ return 1;
++
++ if (rc > 0)
++ {
++ errexit=EX_TEMPFAIL;
++ throw "Temporary authentication failure.";
++ }
++
++ return 0;
++}
++#endif
++
+ static void tempfail(const char *msg)
+ {
+ errexit = EX_TEMPFAIL;
+@@ -361,6 +471,9 @@
+ const char *numuidgid=0;
+ #endif
+ #endif
++#if DOVECOTAUTH
++const char *dovecotauth_addr=0;
++#endif
+
+
+ umask( 0007 );
+@@ -446,6 +559,18 @@
+ case 'a':
+ maildrop.authlib_essential=1;
+ break;
++#if DOVECOTAUTH
++ case 't':
++ if (!*optarg && argn < argc) optarg=argv[argn++];
++ if (!*optarg)
++ {
++ mout << "You didn't specify the location of Dovecot auth socket.\n";
++ return (EX_TEMPFAIL);
++ }
++ else
++ dovecotauth_addr=optarg;
++ break;
++#endif
+ case 'h':
+ help();
+ return (EX_TEMPFAIL);
+@@ -467,7 +592,17 @@
+
+ if (*deliverymode)
+ {
+- found = find_in_authlib(&maildrop, deliverymode);
++
++#if DOVECOTAUTH
++ if (dovecotauth_addr)
++ {
++ found = find_in_dovecotauth(dovecotauth_addr, &maildrop, deliverymode);
++ }
++ else
++#endif
++ {
++ found = find_in_authlib(&maildrop, deliverymode);
++ }
+
+ if ( !found )
+ {
+diff -Naur maildrop-2.3.0/maildrop/Makefile.am maildrop-2.3.0-dovecotauth/maildrop/Makefile.am
+--- maildrop-2.3.0/maildrop/Makefile.am 2009-11-14 23:16:32.000000000 +0100
++++ maildrop-2.3.0-dovecotauth/maildrop/Makefile.am 2010-01-31 15:01:38.000000000 +0100
+@@ -46,7 +46,7 @@
+ recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \
+ reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \
+ rematchstr.C rematchstr.h search.C search.h token.C \
+- token.h varlist.C varlist.h
++ token.h varlist.C varlist.h dovecotauth.c dovecotauth.h
+
+ maildrop_DEPENDENCIES = libmdcommon.la ../maildir/maildir.libdeps
+
+diff -Naur maildrop-2.3.0/maildrop/Makefile.in maildrop-2.3.0-dovecotauth/maildrop/Makefile.in
+--- maildrop-2.3.0/maildrop/Makefile.in 2009-12-25 23:14:47.000000000 +0100
++++ maildrop-2.3.0-dovecotauth/maildrop/Makefile.in 2010-01-31 15:01:38.000000000 +0100
+@@ -88,7 +88,7 @@
+ re.$(OBJEXT) recipe.$(OBJEXT) recipenode.$(OBJEXT) \
+ recipeparse.$(OBJEXT) reeval.$(OBJEXT) rematch.$(OBJEXT) \
+ rematchmsg.$(OBJEXT) rematchstr.$(OBJEXT) search.$(OBJEXT) \
+- token.$(OBJEXT) varlist.$(OBJEXT)
++ token.$(OBJEXT) varlist.$(OBJEXT) dovecotauth.$(OBJEXT)
+ maildrop_OBJECTS = $(am_maildrop_OBJECTS)
+ maildrop_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+@@ -308,7 +308,7 @@
+ recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \
+ reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \
+ rematchstr.C rematchstr.h search.C search.h token.C \
+- token.h varlist.C varlist.h
++ token.h varlist.C varlist.h dovecotauth.c dovecotauth.h
+
+ maildrop_DEPENDENCIES = libmdcommon.la ../maildir/maildir.libdeps
+ maildrop_LDADD = libmdcommon.la `cat ../maildir/maildir.libdeps`\
+@@ -471,6 +471,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempfile.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varlist.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dovecotauth.Po@am__quote@
+
+ .C.o:
+ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+diff -Naur maildrop-2.3.0/README.dovecotauth maildrop-2.3.0-dovecotauth/README.dovecotauth
+--- maildrop-2.3.0/README.dovecotauth 1970-01-01 01:00:00.000000000 +0100
++++ maildrop-2.3.0-dovecotauth/README.dovecotauth 2010-01-31 15:01:38.000000000 +0100
+@@ -0,0 +1,46 @@
++Dovecot Authentication extension for maildrop
++=============================================
++** Copyright 2009 Marko Njezic
++** Licensed under the same terms as Courier Authlib AND/OR Courier Maildrop.
++
++When you patch maildrop to include Dovecot Authentication extension, you'll be
++able to do user database lookups against Dovecot. This extension can happily
++coexist with Courier Authlib extension if it is also compiled.
++
++In order to use it you'll need to specify additional option "-t" that will point
++to the location of Dovecot's auth master socket when starting maildrop in
++delivery mode. For example:
++
++maildrop -d USER -t /var/run/dovecot/auth-master
++
++By specifying "-t" option, maildrop will first try user lookup against Dovecot's
++database. If user is not found, maildrop will fallback to local user database
++(i.e. passwd), as usual. Lookups against Courier Authlib will not be done when
++"-t" option is specified. If you want to perform such lookup when both
++extensions are compiled, simply remove "-t" option and maildrop will behave as
++usual.
++
++One significant difference compared to Courier Authlib extension is that Dovecot
++Authentication extension will never return uid/gid that's equal to zero. If such
++value was returned from database, maildrop will exit with temporary failure.
++This was done in order to prevent accidental mistakes. If you really want to
++deliver as/to root, you'll have to start maildrop without "-t" option and let
++it directly query system user database on its own.
++
++Make sure that correct permissions are set on Dovecot's auth master socket so
++that maildrop can communicate with it. Also, depending on what type of users are
++being served from Dovecot's database, if user lookup returns local user
++accounts, you may end up with problems when maildrop tries to write mails to the
++spool directory if wrong permission are set on it, since maildrop will reset its
++permissions (uid/gid) to the values returned from user database. This behavior
++is the same as the behavior of lookups against Courier Authlib, since they also
++reset maildrop's permissions. When you want maildrop to deliver to the local
++users, it's best to let it directly query system user database on its own,
++since then it can apply its own "RESET_GID" magic, which will hopefully result
++in "correct" permissions that will allow maildrop to write to the spool
++directory.
++
++And last but not least, I hope that you'll find this extension useful.
++Especially if you already have an existing user database in Dovecot, but would
++like to use maildrop (with its powerful "xfilter" command) to deliver e-mails,
++without setting up another authentication user database, like Courier Authlib.
|