Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 343619
Collapse All | Expand All

(-)maildrop-2.3.0/maildrop/dovecotauth.c (+480 lines)
Line 0 Link Here
1
/*
2
** Copyright 2009 Marko Njezic
3
** Licensed under the same terms as Courier Authlib AND/OR Courier Maildrop.
4
**
5
** Partially based on authdaemonlib.c from Courier Authlib, which had the following statement:
6
**
7
** Copyright 2000-2006 Double Precision, Inc.  See COPYING for
8
** distribution information.
9
**
10
** Code that was taken from authdaemonlib.c is as follows:
11
**  - s_connect() function
12
**  - opensock() function with modification to accept socket address
13
**  - writeauth() function
14
**  - readline() function with related support functions (with modification 
15
**    to time-out after TIMEOUT_READ seconds)
16
*/
17
18
#include	"dovecotauth.h"
19
#include	<stdio.h>
20
#include	<stdlib.h>
21
#include	<string.h>
22
#include	<errno.h>
23
#include	<fcntl.h>
24
#include	<pwd.h>
25
#include	<time.h>
26
#include	<unistd.h>
27
#include	<sys/types.h>
28
#include	<sys/socket.h>
29
#include	<sys/un.h>
30
#include	<sys/select.h>
31
32
static const char rcsid[]="$Id$";
33
34
static int TIMEOUT_SOCK=10,
35
	TIMEOUT_WRITE=10,
36
	TIMEOUT_READ=30; 
37
38
static int s_connect(int sockfd,
39
		     const struct sockaddr *addr,
40
		     size_t addr_s,
41
		     time_t connect_timeout)
42
{
43
	fd_set fdr;
44
	struct timeval tv;
45
	int	rc;
46
47
#ifdef SOL_KEEPALIVE
48
	setsockopt(sockfd, SOL_SOCKET, SOL_KEEPALIVE,
49
		   (const char *)&dummy, sizeof(dummy));
50
#endif
51
52
#ifdef  SOL_LINGER
53
        {
54
		struct linger l;
55
56
                l.l_onoff=0;
57
                l.l_linger=0;
58
59
                setsockopt(sockfd, SOL_SOCKET, SOL_LINGER,
60
			   (const char *)&l, sizeof(l));
61
        }
62
#endif
63
64
        /*
65
        ** If configuration says to use the kernel's timeout settings,
66
        ** just call connect, and be done with it.
67
        */
68
69
        if (connect_timeout == 0)
70
                return ( connect(sockfd, addr, addr_s));
71
72
        /* Asynchronous connect with timeout. */
73
74
        if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)     return (-1);
75
76
        if ( connect(sockfd, addr, addr_s) == 0)
77
        {
78
                /* That was easy, we're done. */
79
80
                if (fcntl(sockfd, F_SETFL, 0) < 0)      return (-1);
81
                return (0);
82
        }
83
84
	if (errno != EINPROGRESS)
85
		return -1;
86
87
	/* Wait for the connection to go through, until the timeout expires */
88
89
        FD_ZERO(&fdr);
90
        FD_SET(sockfd, &fdr);
91
        tv.tv_sec=connect_timeout;
92
        tv.tv_usec=0;
93
94
        rc=select(sockfd+1, 0, &fdr, 0, &tv);
95
        if (rc < 0)     return (-1);
96
97
        if (!FD_ISSET(sockfd, &fdr))
98
        {
99
                errno=ETIMEDOUT;
100
                return (-1);
101
        }
102
103
	{
104
		int     gserr;
105
		socklen_t gslen = sizeof(gserr);
106
107
		if (getsockopt(sockfd, SOL_SOCKET,
108
			       SO_ERROR,
109
			       (char *)&gserr, &gslen)==0)
110
		{
111
			if (gserr == 0)
112
				return 0;
113
114
			errno=gserr;
115
		}
116
	}
117
	return (-1);
118
}
119
120
static int opensock(const char *addr)
121
{
122
	int	s=socket(PF_UNIX, SOCK_STREAM, 0);
123
	struct  sockaddr_un skun;
124
125
	skun.sun_family=AF_UNIX;
126
	strncpy(skun.sun_path, addr, sizeof(skun.sun_path));
127
128
	if (s < 0)
129
	{
130
		perror("CRIT: dovecotauth: socket() failed");
131
		return (-1);
132
	}
133
134
	{
135
		const char *p=getenv("TIMEOUT_SOCK");
136
		int n=atoi(p ? p:"0");
137
138
		if (n > 0)
139
			TIMEOUT_SOCK=n;
140
	}
141
142
	{
143
		const char *p=getenv("TIMEOUT_READ");
144
		int n=atoi(p ? p:"0");
145
146
		if (n > 0)
147
			TIMEOUT_READ=n;
148
	}
149
150
	{
151
		const char *p=getenv("TIMEOUT_WRITE");
152
		int n=atoi(p ? p:"0");
153
154
		if (n > 0)
155
			TIMEOUT_WRITE=n;
156
	}
157
158
	if (s_connect(s, (const struct sockaddr *)&skun, sizeof(skun),
159
		      TIMEOUT_SOCK))
160
	{
161
		perror("ERR: dovecotauth: s_connect() failed");
162
		if (errno == ETIMEDOUT || errno == ECONNREFUSED)
163
			fprintf(stderr, "ERR: [Hint: perhaps dovecot-auth daemon is not running?]\n");
164
		close(s);
165
		return (-1);
166
	}
167
	return (s);
168
}
169
170
static int writeauth(int fd, const char *p, unsigned pl)
171
{
172
fd_set  fds;
173
struct  timeval tv;
174
175
	while (pl)
176
	{
177
	int     n;
178
179
		FD_ZERO(&fds);
180
		FD_SET(fd, &fds);
181
		tv.tv_sec=TIMEOUT_WRITE;
182
		tv.tv_usec=0;
183
		if (select(fd+1, 0, &fds, 0, &tv) <= 0 || !FD_ISSET(fd, &fds))
184
			return (-1);
185
		n=write(fd, p, pl);
186
		if (n <= 0)     return (-1);
187
		p += n;
188
		pl -= n;
189
	}
190
	return (0);
191
}
192
193
struct enum_getch {
194
	char buffer[BUFSIZ];
195
	char *buf_ptr;
196
	size_t buf_left;
197
};
198
199
#define getauthc(fd,eg) ((eg)->buf_left-- ? \
200
			(unsigned char)*((eg)->buf_ptr)++:\
201
			fillgetauthc((fd),(eg)))
202
203
static int fillgetauthc(int fd, struct enum_getch *eg)
204
{
205
	time_t	end_time, curtime;
206
207
	time(&end_time);
208
	end_time += TIMEOUT_READ;
209
210
	for (;;)
211
	{
212
		int     n;
213
		fd_set  fds;
214
		struct  timeval tv;
215
216
		time(&curtime);
217
		if (curtime >= end_time)
218
			break;
219
220
		FD_ZERO(&fds);
221
		FD_SET(fd, &fds);
222
		tv.tv_sec=end_time - curtime;
223
		tv.tv_usec=0;
224
		if (select(fd+1, &fds, 0, 0, &tv) <= 0 || !FD_ISSET(fd, &fds))
225
			break;
226
227
		n=read(fd, eg->buffer, sizeof(eg->buffer));
228
		if (n <= 0)
229
			break;
230
231
		eg->buf_ptr=eg->buffer;
232
		eg->buf_left=n;
233
234
		--eg->buf_left;
235
		return (unsigned char)*(eg->buf_ptr)++;
236
	}
237
	return EOF;
238
}
239
240
static int readline(int fd, struct enum_getch *eg,
241
		    char *buf,
242
		    size_t bufsize)
243
{
244
	if (bufsize == 0)
245
		return EOF;
246
247
	while (--bufsize)
248
	{
249
		int ch=getauthc(fd, eg);
250
251
		if (ch == EOF)
252
			return -1;
253
		if (ch == '\n')
254
			break;
255
256
		*buf++=ch;
257
	}
258
	*buf=0;
259
	return 0;
260
}
261
262
/*
263
** The actual implementation of Dovecot authentication protocol handling follows.
264
** Full specification of the protocol can be found at: http://wiki.dovecot.org/Authentication%20Protocol
265
** We are only interested in the "master" type requests for user information.
266
*/
267
268
int parse_userinfo(const char *user, const char *linebuf,
269
	int (*func)(struct dovecotauthinfo *, void *), void *arg)
270
{
271
	int return_value=1;
272
	struct dovecotauthinfo a;
273
	char *buf, *p;
274
	uid_t u;
275
276
	/* Validate input arguments */
277
	if (!user || !linebuf)
278
		return (1);
279
280
	/* Try to allocate buffer */
281
	buf = (char *)malloc(strlen(linebuf)+1);
282
	if (!buf)
283
		return (1);
284
	strcpy(buf, linebuf);
285
286
	memset(&a, 0, sizeof(a));
287
	a.homedir="";
288
289
	p = strtok(buf, "\t");
290
	if (p)
291
		a.address=p;
292
	else
293
		a.address=user;
294
295
	/* Parse any additional parameters */
296
	while ((p = strtok(0, "\t")) != 0)
297
	{
298
		if (strncmp(p, "uid=", 4) == 0)
299
		{
300
			u=atol(p+4);
301
			a.sysuserid = &u;
302
			if (u == 0)
303
			{
304
				fprintf(stderr, "ERR: dovecotauth: Received invalid uid from auth socket\n");
305
				return_value=1;
306
				goto cleanup_parse_userinfo;
307
			}
308
		}
309
		else if (strncmp(p, "gid=", 4) == 0)
310
		{
311
			a.sysgroupid=atol(p+4);
312
			if (a.sysgroupid == 0)
313
			{
314
				fprintf(stderr, "ERR: dovecotauth: Received invalid gid from auth socket\n");
315
				return_value=1;
316
				goto cleanup_parse_userinfo;
317
			}
318
		}
319
		else if (strncmp(p, "system_user=", 12) == 0)
320
		{
321
			a.sysusername=p+12;
322
			if (a.sysusername)
323
			{
324
				struct passwd *q=getpwnam(a.sysusername);
325
326
				if (q && q->pw_uid == 0)
327
				{
328
					fprintf(stderr, "ERR: dovecotauth: Received invalid system user from auth socket\n");
329
					return_value=1;
330
					goto cleanup_parse_userinfo;
331
				}
332
			}
333
		}
334
		else if (strncmp(p, "home=", 5) == 0)
335
		{
336
			a.homedir=p+5;
337
		}
338
		else if (strncmp(p, "mail=", 5) == 0)
339
		{
340
			a.maildir=p+5;
341
		}
342
	}
343
344
	return_value = (*func)(&a, arg);
345
346
cleanup_parse_userinfo:
347
	free(buf);
348
	return return_value;
349
}
350
351
#define	DOVECOTAUTH_LINEBUFSIZE	8192
352
353
int _dovecotauth_getuserinfo(int wrfd, int rdfd, const char *user,
354
	int (*func)(struct dovecotauthinfo *, void *), void *arg)
355
{
356
	static char cmdpart1[]="VERSION\t1\t0\nUSER\t1\t";
357
	static char cmdpart2[]="\tservice=maildrop\n";
358
	int return_value=1, handshake=0;
359
	struct enum_getch eg;
360
	char *cmdbuf, *linebuf;
361
362
	/* Validate input arguments */
363
	if (!user)
364
		return (1);
365
366
	/* Try to allocate buffers */
367
	cmdbuf=(char *)malloc(strlen(cmdpart1)+strlen(cmdpart2)+strlen(user)+20);
368
	if (!cmdbuf)
369
		return (1);
370
371
	linebuf=(char *)malloc(DOVECOTAUTH_LINEBUFSIZE);
372
	if (!linebuf)
373
		return (1);
374
375
	/* Initial handshake */
376
	eg.buf_left=0;
377
	while (readline(rdfd, &eg, linebuf, DOVECOTAUTH_LINEBUFSIZE) == 0)
378
	{
379
		if (strncmp(linebuf, "VERSION\t", 8) == 0)
380
		{
381
			if (strncmp(linebuf+8, "1\t", 2) != 0)
382
			{
383
				fprintf(stderr, "ERR: dovecotauth: Authentication protocol version mismatch\n");
384
				return_value=1;
385
				goto cleanup_dovecotauth_getuserinfo;
386
			}
387
		}
388
		else if (strncmp(linebuf, "SPID\t", 5) == 0)
389
		{
390
			/* End of server side handshake */
391
			handshake=1;
392
			break;
393
		}
394
	}
395
396
	if (!handshake)
397
	{
398
		fprintf(stderr, "ERR: dovecotauth: Did not receive proper server handshake from auth socket\n");
399
		return_value=1;
400
		goto cleanup_dovecotauth_getuserinfo;
401
	}
402
403
	/*
404
	** Try to be helpful in case that user tries to connect to the wrong auth socket.
405
	** There's a slight chance that this won't execute in case that the previously 
406
	** returned line ends exactly at the buffer end, but we won't handle that case,
407
	** since this is just a hint to the user, and not really neccessary.
408
	** Normally, if user tries to communicate with wrong auth socket, 
409
	** we would simply time-out, while waiting for information.
410
	*/
411
	if (eg.buf_left > 0 && readline(rdfd, &eg, linebuf, DOVECOTAUTH_LINEBUFSIZE) == 0)
412
	{
413
		if (strncmp(linebuf, "CUID\t", 5) == 0)
414
		{
415
			fprintf(stderr, "ERR: dovecotauth: Trying to connect to what appears to be a client auth socket, instead of a master auth socket\n");
416
			return_value=1;
417
			goto cleanup_dovecotauth_getuserinfo;
418
		}
419
	}
420
421
	/* Generate our part of communication */
422
	strcat(strcat(strcpy(cmdbuf, cmdpart1), user), cmdpart2);
423
424
	/* Send our part of communication */
425
	if (writeauth(wrfd, cmdbuf, strlen(cmdbuf)))
426
	{
427
		return_value=1;
428
		goto cleanup_dovecotauth_getuserinfo;
429
	}
430
431
	/* Parse returned information */
432
	eg.buf_left=0;
433
	if (readline(rdfd, &eg, linebuf, DOVECOTAUTH_LINEBUFSIZE) == 0)
434
	{
435
		if (strncmp(linebuf, "USER\t1\t", 7) == 0)
436
		{
437
			/* User was found in the database and we now parse returned information */
438
			return_value=parse_userinfo(user, linebuf+7, func, arg);
439
			goto cleanup_dovecotauth_getuserinfo;
440
		}
441
		else if (strcmp(linebuf, "NOTFOUND\t1") == 0)
442
		{
443
			/* User was not found in the database */
444
			return_value=-1; /* Negative return value means that user is not found! */
445
			goto cleanup_dovecotauth_getuserinfo;
446
		}
447
		else if (strncmp(linebuf, "FAIL\t1", 6) == 0)
448
		{
449
			/* An internal error has occurred on Dovecot's end */
450
			return_value=1;
451
			goto cleanup_dovecotauth_getuserinfo;
452
		}
453
		else
454
		{
455
			fprintf(stderr, "ERR: dovecotauth: Received unknown input from auth socket\n");
456
		}
457
	}
458
	else
459
		fprintf(stderr, "ERR: dovecotauth: Did not receive proper input from auth socket\n");
460
461
cleanup_dovecotauth_getuserinfo:
462
	free(cmdbuf);
463
	free(linebuf);
464
	return return_value;
465
}
466
467
int dovecotauth_getuserinfo(const char *addr, const char *user,
468
	int (*func)(struct dovecotauthinfo *, void *), void *arg)
469
{
470
	int	s=opensock(addr);
471
	int	rc;
472
473
	if (s < 0)
474
	{
475
		return (1);
476
	}
477
	rc = _dovecotauth_getuserinfo(s, s, user, func, arg);
478
	close(s);
479
	return rc;
480
}
(-)maildrop-2.3.0/maildrop/dovecotauth.h (+59 lines)
Line 0 Link Here
1
#ifndef	dovecotauth_h
2
#define	dovecotauth_h
3
4
/*
5
** Copyright 2009 Marko Njezic
6
** Licensed under the same terms as Courier Authlib AND/OR Courier Maildrop.
7
**
8
** Partially based on courierauth.h from Courier Authlib, which had the following statement:
9
**
10
** Copyright 2004 Double Precision, Inc.  See COPYING for
11
** distribution information.
12
*/
13
14
#include	<sys/types.h>
15
16
#ifdef	__cplusplus
17
extern "C" {
18
#endif
19
20
static const char dovecotauth_h_rcsid[]="$Id$";
21
22
struct dovecotauthinfo {
23
	const char *address;
24
	const char *sysusername;
25
	const uid_t *sysuserid;
26
	gid_t sysgroupid;
27
	const char *homedir;
28
	const char *maildir;
29
	} ;
30
31
/*
32
	This structure is modeled after authinfo structure from Courier Authlib.
33
34
	Either sysusername or sysuserid may be NULL, but not both of them.
35
	They, and sysgroupid, specify the authenticated user's system
36
	userid and groupid.  homedir points to the authenticated user's
37
	home directory.  address and maildir, are obvious.
38
39
	After populating this tructure, the lookup function calls the
40
	callback function that's specified in its second argument.  The
41
	callback function receives a pointer to the authinfo structure.
42
43
	The callback function also receives a context pointer, which is
44
	the third argument to the lookup function.
45
46
	The lookup function should return a negative value if the userid
47
	does not exist, a positive value if there was a temporary error
48
	looking up the userid, or whatever is the return code from the
49
	callback function, if the user exists.
50
*/
51
52
int dovecotauth_getuserinfo(const char *addr, const char *user,
53
	int (*func)(struct dovecotauthinfo *, void *), void *arg);
54
55
#ifdef	__cplusplus
56
}
57
#endif
58
59
#endif
(-)maildrop-2.3.0/maildrop/main.C (-1 / +136 lines)
Lines 32-37 Link Here
32
#include	<pwd.h>
32
#include	<pwd.h>
33
#include	<grp.h>
33
#include	<grp.h>
34
#include	"../dbobj.h"
34
#include	"../dbobj.h"
35
36
/*
37
** This switch can later be moved to config.h file with appropriate 
38
** configure option like --with-dovecotauth or something similar
39
*/
40
#define	DOVECOTAUTH	1
41
#if DOVECOTAUTH
42
#include	"dovecotauth.h"
43
#endif
44
35
#if AUTHLIB
45
#if AUTHLIB
36
#include	<courierauth.h>
46
#include	<courierauth.h>
37
#endif
47
#endif
Lines 171-176 Link Here
171
	"\n"
181
	"\n"
172
#endif
182
#endif
173
#endif
183
#endif
184
#if DOVECOTAUTH
185
	"Dovecot Authentication extension enabled."
186
#if CRLF_TERM
187
	"\r\n"
188
#else
189
	"\n"
190
#endif
191
#endif
174
#if AUTHLIB
192
#if AUTHLIB
175
	"Courier Authentication Library extension enabled."
193
	"Courier Authentication Library extension enabled."
176
#if CRLF_TERM
194
#if CRLF_TERM
Lines 337-342 Link Here
337
}
355
}
338
#endif
356
#endif
339
357
358
#if DOVECOTAUTH
359
static int callback_dovecotauth(struct dovecotauthinfo *auth,
360
			    void *void_arg)
361
{
362
	Maildrop &maildrop=*(Maildrop *)void_arg;
363
364
	if (VerboseLevel() > 1)
365
	{
366
		Buffer b;
367
368
		b.set(auth->sysgroupid);
369
		b.push(0);
370
371
		merr << "maildrop: dovecotauth: groupid="
372
		     << b << "\n";
373
	}
374
375
	setgroupid(auth->sysgroupid);
376
377
	uid_t u;
378
	if (auth->sysusername)
379
	{
380
		struct	passwd *q=getpwnam(auth->sysusername);
381
382
		if (q == NULL)
383
		{
384
			merr << "Cannot find system user "
385
			     << auth->sysusername
386
			     << "\n";
387
388
			nochangeuidgid();
389
		}
390
391
		u=q->pw_uid;
392
	}
393
	else
394
		u=*auth->sysuserid;
395
396
	if (VerboseLevel() > 1)
397
	{
398
		Buffer b;
399
400
		b.set(u);
401
		b.push(0);
402
403
		merr << "maildrop: dovecotauth: userid="
404
		     << b << "\n";
405
	}
406
407
	setuid(u);
408
409
	if ( getuid() != u)
410
		nochangeuidgid();
411
412
	if (VerboseLevel() > 1)
413
	{
414
		merr << "maildrop: dovecotauth: logname="
415
		     << auth->address
416
		     << ", home="
417
		     << auth->homedir
418
		     << ", mail="
419
		     << (auth->maildir ? auth->maildir:"(default)")
420
		     << "\n";
421
	}
422
423
	maildrop.init_home=auth->homedir;
424
	maildrop.init_logname=auth->address;
425
	maildrop.init_shell="/bin/sh";
426
	maildrop.init_default=auth->maildir ? auth->maildir:
427
		GetDefaultMailbox(auth->address);
428
429
	return 0;
430
}
431
432
int find_in_dovecotauth(const char *addr, Maildrop *maildrop, const char* user)
433
{
434
	int rc=dovecotauth_getuserinfo(addr,
435
				user, callback_dovecotauth, maildrop);
436
437
	if (rc == 0)
438
		return 1;
439
440
	if (rc > 0)
441
	{
442
		errexit=EX_TEMPFAIL;
443
		throw "Temporary authentication failure.";
444
	}
445
446
	return 0;
447
}
448
#endif
449
340
static void tempfail(const char *msg)
450
static void tempfail(const char *msg)
341
{
451
{
342
	errexit = EX_TEMPFAIL;
452
	errexit = EX_TEMPFAIL;
Lines 361-366 Link Here
361
const	char *numuidgid=0;
471
const	char *numuidgid=0;
362
#endif
472
#endif
363
#endif
473
#endif
474
#if DOVECOTAUTH
475
const	char *dovecotauth_addr=0;
476
#endif
364
477
365
478
366
	umask( 0007 );
479
	umask( 0007 );
Lines 446-451 Link Here
446
		case 'a':
559
		case 'a':
447
			maildrop.authlib_essential=1;
560
			maildrop.authlib_essential=1;
448
			break;
561
			break;
562
#if DOVECOTAUTH
563
		case 't':
564
			if (!*optarg && argn < argc)	optarg=argv[argn++];
565
			if (!*optarg)
566
			{
567
				mout << "You didn't specify the location of Dovecot auth socket.\n";
568
				return (EX_TEMPFAIL);
569
			}
570
			else
571
				dovecotauth_addr=optarg;
572
			break;
573
#endif
449
		case 'h':
574
		case 'h':
450
			help();
575
			help();
451
			return (EX_TEMPFAIL);
576
			return (EX_TEMPFAIL);
Lines 467-473 Link Here
467
592
468
		if (*deliverymode)
593
		if (*deliverymode)
469
		{
594
		{
470
			found = find_in_authlib(&maildrop, deliverymode);
595
596
#if DOVECOTAUTH
597
			if (dovecotauth_addr)
598
			{
599
				found = find_in_dovecotauth(dovecotauth_addr, &maildrop, deliverymode);
600
			}
601
			else
602
#endif
603
			{
604
				found = find_in_authlib(&maildrop, deliverymode);
605
			}
471
606
472
			if ( !found )
607
			if ( !found )
473
			{
608
			{
(-)maildrop-2.3.0/maildrop/Makefile.am (-1 / +1 lines)
Lines 46-52 Link Here
46
	recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \
46
	recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \
47
	reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \
47
	reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \
48
	rematchstr.C rematchstr.h search.C search.h token.C \
48
	rematchstr.C rematchstr.h search.C search.h token.C \
49
	token.h varlist.C varlist.h
49
	token.h varlist.C varlist.h dovecotauth.c dovecotauth.h
50
50
51
maildrop_DEPENDENCIES = libmdcommon.la ../maildir/maildir.libdeps
51
maildrop_DEPENDENCIES = libmdcommon.la ../maildir/maildir.libdeps
52
52
(-)maildrop-2.3.0/maildrop/Makefile.in (-2 / +3 lines)
Lines 88-94 Link Here
88
	re.$(OBJEXT) recipe.$(OBJEXT) recipenode.$(OBJEXT) \
88
	re.$(OBJEXT) recipe.$(OBJEXT) recipenode.$(OBJEXT) \
89
	recipeparse.$(OBJEXT) reeval.$(OBJEXT) rematch.$(OBJEXT) \
89
	recipeparse.$(OBJEXT) reeval.$(OBJEXT) rematch.$(OBJEXT) \
90
	rematchmsg.$(OBJEXT) rematchstr.$(OBJEXT) search.$(OBJEXT) \
90
	rematchmsg.$(OBJEXT) rematchstr.$(OBJEXT) search.$(OBJEXT) \
91
	token.$(OBJEXT) varlist.$(OBJEXT)
91
	token.$(OBJEXT) varlist.$(OBJEXT) dovecotauth.$(OBJEXT)
92
maildrop_OBJECTS = $(am_maildrop_OBJECTS)
92
maildrop_OBJECTS = $(am_maildrop_OBJECTS)
93
maildrop_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
93
maildrop_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
94
	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
94
	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
Lines 308-314 Link Here
308
	recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \
308
	recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \
309
	reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \
309
	reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \
310
	rematchstr.C rematchstr.h search.C search.h token.C \
310
	rematchstr.C rematchstr.h search.C search.h token.C \
311
	token.h varlist.C varlist.h
311
	token.h varlist.C varlist.h dovecotauth.c dovecotauth.h
312
312
313
maildrop_DEPENDENCIES = libmdcommon.la ../maildir/maildir.libdeps
313
maildrop_DEPENDENCIES = libmdcommon.la ../maildir/maildir.libdeps
314
maildrop_LDADD = libmdcommon.la `cat ../maildir/maildir.libdeps`\
314
maildrop_LDADD = libmdcommon.la `cat ../maildir/maildir.libdeps`\
Lines 471-476 Link Here
471
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempfile.Plo@am__quote@
471
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempfile.Plo@am__quote@
472
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@
472
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@
473
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varlist.Po@am__quote@
473
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varlist.Po@am__quote@
474
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dovecotauth.Po@am__quote@
474
475
475
.C.o:
476
.C.o:
476
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
477
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
(-)maildrop-2.3.0/README.dovecotauth (+46 lines)
Line 0 Link Here
1
Dovecot Authentication extension for maildrop
2
=============================================
3
** Copyright 2009 Marko Njezic
4
** Licensed under the same terms as Courier Authlib AND/OR Courier Maildrop.
5
6
When you patch maildrop to include Dovecot Authentication extension, you'll be 
7
able to do user database lookups against Dovecot. This extension can happily 
8
coexist with Courier Authlib extension if it is also compiled.
9
10
In order to use it you'll need to specify additional option "-t" that will point 
11
to the location of Dovecot's auth master socket when starting maildrop in 
12
delivery mode. For example:
13
14
maildrop -d USER -t /var/run/dovecot/auth-master
15
16
By specifying "-t" option, maildrop will first try user lookup against Dovecot's 
17
database. If user is not found, maildrop will fallback to local user database 
18
(i.e. passwd), as usual. Lookups against Courier Authlib will not be done when 
19
"-t" option is specified. If you want to perform such lookup when both 
20
extensions are compiled, simply remove "-t" option and maildrop will behave as 
21
usual.
22
23
One significant difference compared to Courier Authlib extension is that Dovecot 
24
Authentication extension will never return uid/gid that's equal to zero. If such 
25
value was returned from database, maildrop will exit with temporary failure. 
26
This was done in order to prevent accidental mistakes. If you really want to 
27
deliver as/to root, you'll have to start maildrop without "-t" option and let 
28
it directly query system user database on its own.
29
30
Make sure that correct permissions are set on Dovecot's auth master socket so 
31
that maildrop can communicate with it. Also, depending on what type of users are 
32
being served from Dovecot's database, if user lookup returns local user 
33
accounts, you may end up with problems when maildrop tries to write mails to the 
34
spool directory if wrong permission are set on it, since maildrop will reset its 
35
permissions (uid/gid) to the values returned from user database. This behavior 
36
is the same as the behavior of lookups against Courier Authlib, since they also 
37
reset maildrop's permissions. When you want maildrop to deliver to the local 
38
users, it's best to let it directly query system user database on its own, 
39
since then it can apply its own "RESET_GID" magic, which will hopefully result 
40
in "correct" permissions that will allow maildrop to write to the spool 
41
directory.
42
43
And last but not least, I hope that you'll find this extension useful. 
44
Especially if you already have an existing user database in Dovecot, but would 
45
like to use maildrop (with its powerful "xfilter" command) to deliver e-mails, 
46
without setting up another authentication user database, like Courier Authlib.

Return to bug 343619