X-Original-To: alpine-devel@lists.alpinelinux.org Delivered-To: alpine-devel@lists.alpinelinux.org Received: from mailhost.ba.ew.sk (smtp.swan.sk [212.26.172.11]) by lists.alpinelinux.org (Postfix) with ESMTP id 328151EBFF6 for ; Fri, 4 Feb 2011 22:47:39 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by mailhost.ba.ew.sk (Postfix) with ESMTP id BA5D034A73 for ; Fri, 4 Feb 2011 23:47:37 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mailhost.ba.ew.sk Received: from mailhost.ba.ew.sk ([127.0.0.1]) by localhost (mailhost2.ba.ew.sk [127.0.0.1]) (amavisd-new, port 10024) with LMTP id wmNQvMqaotLB for ; Fri, 4 Feb 2011 23:47:37 +0100 (CET) Received: from alpine.localdomain (unknown [62.197.204.231]) by mailhost.ba.ew.sk (Postfix) with ESMTP id 8CE7834A58 for ; Fri, 4 Feb 2011 23:47:37 +0100 (CET) Received: from alpine.sofy.sk (localhost [127.0.0.1]) by alpine.localdomain (Postfix) with ESMTP id EFA86205 for ; Fri, 4 Feb 2011 23:47:36 +0100 (MET) Date: Fri, 4 Feb 2011 23:47:36 +0100 From: Juraj Sujan To: alpine-devel@lists.alpinelinux.org Subject: [alpine-devel] maildrop: new aport Message-ID: <20110204234736.2b4ac96c@alpine.sofy.sk> X-Mailer: Claws Mail 3.7.8 (GTK+ 2.22.1; x86_64-unknown-linux-gnu) X-Mailinglist: alpine-devel Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/5BhdIZmLDKAl7UHPOY9bAFu" --MP_/5BhdIZmLDKAl7UHPOY9bAFu Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi, I've created APKBUILD for maildrop and I've also included the dovecotauth patch, so there is no need for courier-authlib. It is possible to do user database lookups directly against Dovecot. I've disabled gdbm support in APKBUILD, because as stated in maildrop INSTALL file "supporting GDBM/DB databases significantly increases the size of maildrop" and also I've never used this feature. Juraj =C5=A0ujan --MP_/5BhdIZmLDKAl7UHPOY9bAFu Content-Type: text/x-patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=0001-added-maildrop-package.patch >From d574e68c98fe9e70fe8782ceb5caadfbac589686 Mon Sep 17 00:00:00 2001 From: Juraj Sujan Date: Fri, 4 Feb 2011 22:56:47 +0100 Subject: [PATCH] added maildrop package --- testing/maildrop/APKBUILD | 46 ++ testing/maildrop/maildrop-2.3.0-dovecotauth.patch | 820 +++++++++++++++++++++ 2 files changed, 866 insertions(+), 0 deletions(-) create mode 100644 testing/maildrop/APKBUILD create mode 100644 testing/maildrop/maildrop-2.3.0-dovecotauth.patch diff --git a/testing/maildrop/APKBUILD b/testing/maildrop/APKBUILD new file mode 100644 index 0000000..541c168 --- /dev/null +++ b/testing/maildrop/APKBUILD @@ -0,0 +1,46 @@ +# Contributor: Juraj Sujan +# Maintainer: Juraj Sujan +pkgname=maildrop +pkgver=2.5.2 +pkgrel=0 +pkgdesc="Mail delivery agent with filtering abilities" +url="http://courier-mta.org/maildrop/" +arch="all" +license="GPL3" +depends= +makedepends="pcre-dev" +install= +subpackages="$pkgname-doc" +source="http://downloads.sourceforge.net/project/courier/$pkgname/$pkgver/$pkgname-$pkgver.tar.bz2 + maildrop-2.3.0-dovecotauth.patch" + +_builddir="$srcdir"/$pkgname-$pkgver + +prepare() { + cd "$_builddir" + # apply patches here + for i in ../*.patch; do + msg "Applying $i" + if ! patch --verbose -p1 -i $i; then + error "$i failed" + return 1 + fi + done +} + +build() { + cd "$_builddir" + ./configure --prefix=/usr --disable-authlib --without-db + make || return 1 +} + +package() { + cd "$_builddir" + make DESTDIR="$pkgdir" install + mkdir "$pkgdir"/usr/share/doc + mv "$pkgdir"/usr/share/maildrop "$pkgdir"/usr/share/doc/ + cp README.dovecotauth "$pkgdir"/usr/share/doc/maildrop/ +} + +md5sums="3edb56534ae442a494255db6c8aaab99 maildrop-2.5.2.tar.bz2 +f5e0fd910d76c4fba2a5fcdd40c6b375 maildrop-2.3.0-dovecotauth.patch" diff --git a/testing/maildrop/maildrop-2.3.0-dovecotauth.patch b/testing/maildrop/maildrop-2.3.0-dovecotauth.patch new file mode 100644 index 0000000..7fc80f0 --- /dev/null +++ b/testing/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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++ ++#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 + #include + #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 + #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. -- 1.7.3.5 --MP_/5BhdIZmLDKAl7UHPOY9bAFu-- --- Unsubscribe: alpine-devel+unsubscribe@lists.alpinelinux.org Help: alpine-devel+help@lists.alpinelinux.org ---