aports/testing/maildrop/maildrop-2.3.0-dovecotauth.patch
2014-10-28 12:59:15 +01:00

821 lines
22 KiB
Diff

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.