]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixed plugins to work with config rewrite.
authorTimo Sirainen <tss@iki.fi>
Mon, 2 Feb 2009 06:06:53 +0000 (01:06 -0500)
committerTimo Sirainen <tss@iki.fi>
Mon, 2 Feb 2009 06:06:53 +0000 (01:06 -0500)
--HG--
branch : HEAD

49 files changed:
TODO
src/lib-storage/mail-namespace.h
src/lib-storage/mail-storage-settings.c
src/lib-storage/mail-storage-settings.h
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h
src/master/mail-process.c
src/master/master-settings.c
src/plugins/acl/acl-backend.c
src/plugins/acl/acl-lookup-dict.c
src/plugins/acl/acl-lookup-dict.h
src/plugins/acl/acl-mailbox-list.c
src/plugins/acl/acl-plugin.c
src/plugins/acl/acl-storage.c
src/plugins/autocreate/autocreate-plugin.c
src/plugins/convert/Makefile.am
src/plugins/convert/convert-plugin.c
src/plugins/convert/convert-settings.c [new file with mode: 0644]
src/plugins/convert/convert-settings.h [new file with mode: 0644]
src/plugins/convert/convert-storage.c
src/plugins/convert/convert-storage.h
src/plugins/convert/convert-tool.c
src/plugins/expire/Makefile.am
src/plugins/expire/expire-plugin.c
src/plugins/expire/expire-settings.c [new file with mode: 0644]
src/plugins/expire/expire-settings.h [new file with mode: 0644]
src/plugins/expire/expire-tool.c
src/plugins/fts-solr/fts-backend-solr.c
src/plugins/fts-solr/fts-solr-plugin.c
src/plugins/fts-solr/fts-solr-plugin.h
src/plugins/fts-squat/fts-backend-squat.c
src/plugins/fts/fts-plugin.c
src/plugins/fts/fts-storage.c
src/plugins/imap-acl/Makefile.am
src/plugins/imap-acl/imap-acl-plugin.c
src/plugins/imap-quota/imap-quota-plugin.c
src/plugins/lazy-expunge/lazy-expunge-plugin.c
src/plugins/listescape/listescape-plugin.c
src/plugins/mail-log/mail-log-plugin.c
src/plugins/mbox-snarf/mbox-snarf-plugin.c
src/plugins/quota/quota-maildir.c
src/plugins/quota/quota-plugin.c
src/plugins/quota/quota-plugin.h
src/plugins/quota/quota-storage.c
src/plugins/quota/quota.c
src/plugins/quota/quota.h
src/plugins/trash/trash-plugin.c

diff --git a/TODO b/TODO
index b2df19e2d23c3c3b79057fc50d62213133df226f..e428618a99b1f1f41685b077142796f44c042068 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,14 +1,11 @@
+ - dict pooling
  - config rewrite
-   - deliver: plugin var expanding
-   - master: expands only known vars, not all_settings.. should it expand
-     anything after all? use the 1/0 prefix to mark which vars have been
-     expanded (config vs userdb)?
    - go through mail-process.c. nfs test?
    - support !include and !include_try
-   - check plugins to make sure they're using only internal getenv()s,
-     especially fix DEBUG env checks
    - add back all setting verification code from master
-   - put plugin settings to some plugins array, not envs, var expand
+   - plugins:
+      - backwards compatibility so userdb can continue returning quota_* etc?
+      - acl: master_user, acl_groups are now plugin envs..
  - proxying: support fallbacking to local (or other?) server if the first
    one is down
 user_attrs {
index dbda0f341d59032ea2afff840c14e63957a05ce4..ff2d02c196238588a3ac1b18b5134b4aa5a08de1 100644 (file)
@@ -3,8 +3,6 @@
 
 #include "mail-user.h"
 
-struct mail_storage_root_settings;
-
 enum namespace_type {
        NAMESPACE_PRIVATE,
        NAMESPACE_SHARED,
index d7b545ffff491db565073cf4923a00409a19247d..b1ff03bbb4d316e3c98673d934f7337c9533e1c4 100644 (file)
@@ -125,6 +125,7 @@ static struct setting_define mail_user_setting_defines[] = {
        DEF(SET_UINT, umask),
 
        DEFLIST(namespaces, "namespace", &mail_namespace_setting_parser_info),
+       { SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL },
 
        SETTING_DEFINE_LIST_END
 };
@@ -132,7 +133,8 @@ static struct setting_define mail_user_setting_defines[] = {
 static struct mail_user_settings mail_user_default_settings = {
        MEMBER(umask) 0077,
 
-       MEMBER(namespaces) ARRAY_INIT
+       MEMBER(namespaces) ARRAY_INIT,
+       MEMBER(plugin_envs) ARRAY_INIT
 };
 
 struct setting_parser_info mail_user_setting_parser_info = {
index f107a88c442137cf7697bc9e6301498ca3138124..bf85598a38c9009e8630dac54756bfaed36fb1a9 100644 (file)
@@ -41,6 +41,7 @@ struct mail_user_settings {
        unsigned int umask;
 
        ARRAY_DEFINE(namespaces, struct mail_namespace_settings *);
+       ARRAY_DEFINE(plugin_envs, const char *);
 };
 
 extern struct setting_parser_info mail_user_setting_parser_info;
index 6a5bc9be89a6ee95c28399fd1294a66847a43e2a..49315534653ed6a274d295d4a8c405ec6e5cfd9c 100644 (file)
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "hostpid.h"
 #include "network.h"
+#include "str.h"
 #include "var-expand.h"
 #include "settings-parser.h"
 #include "auth-master.h"
@@ -45,8 +46,39 @@ struct mail_user *mail_user_alloc(const char *username,
        return user;
 }
 
+static int
+mail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
+{
+       const char **envs, *home;
+       string_t *str;
+       unsigned int i, count;
+
+       if (!array_is_created(&user->set->plugin_envs))
+               return 0;
+
+       str = t_str_new(256);
+       envs = array_get_modifiable(&user->set->plugin_envs, &count);
+       i_assert((count % 2) == 0);
+       for (i = 0; i < count; i += 2) {
+               if (user->_home == NULL &&
+                   var_has_key(envs[i+1], 'h', "home") &&
+                   mail_user_get_home(user, &home) <= 0) {
+                       *error_r = t_strdup_printf(
+                               "userdb didn't return a home directory, "
+                               "but plugin setting %s used it (%%h): %s",
+                               envs[i], envs[i+1]);
+                       return -1;
+               }
+               str_truncate(str, 0);
+               var_expand(str, envs[i+1], mail_user_var_expand_table(user));
+               envs[i+1] = p_strdup(user->pool, str_c(str));
+       }
+       return 0;
+}
+
 int mail_user_init(struct mail_user *user, const char **error_r)
 {
+       const struct mail_storage_settings *mail_set;
        const char *home, *key, *value;
 
        if (user->_home == NULL &&
@@ -61,6 +93,11 @@ int mail_user_init(struct mail_user *user, const char **error_r)
 
        settings_var_expand(&mail_user_setting_parser_info, user->set,
                            user->pool, mail_user_var_expand_table(user));
+       if (mail_user_expand_plugins_envs(user, error_r) < 0)
+               return -1;
+
+       mail_set = mail_user_set_get_driver_settings(user->set, "MAIL");
+       user->mail_debug = mail_set->mail_debug;
 
        user->initialized = TRUE;
        if (hook_mail_user_created != NULL)
@@ -225,6 +262,23 @@ int mail_user_get_home(struct mail_user *user, const char **home_r)
        return ret;
 }
 
+const char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
+{
+       const char *const *envs;
+       unsigned int i, count, name_len = strlen(name);
+
+       if (!array_is_created(&user->set->plugin_envs))
+               return NULL;
+
+       envs = array_get(&user->set->plugin_envs, &count);
+       for (i = 0; i < count; i++) {
+               if (strncmp(envs[i], name, name_len) == 0 &&
+                   envs[i][name_len] == '=')
+                       return envs[i] + name_len + 1;
+       }
+       return NULL;
+}
+
 int mail_user_try_home_expand(struct mail_user *user, const char **pathp)
 {
        const char *home, *path = *pathp;
index 873873bfcfc0cb1dcdaa82ea4dad9b2c79182969..db1eb3ac1db627d619108cfc7b08456f7775e73e 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef MAIL_USER_H
 #define MAIL_USER_H
 
+#include "mail-storage-settings.h"
+
 struct mail_user;
 
 struct mail_user_vfuncs {
@@ -37,6 +39,8 @@ struct mail_user {
        unsigned int admin:1;
        /* mail_user_init() has been called */
        unsigned int initialized:1;
+       /* Shortcut to mail_storage_settings.mail_debug */
+       unsigned int mail_debug:1;
 };
 
 struct mail_user_module_register {
@@ -82,6 +86,8 @@ void mail_user_set_home(struct mail_user *user, const char *home);
    successfully, 0 if there is no home directory (either user doesn't exist or
    has no home directory) or -1 if lookup failed. */
 int mail_user_get_home(struct mail_user *user, const char **home_r);
+/* If name exists in plugin_envs, return its value. */
+const char *mail_user_plugin_getenv(struct mail_user *user, const char *name);
 
 /* Add more namespaces to user's namespaces. The ->next pointers may be
    changed, so the namespaces pointer will be updated to user->namespaces. */
index 912f9eb385b7d7207b1f62aa261592462469f427..75d7b0ac9aef9dc3644b97db466ebfba59eb3e6a 100644 (file)
@@ -262,6 +262,12 @@ mailbox_list_get_namespace(const struct mailbox_list *list)
        return list->ns;
 }
 
+struct mail_user *
+mailbox_list_get_user(const struct mailbox_list *list)
+{
+       return list->ns->user;
+}
+
 void mailbox_list_get_permissions(struct mailbox_list *list,
                                  mode_t *mode_r, gid_t *gid_r)
 {
index 50366388a6d96ccb977a1eeeca211e8dbc062434..92a3181b231754d9a4f5ac581a1876ad26036f93 100644 (file)
@@ -133,6 +133,8 @@ enum mailbox_list_flags
 mailbox_list_get_flags(const struct mailbox_list *list) ATTR_PURE;
 struct mail_namespace *
 mailbox_list_get_namespace(const struct mailbox_list *list) ATTR_PURE;
+struct mail_user *
+mailbox_list_get_user(const struct mailbox_list *list) ATTR_PURE;
 
 /* Returns the mode and GID that should be used when creating new global files
    to the mailbox list root directories. (gid_t)-1 is returned if it's not
index 28a8c60f6e39a03d16d6e01f7814975556e30507..1f934d5f75c5bc2833d3efada2aae65c4f814867 100644 (file)
@@ -206,55 +206,14 @@ get_var_expand_table(const char *protocol,
        return tab;
 }
 
-static bool
-has_missing_used_home(const char *str, const struct var_expand_table *table)
+static void mail_process_set_environment(struct master_settings *set)
 {
-       i_assert(table[VAR_EXPAND_HOME_IDX].key == 'h');
-
-       return table[VAR_EXPAND_HOME_IDX].value == NULL &&
-               var_has_key(str, 'h', "home");
-}
-
-static void
-mail_process_set_environment(struct master_settings *set,
-                            const struct var_expand_table *table,
-                            string_t *expanded_vars)
-{
-
-       const char **envs;
-       string_t *str;
-       unsigned int i, count;
-
-       str_append(expanded_vars, "VARS_EXPANDED=");
-
        /* we don't know all the settings, so since we can't expand all of
           them just let the mail process expand all of them internally.
           except for plugin settings - we know all of them so expand them. */
        master_settings_export_to_env(set);
 
        (void)umask(set->umask);
-
-       if (array_is_created(&set->plugin_envs))
-               envs = array_get_modifiable(&set->plugin_envs, &count);
-       else {
-               count = 0;
-               envs = NULL;
-       }
-       str = t_str_new(256);
-       i_assert((count % 2) == 0);
-       for (i = 0; i < count; i += 2) {
-               if (has_missing_used_home(envs[i+1], table)) {
-                       i_error("userdb didn't return a home directory, "
-                               "but it's used in plugin setting %s: %s",
-                               envs[i], envs[i+1]);
-               }
-               str_truncate(str, 0);
-               var_expand(str, envs[i+1], table);
-               env_put(t_strconcat(t_str_ucase(envs[i]), "=", str_c(str), NULL));
-
-               str_append(expanded_vars, envs[i]);
-               str_append_c(expanded_vars, ' ');
-       }
 }
 
 void mail_process_exec(const char *protocol, const char **args)
@@ -262,7 +221,6 @@ void mail_process_exec(const char *protocol, const char **args)
        const struct var_expand_table *var_expand_table;
        struct master_settings *set;
        const char *executable;
-       string_t *expanded_vars;
 
        if (strcmp(protocol, "ext") == 0) {
                /* external binary. section contains path for it. */
@@ -303,10 +261,7 @@ void mail_process_exec(const char *protocol, const char **args)
                env_put(str_c(str));
        }
 
-       expanded_vars = t_str_new(128);
-       mail_process_set_environment(set, var_expand_table, expanded_vars);
-       env_put(str_c(expanded_vars));
-
+       mail_process_set_environment(set);
        if (args == NULL)
                client_process_exec(executable, "");
        else
@@ -637,10 +592,11 @@ create_mail_process(enum process_type process_type, struct master_settings *set,
                        i_fatal("chdir(/tmp) failed: %m");
        }
 
-       expanded_vars = t_str_new(128);
-       mail_process_set_environment(set, var_expand_table, expanded_vars);
+       mail_process_set_environment(set);
 
        /* extra args. uppercase key value. */
+       expanded_vars = t_str_new(128);
+       str_append(expanded_vars, "VARS_EXPANDED=");
        args = array_get(&extra_args, &count);
        for (i = 0; i < count; i++) {
                if (*args[i] == '=') {
index 964ba597028515fdd35f6e77e2ee10c98eb42e8b..8734812787fab220019cd2ccb0804f1884fb2179 100644 (file)
@@ -1023,10 +1023,8 @@ void master_settings_export_to_env(const struct master_settings *set)
        unsigned int i, count;
 
        sets = array_get(&set->all_settings, &count);
-       for (i = 0; i < count; i++) {
-               if (strncmp(sets[i], "plugin/", 7) != 0)
-                       env_put(sets[i]);
-       }
+       for (i = 0; i < count; i++)
+               env_put(sets[i]);
 }
 
 void master_settings_init(void)
index dbd12c021587dc7269f87af6afff1250d74c1452..61d46fa21395e12534f368e24b9f4bde11f7f649 100644 (file)
@@ -2,6 +2,9 @@
 
 #include "lib.h"
 #include "hash.h"
+#include "mail-storage-settings.h"
+#include "mailbox-list.h"
+#include "mail-user.h"
 #include "acl-cache.h"
 #include "acl-api-private.h"
 
@@ -31,12 +34,11 @@ acl_backend_init(const char *data, struct mailbox_list *list,
                 const char *acl_username, const char *const *groups,
                 bool owner)
 {
+       struct mail_user *user = mailbox_list_get_user(list);
        struct acl_backend *backend;
        unsigned int i, group_count;
-       bool debug;
 
-       debug = getenv("DEBUG") != NULL;
-       if (debug) {
+       if (user->mail_debug) {
                i_info("acl: initializing backend with data: %s", data);
                i_info("acl: acl username = %s", acl_username);
                i_info("acl: owner = %d", owner);
@@ -52,7 +54,7 @@ acl_backend_init(const char *data, struct mailbox_list *list,
                i_fatal("Unknown ACL backend: %s", t_strcut(data, ':'));
 
        backend = acl_backend_vfile.alloc();
-       backend->debug = debug;
+       backend->debug = user->mail_debug;
        backend->v = acl_backend_vfile;
        backend->list = list;
        backend->username = p_strdup(backend->pool, acl_username);
index 5454244c64854f619efb4b3a0ca24acfca83e265..3e5b871ae40290a70a3fa4dcda61c2738187ef15 100644 (file)
@@ -17,6 +17,7 @@
 
 struct acl_lookup_dict {
        struct mail_user *user;
+       struct dict *dict;
 };
 
 struct acl_lookup_dict_iter {
@@ -33,38 +34,23 @@ struct acl_lookup_dict_iter {
        unsigned int failed:1;
 };
 
-static struct dict *acl_dict;
-
-void acl_lookup_dicts_init(void)
-{
-       const char *uri;
-
-       uri = getenv("ACL_SHARED_DICT");
-       if (uri == NULL) {
-               if (getenv("DEBUG") != NULL) {
-                       i_info("acl: No acl_shared_dict setting - "
-                              "shared mailbox listing is disabled");
-               }
-               return;
-       }
-
-       acl_dict = dict_init(uri, DICT_DATA_TYPE_STRING, "");
-       if (acl_dict == NULL)
-               i_fatal("acl: dict_init(%s) failed", uri);
-}
-
-void acl_lookup_dicts_deinit(void)
-{
-       if (acl_dict != NULL)
-               dict_deinit(&acl_dict);
-}
-
 struct acl_lookup_dict *acl_lookup_dict_init(struct mail_user *user)
 {
        struct acl_lookup_dict *dict;
+       const char *uri;
 
        dict = i_new(struct acl_lookup_dict, 1);
        dict->user = user;
+
+       uri = mail_user_plugin_getenv(user, "acl_shared_dict");
+       if (uri != NULL) {
+               dict->dict = dict_init(uri, DICT_DATA_TYPE_STRING, "");
+               if (dict->dict == NULL)
+                       i_error("acl: dict_init(%s) failed", uri);
+       } else if (user->mail_debug) {
+               i_info("acl: No acl_shared_dict setting - "
+                      "shared mailbox listing is disabled");
+       }
        return dict;
 }
 
@@ -73,6 +59,8 @@ void acl_lookup_dict_deinit(struct acl_lookup_dict **_dict)
        struct acl_lookup_dict *dict = *_dict;
 
        *_dict = NULL;
+       if (dict->dict != NULL)
+               dict_deinit(&dict->dict);
        i_free(dict);
 }
 
@@ -164,7 +152,7 @@ acl_lookup_dict_rebuild_update(struct acl_lookup_dict *dict,
        t_array_init(&old_ids_arr, 128);
        prefix = DICT_PATH_SHARED DICT_SHARED_BOXES_PATH;
        prefix_len = strlen(prefix);
-       iter = dict_iterate_init(acl_dict, prefix, DICT_ITERATE_FLAG_RECURSE);
+       iter = dict_iterate_init(dict->dict, prefix, DICT_ITERATE_FLAG_RECURSE);
        while ((ret = dict_iterate(iter, &key, &value)) > 0) {
                /* prefix/$dest/$source */
                key += prefix_len;
@@ -188,7 +176,7 @@ acl_lookup_dict_rebuild_update(struct acl_lookup_dict *dict,
        path = t_str_new(256);
        str_append(path, prefix);
 
-       dt = dict_transaction_begin(acl_dict);
+       dt = dict_transaction_begin(dict->dict);
        new_ids = array_get(new_ids_arr, &new_count);
        for (newi = oldi = 0; newi < new_count || oldi < old_count; ) {
                ret = newi == new_count ? 1 :
@@ -227,7 +215,7 @@ int acl_lookup_dict_rebuild(struct acl_lookup_dict *dict)
        unsigned int i, dest, count;
        int ret = 0;
 
-       if (acl_dict == NULL)
+       if (dict->dict == NULL)
                return 0;
 
        /* get all ACL identifiers with a positive lookup right */
@@ -267,7 +255,7 @@ static void acl_lookup_dict_iterate_start(struct acl_lookup_dict_iter *iter)
                                   DICT_SHARED_BOXES_PATH, *idp, "/", NULL);
        iter->prefix_len = strlen(iter->prefix);
 
-       iter->dict_iter = dict_iterate_init(acl_dict, iter->prefix,
+       iter->dict_iter = dict_iterate_init(iter->dict->dict, iter->prefix,
                                            DICT_ITERATE_FLAG_RECURSE);
 }
 
@@ -302,7 +290,7 @@ acl_lookup_dict_iterate_visible_init(struct acl_lookup_dict *dict)
 
        /* iterate through all identifiers that match us, start with the
           first one */
-       if (acl_dict != NULL)
+       if (dict->dict != NULL)
                acl_lookup_dict_iterate_start(iter);
        return iter;
 }
index f59c2bb3470daaf98c054a7983623187bcb276c4..8fca8c0095ffcf0b1e9f08dc28549b6ebea8f25c 100644 (file)
@@ -1,9 +1,6 @@
 #ifndef ACL_LOOKUP_DICT_H
 #define ACL_LOOKUP_DICT_H
 
-void acl_lookup_dicts_init(void);
-void acl_lookup_dicts_deinit(void);
-
 struct acl_lookup_dict *acl_lookup_dict_init(struct mail_user *user);
 void acl_lookup_dict_deinit(struct acl_lookup_dict **dict);
 
index f7c9f0585ffb7c5121b0cbff612ad5e21ab94e7c..d89bb11063800ddde111ab697cde803934ef6b5f 100644 (file)
@@ -554,7 +554,11 @@ static void acl_mailbox_list_init_default(struct mailbox_list *list)
 
 void acl_mailbox_list_created(struct mailbox_list *list)
 {
-       if ((list->ns->flags & NAMESPACE_FLAG_INTERNAL) != 0) {
+       struct acl_user *auser = ACL_USER_CONTEXT(list->ns->user);
+
+       if (auser == NULL) {
+               /* ACLs disabled for this user */
+       } else if ((list->ns->flags & NAMESPACE_FLAG_INTERNAL) != 0) {
                /* no ACL checks for internal namespaces (deliver, shared) */
                if (list->ns->type == NAMESPACE_SHARED)
                        acl_mailbox_list_init_shared(list);
index c9027708ecb641f355a3e3aa3a455a32c5b37b64..a7a2019bea33416da457f5edeec4eb5ae3af619f 100644 (file)
@@ -3,7 +3,6 @@
 #include "lib.h"
 #include "mailbox-list-private.h"
 #include "acl-api.h"
-#include "acl-lookup-dict.h"
 #include "acl-plugin.h"
 
 #include <stdlib.h>
@@ -16,30 +15,19 @@ const char *acl_plugin_version = PACKAGE_VERSION;
 
 void acl_plugin_init(void)
 {
-       if (getenv("ACL") != NULL) {
-               acl_next_hook_mail_storage_created =
-                       hook_mail_storage_created;
-               hook_mail_storage_created = acl_mail_storage_created;
-
-               acl_next_hook_mailbox_list_created = hook_mailbox_list_created;
-               hook_mailbox_list_created = acl_mailbox_list_created;
-
-               acl_next_hook_mail_user_created = hook_mail_user_created;
-               hook_mail_user_created = acl_mail_user_created;
-
-               acl_lookup_dicts_init();
-       } else {
-               if (getenv("DEBUG") != NULL)
-                       i_info("acl: No acl setting - ACLs are disabled");
-       }
+       acl_next_hook_mail_storage_created = hook_mail_storage_created;
+       hook_mail_storage_created = acl_mail_storage_created;
+
+       acl_next_hook_mailbox_list_created = hook_mailbox_list_created;
+       hook_mailbox_list_created = acl_mailbox_list_created;
+
+       acl_next_hook_mail_user_created = hook_mail_user_created;
+       hook_mail_user_created = acl_mail_user_created;
 }
 
 void acl_plugin_deinit(void)
 {
-       if (acl_next_hook_mail_storage_created != NULL) {
-               acl_lookup_dicts_deinit();
-               hook_mail_storage_created = acl_next_hook_mail_storage_created;
-               hook_mailbox_list_created = acl_next_hook_mailbox_list_created;
-               hook_mail_user_created = acl_next_hook_mail_user_created;
-       }
+       hook_mail_storage_created = acl_next_hook_mail_storage_created;
+       hook_mailbox_list_created = acl_next_hook_mailbox_list_created;
+       hook_mail_user_created = acl_next_hook_mail_user_created;
 }
index 8c27dc727f718923b91fbb217aa94c2f9ac9118f..fa34d48a62c423aa944eed2f14904890ed55b009 100644 (file)
@@ -169,24 +169,26 @@ static int acl_mailbox_create(struct mail_storage *storage, const char *name,
 
 void acl_mail_storage_created(struct mail_storage *storage)
 {
+       struct acl_user *auser = ACL_USER_CONTEXT(storage->ns->user);
        struct acl_mail_storage *astorage;
        struct acl_backend *backend;
 
-       if ((storage->ns->flags & NAMESPACE_FLAG_INTERNAL) != 0) {
+       if (auser == NULL) {
+               /* ACLs disabled for this user */
+       } else if ((storage->ns->flags & NAMESPACE_FLAG_INTERNAL) != 0) {
                /* no ACL checks for internal namespaces (deliver) */
-               return;
-       }
-
-       astorage = p_new(storage->pool, struct acl_mail_storage, 1);
-       astorage->module_ctx.super = storage->v;
-       storage->v.destroy = acl_storage_destroy;
-       storage->v.mailbox_open = acl_mailbox_open;
-       storage->v.mailbox_create = acl_mailbox_create;
+       } else {
+               astorage = p_new(storage->pool, struct acl_mail_storage, 1);
+               astorage->module_ctx.super = storage->v;
+               storage->v.destroy = acl_storage_destroy;
+               storage->v.mailbox_open = acl_mailbox_open;
+               storage->v.mailbox_create = acl_mailbox_create;
 
-       backend = acl_mailbox_list_get_backend(mail_storage_get_list(storage));
-       acl_storage_rights_ctx_init(&astorage->rights, backend);
+               backend = acl_mailbox_list_get_backend(mail_storage_get_list(storage));
+               acl_storage_rights_ctx_init(&astorage->rights, backend);
 
-       MODULE_CONTEXT_SET(storage, acl_storage_module, astorage);
+               MODULE_CONTEXT_SET(storage, acl_storage_module, astorage);
+       }
 
        if (acl_next_hook_mail_storage_created != NULL)
                acl_next_hook_mail_storage_created(storage);
@@ -200,27 +202,38 @@ static void acl_user_deinit(struct mail_user *user)
        auser->module_ctx.super.deinit(user);
 }
 
-void acl_mail_user_created(struct mail_user *user)
+static void acl_mail_user_create(struct mail_user *user, const char *env)
 {
        struct acl_user *auser;
-       const char *env;
 
        auser = p_new(user->pool, struct acl_user, 1);
        auser->module_ctx.super = user->v;
        user->v.deinit = acl_user_deinit;
        auser->acl_lookup_dict = acl_lookup_dict_init(user);
 
-       auser->acl_env = getenv("ACL");
-       i_assert(auser->acl_env != NULL);
-       auser->master_user = getenv("MASTER_USER");
+       auser->acl_env = env;
+       auser->master_user = mail_user_plugin_getenv(user, "master_user");
 
-       env = getenv("ACL_GROUPS");
+       env = mail_user_plugin_getenv(user, "acl_groups");
        if (env != NULL) {
                auser->groups =
                        (const char *const *)p_strsplit(user->pool, env, ",");
        }
 
        MODULE_CONTEXT_SET(user, acl_user_module, auser);
+}
+
+void acl_mail_user_created(struct mail_user *user)
+{
+       const char *env;
+
+       env = mail_user_plugin_getenv(user, "acl");
+       if (env != NULL)
+               acl_mail_user_create(user, env);
+       else {
+               if (user->mail_debug)
+                       i_info("acl: No acl setting - ACLs are disabled");
+       }
 
        if (acl_next_hook_mail_user_created != NULL)
                acl_next_hook_mail_user_created(user);
index 57d167e459c4bedc182ccff5ab658c9aaa4a053c..d8e04a89d32d7c23cdb905f07efed3ff2cc27368 100644 (file)
@@ -21,14 +21,14 @@ autocreate_mailbox(struct mail_namespace *namespaces, const char *name)
 
        ns = mail_namespace_find(namespaces, &name);
        if (ns == NULL) {
-               if (getenv("DEBUG") != NULL)
+               if (namespaces->mail_set->mail_debug)
                        i_info("autocreate: No namespace found for %s", name);
                return;
        }
 
        if (mail_storage_mailbox_create(ns->storage, name, FALSE) < 0) {
                str = mail_storage_get_last_error(ns->storage, &error);
-               if (error != MAIL_ERROR_EXISTS && getenv("DEBUG") != NULL) {
+               if (error != MAIL_ERROR_EXISTS && ns->mail_set->mail_debug) {
                        i_info("autocreate: Failed to create mailbox %s: %s",
                               name, str);
                }
@@ -37,36 +37,38 @@ autocreate_mailbox(struct mail_namespace *namespaces, const char *name)
 
 static void autocreate_mailboxes(struct mail_namespace *namespaces)
 {
+       struct mail_user *user = namespaces->user;
        char env_name[20];
        const char *name;
        unsigned int i;
 
        i = 1;
-       name = getenv("AUTOCREATE");
+       name = mail_user_plugin_getenv(user, "autocreate");
        while (name != NULL) {
                autocreate_mailbox(namespaces, name);
 
-               i_snprintf(env_name, sizeof(env_name), "AUTOCREATE%d", ++i);
-               name = getenv(env_name);
+               i_snprintf(env_name, sizeof(env_name), "autocreate%d", ++i);
+               name = mail_user_plugin_getenv(user, env_name);
        }
 }
 
 static void autosubscribe_mailboxes(struct mail_namespace *namespaces)
 {
+       struct mail_user *user = namespaces->user;
        struct mail_namespace *ns;
        char env_name[20];
        const char *name;
        unsigned int i;
 
        i = 1;
-       name = getenv("AUTOSUBSCRIBE");
+       name = mail_user_plugin_getenv(user, "autosubscribe");
        while (name != NULL) {
                ns = mail_namespace_find(namespaces, &name);
                if (ns != NULL)
                        (void)mailbox_list_set_subscribed(ns->list, name, TRUE);
 
-               i_snprintf(env_name, sizeof(env_name), "AUTOSUBSCRIBE%d", ++i);
-               name = getenv(env_name);
+               i_snprintf(env_name, sizeof(env_name), "autosubscribe%d", ++i);
+               name = mail_user_plugin_getenv(user, env_name);
        }
 }
 
index d779db76d88f715db21e79b8adead0dd71256d12..5946629ab12570c4b0f729fd4ae6b12d46b812e3 100644 (file)
@@ -2,10 +2,12 @@ pkglibexecdir = $(libexecdir)/dovecot
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
+       -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-mail \
        -I$(top_srcdir)/src/lib-index \
        -I$(top_srcdir)/src/lib-storage \
-       -I$(top_srcdir)/src/lib-storage/index
+       -I$(top_srcdir)/src/lib-storage/index \
+       -DPKG_RUNDIR=\""$(rundir)"\"
 
 lib20_convert_plugin_la_LDFLAGS = -module -avoid-version
 
@@ -17,18 +19,21 @@ lib20_convert_plugin_la_SOURCES = \
        convert-plugin.c
 
 noinst_HEADERS = \
+       convert-settings.h \
        convert-storage.h \
        convert-plugin.h
 
 pkglibexec_PROGRAMS = convert-tool
 
 convert_tool_SOURCES = \
+       convert-settings.c \
        convert-tool.c
 
 common_objects = \
        convert-storage.lo
 
-libs = $(STORAGE_LIBS)
+libs = $(STORAGE_LIBS) \
+       $(top_builddir)/src/lib-settings/libsettings.a
 
 convert_tool_LDADD = \
        $(common_objects) \
index 5e4639bce89acfbe8f9c929ab475054f89a13d5a..442accde859e69ef4f7924b9719fa32ecb1e37e1 100644 (file)
@@ -16,17 +16,21 @@ static void convert_mail_storage(struct mail_namespace *namespaces,
                                 const char *convert_mail)
 {
        const char *str;
-       struct convert_settings set;
+       struct convert_plugin_settings set;
 
        memset(&set, 0, sizeof(set));
        if (mail_user_get_home(namespaces->user, &str) <= 0)
                i_fatal("convert plugin: HOME unset");
 
        set.skip_broken_mailboxes =
-               getenv("CONVERT_SKIP_BROKEN_MAILBOXES") != NULL;
-       set.skip_dotdirs = getenv("CONVERT_SKIP_DOTDIRS") != NULL;
+               mail_user_plugin_getenv(namespaces->user,
+                                       "convert_skip_broken_mailboxes") != NULL;
+       set.skip_dotdirs =
+               mail_user_plugin_getenv(namespaces->user,
+                                       "convert_skip_dotdirs") != NULL;
 
-       str = getenv("CONVERT_ALT_HIERARCHY_CHAR");
+       str = mail_user_plugin_getenv(namespaces->user,
+                                     "convert_alt_hierarchy_char");
        set.alt_hierarchy_char = str != NULL && *str != '\0' ? *str : '_';
 
        if (convert_storage(convert_mail, namespaces, &set) < 0)
@@ -38,10 +42,11 @@ convert_hook_mail_namespaces_created(struct mail_namespace *namespaces)
 {
        const char *convert_mail;
 
-       convert_mail = getenv("CONVERT_MAIL");
+       convert_mail = mail_user_plugin_getenv(namespaces->user,
+                                              "convert_mail");
        if (convert_mail != NULL)
                convert_mail_storage(namespaces, convert_mail);
-       else if (getenv("DEBUG") != NULL)
+       else if (namespaces->user->mail_debug)
                i_info("convert: No convert_mail setting - plugin disabled");
 
        if (convert_next_hook_mail_namespaces_created != NULL)
diff --git a/src/plugins/convert/convert-settings.c b/src/plugins/convert/convert-settings.c
new file mode 100644 (file)
index 0000000..628b1a4
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "settings-parser.h"
+#include "mail-storage-settings.h"
+#include "convert-settings.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#undef DEF
+#define DEF(type, name) \
+       { type, #name, offsetof(struct convert_settings, name), NULL }
+
+static struct setting_define convert_setting_defines[] = {
+       DEF(SET_STR, auth_socket_path),
+       { SET_STRLIST, "plugin", offsetof(struct convert_settings, plugin_envs), NULL },
+
+       SETTING_DEFINE_LIST_END
+};
+
+static struct convert_settings convert_default_settings = {
+       MEMBER(auth_socket_path) PKG_RUNDIR"/auth-master"
+};
+
+struct setting_parser_info convert_setting_parser_info = {
+       MEMBER(defines) convert_setting_defines,
+       MEMBER(defaults) &convert_default_settings,
+
+       MEMBER(parent) NULL,
+       MEMBER(parent_offset) (size_t)-1,
+       MEMBER(type_offset) (size_t)-1,
+       MEMBER(struct_size) sizeof(struct convert_settings)
+};
+
+static pool_t settings_pool = NULL;
+
+void convert_settings_read(const struct convert_settings **set_r,
+                          const struct mail_user_settings **user_set_r)
+{
+       static const struct setting_parser_info *roots[] = {
+                &convert_setting_parser_info,
+                &mail_user_setting_parser_info
+       };
+       struct setting_parser_context *parser;
+       const char *const *expanded;
+       void **sets;
+
+       if (settings_pool == NULL)
+               settings_pool = pool_alloconly_create("convert settings", 1024);
+       else
+               p_clear(settings_pool);
+
+       mail_storage_namespace_defines_init(settings_pool);
+
+       parser = settings_parser_init_list(settings_pool,
+                               roots, N_ELEMENTS(roots),
+                               SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS);
+
+       if (settings_parse_environ(parser) < 0) {
+               i_fatal("Error reading configuration: %s",
+                       settings_parser_get_error(parser));
+       }
+
+       expanded = t_strsplit(getenv("VARS_EXPANDED"), " ");
+       settings_parse_set_keys_expandeded(parser, settings_pool, expanded);
+
+       sets = settings_parser_get_list(parser);
+       *set_r = sets[0];
+       *user_set_r = sets[1];
+       settings_parser_deinit(&parser);
+}
diff --git a/src/plugins/convert/convert-settings.h b/src/plugins/convert/convert-settings.h
new file mode 100644 (file)
index 0000000..97ea2d1
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef CONVERT_SETTINGS_H
+#define CONVERT_SETTINGS_H
+
+struct mail_user_settings;
+
+struct convert_settings {
+       const char *auth_socket_path;
+
+       ARRAY_DEFINE(plugin_envs, const char *);
+};
+
+void convert_settings_read(const struct convert_settings **set_r,
+                          const struct mail_user_settings **user_set_r);
+
+#endif
index 9471b2a5ce891106a37f23c4a49b359d6fd1428b..bb0afb6d49548ff4d7b2163a825b245ed4a4c82c 100644 (file)
@@ -108,7 +108,8 @@ static int mailbox_copy_mails(struct mailbox *srcbox, struct mailbox *destbox,
 static const char *
 mailbox_name_convert(struct mail_storage *dest_storage,
                     struct mail_storage *source_storage,
-                    const struct convert_settings *set, const char *name)
+                    const struct convert_plugin_settings *set,
+                    const char *name)
 {
        char *dest_name, *p, src_sep, dest_sep;
 
@@ -241,7 +242,7 @@ static int mailbox_convert_list_item(struct mail_storage *source_storage,
                                     struct mail_storage *dest_storage,
                                     const struct mailbox_info *info,
                                     struct dotlock *dotlock,
-                                    const struct convert_settings *set)
+                                    const struct convert_plugin_settings *set)
 {
        const char *name, *dest_name, *error;
        struct mailbox *srcbox, *destbox;
@@ -328,7 +329,7 @@ static int mailbox_convert_list_item(struct mail_storage *source_storage,
 static int mailbox_list_copy(struct mail_storage *source_storage,
                             struct mail_namespace *dest_namespaces,
                             struct dotlock *dotlock,
-                            const struct convert_settings *set)
+                            const struct convert_plugin_settings *set)
 {
        struct mailbox_list_iterate_context *iter;
        struct mail_namespace *dest_ns;
@@ -359,7 +360,7 @@ static int mailbox_list_copy(struct mail_storage *source_storage,
 static int
 mailbox_list_copy_subscriptions(struct mail_storage *source_storage,
                                struct mail_namespace *dest_namespaces,
-                               const struct convert_settings *set)
+                               const struct convert_plugin_settings *set)
 {
        struct mailbox_list_iterate_context *iter;
        struct mail_namespace *dest_ns;
@@ -390,24 +391,23 @@ mailbox_list_copy_subscriptions(struct mail_storage *source_storage,
 
 int convert_storage(const char *source_data,
                    struct mail_namespace *dest_namespaces,
-                   const struct convert_settings *set)
+                   const struct convert_plugin_settings *set)
 {
        struct mail_user *user = dest_namespaces->user;
-       struct mail_namespace *source_ns, *dest_inbox_ns;
+       struct mail_namespace *source_ns;
        struct dotlock *dotlock;
-        enum mail_storage_flags src_flags;
-        enum file_lock_method lock_method;
+       struct mail_namespace_settings ns_set;
        const char *home, *path, *error;
        int ret;
 
+       memset(&ns_set, 0, sizeof(ns_set));
+       ns_set.location = source_data;
+
        source_ns = mail_namespaces_init_empty(user);
-       dest_inbox_ns = mail_namespace_find_inbox(dest_namespaces);
-       src_flags = dest_inbox_ns->storage->flags;
-       lock_method = dest_inbox_ns->storage->lock_method;
+       source_ns->set = &ns_set;
 
-       src_flags |= MAIL_STORAGE_FLAG_NO_AUTOCREATE;
-       if (mail_storage_create(source_ns, NULL, source_data,
-                               src_flags, lock_method, &error) < 0) {
+       if (mail_storage_create(source_ns, NULL,
+                               MAIL_STORAGE_FLAG_NO_AUTOCREATE, &error) < 0) {
                /* No need for conversion. */
                return 0;
        }
@@ -416,11 +416,9 @@ int convert_storage(const char *source_data,
                i_unreached();
         path = t_strconcat(home, "/"CONVERT_LOCK_FILENAME, NULL);
        dotlock_settings.use_excl_lock =
-               (source_ns->storage->flags &
-                MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0;
+               source_ns->storage->set->dotlock_use_excl;
        dotlock_settings.nfs_flush =
-               (source_ns->storage->flags &
-                MAIL_STORAGE_FLAG_NFS_FLUSH_STORAGE) != 0;
+               source_ns->storage->set->mail_nfs_storage;
        ret = file_dotlock_create(&dotlock_settings, path, 0, &dotlock);
        if (ret <= 0) {
                if (ret == 0)
@@ -433,8 +431,8 @@ int convert_storage(const char *source_data,
        /* just in case if another process just had converted the mailbox,
           reopen the source storage */
        mail_storage_destroy(&source_ns->storage);
-       if (mail_storage_create(source_ns, NULL, source_data,
-                               src_flags, lock_method, &error) < 0) {
+       if (mail_storage_create(source_ns, NULL,
+                               MAIL_STORAGE_FLAG_NO_AUTOCREATE, &error) < 0) {
                /* No need for conversion anymore. */
                file_dotlock_delete(&dotlock);
                return 0;
index ab121e8220a7b5a3f92794aaae889a3c4ab98cdf..15b9b4077c0960ca615852e6f8b3aadaad682389 100644 (file)
@@ -3,7 +3,7 @@
 
 struct mail_namespace;
 
-struct convert_settings {
+struct convert_plugin_settings {
        bool skip_broken_mailboxes;
        bool skip_dotdirs;
        char alt_hierarchy_char;
@@ -11,6 +11,6 @@ struct convert_settings {
 
 int convert_storage(const char *source_data,
                    struct mail_namespace *dest_namespaces,
-                   const struct convert_settings *set);
+                   const struct convert_plugin_settings *set);
 
 #endif
index 59114a89ea6044e48bcc94ac09c465b736e3541f..1fb51548b633a97a3e4a1f5de06bfb378c4ba652 100644 (file)
@@ -6,6 +6,7 @@
 #include "lib-signals.h"
 #include "mail-namespace.h"
 #include "mail-storage-private.h"
+#include "convert-settings.h"
 #include "convert-storage.h"
 
 #include <stdlib.h>
 int main(int argc, const char *argv[])
 {
        struct ioloop *ioloop;
-       struct convert_settings set;
        struct mail_user *user;
+       const struct convert_settings *set;
+       const struct mail_user_settings *user_set;
+       const struct mail_storage_settings *mail_set;
+       struct convert_plugin_settings set2;
        struct mail_namespace *dest_ns;
-        enum mail_storage_flags dest_flags;
-       enum file_lock_method lock_method;
+       struct mail_namespace_settings ns_set;
        const char *error;
        int i, ret = 0;
 
        lib_init();
        lib_signals_init();
        random_init();
-       mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
        mail_storage_init();
        mail_storage_register_all();
        mailbox_list_register_all();
 
+       convert_settings_read(&set, &user_set);
+       mail_set = mail_user_set_get_driver_settings(user_set, "MAIL");
+       mail_users_init(set->auth_socket_path, mail_set->mail_debug);
+
        if (argc <= 4)
                i_fatal(USAGE_STRING);
 
        ioloop = io_loop_create();
 
-       memset(&set, 0, sizeof(set));
+       memset(&set2, 0, sizeof(set2));
        for (i = 5; i < argc; i++) {
                if (strcmp(argv[i], "skip_broken_mailboxes") != 0)
-                       set.skip_broken_mailboxes = TRUE;
+                       set2.skip_broken_mailboxes = TRUE;
                else if (strcmp(argv[i], "skip_dotdirs") != 0)
-                       set.skip_dotdirs = TRUE;
+                       set2.skip_dotdirs = TRUE;
                else if (strncmp(argv[i], "alt_hierarchy_char=", 19) != 0)
-                       set.alt_hierarchy_char = argv[i][19];
+                       set2.alt_hierarchy_char = argv[i][19];
        }
 
-       mail_storage_parse_env(&dest_flags, &lock_method);
-       user = mail_user_init(argv[1]);
+       user = mail_user_alloc(argv[1], user_set);
        mail_user_set_home(user, argv[2]);
+       mail_user_set_vars(user, geteuid(), "convert", NULL, NULL);
+       if (mail_user_init(user, &error) < 0)
+               i_fatal("Mail user initialization failed: %s", error);
+
+       memset(&ns_set, 0, sizeof(ns_set));
+       ns_set.location = argv[4];
+
        dest_ns = mail_namespaces_init_empty(user);
+       dest_ns->set = &ns_set;
 
-       if (mail_storage_create(dest_ns, NULL, argv[4],
-                               dest_flags, lock_method, &error) < 0) {
+       if (mail_storage_create(dest_ns, NULL, 0, &error) < 0) {
                i_fatal("Failed to create destination "
                        "mail storage with data '%s': %s", argv[4], error);
        }
 
-       ret = convert_storage(argv[3], dest_ns, &set);
+       ret = convert_storage(argv[3], dest_ns, &set2);
        if (ret > 0)
                i_info("Successfully converted");
        else if (ret == 0)
index 05f3338fe9b77f6c97e06ae2205f33fb5d82900a..1e6753e1e7d3c30e374d256625299e094d13d7b3 100644 (file)
@@ -3,6 +3,7 @@ pkglibexecdir = $(libexecdir)/dovecot
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-auth \
+       -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-dict \
        -I$(top_srcdir)/src/lib-mail \
        -I$(top_srcdir)/src/lib-imap \
@@ -23,16 +24,19 @@ lib20_expire_plugin_la_SOURCES = \
 noinst_HEADERS = \
        auth-client.h \
        expire-env.h \
-       expire-plugin.h
+       expire-plugin.h \
+       expire-settings.h
 
 pkglibexec_PROGRAMS = expire-tool
 
 expire_tool_SOURCES = \
        auth-client.c \
+       expire-settings.c \
        expire-tool.c
 
 libs = \
        $(STORAGE_LIBS) \
+       $(top_builddir)/src/lib-settings/libsettings.a \
        $(top_builddir)/src/lib-dict/libdict.a
 
 expire_tool_LDADD = \
index 74fe2ba2a60a4011decc27a4524c68c295bf80aa..157b1fc38e1ebb476d98b7dad04c487a677b1324 100644 (file)
        MODULE_CONTEXT(obj, expire_storage_module)
 #define EXPIRE_MAIL_CONTEXT(obj) \
        MODULE_CONTEXT(obj, expire_mail_module)
+#define EXPIRE_USER_CONTEXT(obj) \
+       MODULE_CONTEXT(obj, expire_mail_user_module)
+
+struct expire_mail_user {
+       union mail_user_module_context module_ctx;
 
-struct expire {
        struct dict *db;
        struct expire_env *env;
-
-       void (*next_hook_mail_storage_created)(struct mail_storage *storage);
 };
 
 struct expire_mailbox {
@@ -40,10 +42,14 @@ struct expire_transaction_context {
 
 const char *expire_plugin_version = PACKAGE_VERSION;
 
-static struct expire expire;
+static void (*next_hook_mail_storage_created)(struct mail_storage *storage);
+static void (*next_hook_mail_user_created)(struct mail_user *user);
+
 static MODULE_CONTEXT_DEFINE_INIT(expire_storage_module,
                                  &mail_storage_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(expire_mail_module, &mail_module_register);
+static MODULE_CONTEXT_DEFINE_INIT(expire_mail_user_module,
+                                 &mail_user_module_register);
 
 static struct mailbox_transaction_context *
 expire_mailbox_transaction_begin(struct mailbox *box,
@@ -96,6 +102,8 @@ expire_mailbox_transaction_commit(struct mailbox_transaction_context *t,
                                  uint32_t *first_saved_uid_r,
                                  uint32_t *last_saved_uid_r)
 {
+       struct expire_mail_user *euser =
+               EXPIRE_USER_CONTEXT(t->box->storage->ns->user);
        struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
        struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
        struct mailbox *box = t->box;
@@ -129,7 +137,7 @@ expire_mailbox_transaction_commit(struct mailbox_transaction_context *t,
                if (!xt->first_expunged && xt->saves) {
                        /* saved new mails. dict needs to be updated only if
                           this is the first mail in the database */
-                       ret = dict_lookup(expire.db, pool_datastack_create(),
+                       ret = dict_lookup(euser->db, pool_datastack_create(),
                                          key, &value);
                        update_dict = ret == 0 ||
                                (ret > 0 && strtoul(value, NULL, 10) == 0);
@@ -141,7 +149,7 @@ expire_mailbox_transaction_commit(struct mailbox_transaction_context *t,
                if (update_dict) {
                        struct dict_transaction_context *dctx;
 
-                       dctx = dict_transaction_begin(expire.db);
+                       dctx = dict_transaction_begin(euser->db);
                        if (new_stamp == 0) {
                                /* everything expunged */
                                dict_unset(dctx, key);
@@ -250,6 +258,7 @@ static struct mailbox *
 expire_mailbox_open(struct mail_storage *storage, const char *name,
                    struct istream *input, enum mailbox_open_flags flags)
 {
+       struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(storage->ns->user);
        union mail_storage_module_context *xpr_storage =
                EXPIRE_CONTEXT(storage);
        struct mailbox *box;
@@ -262,7 +271,7 @@ expire_mailbox_open(struct mail_storage *storage, const char *name,
                vname = t_str_new(128);
                (void)mail_namespace_get_vname(storage->ns, vname, name);
 
-               secs = expire_box_find_min_secs(expire.env, str_c(vname),
+               secs = expire_box_find_min_secs(euser->env, str_c(vname),
                                                &altmove);
                if (secs != 0)
                        mailbox_expire_hook(box, secs, altmove);
@@ -272,53 +281,78 @@ expire_mailbox_open(struct mail_storage *storage, const char *name,
 
 static void expire_mail_storage_created(struct mail_storage *storage)
 {
+       struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(storage->ns->user);
        union mail_storage_module_context *xpr_storage;
 
-       xpr_storage =
-               p_new(storage->pool, union mail_storage_module_context, 1);
-       xpr_storage->super = storage->v;
-       storage->v.mailbox_open = expire_mailbox_open;
+       if (euser != NULL) {
+               xpr_storage = p_new(storage->pool,
+                                   union mail_storage_module_context, 1);
+               xpr_storage->super = storage->v;
+               storage->v.mailbox_open = expire_mailbox_open;
 
-       MODULE_CONTEXT_SET_SELF(storage, expire_storage_module, xpr_storage);
+               MODULE_CONTEXT_SET_SELF(storage, expire_storage_module,
+                                       xpr_storage);
+       }
 
-       if (expire.next_hook_mail_storage_created != NULL)
-               expire.next_hook_mail_storage_created(storage);
+       if (next_hook_mail_storage_created != NULL)
+               next_hook_mail_storage_created(storage);
 }
 
-void expire_plugin_init(void)
+static void expire_mail_user_deinit(struct mail_user *user)
 {
-       const char *expunge_env, *altmove_env, *dict_uri;
+       struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(user);
+
+       dict_deinit(&euser->db);
+       expire_env_deinit(euser->env);
 
-       expunge_env = getenv("EXPIRE");
-       altmove_env = getenv("EXPIRE_ALTMOVE");
-       if (expunge_env != NULL || altmove_env != NULL) {
-               dict_uri = getenv("EXPIRE_DICT");
-               if (dict_uri == NULL)
-                       i_fatal("expire plugin: expire_dict setting missing");
+       euser->module_ctx.super.deinit(user);
+}
+
+static void expire_mail_user_created(struct mail_user *user)
+{
+       struct expire_mail_user *euser;
+       const char *expunge_env, *altmove_env, *dict_uri;
 
-               expire.env = expire_env_init(expunge_env, altmove_env);
+       expunge_env = mail_user_plugin_getenv(user, "expire");
+       altmove_env = mail_user_plugin_getenv(user, "expire_altmove");
+       dict_uri = mail_user_plugin_getenv(user, "expire_dict");
+       if (expunge_env == NULL && altmove_env == NULL) {
+               if (user->mail_debug) {
+                       i_info("expire: No expire or expire_altmove settings - "
+                              "plugin disabled");
+               }
+       } else if (dict_uri == NULL) {
+               i_error("expire plugin: expire_dict setting missing");
+       } else {
+               euser = p_new(user->pool, struct expire_mail_user, 1);
+               euser->module_ctx.super = user->v;
+               user->v.deinit = expire_mail_user_deinit;
+
+               euser->env = expire_env_init(expunge_env, altmove_env);
                /* we're using only shared dictionary, the username
                   doesn't matter. */
-               expire.db = dict_init(dict_uri, DICT_DATA_TYPE_UINT32, "");
-               if (expire.db == NULL)
-                       i_fatal("expire plugin: dict_init() failed");
-
-               expire.next_hook_mail_storage_created =
-                       hook_mail_storage_created;
-               hook_mail_storage_created = expire_mail_storage_created;
-       } else if (getenv("DEBUG") != NULL) {
-               i_info("expire: No expire or expire_altmove settings - "
-                      "plugin disabled");
+               euser->db = dict_init(dict_uri, DICT_DATA_TYPE_UINT32, "");
+               if (euser->db == NULL)
+                       i_error("expire plugin: dict_init(%s) failed", dict_uri);
+               else
+                       MODULE_CONTEXT_SET(user, expire_mail_user_module, euser);
        }
+
+       if (next_hook_mail_user_created != NULL)
+               next_hook_mail_user_created(user);
 }
 
-void expire_plugin_deinit(void)
+void expire_plugin_init(void)
 {
-       if (expire.db != NULL) {
-               hook_mail_storage_created =
-                       expire.next_hook_mail_storage_created;
+       next_hook_mail_storage_created = hook_mail_storage_created;
+       hook_mail_storage_created = expire_mail_storage_created;
 
-               dict_deinit(&expire.db);
-               expire_env_deinit(expire.env);
-       }
+       next_hook_mail_user_created = hook_mail_user_created;
+       hook_mail_user_created = expire_mail_user_created;
+}
+
+void expire_plugin_deinit(void)
+{
+       hook_mail_storage_created = next_hook_mail_storage_created;
+       hook_mail_user_created = next_hook_mail_user_created;
 }
diff --git a/src/plugins/expire/expire-settings.c b/src/plugins/expire/expire-settings.c
new file mode 100644 (file)
index 0000000..16525f1
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "settings-parser.h"
+#include "mail-storage-settings.h"
+#include "expire-settings.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#undef DEF
+#define DEF(type, name) \
+       { type, #name, offsetof(struct expire_settings, name), NULL }
+
+static struct setting_define expire_setting_defines[] = {
+       DEF(SET_STR, auth_socket_path),
+       { SET_STRLIST, "plugin", offsetof(struct expire_settings, plugin_envs), NULL },
+
+       SETTING_DEFINE_LIST_END
+};
+
+static struct expire_settings expire_default_settings = {
+       MEMBER(auth_socket_path) PKG_RUNDIR"/auth-master"
+};
+
+struct setting_parser_info expire_setting_parser_info = {
+       MEMBER(defines) expire_setting_defines,
+       MEMBER(defaults) &expire_default_settings,
+
+       MEMBER(parent) NULL,
+       MEMBER(parent_offset) (size_t)-1,
+       MEMBER(type_offset) (size_t)-1,
+       MEMBER(struct_size) sizeof(struct expire_settings)
+};
+
+static pool_t settings_pool = NULL;
+
+void expire_settings_read(const struct expire_settings **set_r,
+                         const struct mail_user_settings **user_set_r)
+{
+       static const struct setting_parser_info *roots[] = {
+                &expire_setting_parser_info,
+                &mail_user_setting_parser_info
+       };
+       struct setting_parser_context *parser;
+       const char *const *expanded;
+       void **sets;
+
+       if (settings_pool == NULL)
+               settings_pool = pool_alloconly_create("expire settings", 1024);
+       else
+               p_clear(settings_pool);
+
+       mail_storage_namespace_defines_init(settings_pool);
+
+       parser = settings_parser_init_list(settings_pool,
+                               roots, N_ELEMENTS(roots),
+                               SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS);
+
+       if (settings_parse_environ(parser) < 0) {
+               i_fatal("Error reading configuration: %s",
+                       settings_parser_get_error(parser));
+       }
+
+       expanded = t_strsplit(getenv("VARS_EXPANDED"), " ");
+       settings_parse_set_keys_expandeded(parser, settings_pool, expanded);
+
+       sets = settings_parser_get_list(parser);
+       *set_r = sets[0];
+       *user_set_r = sets[1];
+       settings_parser_deinit(&parser);
+}
diff --git a/src/plugins/expire/expire-settings.h b/src/plugins/expire/expire-settings.h
new file mode 100644 (file)
index 0000000..9ff06bf
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef CONVERT_SETTINGS_H
+#define CONVERT_SETTINGS_H
+
+struct mail_user_settings;
+
+struct expire_settings {
+       const char *auth_socket_path;
+
+       ARRAY_DEFINE(plugin_envs, const char *);
+};
+
+void expire_settings_read(const struct expire_settings **set_r,
+                         const struct mail_user_settings **user_set_r);
+
+#endif
index 9b94907ab37137d5f613813de88e369fc2857413..e0c832c25807692b7fe61c690fe567bfa5110c0b 100644 (file)
@@ -14,6 +14,7 @@
 #include "auth-client.h"
 #include "auth-master.h"
 #include "expire-env.h"
+#include "expire-settings.h"
 
 #include <stdlib.h>
 
    dynamic object.. */
 #include "expire-env.c"
 
-#define DEFAULT_AUTH_SOCKET_PATH PKG_RUNDIR"/auth-master"
-
 struct expire_context {
        struct auth_master_connection *auth_conn;
 
        char *user;
        struct mail_user *mail_user;
+       const struct expire_settings *set;
        bool testrun;
 };
 
 static int user_init(struct expire_context *ctx, const char *user)
 {
+       const struct mail_user_settings *user_set;
+       const char *error;
        int ret;
 
        env_clean();
@@ -44,10 +46,19 @@ static int user_init(struct expire_context *ctx, const char *user)
                return 0;
        }
 
-       ctx->mail_user = mail_user_init(user);
+       expire_settings_read(&ctx->set, &user_set);
+
+       ctx->mail_user = mail_user_alloc(user, user_set);
        mail_user_set_home(ctx->mail_user, getenv("HOME"));
-       if (mail_namespaces_init(ctx->mail_user) < 0)
+       mail_user_set_vars(ctx->mail_user, geteuid(), "expire", NULL, NULL);
+       if (mail_user_init(ctx->mail_user, &error) < 0) {
+               i_error("Mail user initialization failed: %s", error);
+               return -1;
+       }
+       if (mail_namespaces_init(ctx->mail_user, &error) < 0) {
+               i_error("Namespace initialization failed: %s", error);
                return -1;
+       }
        return 1;
 }
 
@@ -179,39 +190,61 @@ mailbox_delete_old_mails(struct expire_context *ctx, const char *user,
        return ret < 0 ? -1 : 0;
 }
 
+static const char *expire_getenv(struct expire_context *ctx, const char *name)
+{
+       const char *const *envs;
+       unsigned int i, count, name_len = strlen(name);
+
+       if (!array_is_created(&ctx->set->plugin_envs))
+               return NULL;
+
+       envs = array_get(&ctx->set->plugin_envs, &count);
+       for (i = 0; i < count; i++) {
+               if (strncmp(envs[i], name, name_len) == 0 &&
+                   envs[i][name_len] == '=')
+                       return envs[i] + name_len + 1;
+       }
+       return NULL;
+}
+
 static void expire_run(bool testrun)
 {
        struct expire_context ctx;
        struct dict *dict = NULL;
        struct dict_transaction_context *trans;
+       const struct mail_user_settings *user_set;
+       const struct mail_storage_settings *mail_set;
        struct dict_iterate_context *iter;
        struct expire_env *env;
        time_t oldest;
        unsigned int expunge_secs, altmove_secs;
-       const char *auth_socket, *p, *key, *value;
+       const char *p, *key, *value;
        const char *userp, *mailbox;
        int ret;
 
        dict_drivers_register_builtin();
-       mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
        mail_storage_init();
        mail_storage_register_all();
        mailbox_list_register_all();
 
-       if (getenv("EXPIRE") == NULL && getenv("EXPIRE_ALTMOVE") == NULL)
+       memset(&ctx, 0, sizeof(ctx));
+       expire_settings_read(&ctx.set, &user_set);
+       mail_set = mail_user_set_get_driver_settings(user_set, "MAIL");
+       mail_users_init(ctx.set->auth_socket_path, mail_set->mail_debug);
+
+       if (expire_getenv(&ctx, "EXPIRE") == NULL &&
+           expire_getenv(&ctx, "EXPIRE_ALTMOVE") == NULL)
                i_fatal("expire and expire_altmove settings not set");
-       if (getenv("EXPIRE_DICT") == NULL)
+       if (expire_getenv(&ctx, "EXPIRE_DICT") == NULL)
                i_fatal("expire_dict setting not set");
 
-       auth_socket = getenv("AUTH_SOCKET_PATH");
-       if (auth_socket == NULL)
-               auth_socket = DEFAULT_AUTH_SOCKET_PATH;
-
-       memset(&ctx, 0, sizeof(ctx));
        ctx.testrun = testrun;
-       ctx.auth_conn = auth_master_init(auth_socket, getenv("DEBUG") != NULL);
-       env = expire_env_init(getenv("EXPIRE"), getenv("EXPIRE_ALTMOVE"));
-       dict = dict_init(getenv("EXPIRE_DICT"), DICT_DATA_TYPE_UINT32, "");
+       ctx.auth_conn = auth_master_init(ctx.set->auth_socket_path,
+                                        mail_set->mail_debug);
+       env = expire_env_init(expire_getenv(&ctx, "EXPIRE"),
+                             expire_getenv(&ctx, "EXPIRE_ALTMOVE"));
+       dict = dict_init(expire_getenv(&ctx, "EXPIRE_DICT"),
+                        DICT_DATA_TYPE_UINT32, "");
        if (dict == NULL)
                i_fatal("dict_init() failed");
 
index 28481049c1704b87acf25abbe9948aabc6dd8039..3bfee129f796112bfddba9c4d14f4c441ea7aa28 100644 (file)
@@ -122,7 +122,9 @@ static void solr_quote_http(string_t *dest, const char *str)
 static struct fts_backend *
 fts_backend_solr_init(struct mailbox *box)
 {
-       const struct fts_solr_settings *set = &fts_solr_settings;
+       struct fts_solr_user *fuser =
+               FTS_SOLR_USER_CONTEXT(box->storage->ns->user);
+       const struct fts_solr_settings *set = &fuser->set;
        struct solr_fts_backend *backend;
        struct mail_namespace *ns = box->storage->ns;
        const char *str;
@@ -134,10 +136,10 @@ fts_backend_solr_init(struct mailbox *box)
                solr_conn = solr_connection_init(set->url, set->debug);
 
        backend = i_new(struct solr_fts_backend, 1);
-       str = fts_solr_settings.default_ns_prefix;
-       if (str != NULL) {
+       if (set->default_ns_prefix != NULL) {
                backend->default_ns =
-                       mail_namespace_find_prefix(ns->user->namespaces, str);
+                       mail_namespace_find_prefix(ns->user->namespaces,
+                                                  set->default_ns_prefix);
                if (backend->default_ns == NULL) {
                        i_fatal("fts_solr: default_ns setting points to "
                                "nonexisting namespace");
index 09548f5a3c90faed33be676284cd3684f5204aca..cab40debef87615d30ff60dcf3d30d56cd203a34 100644 (file)
@@ -1,16 +1,22 @@
 /* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "array.h"
+#include "mail-user.h"
 #include "fts-solr-plugin.h"
 
 #include <stdlib.h>
 
 const char *fts_solr_plugin_version = PACKAGE_VERSION;
-struct fts_solr_settings fts_solr_settings;
 
-static void fts_solr_plugin_init_settings(const char *str)
+static void (*fts_solr_next_hook_mail_user_created)(struct mail_user *user);
+struct fts_solr_user_module fts_solr_user_module =
+       MODULE_CONTEXT_INIT(&mail_user_module_register);
+
+static int
+fts_solr_plugin_init_settings(struct mail_user *user,
+                             struct fts_solr_settings *set, const char *str)
 {
-       struct fts_solr_settings *set = &fts_solr_settings;
        const char *const *tmp;
 
        if (str == NULL)
@@ -18,31 +24,62 @@ static void fts_solr_plugin_init_settings(const char *str)
 
        for (tmp = t_strsplit_spaces(str, " "); *tmp != NULL; tmp++) {
                if (strncmp(*tmp, "url=", 4) == 0) {
-                       i_free(set->url);
-                       set->url = i_strdup(*tmp + 4);
+                       set->url = p_strdup(user->pool, *tmp + 4);
                } else if (strcmp(*tmp, "debug") == 0) {
                        set->debug = TRUE;
                } else if (strcmp(*tmp, "break-imap-search") == 0) {
                        set->substring_search = TRUE;
                } else if (strcmp(*tmp, "default_ns=") == 0) {
-                       i_free(set->default_ns_prefix);
-                       set->default_ns_prefix = i_strdup(*tmp + 11);
+                       set->default_ns_prefix =
+                               p_strdup(user->pool, *tmp + 11);
                } else {
-                       i_fatal("fts_solr: Invalid setting: %s", *tmp);
+                       i_error("fts_solr: Invalid setting: %s", *tmp);
+                       return -1;
                }
        }
-       if (set->url == NULL)
-               i_fatal("fts_solr: url setting missing");
+       if (set->url == NULL) {
+               i_error("fts_solr: url setting missing");
+               return -1;
+       }
+       return 0;
+}
+
+static void fts_solr_mail_user_create(struct mail_user *user, const char *env)
+{
+       struct fts_solr_user *fuser;
+
+       fuser = p_new(user->pool, struct fts_solr_user, 1);
+       fuser->module_ctx.super = user->v;
+       if (fts_solr_plugin_init_settings(user, &fuser->set, env) < 0) {
+               /* invalid settings, disabling */
+               return;
+       }
+
+       MODULE_CONTEXT_SET(user, fts_solr_user_module, fuser);
+}
+
+static void fts_solr_mail_user_created(struct mail_user *user)
+{
+       const char *env;
+
+       env = mail_user_plugin_getenv(user, "fts_solr");
+       if (env != NULL)
+               fts_solr_mail_user_create(user, env);
+
+       if (fts_solr_next_hook_mail_user_created != NULL)
+               fts_solr_next_hook_mail_user_created(user);
 }
 
 void fts_solr_plugin_init(void)
 {
-       fts_solr_plugin_init_settings(getenv("FTS_SOLR"));
        fts_backend_register(&fts_backend_solr);
+
+       fts_solr_next_hook_mail_user_created = hook_mail_user_created;
+       hook_mail_user_created = fts_solr_mail_user_created;
 }
 
 void fts_solr_plugin_deinit(void)
 {
-       i_free(fts_solr_settings.url);
        fts_backend_unregister(fts_backend_solr.name);
+       hook_mail_user_created = fts_solr_next_hook_mail_user_created;
 }
index 2721d6c5b1f7d70b59790e39d961f5cbc28ed334..a47d78d5ed0139cd267dadf3addedae596b4deeb 100644 (file)
@@ -1,16 +1,25 @@
 #ifndef FTS_SOLR_PLUGIN_H
 #define FTS_SOLR_PLUGIN_H
 
+#include "module-context.h"
 #include "fts-api-private.h"
 
+#define FTS_SOLR_USER_CONTEXT(obj) \
+       MODULE_CONTEXT(obj, fts_solr_user_module)
+
 struct fts_solr_settings {
-       char *url, *default_ns_prefix;
+       const char *url, *default_ns_prefix;
        bool debug;
        bool substring_search;
 };
 
-extern struct fts_solr_settings fts_solr_settings;
+struct fts_solr_user {
+       union mail_user_module_context module_ctx;
+       struct fts_solr_settings set;
+};
+
 extern struct fts_backend fts_backend_solr;
+extern MODULE_CONTEXT_DEFINE(fts_solr_user_module, &mail_user_module_register);
 
 void fts_solr_plugin_init(void);
 void fts_solr_plugin_deinit(void);
index c2a3d049483b1a4589522c66db1b4d6b323fbea6..a8b80c7a8abbbc26f70d7708c8b1eb8e2ace9ecd 100644 (file)
@@ -2,6 +2,8 @@
 
 #include "lib.h"
 #include "array.h"
+#include "mail-user.h"
+#include "mail-namespace.h"
 #include "mail-storage-private.h"
 #include "mail-search-build.h"
 #include "squat-trie.h"
@@ -67,7 +69,7 @@ static struct fts_backend *fts_backend_squat_init(struct mailbox *box)
        }
 
        mailbox_get_status(box, STATUS_UIDVALIDITY, &status);
-       if (storage->set->mmap_disable || storage->set->mmap_no_write)
+       if (storage->set->mmap_disable)
                flags |= SQUAT_INDEX_FLAG_MMAP_DISABLE;
        if (storage->set->mail_nfs_index)
                flags |= SQUAT_INDEX_FLAG_NFS_FLUSH;
@@ -82,7 +84,7 @@ static struct fts_backend *fts_backend_squat_init(struct mailbox *box)
                                flags, box->file_create_mode,
                                box->file_create_gid);
 
-       env = getenv("FTS_SQUAT");
+       env = mail_user_plugin_getenv(box->storage->ns->user, "fts_squat");
        if (env != NULL)
                fts_backend_squat_set(backend, env);
        return &backend->backend;
index 9c47bdc8b1fd6e4fbb6c5650f610f5f894232536..1f7baf3ec971191e4f589404b306c86cb38e2f9d 100644 (file)
@@ -12,15 +12,11 @@ void (*fts_next_hook_mailbox_opened)(struct mailbox *box);
 
 void fts_plugin_init(void)
 {
-       if (getenv("FTS") != NULL) {
-               fts_next_hook_mailbox_opened = hook_mailbox_opened;
-               hook_mailbox_opened = fts_mailbox_opened;
-       } else if (getenv("DEBUG") != NULL)
-               i_info("fts: No fts setting - plugin disabled");
+       fts_next_hook_mailbox_opened = hook_mailbox_opened;
+       hook_mailbox_opened = fts_mailbox_opened;
 }
 
 void fts_plugin_deinit(void)
 {
-       if (hook_mailbox_opened == fts_mailbox_opened)
-               hook_mailbox_opened = fts_next_hook_mailbox_opened;
+       hook_mailbox_opened = fts_next_hook_mailbox_opened;
 }
index 87176101a5ce0202c6310bdeef257b3d5f7dd1e2..23d80d11f9a3d0084e7f40e4d2f865471b6d92d4 100644 (file)
@@ -1031,9 +1031,9 @@ void fts_mailbox_opened(struct mailbox *box)
 {
        const char *env;
 
-       env = getenv("FTS");
-       i_assert(env != NULL);
-       fts_mailbox_init(box, env);
+       env = mail_user_plugin_getenv(box->storage->ns->user, "fts");
+       if (env != NULL)
+               fts_mailbox_init(box, env);
 
        if (fts_next_hook_mailbox_opened != NULL)
                fts_next_hook_mailbox_opened(box);
index bbc8eb92e56c1ba239ac63dafa6b976da998a7db..76859e664b9110328f1da83f6fdb0771208a5ad0 100644 (file)
@@ -2,6 +2,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-mail \
        -I$(top_srcdir)/src/lib-imap \
+       -I$(top_srcdir)/src/lib-index \
        -I$(top_srcdir)/src/lib-storage \
        -I$(top_srcdir)/src/imap \
        -I$(top_srcdir)/src/plugins/acl
index 550d8f0ddaf2202399ac1df3f146b34decfb2710..94345921b779da116aaf97caf5f60b452ee02142 100644 (file)
@@ -9,6 +9,7 @@
 #include "mail-namespace.h"
 #include "acl-api.h"
 #include "acl-storage.h"
+#include "acl-plugin.h"
 #include "imap-acl-plugin.h"
 
 #include <stdlib.h>
@@ -49,7 +50,6 @@ static const struct imap_acl_letter_map imap_acl_letter_map[] = {
 const char *imap_acl_plugin_version = PACKAGE_VERSION;
 
 static void (*next_hook_client_created)(struct client **client);
-static bool acl_anyone_allow = FALSE;
 
 static struct mailbox *
 acl_mailbox_open_as_admin(struct client_command_context *cmd, const char *name)
@@ -58,6 +58,11 @@ acl_mailbox_open_as_admin(struct client_command_context *cmd, const char *name)
        struct mailbox *box;
        int ret;
 
+       if (ACL_USER_CONTEXT(cmd->client->user) == NULL) {
+               client_send_command_error(cmd, "ACLs disabled.");
+               return NULL;
+       }
+
        storage = client_find_storage(cmd, &name);
        if (storage == NULL)
                return NULL;
@@ -230,6 +235,11 @@ static bool cmd_myrights(struct client_command_context *cmd)
                return TRUE;
        }
 
+       if (ACL_USER_CONTEXT(cmd->client->user) == NULL) {
+               client_send_command_error(cmd, "ACLs disabled.");
+               return TRUE;
+       }
+
        real_mailbox = mailbox;
        storage = client_find_storage(cmd, &real_mailbox);
        if (storage == NULL)
@@ -325,10 +335,21 @@ imap_acl_letters_parse(const char *letters, const char *const **rights_r,
        return 0;
 }
 
+static bool acl_anyone_allow(struct mail_user *user)
+{
+       const char *env;
+
+       env = mail_user_plugin_getenv(user, "acl_anyone");
+       return env != NULL && strcmp(env, "allow") == 0;
+}
+
 static int
-imap_acl_identifier_parse(const char *id, struct acl_rights *rights,
+imap_acl_identifier_parse(struct client_command_context *cmd,
+                         const char *id, struct acl_rights *rights,
                          bool check_anyone, const char **error_r)
 {
+       struct mail_user *user = cmd->client->user;
+
        if (strncmp(id, IMAP_ACL_GLOBAL_PREFIX,
                    strlen(IMAP_ACL_GLOBAL_PREFIX)) == 0) {
                *error_r = t_strdup_printf("Global ACLs can't be modified: %s",
@@ -337,13 +358,13 @@ imap_acl_identifier_parse(const char *id, struct acl_rights *rights,
        }
 
        if (strcmp(id, IMAP_ACL_ANYONE) == 0) {
-               if (!acl_anyone_allow && check_anyone) {
+               if (check_anyone && !acl_anyone_allow(user)) {
                        *error_r = "'anyone' identifier is disallowed";
                        return -1;
                }
                rights->id_type = ACL_ID_ANYONE;
        } else if (strcmp(id, IMAP_ACL_AUTHENTICATED) == 0) {
-               if (!acl_anyone_allow && check_anyone) {
+               if (check_anyone && !acl_anyone_allow(user)) {
                        *error_r = "'authenticated' identifier is disallowed";
                        return -1;
                }
@@ -399,7 +420,7 @@ static bool cmd_setacl(struct client_command_context *cmd)
                break;
        }
 
-       if (imap_acl_identifier_parse(identifier, &update.rights,
+       if (imap_acl_identifier_parse(cmd, identifier, &update.rights,
                                      TRUE, &error) < 0) {
                client_send_command_error(cmd, error);
                return TRUE;
@@ -448,7 +469,7 @@ static bool cmd_deleteacl(struct client_command_context *cmd)
                identifier++;
        }
 
-       if (imap_acl_identifier_parse(identifier, &update.rights,
+       if (imap_acl_identifier_parse(cmd, identifier, &update.rights,
                                      FALSE, &error) < 0) {
                client_send_command_error(cmd, error);
                return TRUE;
@@ -476,15 +497,6 @@ static void imap_acl_client_created(struct client **client)
 
 void imap_acl_plugin_init(void)
 {
-       const char *env;
-
-       if (getenv("ACL") == NULL)
-               return;
-
-       env = getenv("ACL_ANYONE");
-       if (env != NULL)
-               acl_anyone_allow = strcmp(env, "allow") == 0;
-
        command_register("LISTRIGHTS", cmd_listrights, 0);
        command_register("GETACL", cmd_getacl, 0);
        command_register("MYRIGHTS", cmd_myrights, 0);
@@ -497,9 +509,6 @@ void imap_acl_plugin_init(void)
 
 void imap_acl_plugin_deinit(void)
 {
-       if (getenv("ACL") == NULL)
-               return;
-
        command_unregister("GETACL");
        command_unregister("MYRIGHTS");
        command_unregister("SETACL");
index 67d618e1c39fc8dd89ce81ce15817a9db5567fb3..5cd57691945e4e34e858bccd1136a9f64bcaf2f6 100644 (file)
@@ -67,6 +67,7 @@ quota_send(struct client_command_context *cmd, struct mail_user *owner,
 static bool cmd_getquotaroot(struct client_command_context *cmd)
 {
        struct client *client = cmd->client;
+       struct quota_user *quser = QUOTA_USER_CONTEXT(client->user);
        struct mail_storage *storage;
        struct mail_namespace *ns;
        struct mailbox *box;
@@ -93,7 +94,7 @@ static bool cmd_getquotaroot(struct client_command_context *cmd)
        }
 
        ns = mail_storage_get_namespace(storage);
-       if (quota_set == NULL || ns->owner == NULL) {
+       if (quser == NULL || ns->owner == NULL) {
                mailbox_close(&box);
                client_send_tagline(cmd, "OK No quota.");
                return TRUE;
@@ -139,11 +140,6 @@ static bool cmd_getquota(struct client_command_context *cmd)
        if (!client_read_string_args(cmd, 1, &root_name))
                return FALSE;
 
-       if (quota_set == NULL) {
-               client_send_tagline(cmd, "OK No quota.");
-               return TRUE;
-       }
-
        root = quota_root_lookup(cmd->client->user, root_name);
        if (root == NULL && cmd->client->user->admin) {
                /* we're an admin. see if there's a quota root for another
@@ -183,11 +179,6 @@ static bool cmd_setquota(struct client_command_context *cmd)
                return TRUE;
        }
 
-       if (quota_set == NULL) {
-               client_send_tagline(cmd, "OK No quota.");
-               return TRUE;
-       }
-
        root = quota_root_lookup(cmd->client->user, root_name);
        if (root == NULL) {
                client_send_tagline(cmd, "NO Quota root doesn't exist.");
index ada7cf4b2b58c5ce180a2b29e6744edb4f8e6ab8..54f55456b90eaa1e07c7947e4bb3be66822fba07 100644 (file)
@@ -34,6 +34,7 @@ struct lazy_expunge_mail_user {
        union mail_user_module_context module_ctx;
 
        struct mail_namespace *lazy_ns[LAZY_NAMESPACE_COUNT];
+       const char *env;
 };
 
 struct lazy_expunge_mailbox_list {
@@ -487,15 +488,20 @@ lazy_expunge_mailbox_list_delete(struct mailbox_list *list, const char *name)
 
 static void lazy_expunge_mail_storage_init(struct mail_storage *storage)
 {
+       struct lazy_expunge_mail_user *luser =
+               LAZY_EXPUNGE_USER_CONTEXT(storage->ns->user);
        struct lazy_expunge_mailbox_list *llist =
                LAZY_EXPUNGE_LIST_CONTEXT(storage->list);
        struct lazy_expunge_mail_storage *lstorage;
        const char *const *p;
        unsigned int i;
 
+       if (llist == NULL)
+               return;
+
        /* if this is one of our internal storages, mark it as such before
           quota plugin sees it */
-       p = t_strsplit_spaces(getenv("LAZY_EXPUNGE"), " ");
+       p = t_strsplit_spaces(luser->env, " ");
        for (i = 0; i < LAZY_NAMESPACE_COUNT; i++, p++) {
                if (strcmp(storage->ns->prefix, *p) == 0) {
                        storage->ns->flags |= NAMESPACE_FLAG_INTERNAL;
@@ -524,16 +530,21 @@ static void lazy_expunge_mail_storage_created(struct mail_storage *storage)
 
 static void lazy_expunge_mailbox_list_created(struct mailbox_list *list)
 {
+       struct lazy_expunge_mail_user *luser =
+               LAZY_EXPUNGE_USER_CONTEXT(list->ns->user);
        struct lazy_expunge_mailbox_list *llist;
 
-       if (lazy_expunge_next_hook_mailbox_list_created != NULL)
-               lazy_expunge_next_hook_mailbox_list_created(list);
+       if (luser != NULL) {
+               llist = p_new(list->pool, struct lazy_expunge_mailbox_list, 1);
+               llist->module_ctx.super = list->v;
+               list->v.delete_mailbox = lazy_expunge_mailbox_list_delete;
 
-       llist = p_new(list->pool, struct lazy_expunge_mailbox_list, 1);
-       llist->module_ctx.super = list->v;
-       list->v.delete_mailbox = lazy_expunge_mailbox_list_delete;
+               MODULE_CONTEXT_SET(list, lazy_expunge_mailbox_list_module,
+                                  llist);
+       }
 
-       MODULE_CONTEXT_SET(list, lazy_expunge_mailbox_list_module, llist);
+       if (lazy_expunge_next_hook_mailbox_list_created != NULL)
+               lazy_expunge_next_hook_mailbox_list_created(list);
 }
 
 static void
@@ -545,7 +556,10 @@ lazy_expunge_hook_mail_namespaces_created(struct mail_namespace *namespaces)
        const char *const *p;
        int i;
 
-       p = t_strsplit_spaces(getenv("LAZY_EXPUNGE"), " ");
+       if (luser == NULL)
+               return;
+
+       p = t_strsplit_spaces(luser->env, " ");
        for (i = 0; i < LAZY_NAMESPACE_COUNT; i++, p++) {
                const char *name = *p;
 
@@ -574,11 +588,19 @@ lazy_expunge_hook_mail_namespaces_created(struct mail_namespace *namespaces)
 static void lazy_expunge_mail_user_created(struct mail_user *user)
 {
        struct lazy_expunge_mail_user *luser;
-
-       luser = p_new(user->pool, struct lazy_expunge_mail_user, 1);
-       luser->module_ctx.super = user->v;
-
-       MODULE_CONTEXT_SET(user, lazy_expunge_mail_user_module, luser);
+       const char *env;
+
+       env = mail_user_plugin_getenv(user, "lazy_expunge");
+       if (env != NULL) {
+               luser = p_new(user->pool, struct lazy_expunge_mail_user, 1);
+               luser->module_ctx.super = user->v;
+               luser->env = env;
+
+               MODULE_CONTEXT_SET(user, lazy_expunge_mail_user_module, luser);
+       } else if (user->mail_debug) {
+               i_info("lazy_expunge: No lazy_expunge setting - "
+                      "plugin disabled");
+       }
 
        if (lazy_expunge_next_hook_mail_user_created != NULL)
                lazy_expunge_next_hook_mail_user_created(user);
@@ -586,14 +608,6 @@ static void lazy_expunge_mail_user_created(struct mail_user *user)
 
 void lazy_expunge_plugin_init(void)
 {
-       if (getenv("LAZY_EXPUNGE") == NULL) {
-               if (getenv("DEBUG") != NULL) {
-                       i_info("lazy_expunge: No lazy_expunge setting - "
-                              "plugin disabled");
-               }
-               return;
-       }
-
        lazy_expunge_next_hook_mail_namespaces_created =
                hook_mail_namespaces_created;
        hook_mail_namespaces_created =
@@ -611,9 +625,6 @@ void lazy_expunge_plugin_init(void)
 
 void lazy_expunge_plugin_deinit(void)
 {
-       if (getenv("LAZY_EXPUNGE") != NULL)
-               return;
-
        hook_mail_namespaces_created =
                lazy_expunge_hook_mail_namespaces_created;
        hook_mail_storage_created = lazy_expunge_next_hook_mail_storage_created;
index 73605254c1b3966b0b43ad03393cbb0d999d55fb..ad54edade5a7e355fa125e8419c4a41b14182428 100644 (file)
@@ -26,6 +26,7 @@ struct listescape_mailbox_list {
        union mailbox_list_module_context module_ctx;
        struct mailbox_info info;
        string_t *list_name;
+       char escape_char;
        bool name_escaped;
 };
 
@@ -37,7 +38,6 @@ static void (*listescape_next_hook_mailbox_list_created)
        (struct mailbox_list *list);
 static void (*listescape_next_hook_mail_namespaces_created)
        (struct mail_namespace *namespaces);
-static char escape_char = DEFAULT_ESCAPE_CHAR;
 
 static MODULE_CONTEXT_DEFINE_INIT(listescape_storage_module,
                                  &mail_storage_module_register);
@@ -47,18 +47,20 @@ static MODULE_CONTEXT_DEFINE_INIT(listescape_list_module,
 static const char *list_escape(struct mail_namespace *ns,
                               const char *str, bool change_sep)
 {
+       struct listescape_mailbox_list *mlist =
+               LIST_ESCAPE_LIST_CONTEXT(ns->list);
        string_t *esc = t_str_new(64);
 
        if (*str == '~') {
-               str_printfa(esc, "%c%02x", escape_char, *str);
+               str_printfa(esc, "%c%02x", mlist->escape_char, *str);
                str++;
        }
        for (; *str != '\0'; str++) {
                if (*str == ns->sep && change_sep)
                        str_append_c(esc, ns->list->hierarchy_sep);
                else if (*str == ns->list->hierarchy_sep ||
-                        *str == escape_char || *str == '/')
-                       str_printfa(esc, "%c%02x", escape_char, *str);
+                        *str == mlist->escape_char || *str == '/')
+                       str_printfa(esc, "%c%02x", mlist->escape_char, *str);
                else
                        str_append_c(esc, *str);
        }
@@ -68,10 +70,12 @@ static const char *list_escape(struct mail_namespace *ns,
 static void list_unescape_str(struct mail_namespace *ns,
                              const char *str, string_t *dest)
 {
+       struct listescape_mailbox_list *mlist =
+               LIST_ESCAPE_LIST_CONTEXT(ns->list);
        unsigned int num;
 
        for (; *str != '\0'; str++) {
-               if (*str == escape_char &&
+               if (*str == mlist->escape_char &&
                    i_isxdigit(str[1]) && i_isxdigit(str[2])) {
                        if (str[1] >= '0' && str[1] <= '9')
                                num = str[1] - '0';
@@ -269,6 +273,7 @@ static void listescape_mail_storage_created(struct mail_storage *storage)
 static void listescape_mailbox_list_created(struct mailbox_list *list)
 {
        struct listescape_mailbox_list *mlist;
+       const char *env;
 
        if (listescape_next_hook_mailbox_list_created != NULL)
                listescape_next_hook_mailbox_list_created(list);
@@ -289,6 +294,10 @@ static void listescape_mailbox_list_created(struct mailbox_list *list)
        list->v.is_valid_existing_name = listescape_is_valid_existing_name;
        list->v.is_valid_create_name = listescape_is_valid_create_name;
 
+       env = mail_user_plugin_getenv(list->ns->user, "listescape_char");
+       mlist->escape_char = env != NULL && *env != '\0' ?
+               env[0] : DEFAULT_ESCAPE_CHAR;
+
        MODULE_CONTEXT_SET(list, listescape_list_module, mlist);
 }
 
@@ -308,12 +317,6 @@ listescape_mail_namespaces_created(struct mail_namespace *namespaces)
 
 void listescape_plugin_init(void)
 {
-       const char *env;
-
-       env = getenv("LISTESCAPE_CHAR");
-       if (env != NULL && *env != '\0')
-               escape_char = env[0];
-
        listescape_next_hook_mail_storage_created = hook_mail_storage_created;
        hook_mail_storage_created = listescape_mail_storage_created;
 
index bde0b277f62bf06a5dfec6b02232ba9776d6e1aa..f5cd2bd08327640dbd3f15eb102cb52269e88ce7 100644 (file)
@@ -7,6 +7,7 @@
 #include "imap-util.h"
 #include "mail-storage-private.h"
 #include "mailbox-list-private.h"
+#include "mail-user.h"
 #include "mail-log-plugin.h"
 
 #include <stdlib.h>
@@ -20,6 +21,8 @@
        MODULE_CONTEXT(obj, mail_log_mail_module)
 #define MAIL_LOG_LIST_CONTEXT(obj) \
        MODULE_CONTEXT(obj, mail_log_mailbox_list_module)
+#define MAIL_LOG_USER_CONTEXT(obj) \
+       MODULE_CONTEXT(obj, mail_log_mail_user_module)
 
 enum mail_log_field {
        MAIL_LOG_FIELD_UID      = 0x01,
@@ -74,7 +77,9 @@ static const char *event_names[] = {
        NULL
 };
 
-struct mail_log_settings {
+struct mail_log_user {
+       union mail_user_module_context module_ctx;
+
        enum mail_log_field fields;
        enum mail_log_event events;
 
@@ -101,18 +106,19 @@ struct mail_log_transaction_context {
 
 const char *mail_log_plugin_version = PACKAGE_VERSION;
 
-static struct mail_log_settings mail_log_set;
-
 static void (*mail_log_next_hook_mail_storage_created)
        (struct mail_storage *storage);
 static void (*mail_log_next_hook_mailbox_list_created)
        (struct mailbox_list *list);
+static void (*mail_log_next_hook_mail_user_created)(struct mail_user *user);
 
 static MODULE_CONTEXT_DEFINE_INIT(mail_log_storage_module,
                                  &mail_storage_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(mail_log_mail_module, &mail_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(mail_log_mailbox_list_module,
                                  &mailbox_list_module_register);
+static MODULE_CONTEXT_DEFINE_INIT(mail_log_mail_user_module,
+                                 &mail_user_module_register);
 
 static enum mail_log_field mail_log_field_find(const char *name)
 {
@@ -176,24 +182,26 @@ mail_log_action_add_group(struct mail_log_transaction_context *lt,
                          struct mail *mail, enum mail_log_event event,
                          const char *data)
 {
+       struct mail_log_user *muser =
+               MAIL_LOG_USER_CONTEXT(mail->box->storage->ns->user);
        struct mail_log_group_changes *group;
        uoff_t size;
 
        group = mail_log_action_get_group(lt, event, data);
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0) {
+       if ((muser->fields & MAIL_LOG_FIELD_UID) != 0) {
                if (!array_is_created(&group->uids))
                        p_array_init(&group->uids, lt->pool, 32);
                seq_range_array_add(&group->uids, 0, mail->uid);
        }
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
+       if ((muser->fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
            (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
                if (mail_get_physical_size(mail, &size) == 0)
                        group->psize_total += size;
        }
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
+       if ((muser->fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
            (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
                if (mail_get_virtual_size(mail, &size) == 0)
                        group->vsize_total += size;
@@ -216,6 +224,8 @@ static void mail_log_append_mailbox_name(string_t *str, struct mailbox *box)
 static void
 mail_log_group(struct mailbox *box, const struct mail_log_group_changes *group)
 {
+       struct mail_log_user *muser =
+               MAIL_LOG_USER_CONTEXT(box->storage->ns->user);
        const struct seq_range *range;
        unsigned int i, count;
        string_t *str;
@@ -223,7 +233,7 @@ mail_log_group(struct mailbox *box, const struct mail_log_group_changes *group)
        str = t_str_new(128);
        str_printfa(str, "%s: ", mail_log_event_get_name(group->event));
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0 &&
+       if ((muser->fields & MAIL_LOG_FIELD_UID) != 0 &&
            array_is_created(&group->uids)) {
                str_append(str, "uids=");
 
@@ -239,7 +249,7 @@ mail_log_group(struct mailbox *box, const struct mail_log_group_changes *group)
                str_append(str, ", ");
        }
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_BOX) != 0)
+       if ((muser->fields & MAIL_LOG_FIELD_BOX) != 0)
                mail_log_append_mailbox_name(str, box);
 
        if (group->event == MAIL_LOG_EVENT_COPY)
@@ -284,15 +294,17 @@ static void mail_log_action(struct mailbox_transaction_context *dest_trans,
                            const char *data)
 {
        struct mail_log_transaction_context *lt = MAIL_LOG_CONTEXT(dest_trans);
+       struct mail_log_user *muser =
+               MAIL_LOG_USER_CONTEXT(mail->box->storage->ns->user);
        uoff_t size;
        string_t *str;
 
-       if ((mail_log_set.events & event) == 0)
+       if ((muser->events & event) == 0)
                return;
 
        lt->changes++;
 
-       if (mail_log_set.group_events) {
+       if (muser->group_events) {
                mail_log_action_add_group(lt, mail, event, data);
                return;
        }
@@ -300,12 +312,12 @@ static void mail_log_action(struct mailbox_transaction_context *dest_trans,
        str = t_str_new(128);
        str_printfa(str, "%s: ", mail_log_event_get_name(event));
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0 && mail->uid != 0)
+       if ((muser->fields & MAIL_LOG_FIELD_UID) != 0 && mail->uid != 0)
                str_printfa(str, "uid=%u, ", mail->uid);
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_BOX) != 0)
+       if ((muser->fields & MAIL_LOG_FIELD_BOX) != 0)
                mail_log_append_mailbox_name(str, mail->box);
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_FLAGS) != 0) {
+       if ((muser->fields & MAIL_LOG_FIELD_FLAGS) != 0) {
                str_printfa(str, "flags=(");
                imap_write_flags(str, mail_get_flags(mail),
                                 mail_get_keywords(mail));
@@ -314,19 +326,19 @@ static void mail_log_action(struct mailbox_transaction_context *dest_trans,
        if (event == MAIL_LOG_EVENT_COPY)
                str_printfa(str, "dest=%s, ", data);
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_MSGID) != 0)
+       if ((muser->fields & MAIL_LOG_FIELD_MSGID) != 0)
                mail_log_add_hdr(mail, str, "msgid", "Message-ID");
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_FROM) != 0)
+       if ((muser->fields & MAIL_LOG_FIELD_FROM) != 0)
                mail_log_add_hdr(mail, str, "from", "From");
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_SUBJECT) != 0)
+       if ((muser->fields & MAIL_LOG_FIELD_SUBJECT) != 0)
                mail_log_add_hdr(mail, str, "subject", "Subject");
 
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
+       if ((muser->fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
            (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
                if (mail_get_physical_size(mail, &size) == 0)
                        str_printfa(str, "size=%"PRIuUOFF_T", ", size);
        }
-       if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
+       if ((muser->fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
            (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
                if (mail_get_virtual_size(mail, &size) == 0)
                        str_printfa(str, "vsize=%"PRIuUOFF_T", ", size);
@@ -509,8 +521,10 @@ mail_log_transaction_commit(struct mailbox_transaction_context *t,
 {
        struct mail_log_transaction_context *lt = MAIL_LOG_CONTEXT(t);
        union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
+       struct mail_log_user *muser =
+               MAIL_LOG_USER_CONTEXT(t->box->storage->ns->user);
 
-       if (lt->changes > 0 && mail_log_set.group_events)
+       if (lt->changes > 0 && muser->group_events)
                mail_log_group_changes(t->box, lt);
        if (lt->tmp_mail != NULL)
                mail_free(&lt->tmp_mail);
@@ -526,8 +540,10 @@ mail_log_transaction_rollback(struct mailbox_transaction_context *t)
 {
        struct mail_log_transaction_context *lt = MAIL_LOG_CONTEXT(t);
        union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
+       struct mail_log_user *muser =
+               MAIL_LOG_USER_CONTEXT(t->box->storage->ns->user);
 
-       if (lt->changes > 0 && !mail_log_set.group_events) {
+       if (lt->changes > 0 && !muser->group_events) {
                i_info("Transaction rolled back: "
                       "Ignore last %u changes", lt->changes);
        }
@@ -568,11 +584,12 @@ static int
 mail_log_mailbox_list_delete(struct mailbox_list *list, const char *name)
 {
        union mailbox_list_module_context *llist = MAIL_LOG_LIST_CONTEXT(list);
+       struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(list->ns->user);
 
        if (llist->super.delete_mailbox(list, name) < 0)
                return -1;
 
-       if ((mail_log_set.events & MAIL_LOG_EVENT_MAILBOX_DELETE) == 0)
+       if ((muser->events & MAIL_LOG_EVENT_MAILBOX_DELETE) == 0)
                return 0;
 
        i_info("Mailbox deleted: %s", str_sanitize(name, MAILBOX_NAME_LOG_LEN));
@@ -584,11 +601,12 @@ mail_log_mailbox_list_rename(struct mailbox_list *list, const char *oldname,
                             const char *newname)
 {
        union mailbox_list_module_context *llist = MAIL_LOG_LIST_CONTEXT(list);
+       struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(list->ns->user);
 
        if (llist->super.rename_mailbox(list, oldname, newname) < 0)
                return -1;
 
-       if ((mail_log_set.events & MAIL_LOG_EVENT_MAILBOX_RENAME) == 0)
+       if ((muser->events & MAIL_LOG_EVENT_MAILBOX_RENAME) == 0)
                return 0;
 
        i_info("Mailbox renamed: %s -> %s",
@@ -626,64 +644,84 @@ static void mail_log_mailbox_list_created(struct mailbox_list *list)
                mail_log_next_hook_mailbox_list_created(list);
 }
 
-static enum mail_log_field mail_log_parse_fields(const char *str)
+static int mail_log_parse_fields(const char *str, enum mail_log_field *fields_r)
 {
        const char *const *tmp;
        static enum mail_log_field field, fields = 0;
 
        for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
                field = mail_log_field_find(*tmp);
-               if (field == 0)
-                       i_fatal("Unknown field in mail_log_fields: '%s'", *tmp);
+               if (field == 0) {
+                       i_error("Unknown field in mail_log_fields: '%s'", *tmp);
+                       return -1;
+               }
                fields |= field;
        }
-       return fields;
+       *fields_r = fields;
+       return 0;
 }
 
-static enum mail_log_event mail_log_parse_events(const char *str)
+static int mail_log_parse_events(const char *str, enum mail_log_event *events_r)
 {
        const char *const *tmp;
        static enum mail_log_event event, events = 0;
 
        for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
                event = mail_log_event_find(*tmp);
-               if (event == 0)
-                       i_fatal("Unknown event in mail_log_events: '%s'", *tmp);
+               if (event == 0) {
+                       i_error("Unknown event in mail_log_events: '%s'", *tmp);
+                       return -1;
+               }
                events |= event;
        }
-       return events;
+       *events_r = events;
+       return 0;
 }
 
-static void mail_log_read_settings(struct mail_log_settings *set)
+static void
+mail_log_read_settings(struct mail_user *user, struct mail_log_user *muser)
 {
        const char *str;
 
-       memset(set, 0, sizeof(*set));
+       str = mail_user_plugin_getenv(user, "mail_log_fields");
+       if (str == NULL || mail_log_parse_fields(str, &muser->fields) < 0)
+               muser->fields = MAIL_LOG_DEFAULT_FIELDS;
 
-       str = getenv("MAIL_LOG_FIELDS");
-       set->fields = str == NULL ? MAIL_LOG_DEFAULT_FIELDS :
-               mail_log_parse_fields(str);
+       str = mail_user_plugin_getenv(user, "mail_log_events");
+       if (str == NULL || mail_log_parse_events(str, &muser->events) < 0)
+               muser->events = MAIL_LOG_DEFAULT_EVENTS;
 
-       str = getenv("MAIL_LOG_EVENTS");
-       set->events = str == NULL ? MAIL_LOG_DEFAULT_EVENTS :
-               mail_log_parse_events(str);
+       muser->group_events =
+               mail_user_plugin_getenv(user, "mail_log_group_events") != NULL;
+}
+
+static void mail_log_mail_user_created(struct mail_user *user)
+{
+       struct mail_log_user *muser;
 
-       set->group_events = getenv("MAIL_LOG_GROUP_EVENTS") != NULL;
+       muser = p_new(user->pool, struct mail_log_user, 1);
+       mail_log_read_settings(user, muser);
+       MODULE_CONTEXT_SET(user, mail_log_mail_user_module, muser);
+
+       if (mail_log_next_hook_mail_user_created != NULL)
+               mail_log_next_hook_mail_user_created(user);
 }
 
 void mail_log_plugin_init(void)
 {
-       mail_log_read_settings(&mail_log_set);
-
        mail_log_next_hook_mail_storage_created = hook_mail_storage_created;
        hook_mail_storage_created = mail_log_mail_storage_created;
 
        mail_log_next_hook_mailbox_list_created = hook_mailbox_list_created;
        hook_mailbox_list_created = mail_log_mailbox_list_created;
+
+       mail_log_next_hook_mail_user_created = hook_mail_user_created;
+       hook_mail_user_created = mail_log_mail_user_created;
 }
 
 void mail_log_plugin_deinit(void)
 {
        hook_mail_storage_created = mail_log_next_hook_mail_storage_created;
        hook_mailbox_list_created = mail_log_next_hook_mailbox_list_created;
+       hook_mail_user_created = mail_log_next_hook_mail_user_created;
 }
index 7d16d85906c033b179fa5289d944e45252e9bc6d..b10cee4164d8ac96c7b2286e6045f97946cad468 100644 (file)
@@ -6,6 +6,7 @@
 #include "mail-search-build.h"
 #include "mail-storage-private.h"
 #include "mailbox-list-private.h"
+#include "mail-user.h"
 #include "mbox-snarf-plugin.h"
 
 #include <stdlib.h>
@@ -147,7 +148,7 @@ mbox_snarf_mailbox_open(struct mail_storage *storage, const char *name,
                        /* use ~/mbox as the INBOX */
                        name = mstorage->snarf_inbox_path;
                        use_snarfing = TRUE;
-                       storage->set->mail_full_filesystem_access = TRUE;
+                       //FIXME:storage->set->mail_full_filesystem_access = TRUE;
                } else if (errno != ENOENT) {
                        mail_storage_set_critical(storage,
                                                  "stat(%s) failed: %m",
@@ -171,18 +172,27 @@ mbox_snarf_mailbox_open(struct mail_storage *storage, const char *name,
        return box;
 }
 
-static void mbox_snarf_mail_storage_created(struct mail_storage *storage)
+static void
+mbox_snarf_mail_storage_create(struct mail_storage *storage, const char *path)
 {
        struct mbox_snarf_mail_storage *mstorage;
-       const char *path;
 
-       path = mail_user_home_expand(storage->ns->user, getenv("MBOX_SNARF"));
+       path = mail_user_home_expand(storage->ns->user, path);
        mstorage = p_new(storage->pool, struct mbox_snarf_mail_storage, 1);
        mstorage->snarf_inbox_path = p_strdup(storage->pool, path);
        mstorage->module_ctx.super = storage->v;
        storage->v.mailbox_open = mbox_snarf_mailbox_open;
 
        MODULE_CONTEXT_SET(storage, mbox_snarf_storage_module, mstorage);
+}
+
+static void mbox_snarf_mail_storage_created(struct mail_storage *storage)
+{
+       const char *path;
+
+       path = mail_user_plugin_getenv(storage->ns->user, "mbox_snarf");
+       if (path != NULL)
+               mbox_snarf_mail_storage_create(storage, path);
 
        if (mbox_snarf_next_hook_mail_storage_created != NULL)
                mbox_snarf_next_hook_mail_storage_created(storage);
@@ -190,21 +200,11 @@ static void mbox_snarf_mail_storage_created(struct mail_storage *storage)
 
 void mbox_snarf_plugin_init(void)
 {
-       const char *path;
-
-       path = getenv("MBOX_SNARF");
-       if (path != NULL) {
-               mbox_snarf_next_hook_mail_storage_created =
-                       hook_mail_storage_created;
-               hook_mail_storage_created = mbox_snarf_mail_storage_created;
-       } else if (getenv("DEBUG") != NULL)
-               i_info("mbox_snarf: No mbox_snarf setting - plugin disabled");
+       mbox_snarf_next_hook_mail_storage_created = hook_mail_storage_created;
+       hook_mail_storage_created = mbox_snarf_mail_storage_created;
 }
 
 void mbox_snarf_plugin_deinit(void)
 {
-       if (getenv("MBOX_SNARF") != NULL) {
-               hook_mail_storage_created =
-                       mbox_snarf_next_hook_mail_storage_created;
-       }
+       hook_mail_storage_created = mbox_snarf_next_hook_mail_storage_created;
 }
index 719348c68e54df0da21bd40d8782f2c363171abe..eedd25e02fb33916e0aa3ea07bdcbf26ba631633 100644 (file)
@@ -235,6 +235,7 @@ static int maildirsize_write(struct maildir_quota_root *root, const char *path)
        mode = 0600; dir_mode = 0700;
        gid = dir_gid = (gid_t)-1;
        storages = array_get(&root->root.quota->storages, &count);
+       i_assert(count > 0);
        for (i = 0; i < count; i++) {
                if ((storages[i]->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
                        mailbox_list_get_permissions(storages[i]->ns->list,
@@ -245,8 +246,8 @@ static int maildirsize_write(struct maildir_quota_root *root, const char *path)
                }
        }
 
-       dotlock_settings.use_excl_lock = getenv("DOTLOCK_USE_EXCL") != NULL;
-       dotlock_settings.nfs_flush = getenv("MAIL_NFS_STORAGE") != NULL;
+       dotlock_settings.use_excl_lock = storages[0]->set->dotlock_use_excl;
+       dotlock_settings.nfs_flush = storages[0]->set->mail_nfs_storage;
        fd = file_dotlock_open_mode(&dotlock_settings, path,
                                    DOTLOCK_CREATE_FLAG_NONBLOCK,
                                    mode, (uid_t)-1, gid, &dotlock);
index 7a78936ab6c4b7a5f7a1d2990baabdbdb1659f1d..c9a0f718559a1106a8a0b08163a860c691055d72 100644 (file)
@@ -16,87 +16,9 @@ void (*quota_next_hook_mail_storage_created)(struct mail_storage *storage);
 void (*quota_next_hook_mailbox_list_created)(struct mailbox_list *list);
 
 const char *quota_plugin_version = PACKAGE_VERSION;
-struct quota_settings *quota_set;
-
-static void quota_root_add_rules(const char *root_name, 
-                                struct quota_root_settings *root_set)
-{
-       const char *rule_name, *rule, *error;
-       unsigned int i;
-
-       rule_name = t_strconcat(root_name, "_RULE", NULL);
-       for (i = 2;; i++) {
-               rule = getenv(rule_name);
-
-               if (rule == NULL)
-                       break;
-
-               if (quota_root_add_rule(root_set, rule, &error) < 0) {
-                       i_fatal("Quota root %s: Invalid rule %s: %s",
-                               root_name, rule, error);
-               }
-               rule_name = t_strdup_printf("%s_RULE%d", root_name, i);
-       }
-}
-
-static void quota_root_add_warning_rules(const char *root_name,
-                                        struct quota_root_settings *root_set)
-{
-       const char *rule_name, *rule, *error;
-       unsigned int i;
-
-       rule_name = t_strconcat(root_name, "_WARNING", NULL);
-       for (i = 2;; i++) {
-               rule = getenv(rule_name);
-
-               if (rule == NULL)
-                       break;
-
-               if (quota_root_add_warning_rule(root_set, rule, &error) < 0) {
-                       i_fatal("Quota root %s: Invalid warning rule: %s",
-                               root_name, rule);
-               }
-               rule_name = t_strdup_printf("%s_WARNING%d", root_name, i);
-       }
-}
 
 void quota_plugin_init(void)
 {
-       struct quota_root_settings *root_set;
-       unsigned int i;
-       const char *env;
-
-       env = getenv("QUOTA");
-       if (env == NULL) {
-               if (getenv("DEBUG") != NULL)
-                       i_info("quota: No quota setting - plugin disabled");
-               return;
-       }
-
-       quota_set = quota_settings_init();
-
-       root_set = quota_root_settings_init(quota_set, env);
-       if (root_set == NULL)
-               i_fatal("Couldn't create quota root: %s", env);
-       quota_root_add_rules("QUOTA", root_set);
-       quota_root_add_warning_rules("QUOTA", root_set);
-
-       for (i = 2;; i++) {
-               const char *root_name;
-
-               root_name = t_strdup_printf("QUOTA%d", i);
-               env = getenv(root_name);
-
-               if (env == NULL)
-                       break;
-
-               root_set = quota_root_settings_init(quota_set, env);
-               if (root_set == NULL)
-                       i_fatal("Couldn't create quota root: %s", env);
-               quota_root_add_rules(root_name, root_set);
-               quota_root_add_warning_rules(root_name, root_set);
-       }
-
        quota_next_hook_mail_user_created = hook_mail_user_created;
        hook_mail_user_created = quota_mail_user_created;
 
@@ -109,12 +31,7 @@ void quota_plugin_init(void)
 
 void quota_plugin_deinit(void)
 {
-       if (quota_set != NULL) {
-               hook_mail_user_created = quota_next_hook_mail_user_created;
-               hook_mail_storage_created =
-                       quota_next_hook_mail_storage_created;
-               hook_mailbox_list_created =
-                       quota_next_hook_mailbox_list_created;
-               quota_settings_deinit(&quota_set);
-       }
+       hook_mail_user_created = quota_next_hook_mail_user_created;
+       hook_mail_storage_created = quota_next_hook_mail_storage_created;
+       hook_mailbox_list_created = quota_next_hook_mailbox_list_created;
 }
index 74d9ccd6c956c23e8ccea103ccf7fd4eafb3a91e..3fefbed7f9901d9b689623041dae0b1ae4c5cfc3 100644 (file)
@@ -1,6 +1,17 @@
 #ifndef QUOTA_PLUGIN_H
 #define QUOTA_PLUGIN_H
 
+#include "module-context.h"
+
+#define QUOTA_USER_CONTEXT(obj) \
+       MODULE_CONTEXT(obj, quota_user_module)
+
+struct quota_user {
+       union mail_user_module_context module_ctx;
+
+       struct quota *quota;
+};
+
 struct mail_storage;
 
 extern void (*quota_next_hook_mail_user_created)(struct mail_user *user);
@@ -8,7 +19,7 @@ extern void (*quota_next_hook_mail_storage_created)
        (struct mail_storage *storage);
 extern void (*quota_next_hook_mailbox_list_created)(struct mailbox_list *list);
 
-extern struct quota_settings *quota_set;
+extern MODULE_CONTEXT_DEFINE(quota_user_module, &mail_user_module_register);
 
 void quota_mail_user_created(struct mail_user *user);
 void quota_mail_storage_created(struct mail_storage *storage);
index 413eb1c53c156f58e077b29d84fcfb5958c487c8..51095cefe6a24917c2067b915f4ac7e92add7fc5 100644 (file)
        MODULE_CONTEXT(obj, quota_mail_module)
 #define QUOTA_LIST_CONTEXT(obj) \
        MODULE_CONTEXT(obj, quota_mailbox_list_module)
-#define QUOTA_USER_CONTEXT(obj) \
-       MODULE_CONTEXT(obj, quota_user_module)
-
-struct quota_user {
-       union mail_user_module_context module_ctx;
-
-       struct quota *quota;
-};
 
 struct quota_mailbox_list {
        union mailbox_list_module_context module_ctx;
@@ -44,13 +36,14 @@ struct quota_mailbox {
        unsigned int recalculate:1;
 };
 
+struct quota_user_module quota_user_module =
+       MODULE_CONTEXT_INIT(&mail_user_module_register);
+
 static MODULE_CONTEXT_DEFINE_INIT(quota_storage_module,
                                  &mail_storage_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(quota_mail_module, &mail_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(quota_mailbox_list_module,
                                  &mailbox_list_module_register);
-static MODULE_CONTEXT_DEFINE_INIT(quota_user_module,
-                                 &mail_user_module_register);
 
 static void quota_mail_expunge(struct mail *_mail)
 {
@@ -497,13 +490,19 @@ static void quota_user_deinit(struct mail_user *user)
 void quota_mail_user_created(struct mail_user *user)
 {
        struct quota_user *quser;
-
-       quser = p_new(user->pool, struct quota_user, 1);
-       quser->module_ctx.super = user->v;
-       user->v.deinit = quota_user_deinit;
-       quser->quota = quota_init(quota_set, user);
-
-       MODULE_CONTEXT_SET(user, quota_user_module, quser);
+       struct quota_settings *set;
+
+       set = quota_user_read_settings(user);
+       if (set != NULL) {
+               quser = p_new(user->pool, struct quota_user, 1);
+               quser->module_ctx.super = user->v;
+               user->v.deinit = quota_user_deinit;
+               quser->quota = quota_init(set, user);
+
+               MODULE_CONTEXT_SET(user, quota_user_module, quser);
+       } else if (user->mail_debug) {
+               i_info("quota: No quota setting - plugin disabled");
+       }
 
        if (quota_next_hook_mail_user_created != NULL)
                quota_next_hook_mail_user_created(user);
index e53f754345e325899d13f1ffdfd7ec6e57187275..64093f2149afddd0b1e4c116659bfa376da0debc 100644 (file)
@@ -43,20 +43,84 @@ static const struct quota_backend *quota_backends[] = {
 static int quota_default_test_alloc(struct quota_transaction_context *ctx,
                                    uoff_t size, bool *too_large_r);
 
-struct quota_settings *quota_settings_init(void)
+static void quota_root_add_rules(struct mail_user *user, const char *root_name, 
+                                struct quota_root_settings *root_set)
+{
+       const char *rule_name, *rule, *error;
+       unsigned int i;
+
+       rule_name = t_strconcat(root_name, "_rule", NULL);
+       for (i = 2;; i++) {
+               rule = mail_user_plugin_getenv(user, rule_name);
+               if (rule == NULL)
+                       break;
+
+               if (quota_root_add_rule(root_set, rule, &error) < 0) {
+                       i_fatal("Quota root %s: Invalid rule %s: %s",
+                               root_name, rule, error);
+               }
+               rule_name = t_strdup_printf("%s_rule%d", root_name, i);
+       }
+}
+
+static void
+quota_root_add_warning_rules(struct mail_user *user, const char *root_name,
+                            struct quota_root_settings *root_set)
+{
+       const char *rule_name, *rule, *error;
+       unsigned int i;
+
+       rule_name = t_strconcat(root_name, "_warning", NULL);
+       for (i = 2;; i++) {
+               rule = mail_user_plugin_getenv(user, rule_name);
+               if (rule == NULL)
+                       break;
+
+               if (quota_root_add_warning_rule(root_set, rule, &error) < 0) {
+                       i_fatal("Quota root %s: Invalid warning rule: %s",
+                               root_name, rule);
+               }
+               rule_name = t_strdup_printf("%s_warning%d", root_name, i);
+       }
+}
+
+struct quota_settings *quota_user_read_settings(struct mail_user *user)
 {
        struct quota_settings *quota_set;
+       struct quota_root_settings *root_set;
+       char root_name[6 + MAX_INT_STRLEN];
+       const char *env;
+       unsigned int i;
        pool_t pool;
 
        pool = pool_alloconly_create("quota settings", 1024);
        quota_set = p_new(pool, struct quota_settings, 1);
        quota_set->pool = pool;
        quota_set->test_alloc = quota_default_test_alloc;
-       quota_set->debug = getenv("DEBUG") != NULL;
-       quota_set->quota_exceeded_msg = getenv("QUOTA_EXCEEDED_MESSAGE");
+       quota_set->debug = user->mail_debug;
+       quota_set->quota_exceeded_msg =
+               mail_user_plugin_getenv(user, "quota_exceeded_message");
        if (quota_set->quota_exceeded_msg == NULL)
                quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG;
+
        p_array_init(&quota_set->root_sets, pool, 4);
+       i_strocpy(root_name, "quota", sizeof(root_name));
+       for (i = 2;; i++) {
+               env = mail_user_plugin_getenv(user, root_name);
+               if (env == NULL)
+                       break;
+
+               root_set = quota_root_settings_init(quota_set, env);
+               if (root_set == NULL) {
+                       i_fatal("Couldn't create quota root %s: %s",
+                               root_name, env);
+               }
+               quota_root_add_rules(user, root_name, root_set);
+               quota_root_add_warning_rules(user, root_name, root_set);
+
+               i_snprintf(root_name, sizeof(root_name), "quota%d", i);
+       }
+
        return quota_set;
 }
 
index 3093fa99dfa76a6d056ef38f70e057566052c16c..ec198970d53ddd85a755581a81ae211ca1b4fc85 100644 (file)
@@ -17,7 +17,7 @@ struct quota_root;
 struct quota_root_iter;
 struct quota_transaction_context;
 
-struct quota_settings *quota_settings_init(void);
+struct quota_settings *quota_user_read_settings(struct mail_user *user);
 void quota_settings_deinit(struct quota_settings **quota_set);
 
 /* Set up a new quota root. */
index f575c71ac522f23a295a2b507beaf6dd464e70e4..b04216621a252dfcbfd8053fd112df8cca8536f6 100644 (file)
@@ -173,7 +173,7 @@ err:
        }
 
        if (size_expunged < size_needed) {
-               if (getenv("DEBUG") != NULL) {
+               if (ctx->quota->user->mail_debug) {
                        i_info("trash plugin: Failed to remove enough messages "
                               "(needed %llu bytes, expunged only %llu bytes)",
                               (unsigned long long)size_needed,
@@ -198,7 +198,7 @@ trash_quota_test_alloc(struct quota_transaction_context *ctx,
        for (i = 0; ; i++) {
                ret = trash_next_quota_test_alloc(ctx, size, too_large_r);
                if (ret != 0 || *too_large_r) {
-                       if (getenv("DEBUG") != NULL && *too_large_r) {
+                       if (ctx->quota->user->mail_debug && *too_large_r) {
                                i_info("trash plugin: Mail is larger than "
                                       "quota, won't even try to handle");
                        }
@@ -282,7 +282,7 @@ static int read_configuration(struct mail_user *user, const char *path)
                        ret = -1;
                }
 
-               if (getenv("DEBUG") != NULL) {
+               if (user->mail_debug) {
                        i_info("trash plugin: Added '%s' with priority %d",
                               trash->name, trash->priority);
                }
@@ -299,14 +299,15 @@ static void
 trash_hook_mail_namespaces_created(struct mail_namespace *namespaces)
 {
        struct mail_user *user = namespaces->user;
+       struct quota_user *quser = QUOTA_USER_CONTEXT(user);
        struct trash_user *tuser;
        const char *env;
 
-       env = getenv("TRASH");
+       env = mail_user_plugin_getenv(user, "trash");
        if (env == NULL) {
-               if (getenv("DEBUG") != NULL)
+               if (user->mail_debug)
                        i_info("trash: No trash setting - plugin disabled");
-       } else if (quota_set == NULL) {
+       } else if (quser == NULL) {
                i_error("trash plugin: quota plugin not initialized");
        } else {
                tuser = p_new(user->pool, struct trash_user, 1);
@@ -314,8 +315,9 @@ trash_hook_mail_namespaces_created(struct mail_namespace *namespaces)
                MODULE_CONTEXT_SET(user, trash_user_module, tuser);
 
                if (read_configuration(user, env) == 0) {
-                       trash_next_quota_test_alloc = quota_set->test_alloc;
-                       quota_set->test_alloc = trash_quota_test_alloc;
+                       trash_next_quota_test_alloc =
+                               quser->quota->set->test_alloc;
+                       quser->quota->set->test_alloc = trash_quota_test_alloc;
                }
        }
 
@@ -332,5 +334,4 @@ void trash_plugin_init(void)
 void trash_plugin_deinit(void)
 {
        hook_mail_namespaces_created = trash_hook_mail_namespaces_created;
-       quota_set->test_alloc = trash_next_quota_test_alloc;
 }