View | Details | Raw Unified | Return to bug 253093
Collapse All | Expand All

(-)dovecot/Makefile (-6 / +10 lines)
Lines 21-26 Link Here
21
LIB_DEPENDS=	libzstd.so:archivers/zstd
21
LIB_DEPENDS=	libzstd.so:archivers/zstd
22
22
23
USES=		cpe iconv libtool pkgconfig ssl
23
USES=		cpe iconv libtool pkgconfig ssl
24
USES+=		autoreconf gettext-tools
24
USE_RC_SUBR=	dovecot
25
USE_RC_SUBR=	dovecot
25
26
26
GNU_CONFIGURE=	yes
27
GNU_CONFIGURE=	yes
Lines 36-42 Link Here
36
USERS=		dovecot dovenull
37
USERS=		dovecot dovenull
37
GROUPS=		${USERS}
38
GROUPS=		${USERS}
38
39
39
OPTIONS_DEFINE=	LIBSODIUM LIBWRAP LUA LZ4 DOCS EXAMPLES
40
OPTIONS_DEFINE=	LIBSODIUM LIBWRAP LUA LZ4 VPOPMAIL DOCS EXAMPLES
40
OPTIONS_DEFAULT=GSSAPI_NONE LIBWRAP
41
OPTIONS_DEFAULT=GSSAPI_NONE LIBWRAP
41
OPTIONS_SUB=	yes
42
OPTIONS_SUB=	yes
42
43
Lines 48-53 Link Here
48
OPTIONS_SINGLE_GSSAPI=	GSSAPI_NONE GSSAPI_BASE GSSAPI_HEIMDAL GSSAPI_MIT
49
OPTIONS_SINGLE_GSSAPI=	GSSAPI_NONE GSSAPI_BASE GSSAPI_HEIMDAL GSSAPI_MIT
49
50
50
LZ4_DESC=	LZ4 compression support
51
LZ4_DESC=	LZ4 compression support
52
VPOPMAIL_DESC=	vpopmail support (deprecated)
51
53
52
DB_DESC=	Database support
54
DB_DESC=	Database support
53
CDB_DESC=	CDB database support
55
CDB_DESC=	CDB database support
Lines 76-81 Link Here
76
LZ4_CONFIGURE_WITH=	lz4
78
LZ4_CONFIGURE_WITH=	lz4
77
LZ4_LIB_DEPENDS=	liblz4.so:archivers/liblz4
79
LZ4_LIB_DEPENDS=	liblz4.so:archivers/liblz4
78
80
81
VPOPMAIL_BUILD_DEPENDS=	vpopmail>=0:mail/vpopmail
82
VPOPMAIL_CONFIGURE_WITH=vpopmail
83
VPOPMAIL_EXTRA_PATCHES=	${FILESDIR}/vpopmail.patch
84
79
# Databases
85
# Databases
80
CDB_CONFIGURE_WITH=	cdb
86
CDB_CONFIGURE_WITH=	cdb
81
CDB_LIB_DEPENDS=	libcdb.so:databases/tinycdb
87
CDB_LIB_DEPENDS=	libcdb.so:databases/tinycdb
Lines 135-150 Link Here
135
		s,sysconfdir=/etc,sysconfdir=${PREFIX}/etc,g' \
141
		s,sysconfdir=/etc,sysconfdir=${PREFIX}/etc,g' \
136
		${WRKSRC}/doc/example-config/*.conf ${WRKSRC}/doc/example-config/conf.d/* \
142
		${WRKSRC}/doc/example-config/*.conf ${WRKSRC}/doc/example-config/conf.d/* \
137
		${WRKSRC}/doc/example-config/*.conf.ext
143
		${WRKSRC}/doc/example-config/*.conf.ext
138
	@${REINPLACE_CMD} -e '/^LIBS =/s/$$/ @LTLIBICONV@/' \
139
		${WRKSRC}/src/lib-mail/Makefile.in
140
# Install the sample config files into ETCDIR/example-config/
144
# Install the sample config files into ETCDIR/example-config/
141
	@${REINPLACE_CMD} -e '/^exampledir =/s|\$$(docdir)|${ETCDIR}|' \
145
	@${REINPLACE_CMD} -e '/^exampledir =/s|\$$(docdir)|${ETCDIR}|' \
142
		${WRKSRC}/doc/example-config/Makefile.in \
146
		${WRKSRC}/doc/example-config/Makefile.am \
143
		${WRKSRC}/doc/example-config/conf.d/Makefile.in
147
		${WRKSRC}/doc/example-config/conf.d/Makefile.am
144
148
145
post-patch-LUA-on:
149
post-patch-LUA-on:
146
	@${REINPLACE_CMD} -e '/^libdovecot_lua_la_DEPENDENCIES =/ s|LUA_LIBS|true|' \
150
	@${REINPLACE_CMD} -e '/^libdovecot_lua_la_DEPENDENCIES =/ s|LUA_LIBS|true|' \
147
		${WRKSRC}/src/lib-lua/Makefile.in
151
		${WRKSRC}/src/lib-lua/Makefile.am
148
152
149
post-install:
153
post-install:
150
	@${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
154
	@${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
(-)dovecot/files/patch-configure (-28 lines)
Lines 1-28 Link Here
1
--- configure.orig	2020-12-22 13:27:02 UTC
2
+++ configure
3
@@ -26053,7 +26053,7 @@ fi
4
 $as_echo "$with_lua" >&6; }
5
 
6
   if test "x$with_lua" != "xno"; then :
7
-  for LUAPC in lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua; do
8
+  for LUAPC in lua5.4 lua-5.4 lua54 lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua; do
9
 
10
 pkg_failed=no
11
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5
12
@@ -29355,13 +29355,13 @@ fi
13
 
14
 
15
   if test $want_stemmer != no; then
16
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sb_stemmer_new in -lstemmer" >&5
17
-$as_echo_n "checking for sb_stemmer_new in -lstemmer... " >&6; }
18
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sb_stemmer_new in -lclucene-contribs-lib" >&5
19
+$as_echo_n "checking for sb_stemmer_new in -lclucene-contribs-lib... " >&6; }
20
 if ${ac_cv_lib_stemmer_sb_stemmer_new+:} false; then :
21
   $as_echo_n "(cached) " >&6
22
 else
23
   ac_check_lib_save_LIBS=$LIBS
24
-LIBS="-lstemmer  $LIBS"
25
+LIBS="-lclucene-contribs-lib  $LIBS"
26
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
27
 /* end confdefs.h.  */
28
 
(-)dovecot/files/patch-m4_want__lua.m4 (+11 lines)
Line 0 Link Here
1
--- m4/want_lua.m4.orig	2021-01-30 07:45:48 UTC
2
+++ m4/want_lua.m4
3
@@ -13,7 +13,7 @@ AC_DEFUN([DOVECOT_WANT_LUA],[
4
   AC_MSG_RESULT([$with_lua])
5
 
6
   AS_IF([test "x$with_lua" != "xno"],
7
-    [for LUAPC in lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua; do
8
+    [for LUAPC in lua5.4 lua-5.4 lua54 lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua; do
9
        PKG_CHECK_MODULES([LUA], $LUAPC >= 5.1, [
10
          AC_DEFINE([HAVE_LUA], [1], [Define to 1 if you have lua])
11
          with_lua=yes
(-)dovecot/files/patch-m4_want__stemmer.m4 (+10 lines)
Line 0 Link Here
1
--- m4/want_stemmer.m4.orig	2021-01-30 09:18:08 UTC
2
+++ m4/want_stemmer.m4
3
@@ -1,6 +1,6 @@
4
 AC_DEFUN([DOVECOT_WANT_STEMMER], [
5
   if test $want_stemmer != no; then
6
-    AC_CHECK_LIB(stemmer, sb_stemmer_new, [
7
+    AC_CHECK_LIB(clucene-contribs-lib, sb_stemmer_new, [
8
       have_fts_stemmer=yes
9
       AC_DEFINE(HAVE_FTS_STEMMER,, [Define if you want stemming support for FTS])
10
     ], [
(-)dovecot/files/patch-plugins_fts-lucene_Makefile.in (-11 lines)
Lines 1-11 Link Here
1
--- src/plugins/fts-lucene/Makefile.in.orig
2
+++ src/plugins/fts-lucene/Makefile.in
3
@@ -516,7 +516,7 @@
4
 module_LTLIBRARIES = \
5
 	lib21_fts_lucene_plugin.la
6
 
7
-@BUILD_FTS_STEMMER_TRUE@STEMMER_LIBS = -lstemmer
8
+@BUILD_FTS_STEMMER_TRUE@STEMMER_LIBS = -lclucene-contribs-lib
9
 @BUILD_FTS_STEMMER_TRUE@SHOWBALL_SOURCES = Snowball.cc
10
 @BUILD_FTS_EXTTEXTCAT_FALSE@@BUILD_FTS_TEXTCAT_TRUE@TEXTCAT_LIBS = -ltextcat
11
 @BUILD_FTS_EXTTEXTCAT_TRUE@TEXTCAT_LIBS = $(LIBEXTTEXTCAT_LIBS)
(-)dovecot/files/patch-src_lib-fts_Makefile.am (+11 lines)
Line 0 Link Here
1
--- src/lib-fts/Makefile.am.orig	2021-01-30 09:21:54 UTC
2
+++ src/lib-fts/Makefile.am
3
@@ -55,7 +55,7 @@ $(srcdir)/word-break-data.c: $(srcdir)/word-properties
4
 
5
 
6
 if BUILD_FTS_STEMMER
7
-STEMMER_LIBS = -lstemmer
8
+STEMMER_LIBS = -lclucene-contribs-lib
9
 endif
10
 
11
 if BUILD_FTS_EXTTEXTCAT
(-)dovecot/files/patch-src_lib-fts_Makefile.in (-11 lines)
Lines 1-11 Link Here
1
--- src/lib-fts/Makefile.in.orig
2
+++ src/lib-fts/Makefile.in
3
@@ -549,7 +549,7 @@
4
 	word-break-data.c \
5
 	stopwords/stopwords_malformed.txt
6
 
7
-@BUILD_FTS_STEMMER_TRUE@STEMMER_LIBS = -lstemmer
8
+@BUILD_FTS_STEMMER_TRUE@STEMMER_LIBS = -lclucene-contribs-lib
9
 @BUILD_FTS_EXTTEXTCAT_FALSE@@BUILD_FTS_TEXTCAT_TRUE@TEXTCAT_LIBS = -ltextcat
10
 @BUILD_FTS_EXTTEXTCAT_TRUE@TEXTCAT_LIBS = $(LIBEXTTEXTCAT_LIBS)
11
 @BUILD_LIBICU_TRUE@ICU_SOURCES = fts-icu.c
(-)dovecot/files/patch-src_plugins_fts-lucene_Makefile.am (+11 lines)
Line 0 Link Here
1
--- src/plugins/fts-lucene/Makefile.am.orig	2021-01-30 09:20:40 UTC
2
+++ src/plugins/fts-lucene/Makefile.am
3
@@ -20,7 +20,7 @@ module_LTLIBRARIES = \
4
 	lib21_fts_lucene_plugin.la
5
 
6
 if BUILD_FTS_STEMMER
7
-STEMMER_LIBS = -lstemmer
8
+STEMMER_LIBS = -lclucene-contribs-lib
9
 SHOWBALL_SOURCES = Snowball.cc
10
 endif
11
 
(-)dovecot/files/vpopmail.patch (+695 lines)
Line 0 Link Here
1
diff -ruN ../dovecot-2.3.13.orig/configure.ac ./configure.ac
2
--- ../dovecot-2.3.13.orig/configure.ac	2020-12-22 14:26:52.000000000 +0100
3
+++ ./configure.ac	2021-01-29 14:26:35.068783000 +0100
4
@@ -91,6 +91,22 @@
5
   TEST_WITH(libunwind, $withval),
6
   want_libunwind=auto)
7
 
8
+AC_ARG_WITH(vpopmail,
9
+AS_HELP_STRING([--with-vpopmail], [Build with vpopmail support (auto)]),
10
+	if test x$withval = xno; then
11
+		want_vpopmail=no
12
+	else
13
+		if test x$withval = xyes || test x$withval = xauto; then
14
+			vpopmail_home="`echo ~vpopmail`"
15
+			want_vpopmail=$withval
16
+		else
17
+			vpopmail_home="$withval"
18
+			want_vpopmail=yes
19
+		fi
20
+	fi, [
21
+		want_vpopmail=no
22
+	])
23
+
24
 # Berkeley DB support is more or less broken. Disabled for now.
25
 #AC_ARG_WITH(db,
26
 #AS_HELP_STRING([--with-db], [Build with Berkeley DB support]),
27
@@ -548,6 +564,7 @@
28
 DOVECOT_WANT_SODIUM
29
 DOVECOT_WANT_SQLITE
30
 DOVECOT_WANT_CASSANDRA
31
+DOVECOT_WANT_VPOPMAIL
32
 
33
 DOVECOT_SQL
34
 
35
diff -ruN ../dovecot-2.3.13.orig/doc/example-config/conf.d/10-auth.conf ./doc/example-config/conf.d/10-auth.conf
36
--- ../dovecot-2.3.13.orig/doc/example-config/conf.d/10-auth.conf	2020-12-22 14:26:52.000000000 +0100
37
+++ ./doc/example-config/conf.d/10-auth.conf	2021-01-29 13:21:19.267469000 +0100
38
@@ -10,7 +10,7 @@
39
 #disable_plaintext_auth = yes
40
 
41
 # Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
42
-# bsdauth and PAM require cache_key to be set for caching to be used.
43
+# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
44
 #auth_cache_size = 0
45
 # Time to live for cached data. After TTL expires the cached record is no
46
 # longer used, *except* if the main database lookup returns internal failure.
47
@@ -124,4 +124,5 @@
48
 #!include auth-ldap.conf.ext
49
 #!include auth-passwdfile.conf.ext
50
 #!include auth-checkpassword.conf.ext
51
+#!include auth-vpopmail.conf.ext
52
 #!include auth-static.conf.ext
53
diff -ruN ../dovecot-2.3.13.orig/doc/example-config/conf.d/Makefile.am ./doc/example-config/conf.d/Makefile.am
54
--- ../dovecot-2.3.13.orig/doc/example-config/conf.d/Makefile.am	2020-12-22 14:26:52.000000000 +0100
55
+++ ./doc/example-config/conf.d/Makefile.am	2021-01-29 13:21:19.268070000 +0100
56
@@ -11,6 +11,7 @@
57
 	auth-sql.conf.ext \
58
 	auth-static.conf.ext \
59
 	auth-system.conf.ext \
60
+	auth-vpopmail.conf.ext \
61
 	10-auth.conf \
62
 	10-director.conf \
63
 	10-logging.conf \
64
diff -ruN ../dovecot-2.3.13.orig/doc/example-config/conf.d/auth-vpopmail.conf.ext ./doc/example-config/conf.d/auth-vpopmail.conf.ext
65
--- ../dovecot-2.3.13.orig/doc/example-config/conf.d/auth-vpopmail.conf.ext	1970-01-01 01:00:00.000000000 +0100
66
+++ ./doc/example-config/conf.d/auth-vpopmail.conf.ext	2021-01-29 13:24:12.341999000 +0100
67
@@ -0,0 +1,17 @@
68
+# Authentication for vpopmail users. Included from 10-auth.conf.
69
+#
70
+# <doc/wiki/AuthDatabase.VPopMail.txt>
71
+
72
+passdb {
73
+  driver = vpopmail
74
+
75
+  # [cache_key=<key>] [webmail=<ip>]
76
+  args =
77
+}
78
+
79
+userdb {
80
+  driver = vpopmail
81
+
82
+  # [quota_template=<template>] - %q expands to Maildir++ quota
83
+  args = quota_template=quota_rule=*:backend=%q
84
+}
85
diff -ruN ../dovecot-2.3.13.orig/m4/want_vpopmail.m4 ./m4/want_vpopmail.m4
86
--- ../dovecot-2.3.13.orig/m4/want_vpopmail.m4	1970-01-01 01:00:00.000000000 +0100
87
+++ ./m4/want_vpopmail.m4	2021-01-29 13:24:40.287852000 +0100
88
@@ -0,0 +1,33 @@
89
+AC_DEFUN([DOVECOT_WANT_VPOPMAIL], [
90
+  have_vpopmail=no
91
+  if test $want_vpopmail != no; then
92
+          vpop_etc="$vpopmail_home/etc"
93
+          AC_MSG_CHECKING([for vpopmail configuration at $vpop_etc/lib_deps])
94
+          if ! test -f $vpop_etc/lib_deps; then
95
+                  AC_MSG_RESULT(not found)
96
+                  vpop_etc="$vpopmail_home"
97
+                  AC_MSG_CHECKING([for vpopmail configuration at $vpop_etc/lib_deps])
98
+          fi
99
+          if test -f $vpop_etc/lib_deps; then
100
+                  AUTH_CFLAGS="$AUTH_CFLAGS `cat $vpop_etc/inc_deps` $CFLAGS"
101
+                  AUTH_LIBS="$AUTH_LIBS `cat $vpop_etc/lib_deps`"
102
+                  AC_DEFINE(USERDB_VPOPMAIL,, [Build with vpopmail support])
103
+                  AC_DEFINE(PASSDB_VPOPMAIL,, [Build with vpopmail support])
104
+                  AC_MSG_RESULT(found)
105
+                  have_vpopmail=yes
106
+          else
107
+                  AC_MSG_RESULT(not found)
108
+                  if test $want_vpopmail = yes; then
109
+                    AC_ERROR([Can't build with vpopmail support: $vpop_etc/lib_deps not found])
110
+                  fi
111
+          fi
112
+  fi
113
+  
114
+  if test $have_vpopmail = no; then
115
+    not_passdb="$not_passdb vpopmail"
116
+    not_userdb="$not_userdb vpopmail"
117
+  else
118
+    userdb="$userdb vpopmail"
119
+    passdb="$passdb vpopmail"
120
+  fi
121
+])
122
diff -ruN ../dovecot-2.3.13.orig/src/auth/Makefile.am ./src/auth/Makefile.am
123
--- ../dovecot-2.3.13.orig/src/auth/Makefile.am	2020-12-22 14:26:52.000000000 +0100
124
+++ ./src/auth/Makefile.am	2021-01-29 13:21:19.270313000 +0100
125
@@ -134,6 +134,7 @@
126
 	passdb-passwd-file.c \
127
 	passdb-pam.c \
128
 	passdb-shadow.c \
129
+	passdb-vpopmail.c \
130
 	passdb-sql.c \
131
 	passdb-static.c \
132
 	passdb-template.c \
133
@@ -145,6 +146,7 @@
134
 	userdb-passwd-file.c \
135
 	userdb-prefetch.c \
136
 	userdb-static.c \
137
+	userdb-vpopmail.c \
138
 	userdb-sql.c \
139
 	userdb-template.c \
140
 	$(ldap_sources) \
141
@@ -188,7 +190,8 @@
142
 	password-scheme.h \
143
 	userdb.h \
144
 	userdb-blocking.h \
145
-	userdb-template.h
146
+	userdb-template.h \
147
+	userdb-vpopmail.h
148
 
149
 if GSSAPI_PLUGIN
150
 libmech_gssapi_la_LDFLAGS = -module -avoid-version
151
diff -ruN ../dovecot-2.3.13.orig/src/auth/db-checkpassword.c ./src/auth/db-checkpassword.c
152
--- ../dovecot-2.3.13.orig/src/auth/db-checkpassword.c	2020-12-22 14:26:52.000000000 +0100
153
+++ ./src/auth/db-checkpassword.c	2021-01-29 13:21:19.271324000 +0100
154
@@ -116,8 +116,20 @@
155
 checkpassword_request_finish_auth(struct chkpw_auth_request *request)
156
 {
157
 	switch (request->exit_status) {
158
+	/* vpopmail exit codes: */
159
+	case 3:		/* password fail / vpopmail user not found */
160
+	case 12: 	/* null user name given */
161
+	case 13:	/* null password given */
162
+	case 15:	/* user has no password */
163
+	case 20:	/* invalid user/domain characters */
164
+	case 21:	/* system user not found */
165
+	case 22:	/* system user shadow entry not found */
166
+	case 23:	/* system password fail */
167
+
168
 	/* standard checkpassword exit codes: */
169
 	case 1:
170
+		/* (1 is additionally defined in vpopmail for
171
+		   "pop/smtp/webmail/ imap/access denied") */
172
 		e_info(authdb_event(request->request),
173
 		       "Login failed (status=%d)",
174
 		       request->exit_status);
175
diff -ruN ../dovecot-2.3.13.orig/src/auth/passdb-vpopmail.c ./src/auth/passdb-vpopmail.c
176
--- ../dovecot-2.3.13.orig/src/auth/passdb-vpopmail.c	1970-01-01 01:00:00.000000000 +0100
177
+++ ./src/auth/passdb-vpopmail.c	2021-01-29 13:23:23.979572000 +0100
178
@@ -0,0 +1,229 @@
179
+/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
180
+
181
+/* Thanks to Courier-IMAP for showing how the vpopmail API should be used */
182
+
183
+#include "auth-common.h"
184
+#include "passdb.h"
185
+
186
+#ifdef PASSDB_VPOPMAIL
187
+
188
+#include "safe-memset.h"
189
+#include "password-scheme.h"
190
+#include "auth-cache.h"
191
+
192
+#include "userdb-vpopmail.h"
193
+
194
+
195
+#define VPOPMAIL_DEFAULT_PASS_SCHEME "CRYPT"
196
+
197
+/* pw_flags was added in vpopmail 5.4, olders use pw_gid field */
198
+#ifndef VQPASSWD_HAS_PW_FLAGS
199
+#  define pw_flags pw_gid
200
+#endif
201
+
202
+struct vpopmail_passdb_module {
203
+	struct passdb_module module;
204
+
205
+	struct ip_addr webmail_ip;
206
+};
207
+
208
+static bool vpopmail_is_disabled(struct auth_request *request,
209
+				 const struct vqpasswd *vpw)
210
+{
211
+        struct passdb_module *_module = request->passdb->passdb;
212
+	struct vpopmail_passdb_module *module =
213
+		(struct vpopmail_passdb_module *)_module;
214
+
215
+	if (strcasecmp(request->fields.service, "IMAP") == 0) {
216
+		if ((vpw->pw_flags & NO_IMAP) != 0) {
217
+			/* IMAP from webmail IP may still be allowed */
218
+			if (!net_ip_compare(&module->webmail_ip,
219
+					    &request->fields.remote_ip))
220
+				return TRUE;
221
+		}
222
+		if ((vpw->pw_flags & NO_WEBMAIL) != 0) {
223
+			if (net_ip_compare(&module->webmail_ip,
224
+					   &request->fields.remote_ip))
225
+				return TRUE;
226
+		}
227
+	}
228
+	if ((vpw->pw_flags & NO_POP) != 0 &&
229
+	    strcasecmp(request->fields.service, "POP3") == 0)
230
+		return TRUE;
231
+	if ((vpw->pw_flags & NO_SMTP) != 0 &&
232
+	    strcasecmp(request->fields.service, "SMTP") == 0)
233
+		return TRUE;
234
+	return FALSE;
235
+}
236
+
237
+static char *
238
+vpopmail_password_lookup(struct auth_request *auth_request, bool *cleartext,
239
+			 enum passdb_result *result_r)
240
+{
241
+	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
242
+	struct vqpasswd *vpw;
243
+	char *password;
244
+
245
+	vpw = vpopmail_lookup_vqp(auth_request, vpop_user, vpop_domain);
246
+	if (vpw == NULL) {
247
+		*result_r = PASSDB_RESULT_USER_UNKNOWN;
248
+		return NULL;
249
+	}
250
+
251
+	if (vpopmail_is_disabled(auth_request, vpw)) {
252
+		e_info(authdb_event(auth_request),
253
+		       "%s disabled in vpopmail for this user",
254
+		       auth_request->fields.service);
255
+		password = NULL;
256
+		*result_r = PASSDB_RESULT_USER_DISABLED;
257
+	} else {
258
+		if (vpw->pw_clear_passwd != NULL &&
259
+		    *vpw->pw_clear_passwd != '\0') {
260
+			password = t_strdup_noconst(vpw->pw_clear_passwd);
261
+			*cleartext = TRUE;
262
+		} else if (!*cleartext)
263
+			password = t_strdup_noconst(vpw->pw_passwd);
264
+		else
265
+			password = NULL;
266
+		*result_r = password != NULL ? PASSDB_RESULT_OK :
267
+			PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
268
+	}
269
+
270
+	safe_memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd));
271
+	if (vpw->pw_clear_passwd != NULL) {
272
+		safe_memset(vpw->pw_clear_passwd, 0,
273
+			    strlen(vpw->pw_clear_passwd));
274
+	}
275
+
276
+	return password;
277
+}
278
+
279
+static void vpopmail_lookup_credentials(struct auth_request *request,
280
+					lookup_credentials_callback_t *callback)
281
+{
282
+	enum passdb_result result;
283
+	char *password;
284
+	bool cleartext = TRUE;
285
+
286
+	password = vpopmail_password_lookup(request, &cleartext, &result);
287
+	if (password == NULL) {
288
+		callback(result, NULL, 0, request);
289
+		return;
290
+	}
291
+	
292
+	passdb_handle_credentials(PASSDB_RESULT_OK, password, "CLEARTEXT",
293
+				  callback, request);
294
+	safe_memset(password, 0, strlen(password));
295
+}
296
+
297
+static void
298
+vpopmail_verify_plain(struct auth_request *request, const char *password,
299
+		      verify_plain_callback_t *callback)
300
+{
301
+	enum passdb_result result;
302
+	const char *scheme, *tmp_pass;
303
+	char *crypted_pass;
304
+	bool cleartext = FALSE;
305
+	int ret;
306
+
307
+	crypted_pass = vpopmail_password_lookup(request, &cleartext, &result);
308
+	if (crypted_pass == NULL) {
309
+		callback(result, request);
310
+		return;
311
+	}
312
+	tmp_pass = crypted_pass;
313
+
314
+	if (cleartext)
315
+		scheme = "CLEARTEXT";
316
+	else {
317
+		scheme = password_get_scheme(&tmp_pass);
318
+		if (scheme == NULL)
319
+			scheme = request->passdb->passdb->default_pass_scheme;
320
+	}
321
+
322
+	ret = auth_request_password_verify(request, password, tmp_pass,
323
+					   scheme, AUTH_SUBSYS_DB);
324
+	safe_memset(crypted_pass, 0, strlen(crypted_pass));
325
+
326
+	if (ret <= 0) {
327
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
328
+		return;
329
+	}
330
+
331
+#ifdef POP_AUTH_OPEN_RELAY
332
+	if (strcasecmp(request->fields.service, "POP3") == 0 ||
333
+	    strcasecmp(request->fields.service, "IMAP") == 0) {
334
+		const char *host = net_ip2addr(&request->fields.remote_ip);
335
+		/* vpopmail 5.4 does not understand IPv6 */
336
+		if (host[0] != '\0' && IPADDR_IS_V4(&request->fields.remote_ip)) {
337
+			/* use putenv() directly rather than env_put() which
338
+			   would leak memory every time we got here. use a
339
+			   static buffer for putenv() as SUSv2 requirements
340
+			   would otherwise corrupt our environment later. */
341
+			static char ip_env[256];
342
+
343
+			i_snprintf(ip_env, sizeof(ip_env),
344
+				   "TCPREMOTEIP=%s", host);
345
+			putenv(ip_env);
346
+			open_smtp_relay();
347
+		}
348
+	}
349
+#endif
350
+
351
+	callback(PASSDB_RESULT_OK, request);
352
+}
353
+
354
+static struct passdb_module *
355
+vpopmail_preinit(pool_t pool, const char *args)
356
+{
357
+	static bool vauth_load_initialized = FALSE;
358
+	struct vpopmail_passdb_module *module;
359
+	const char *const *tmp;
360
+
361
+	module = p_new(pool, struct vpopmail_passdb_module, 1);
362
+	module->module.default_pass_scheme = VPOPMAIL_DEFAULT_PASS_SCHEME;
363
+	module->module.blocking = TRUE;
364
+
365
+	tmp = t_strsplit_spaces(args, " ");
366
+	for (; *tmp != NULL; tmp++) {
367
+		if (str_begins(*tmp, "cache_key=")) {
368
+			module->module.default_cache_key =
369
+				auth_cache_parse_key(pool, *tmp + 10);
370
+		} else if (str_begins(*tmp, "webmail=")) {
371
+			if (net_addr2ip(*tmp + 8, &module->webmail_ip) < 0)
372
+				i_fatal("vpopmail: Invalid webmail IP address");
373
+		} else if (strcmp(*tmp, "blocking=no") == 0) {
374
+			module->module.blocking = FALSE;
375
+		} else {
376
+			i_fatal("passdb vpopmail: Unknown setting: %s", *tmp);
377
+		}
378
+	}
379
+	if (!vauth_load_initialized) {
380
+		vauth_load_initialized = TRUE;
381
+		if (vauth_open(0) != 0)
382
+			i_fatal("vpopmail: vauth_open() failed");
383
+	}
384
+	return &module->module;
385
+}
386
+
387
+static void vpopmail_deinit(struct passdb_module *module ATTR_UNUSED)
388
+{
389
+	vclose();
390
+}
391
+
392
+struct passdb_module_interface passdb_vpopmail = {
393
+	"vpopmail",
394
+
395
+	vpopmail_preinit,
396
+	NULL,
397
+	vpopmail_deinit,
398
+
399
+	vpopmail_verify_plain,
400
+	vpopmail_lookup_credentials,
401
+	NULL
402
+};
403
+#else
404
+struct passdb_module_interface passdb_vpopmail = {
405
+	.name = "vpopmail"
406
+};
407
+#endif
408
diff -ruN ../dovecot-2.3.13.orig/src/auth/passdb.c ./src/auth/passdb.c
409
--- ../dovecot-2.3.13.orig/src/auth/passdb.c	2020-12-22 14:26:52.000000000 +0100
410
+++ ./src/auth/passdb.c	2021-01-29 13:21:19.273185000 +0100
411
@@ -321,6 +321,7 @@
412
 extern struct passdb_module_interface passdb_passwd_file;
413
 extern struct passdb_module_interface passdb_pam;
414
 extern struct passdb_module_interface passdb_checkpassword;
415
+extern struct passdb_module_interface passdb_vpopmail;
416
 extern struct passdb_module_interface passdb_ldap;
417
 extern struct passdb_module_interface passdb_sql;
418
 extern struct passdb_module_interface passdb_static;
419
@@ -340,6 +341,7 @@
420
 	passdb_register_module(&passdb_pam);
421
 	passdb_register_module(&passdb_checkpassword);
422
 	passdb_register_module(&passdb_shadow);
423
+	passdb_register_module(&passdb_vpopmail);
424
 	passdb_register_module(&passdb_ldap);
425
 	passdb_register_module(&passdb_sql);
426
 	passdb_register_module(&passdb_static);
427
diff -ruN ../dovecot-2.3.13.orig/src/auth/userdb-vpopmail.c ./src/auth/userdb-vpopmail.c
428
--- ../dovecot-2.3.13.orig/src/auth/userdb-vpopmail.c	1970-01-01 01:00:00.000000000 +0100
429
+++ ./src/auth/userdb-vpopmail.c	2021-01-29 13:22:54.910947000 +0100
430
@@ -0,0 +1,202 @@
431
+/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
432
+
433
+/* Thanks to Courier-IMAP for showing how the vpopmail API should be used */
434
+
435
+#include "auth-common.h"
436
+#include "userdb.h"
437
+
438
+#if defined(PASSDB_VPOPMAIL) || defined(USERDB_VPOPMAIL)
439
+#include "str.h"
440
+#include "var-expand.h"
441
+#include "userdb-vpopmail.h"
442
+
443
+struct vpopmail_userdb_module {
444
+	struct userdb_module module;
445
+
446
+	const char *quota_template_key;
447
+	const char *quota_template_value;
448
+};
449
+
450
+struct vqpasswd *vpopmail_lookup_vqp(struct auth_request *request,
451
+				     char vpop_user[VPOPMAIL_LIMIT],
452
+				     char vpop_domain[VPOPMAIL_LIMIT])
453
+{
454
+	struct vqpasswd *vpw;
455
+
456
+	/* vpop_user must be zero-filled or parse_email() leaves an
457
+	   extra character after the user name. we'll fill vpop_domain
458
+	   as well just to be sure... */
459
+	memset(vpop_user, '\0', VPOPMAIL_LIMIT);
460
+	memset(vpop_domain, '\0', VPOPMAIL_LIMIT);
461
+
462
+	if (parse_email(request->fields.user, vpop_user, vpop_domain,
463
+			VPOPMAIL_LIMIT-1) < 0) {
464
+		e_info(authdb_event(request),
465
+		       "parse_email() failed");
466
+		return NULL;
467
+	}
468
+
469
+	e_debug(authdb_event(request),
470
+		"lookup user=%s domain=%s",
471
+		vpop_user, vpop_domain);
472
+
473
+	vpw = vauth_getpw(vpop_user, vpop_domain);
474
+	if (vpw == NULL) {
475
+		auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
476
+		return NULL;
477
+	}
478
+
479
+	return vpw;
480
+}
481
+#endif
482
+
483
+#ifdef USERDB_VPOPMAIL
484
+static int
485
+userdb_vpopmail_get_quota(const char *template, const char *vpop_str,
486
+			  const char **quota_r, const char **error_r)
487
+{
488
+	struct var_expand_table *tab;
489
+	string_t *quota;
490
+
491
+	if (template == NULL || *vpop_str == '\0' ||
492
+	    strcmp(vpop_str, "NOQUOTA") == 0) {
493
+		*quota_r = "";
494
+		return 0;
495
+	}
496
+
497
+	tab = t_new(struct var_expand_table, 2);
498
+	tab[0].key = 'q';
499
+	tab[0].value = format_maildirquota(vpop_str);
500
+
501
+	quota = t_str_new(128);
502
+	if (var_expand(quota, template, tab, error_r) < 0)
503
+		return -1;
504
+
505
+	*quota_r = str_c(quota);
506
+	return 0;
507
+}
508
+
509
+static void vpopmail_lookup(struct auth_request *auth_request,
510
+			    userdb_callback_t *callback)
511
+{
512
+	struct userdb_module *_module = auth_request->userdb->userdb;
513
+	struct vpopmail_userdb_module *module =
514
+		(struct vpopmail_userdb_module *)_module;
515
+	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
516
+	struct vqpasswd *vpw;
517
+	const char *quota, *error;
518
+	uid_t uid;
519
+	gid_t gid;
520
+
521
+	vpw = vpopmail_lookup_vqp(auth_request, vpop_user, vpop_domain);
522
+	if (vpw == NULL) {
523
+		callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
524
+		return;
525
+	}
526
+
527
+	/* we have to get uid/gid separately, because the gid field in
528
+	   struct vqpasswd isn't really gid at all but just some flags... */
529
+	if (vget_assign(vpop_domain, NULL, 0, &uid, &gid) == NULL) {
530
+		e_info(authdb_event(auth_request),
531
+		       "vget_assign(%s) failed", vpop_domain);
532
+		callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
533
+		return;
534
+	}
535
+
536
+	if (auth_request->fields.successful) {
537
+		/* update the last login only when we're really  */
538
+		vset_lastauth(vpop_user, vpop_domain,
539
+			      t_strdup_noconst(auth_request->fields.service));
540
+	}
541
+
542
+	if (vpw->pw_dir == NULL || vpw->pw_dir[0] == '\0') {
543
+		/* user's homedir doesn't exist yet, create it */
544
+		e_info(authdb_event(auth_request),
545
+		       "pw_dir isn't set, creating");
546
+
547
+		if (make_user_dir(vpop_user, vpop_domain, uid, gid) == NULL) {
548
+			e_error(authdb_event(auth_request),
549
+				"make_user_dir(%s, %s) failed",
550
+				vpop_user, vpop_domain);
551
+			callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
552
+			return;
553
+		}
554
+
555
+		/* get the user again so pw_dir is visible */
556
+		vpw = vauth_getpw(vpop_user, vpop_domain);
557
+		if (vpw == NULL) {
558
+			callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
559
+			return;
560
+		}
561
+	}
562
+
563
+	if (userdb_vpopmail_get_quota(module->quota_template_value,
564
+				      vpw->pw_shell, &quota, &error) < 0) {
565
+		e_error(authdb_event(auth_request),
566
+			"userdb_vpopmail_get_quota(%s, %s) failed: %s",
567
+			module->quota_template_value,
568
+			vpw->pw_shell, error);
569
+		callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
570
+		return;
571
+	}
572
+
573
+	auth_request_set_userdb_field(auth_request, "uid", dec2str(uid));
574
+	auth_request_set_userdb_field(auth_request, "gid", dec2str(gid));
575
+	auth_request_set_userdb_field(auth_request, "home", vpw->pw_dir);
576
+
577
+	if (*quota != '\0') {
578
+		auth_request_set_userdb_field(auth_request,
579
+					      module->quota_template_key,
580
+					      quota);
581
+	}
582
+	callback(USERDB_RESULT_OK, auth_request);
583
+}
584
+
585
+static struct userdb_module *
586
+vpopmail_preinit(pool_t pool, const char *args)
587
+{
588
+	struct vpopmail_userdb_module *module;
589
+	const char *const *tmp, *p;
590
+
591
+	module = p_new(pool, struct vpopmail_userdb_module, 1);
592
+	module->module.blocking = TRUE;
593
+
594
+	for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) {
595
+		if (str_begins(*tmp, "cache_key="))
596
+			module->module.default_cache_key =
597
+				p_strdup(pool, *tmp + 10);
598
+		else if (str_begins(*tmp, "quota_template=")) {
599
+			p = strchr(*tmp + 15, '=');
600
+			if (p == NULL) {
601
+				i_fatal("vpopmail userdb: "
602
+					"quota_template missing '='");
603
+			}
604
+			module->quota_template_key =
605
+				p_strdup_until(pool, *tmp + 15, p);
606
+			module->quota_template_value = p_strdup(pool, p + 1);
607
+		} else if (strcmp(*tmp, "blocking=no") == 0) {
608
+			module->module.blocking = FALSE;
609
+		} else
610
+			i_fatal("userdb vpopmail: Unknown setting: %s", *tmp);
611
+	}
612
+	return &module->module;
613
+}
614
+
615
+struct userdb_module_interface userdb_vpopmail = {
616
+	"vpopmail",
617
+
618
+	vpopmail_preinit,
619
+	NULL,
620
+	NULL,
621
+
622
+	vpopmail_lookup,
623
+
624
+	NULL,
625
+	NULL,
626
+	NULL
627
+};
628
+#else
629
+struct userdb_module_interface userdb_vpopmail = {
630
+	.name = "vpopmail"
631
+};
632
+#endif
633
diff -ruN ../dovecot-2.3.13.orig/src/auth/userdb-vpopmail.h ./src/auth/userdb-vpopmail.h
634
--- ../dovecot-2.3.13.orig/src/auth/userdb-vpopmail.h	1970-01-01 01:00:00.000000000 +0100
635
+++ ./src/auth/userdb-vpopmail.h	2021-01-29 13:23:51.526326000 +0100
636
@@ -0,0 +1,17 @@
637
+#ifndef USERDB_VPOPMAIL_H
638
+#define USERDB_VPOPMAIL_H
639
+
640
+#include <stdio.h>
641
+#include <vpopmail.h>
642
+#include <vauth.h>
643
+
644
+/* Limit user and domain to 80 chars each (+1 for \0). I wouldn't recommend
645
+   raising this limit at least much, vpopmail is full of potential buffer
646
+   overflows. */
647
+#define VPOPMAIL_LIMIT 81
648
+
649
+struct vqpasswd *vpopmail_lookup_vqp(struct auth_request *request,
650
+				     char vpop_user[VPOPMAIL_LIMIT],
651
+				     char vpop_domain[VPOPMAIL_LIMIT]);
652
+
653
+#endif
654
diff -ruN ../dovecot-2.3.13.orig/src/auth/userdb.c ./src/auth/userdb.c
655
--- ../dovecot-2.3.13.orig/src/auth/userdb.c	2020-12-22 14:26:52.000000000 +0100
656
+++ ./src/auth/userdb.c	2021-01-29 13:21:19.275688000 +0100
657
@@ -228,6 +228,7 @@
658
 extern struct userdb_module_interface userdb_static;
659
 extern struct userdb_module_interface userdb_passwd;
660
 extern struct userdb_module_interface userdb_passwd_file;
661
+extern struct userdb_module_interface userdb_vpopmail;
662
 extern struct userdb_module_interface userdb_ldap;
663
 extern struct userdb_module_interface userdb_sql;
664
 extern struct userdb_module_interface userdb_checkpassword;
665
@@ -244,6 +245,7 @@
666
 	userdb_register_module(&userdb_passwd_file);
667
 	userdb_register_module(&userdb_prefetch);
668
 	userdb_register_module(&userdb_static);
669
+	userdb_register_module(&userdb_vpopmail);
670
 	userdb_register_module(&userdb_ldap);
671
 	userdb_register_module(&userdb_sql);
672
 	userdb_register_module(&userdb_checkpassword);
673
diff -ruN ../dovecot-2.3.13.orig/src/master/main.c ./src/master/main.c
674
--- ../dovecot-2.3.13.orig/src/master/main.c	2020-12-22 14:26:52.000000000 +0100
675
+++ ./src/master/main.c	2021-01-29 13:21:19.276733000 +0100
676
@@ -706,6 +706,9 @@
677
 #ifdef PASSDB_SQL 
678
 		" sql"
679
 #endif
680
+#ifdef PASSDB_VPOPMAIL
681
+		" vpopmail"
682
+#endif
683
 	"\nUserdb:"
684
 #ifdef USERDB_CHECKPASSWORD
685
 		" checkpassword"
686
@@ -733,6 +736,9 @@
687
 #endif
688
 #ifdef USERDB_STATIC 
689
 		" static"
690
+#endif
691
+#ifdef USERDB_VPOPMAIL
692
+		" vpopmail"
693
 #endif
694
 	"\n", IO_BLOCK_SIZE);
695
 }
(-)dovecot/pkg-plist (+2 lines)
Lines 37-42 Link Here
37
%%ETCDIR%%/example-config/conf.d/auth-sql.conf.ext
37
%%ETCDIR%%/example-config/conf.d/auth-sql.conf.ext
38
%%ETCDIR%%/example-config/conf.d/auth-static.conf.ext
38
%%ETCDIR%%/example-config/conf.d/auth-static.conf.ext
39
%%ETCDIR%%/example-config/conf.d/auth-system.conf.ext
39
%%ETCDIR%%/example-config/conf.d/auth-system.conf.ext
40
%%VPOPMAIL%%%%ETCDIR%%/example-config/conf.d/auth-vpopmail.conf.ext
40
%%ETCDIR%%/example-config/dovecot-dict-auth.conf.ext
41
%%ETCDIR%%/example-config/dovecot-dict-auth.conf.ext
41
%%ETCDIR%%/example-config/dovecot-dict-sql.conf.ext
42
%%ETCDIR%%/example-config/dovecot-dict-sql.conf.ext
42
%%ETCDIR%%/example-config/dovecot-ldap.conf.ext
43
%%ETCDIR%%/example-config/dovecot-ldap.conf.ext
Lines 648-653 Link Here
648
include/dovecot/uri-util.h
649
include/dovecot/uri-util.h
649
include/dovecot/userdb-blocking.h
650
include/dovecot/userdb-blocking.h
650
include/dovecot/userdb-template.h
651
include/dovecot/userdb-template.h
652
%%VPOPMAIL%%include/dovecot/userdb-vpopmail.h
651
include/dovecot/userdb.h
653
include/dovecot/userdb.h
652
include/dovecot/utc-mktime.h
654
include/dovecot/utc-mktime.h
653
include/dovecot/utc-offset.h
655
include/dovecot/utc-offset.h

Return to bug 253093