From: Timo Sirainen Date: Wed, 2 Mar 2022 22:49:27 +0000 (-0500) Subject: virtual: When saving to virtual mailbox, convert it early on to backend mailbox X-Git-Tag: 2.4.0~3794 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aeedbb12e74610d83830050297424cf1507fe199;p=thirdparty%2Fdovecot%2Fcore.git virtual: When saving to virtual mailbox, convert it early on to backend mailbox This fixes some confusion in plugins that don't understand that the mailbox changes. For example when virtual mailbox is configured to save mails to a backend mailbox, saving mails to the virtual mailbox will now trigger the backend mailbox's imapsieve scripts. (Virtual mailbox names can't be used in the imapsieve scripts or configuration, only the backend mailbox names.) --- diff --git a/src/plugins/virtual/Makefile.am b/src/plugins/virtual/Makefile.am index 9ba873db54..0b8b9178dd 100644 --- a/src/plugins/virtual/Makefile.am +++ b/src/plugins/virtual/Makefile.am @@ -15,6 +15,7 @@ module_LTLIBRARIES = \ lib20_virtual_plugin_la_SOURCES = \ virtual-config.c \ + virtual-list.c \ virtual-mail.c \ virtual-plugin.c \ virtual-search.c \ diff --git a/src/plugins/virtual/virtual-list.c b/src/plugins/virtual/virtual-list.c new file mode 100644 index 0000000000..5b4c570117 --- /dev/null +++ b/src/plugins/virtual/virtual-list.c @@ -0,0 +1,66 @@ +/* Copyright (c) 2022 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mailbox-list-private.h" +#include "virtual-storage.h" +#include "virtual-plugin.h" + +#define VIRTUAL_LIST_CONTEXT(obj) \ + MODULE_CONTEXT(obj, virtual_mailbox_list_module) + +struct virtual_mailbox_list { + union mailbox_list_module_context module_ctx; +}; + +static MODULE_CONTEXT_DEFINE_INIT(virtual_mailbox_list_module, + &mailbox_list_module_register); + +static int +virtual_get_storage(struct mailbox_list **list, const char **vname, + enum mailbox_list_get_storage_flags flags, + struct mail_storage **storage_r) +{ + struct virtual_mailbox_list *vlist = VIRTUAL_LIST_CONTEXT(*list); + + if (vlist->module_ctx.super.get_storage(list, vname, flags, storage_r) < 0) + return -1; + + if ((flags & MAILBOX_LIST_GET_STORAGE_FLAG_SAVEONLY) == 0 || + (*storage_r)->storage_class != &virtual_storage) + return 0; + + /* saving to a virtual mailbox - change the list/vname/storage to the + backend mailbox. */ + struct mailbox *vbox = + mailbox_alloc(*list, *vname, flags & ENUM_NEGATE(MAILBOX_FLAG_SAVEONLY)); + i_assert(strcmp(vbox->storage->name, VIRTUAL_STORAGE_NAME) == 0); + struct virtual_mailbox *mbox = (struct virtual_mailbox *)vbox; + const char *path; + int ret = mailbox_get_path_to(vbox, MAILBOX_LIST_PATH_TYPE_MAILBOX, &path); + if (ret > 0) + ret = virtual_config_read(mbox); + if (ret == 0 && mbox->save_bbox != NULL) { + struct mail_namespace *ns = + mail_namespace_find((*storage_r)->user->namespaces, + mbox->save_bbox->name); + *list = ns->list; + *vname = t_strdup(mbox->save_bbox->name); + if (mailbox_list_get_storage(list, vname, flags, storage_r) < 0) + ret = -1; + } + mailbox_free(&vbox); + return 0; +} + +void virtual_mailbox_list_created(struct mailbox_list *list) +{ + struct virtual_mailbox_list *vlist; + struct mailbox_list_vfuncs *v = list->vlast; + + vlist = p_new(list->pool, struct virtual_mailbox_list, 1); + vlist->module_ctx.super = *v; + list->vlast = &vlist->module_ctx.super; + v->get_storage = virtual_get_storage; + + MODULE_CONTEXT_SET(list, virtual_mailbox_list_module, vlist); +} diff --git a/src/plugins/virtual/virtual-plugin.c b/src/plugins/virtual/virtual-plugin.c index 43db7cbf38..fe1d3da757 100644 --- a/src/plugins/virtual/virtual-plugin.c +++ b/src/plugins/virtual/virtual-plugin.c @@ -9,7 +9,8 @@ const char *virtual_plugin_version = DOVECOT_ABI_VERSION; static struct mail_storage_hooks acl_mail_storage_hooks = { .mailbox_allocated = virtual_backend_mailbox_allocated, - .mailbox_opened = virtual_backend_mailbox_opened + .mailbox_opened = virtual_backend_mailbox_opened, + .mailbox_list_created = virtual_mailbox_list_created, }; void virtual_plugin_init(struct module *module ATTR_UNUSED) diff --git a/src/plugins/virtual/virtual-plugin.h b/src/plugins/virtual/virtual-plugin.h index 39f04bbc07..6c33b4758a 100644 --- a/src/plugins/virtual/virtual-plugin.h +++ b/src/plugins/virtual/virtual-plugin.h @@ -1,6 +1,8 @@ #ifndef VIRTUAL_PLUGIN_H #define VIRTUAL_PLUGIN_H +void virtual_mailbox_list_created(struct mailbox_list *list); + void virtual_plugin_init(struct module *module); void virtual_plugin_deinit(void);