]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
virtual: When saving to virtual mailbox, convert it early on to backend mailbox
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 2 Mar 2022 22:49:27 +0000 (17:49 -0500)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Wed, 6 Jul 2022 20:51:20 +0000 (20:51 +0000)
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.)

src/plugins/virtual/Makefile.am
src/plugins/virtual/virtual-list.c [new file with mode: 0644]
src/plugins/virtual/virtual-plugin.c
src/plugins/virtual/virtual-plugin.h

index 9ba873db54b6be29d757255cdcd1331e3c3bcb52..0b8b9178dd26ed811d56e3556d2ead6b3af5df3d 100644 (file)
@@ -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 (file)
index 0000000..5b4c570
--- /dev/null
@@ -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);
+}
index 43db7cbf3848954c18cf5966919368d38b263094..fe1d3da7571fbd014c673268816e1ba3980cc3c9 100644 (file)
@@ -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)
index 39f04bbc07318535144c83a04468b3ab77c73506..6c33b4758aa81fecd811eae1450ae789fb43b417 100644 (file)
@@ -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);