From: Timo Sirainen Date: Wed, 14 May 2003 18:23:04 +0000 (+0300) Subject: Added support for dynamically loadable imap/pop3 modules. X-Git-Tag: 1.1.alpha1~4641 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e708a17f984ef7690ff2468ec19ad62c95b1ac2;p=thirdparty%2Fdovecot%2Fcore.git Added support for dynamically loadable imap/pop3 modules. --HG-- branch : HEAD --- diff --git a/INSTALL b/INSTALL index 6c6dadafea..72acbc6d7d 100644 --- a/INSTALL +++ b/INSTALL @@ -103,18 +103,27 @@ them for auth modules which require external libraries (eg. LDAP and vpopmail). There's no standard way to build them as modules currently, but something like this should work: -gcc -shared -fPIC -DUSERDB_LDAP -DPASSDB_LDAP \ +gcc -shared -fPIC -DHAVE_CONFIG_H -DUSERDB_LDAP -DPASSDB_LDAP \ -I../.. -I../lib -I../lib-settings \ db-ldap.c userdb-ldap.c passdb-ldap.c -o ldap.so \ ../lib-settings/libsettings.a -lldap -gcc -shared -fPIC -DUSERDB_PGSQL -DPASSDB_PGSQL \ +gcc -shared -fPIC -DHAVE_CONFIG_H -DUSERDB_PGSQL -DPASSDB_PGSQL \ -I../.. -I../lib -I../lib-settings -I/usr/include/postgresql \ db-pgsql.c userdb-pgsql.c passdb-pgsql.c -o pgsql.so \ ../lib-settings/libsettings.a -L/usr/lib/postgresql -lpq -gcc -shared -fPIC -DUSERDB_VPOPMAIL -DPASSDB_VPOPMAIL -I../.. -I../lib \ -userdb-vpopmail.c passdb-vpopmail.c -o vpopmail.so -lvpopmail +gcc -shared -fPIC -DHAVE_CONFIG_H -DUSERDB_VPOPMAIL -DPASSDB_VPOPMAIL \ +-I../.. -I../lib userdb-vpopmail.c passdb-vpopmail.c -o vpopmail.so \ +-lvpopmail Including libsettings.a in ldap.so and pgsql.so is kind of annoying, but it's not needed elsewhere in dovecot-auth. + +Dynamic IMAP and POP3 Modules +----------------------------- + +If imap_use_modules or pop3_use_modules is set to yes, Dovecot will load all +*.so modules from directory pointed by imap_modules or pop3_modules. These +modules can do anything, they're only expected to contain _init +and _deinit functions which are called. diff --git a/configure.in b/configure.in index 4eff51c892..1426ab709d 100644 --- a/configure.in +++ b/configure.in @@ -910,14 +910,13 @@ fi dnl * dynamic modules? AC_CHECK_LIB(dl, dlopen, [ - AUTH_LIBS="$AUTH_LIBS -ldl" - AC_DEFINE(AUTH_MODULES,, Define if you want to build with dynamic auth modules) - auth_modules=yes + AC_DEFINE(HAVE_MODULES,, Define if you have dynamic module support) userdb="$userdb (modules)" passdb="$passdb (modules)" -]) -AM_CONDITIONAL(AUTH_MODULES, test "$auth_modules" = "yes") + MODULE_LIBS="-export-dynamic -ldl" + AC_SUBST(MODULE_LIBS) +]) AC_SUBST(AUTH_CFLAGS) AC_SUBST(AUTH_LIBS) @@ -1004,6 +1003,7 @@ src/lib-storage/index/Makefile src/lib-storage/index/maildir/Makefile src/lib-storage/index/mbox/Makefile src/lib-storage/subscription-file/Makefile +src/lib-storage/oracle/Makefile src/lib-storage/register/Makefile src/auth/Makefile src/imap/Makefile diff --git a/dovecot-example.conf b/dovecot-example.conf index 6c1ddb6d93..7a83379d92 100644 --- a/dovecot-example.conf +++ b/dovecot-example.conf @@ -316,6 +316,10 @@ login = pop3 # files, so it shouldn't harm much even if this limit is set pretty high. #imap_process_size = 256 +# Support for dynamically loadable modules. +#imap_use_modules = no +#imap_modules = /usr/lib/dovecot/imap + ## ## POP3 process ## @@ -327,6 +331,10 @@ login = pop3 # files, so it shouldn't harm much even if this limit is set pretty high. #pop3_process_size = 256 +# Support for dynamically loadable modules. +#pop3_use_modules = no +#pop3_modules = /usr/lib/dovecot/pop3 + ## ## Authentication processes ## diff --git a/src/auth/Makefile.am b/src/auth/Makefile.am index 323c07347e..951c99a492 100644 --- a/src/auth/Makefile.am +++ b/src/auth/Makefile.am @@ -12,11 +12,8 @@ dovecot_auth_LDADD = \ ../lib-settings/libsettings.a \ ../lib/liblib.a \ $(AUTH_LIBS) \ - $(RAND_LIBS) - -if AUTH_MODULES -dovecot_auth_LDFLAGS = -export-dynamic -endif + $(RAND_LIBS) \ + $(MODULE_LIBS) dovecot_auth_SOURCES = \ auth-module.c \ diff --git a/src/auth/auth-module.c b/src/auth/auth-module.c index 5e6b60fe1c..9077aa7973 100644 --- a/src/auth/auth-module.c +++ b/src/auth/auth-module.c @@ -2,7 +2,7 @@ #include "lib.h" -#ifdef AUTH_MODULES +#ifdef HAVE_MODULES #include "auth-module.h" diff --git a/src/imap/Makefile.am b/src/imap/Makefile.am index ef38700e0b..712b1866b7 100644 --- a/src/imap/Makefile.am +++ b/src/imap/Makefile.am @@ -8,7 +8,7 @@ INCLUDES = \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-storage -imap_LDADD = \ +libs = \ ../lib-storage/register/libstorage-register.a \ $(STORAGE_LIBS) \ ../lib-storage/libstorage.a \ @@ -16,10 +16,14 @@ imap_LDADD = \ ../lib-imap/libimap.a \ ../lib-mail/libmail.a \ ../lib-charset/libcharset.a \ - ../lib/liblib.a \ - $(LIBICONV) + ../lib/liblib.a + +imap_LDADD = \ + $(libs) \ + $(LIBICONV) \ + $(MODULE_LIBS) -imap_DEPENDENCIES = $(imap_LDADD) +imap_DEPENDENCIES = $(libs) cmds = \ cmd-append.c \ diff --git a/src/imap/main.c b/src/imap/main.c index fe025497e5..165189157e 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -7,6 +7,7 @@ #include "restrict-access.h" #include "fd-close-on-exec.h" #include "process-title.h" +#include "module-dir.h" #include "mail-storage.h" #include "commands.h" @@ -20,6 +21,7 @@ struct ioloop *ioloop; unsigned int max_custom_flag_length, mailbox_check_interval; +static struct module *modules; static char log_prefix[128]; /* syslog() needs this to be permanent */ static void sig_quit(int signo __attr_unused__) @@ -88,8 +90,11 @@ static void main_init(void) mail_storage_init(); mail_storage_register_all(); - commands_init(); clients_init(); + commands_init(); + + modules = getenv("MODULE_DIR") == NULL ? NULL : + module_dir_load(getenv("MODULE_DIR")); mail = getenv("MAIL"); if (mail == NULL) { @@ -144,8 +149,10 @@ static void main_deinit(void) if (lib_signal_kill != 0 && lib_signal_kill != 2) i_warning("Killed with signal %d", lib_signal_kill); - clients_deinit(); + module_dir_unload(modules); + commands_deinit(); + clients_deinit(); mail_storage_deinit(); closelog(); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 20200bfd90..57734bc1e0 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -34,6 +34,7 @@ liblib_a_SOURCES = \ mempool-system.c \ mmap-anon.c \ mmap-util.c \ + module-dir.c \ network.c \ ostream.c \ ostream-file.c \ @@ -85,6 +86,7 @@ noinst_HEADERS = \ md5.h \ mempool.h \ mmap-util.h \ + module-dir.h \ network.h \ ostream.h \ ostream-internal.h \ diff --git a/src/master/Makefile.am b/src/master/Makefile.am index 9f43720a93..ec88429722 100644 --- a/src/master/Makefile.am +++ b/src/master/Makefile.am @@ -8,6 +8,7 @@ INCLUDES = \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ -DPKG_RUNDIR=\""$(localstatedir)/run/$(PACKAGE)"\" \ -DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \ + -DPKG_LIBDIR=\""$(libdir)/$(PACKAGE)"\" \ -DSSLDIR=\""$(ssldir)\"" dovecot_LDADD = \ diff --git a/src/master/login-process.c b/src/master/login-process.c index 2c0055a421..7b26296cbe 100644 --- a/src/master/login-process.c +++ b/src/master/login-process.c @@ -30,6 +30,7 @@ struct login_group { struct login_process *newest_nonlisten_process; const char *executable; + const char *module_dir; unsigned int process_size; int process_type; int *listen_fd, *ssl_listen_fd; @@ -88,12 +89,16 @@ static void login_group_create(struct login_settings *login_set) group->process_type = PROCESS_TYPE_IMAP; group->listen_fd = &mail_fd[FD_IMAP]; group->ssl_listen_fd = &mail_fd[FD_IMAPS]; + group->module_dir = set->imap_use_modules ? NULL : + set->imap_modules; } else if (strcmp(login_set->name, "pop3") == 0) { group->executable = set->pop3_executable; group->process_size = set->pop3_process_size; group->process_type = PROCESS_TYPE_POP3; group->listen_fd = &mail_fd[FD_POP3]; group->ssl_listen_fd = &mail_fd[FD_POP3S]; + group->module_dir = set->pop3_use_modules ? NULL : + set->pop3_modules; } else i_panic("Unknown login group name '%s'", login_set->name); @@ -120,9 +125,10 @@ void auth_master_callback(struct auth_master_reply *reply, master_reply.success = create_mail_process(request->fd, &request->ip, group->executable, + group->module_dir, group->process_size, - group->process_type, reply, - (const char *) data); + group->process_type, + reply, (const char *) data); } /* reply to login */ diff --git a/src/master/mail-process.c b/src/master/mail-process.c index 4862d36e36..5e7cc51ac5 100644 --- a/src/master/mail-process.c +++ b/src/master/mail-process.c @@ -100,9 +100,9 @@ static const char *expand_mail_env(const char *env, const char *user, } int create_mail_process(int socket, struct ip_addr *ip, - const char *executable, unsigned int process_size, - int process_type, struct auth_master_reply *reply, - const char *data) + const char *executable, const char *module_dir, + unsigned int process_size, int process_type, + struct auth_master_reply *reply, const char *data) { static const char *argv[] = { NULL, NULL, NULL }; const char *host, *mail, *chroot_dir, *home_dir, *full_home_dir; @@ -200,6 +200,8 @@ int create_mail_process(int socket, struct ip_addr *ip, if (set->mbox_read_dotlock) env_put("MBOX_READ_DOTLOCK=1"); + env_put(t_strconcat("MODULE_DIR=", module_dir, NULL)); + /* user given environment - may be malicious. virtual_user comes from auth process, but don't trust that too much either. Some auth mechanism might allow leaving extra data there. */ diff --git a/src/master/mail-process.h b/src/master/mail-process.h index 4823695f44..d74a015a7b 100644 --- a/src/master/mail-process.h +++ b/src/master/mail-process.h @@ -4,9 +4,9 @@ struct auth_master_reply; int create_mail_process(int socket, struct ip_addr *ip, - const char *executable, unsigned int process_size, - int process_type, struct auth_master_reply *reply, - const char *data); + const char *executable, const char *module_dir, + unsigned int process_size, int process_type, + struct auth_master_reply *reply, const char *data); void mail_process_destroyed(pid_t pid); diff --git a/src/master/master-settings.c b/src/master/master-settings.c index 386fac3f40..a9062184d3 100644 --- a/src/master/master-settings.c +++ b/src/master/master-settings.c @@ -73,10 +73,14 @@ static struct setting_def setting_defs[] = { /* imap */ DEF(SET_STR, imap_executable), DEF(SET_INT, imap_process_size), + DEF(SET_BOOL, imap_use_modules), + DEF(SET_STR, imap_modules), /* pop3 */ DEF(SET_STR, pop3_executable), DEF(SET_INT, pop3_process_size), + DEF(SET_BOOL, pop3_use_modules), + DEF(SET_STR, pop3_modules), { 0, NULL, 0 } }; @@ -182,10 +186,14 @@ struct settings default_settings = { /* imap */ MEMBER(imap_executable) PKG_LIBEXECDIR"/imap", MEMBER(imap_process_size) 256, + MEMBER(imap_use_modules) FALSE, + MEMBER(imap_modules) PKG_LIBDIR"/imap", /* pop3 */ MEMBER(pop3_executable) PKG_LIBEXECDIR"/pop3", MEMBER(pop3_process_size) 256, + MEMBER(pop3_use_modules) FALSE, + MEMBER(pop3_modules) PKG_LIBDIR"/imap", MEMBER(login_gid) 0, MEMBER(auths) NULL, diff --git a/src/master/master-settings.h b/src/master/master-settings.h index 201a539d03..9756b81b52 100644 --- a/src/master/master-settings.h +++ b/src/master/master-settings.h @@ -57,10 +57,14 @@ struct settings { /* imap */ const char *imap_executable; unsigned int imap_process_size; + int imap_use_modules; + const char *imap_modules; /* pop3 */ const char *pop3_executable; unsigned int pop3_process_size; + int pop3_use_modules; + const char *pop3_modules; /* .. */ gid_t login_gid; diff --git a/src/pop3/Makefile.am b/src/pop3/Makefile.am index a2a3ee0c30..c1cf4862d6 100644 --- a/src/pop3/Makefile.am +++ b/src/pop3/Makefile.am @@ -8,7 +8,7 @@ INCLUDES = \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-storage -pop3_LDADD = \ +libs = \ ../lib-storage/register/libstorage-register.a \ $(STORAGE_LIBS) \ ../lib-storage/libstorage.a \ @@ -16,10 +16,14 @@ pop3_LDADD = \ ../lib-imap/libimap.a \ ../lib-mail/libmail.a \ ../lib-charset/libcharset.a \ - ../lib/liblib.a \ - $(LIBICONV) + ../lib/liblib.a + +pop3_LDADD = \ + $(libs) \ + $(LIBICONV) \ + $(MODULE_LIBS) -pop3_DEPENDENCIES = $(pop3_LDADD) +pop3_DEPENDENCIES = $(libs) pop3_SOURCES = \ client.c \ diff --git a/src/pop3/main.c b/src/pop3/main.c index 4a8507fe41..8fadadac66 100644 --- a/src/pop3/main.c +++ b/src/pop3/main.c @@ -6,6 +6,7 @@ #include "restrict-access.h" #include "fd-close-on-exec.h" #include "process-title.h" +#include "module-dir.h" #include "mail-storage.h" #include @@ -15,6 +16,8 @@ (getenv("LOGGED_IN") == NULL) struct ioloop *ioloop; + +static struct module *modules; static char log_prefix[128]; /* syslog() needs this to be permanent */ static void sig_quit(int signo __attr_unused__) @@ -69,6 +72,9 @@ static int main_init(void) mail_storage_register_all(); clients_init(); + modules = getenv("MODULE_DIR") == NULL ? NULL : + module_dir_load(getenv("MODULE_DIR")); + mail = getenv("MAIL"); if (mail == NULL) { /* support also maildir-specific environment */ @@ -103,6 +109,8 @@ static void main_deinit(void) if (lib_signal_kill != 0 && lib_signal_kill != 2) i_warning("Killed with signal %d", lib_signal_kill); + module_dir_unload(modules); + clients_deinit(); mail_storage_deinit();