mail-user.c revision 1e40531c1de45bc87e72a9d5866ff2af79b63ceb
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2008-2014 Dovecot authors, see the included COPYING file */
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen#include "lib.h"
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen#include "array.h"
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen#include "hostpid.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "net.h"
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen#include "module-dir.h"
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainen#include "home-expand.h"
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen#include "safe-mkstemp.h"
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen#include "str.h"
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen#include "strescape.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "var-expand.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "settings-parser.h"
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen#include "auth-master.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "master-service.h"
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen#include "mountpoint-list.h"
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen#include "dict.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "mail-storage-settings.h"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#include "mail-storage-private.h"
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen#include "mail-storage-service.h"
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen#include "mail-namespace.h"
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen#include "mail-storage.h"
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen#include "mail-user.h"
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen#include <stdlib.h>
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct auth_master_connection *mail_user_auth_master_conn;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen{
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen if (user->_attr_dict != NULL) {
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen (void)dict_wait(user->_attr_dict);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen dict_deinit(&user->_attr_dict);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen }
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen mail_namespaces_deinit(&user->namespaces);
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen if (user->mountpoints != NULL)
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen mountpoint_list_deinit(&user->mountpoints);
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen}
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstruct mail_user *mail_user_alloc(const char *username,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct setting_parser_info *set_info,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct mail_user_settings *set)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen{
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen struct mail_user *user;
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen const char *error;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen pool_t pool;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen i_assert(username != NULL);
4c892b0d94c5b1d6853dbe8e0b38059ea5b08ecaTimo Sirainen i_assert(*username != '\0');
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
abc79eec93e58e0152cd1d483f37be66c26811b9Timo Sirainen pool = pool_alloconly_create("mail user", 16*1024);
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen user = p_new(pool, struct mail_user, 1);
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen user->pool = pool;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen user->refcount = 1;
4c892b0d94c5b1d6853dbe8e0b38059ea5b08ecaTimo Sirainen user->username = p_strdup(pool, username);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user->set_info = set_info;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user->unexpanded_set = settings_dup(set_info, set, pool);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user->set = settings_dup(set_info, set, pool);
013a8a91c83c6ea24bc75322b81235f19e26fa8fTimo Sirainen user->service = master_service_get_name(master_service);
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen user->default_normalizer = uni_utf8_to_decomposed_titlecase;
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen /* check settings so that the duplicated structure will again
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen contain the parsed fields */
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen if (!settings_check(set_info, pool, user->set, &error))
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen i_panic("Settings check unexpectedly failed: %s", error);
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen user->v.deinit = mail_user_deinit_base;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return user;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainenstatic void
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainenmail_user_expand_plugins_envs(struct mail_user *user)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen{
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const char **envs, *home;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen string_t *str;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen unsigned int i, count;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (!array_is_created(&user->set->plugin_envs))
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen return;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen str = t_str_new(256);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen i_assert((count % 2) == 0);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen for (i = 0; i < count; i += 2) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (user->_home == NULL &&
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen var_has_key(envs[i+1], 'h', "home") &&
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mail_user_get_home(user, &home) <= 0) {
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen user->error = p_strdup_printf(user->pool,
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen "userdb didn't return a home directory, "
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen "but plugin setting %s used it (%%h): %s",
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen envs[i], envs[i+1]);
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen return;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen }
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen str_truncate(str, 0);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen envs[i+1] = p_strdup(user->pool, str_c(str));
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen }
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen}
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const struct mail_storage_settings *mail_set;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *home, *key, *value;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen bool need_home_dir;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen need_home_dir = user->_home == NULL &&
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen settings_vars_have_key(user->set_info, user->set,
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen 'h', "home", &key, &value);
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen /* expand mail_home setting before calling mail_user_get_home() */
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen settings_var_expand(user->set_info, user->set,
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen user->pool, mail_user_var_expand_table(user));
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen user->error = p_strdup_printf(user->pool,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "userdb didn't return a home directory, "
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "but %s used it (%%h): %s", key, value);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen mail_user_expand_plugins_envs(user);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen /* autocreated users for shared mailboxes need to be fully initialized
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen if they don't exist, since they're going to be used anyway */
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen if (user->error == NULL || user->nonexistent) {
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen mail_set = mail_user_set_get_storage_set(user);
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen user->mail_debug = mail_set->mail_debug;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen user->initialized = TRUE;
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen hook_mail_user_created(user);
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen }
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen if (user->error != NULL) {
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen *error_r = t_strdup(user->error);
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen return -1;
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return 0;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen}
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainenvoid mail_user_ref(struct mail_user *user)
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen{
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen i_assert(user->refcount > 0);
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen user->refcount++;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen}
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainenvoid mail_user_unref(struct mail_user **_user)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen{
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen struct mail_user *user = *_user;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen i_assert(user->refcount > 0);
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen *_user = NULL;
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen if (user->refcount > 1) {
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen user->refcount--;
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen return;
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen }
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen
4f2fa2e5f5a27e1d59dd38fbbf38e420e006596dTimo Sirainen user->deinitializing = TRUE;
4f2fa2e5f5a27e1d59dd38fbbf38e420e006596dTimo Sirainen
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen /* call deinit() with refcount=1, otherwise we may assert-crash in
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen mail_user_ref() that is called by some deinit() handler. */
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen user->v.deinit(user);
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen i_assert(user->refcount == 1);
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen pool_unref(&user->pool);
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen}
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen{
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen struct mail_namespace *ns;
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen return ns->owner;
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen }
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen return NULL;
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen}
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenvoid mail_user_set_vars(struct mail_user *user, const char *service,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const struct ip_addr *local_ip,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct ip_addr *remote_ip)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
013a8a91c83c6ea24bc75322b81235f19e26fa8fTimo Sirainen i_assert(service != NULL);
013a8a91c83c6ea24bc75322b81235f19e26fa8fTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user->service = p_strdup(user->pool, service);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen if (local_ip != NULL && local_ip->family != 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user->local_ip = p_new(user->pool, struct ip_addr, 1);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen *user->local_ip = *local_ip;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen if (remote_ip != NULL && remote_ip->family != 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user->remote_ip = p_new(user->pool, struct ip_addr, 1);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen *user->remote_ip = *remote_ip;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenconst struct var_expand_table *
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenmail_user_var_expand_table(struct mail_user *user)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen static struct var_expand_table static_tab[] = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'u', NULL, "user" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'n', NULL, "username" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'd', NULL, "domain" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 's', NULL, "service" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'h', NULL, "home" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'l', NULL, "lip" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'r', NULL, "rip" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'p', NULL, "pid" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { 'i', NULL, "uid" },
a2150da2dc906c26a26219cbefbe28a119aafee2Timo Sirainen { '\0', NULL, "gid" },
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen { '\0', NULL, "auth_user" },
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen { '\0', NULL, "auth_username" },
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen { '\0', NULL, "auth_domain" },
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { '\0', NULL, NULL }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen };
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct var_expand_table *tab;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
f9142439f2b5e86065af7420e80fe52835227dc8Timo Sirainen /* use a cached table, unless home directory has been set afterwards */
f9142439f2b5e86065af7420e80fe52835227dc8Timo Sirainen if (user->var_expand_table != NULL &&
f9142439f2b5e86065af7420e80fe52835227dc8Timo Sirainen user->var_expand_table[4].value == user->_home)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return user->var_expand_table;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[0].value = user->username;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[2].value = strchr(user->username, '@');
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (tab[2].value != NULL) tab[2].value++;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[3].value = user->service;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[4].value = user->_home; /* don't look it up unless we need it */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[5].value = user->local_ip == NULL ? NULL :
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen p_strdup(user->pool, net_ip2addr(user->local_ip));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[6].value = user->remote_ip == NULL ? NULL :
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen p_strdup(user->pool, net_ip2addr(user->remote_ip));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[7].value = my_pid;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen tab[8].value = p_strdup(user->pool, dec2str(user->uid));
88b0427d90f1d3c2c5fb3171e53a505c46e2c39dTimo Sirainen tab[9].value = p_strdup(user->pool, dec2str(user->gid));
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen if (user->auth_user == NULL) {
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen tab[10].value = tab[0].value;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen tab[11].value = tab[1].value;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen tab[12].value = tab[2].value;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen } else {
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen tab[10].value = user->auth_user;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen tab[11].value = t_strcut(user->auth_user, '@');
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen tab[12].value = strchr(user->auth_user, '@');
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user->var_expand_table = tab;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return user->var_expand_table;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen{
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen user->_home = p_strdup(user->pool, home);
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen user->home_looked_up = TRUE;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen}
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainenvoid mail_user_add_namespace(struct mail_user *user,
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen struct mail_namespace **namespaces)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen{
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen struct mail_namespace **tmp, *next, *ns = *namespaces;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen for (; ns != NULL; ns = next) {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen next = ns->next;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen tmp = &user->namespaces;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen for (; *tmp != NULL; tmp = &(*tmp)->next) {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen break;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen }
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen ns->next = *tmp;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen *tmp = ns;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen }
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen *namespaces = user->namespaces;
311d3dd2078c1b711a0cef013ba43a94078c115cTimo Sirainen
311d3dd2078c1b711a0cef013ba43a94078c115cTimo Sirainen T_BEGIN {
311d3dd2078c1b711a0cef013ba43a94078c115cTimo Sirainen hook_mail_namespaces_added(user->namespaces);
311d3dd2078c1b711a0cef013ba43a94078c115cTimo Sirainen } T_END;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen}
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen{
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen struct mail_namespace *ns, *next;
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen /* drop all autocreated unusable (typically shared) namespaces.
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen don't drop the autocreated prefix="" namespace that we explicitly
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen created for being the fallback namespace. */
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen next = ns->next;
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0 &&
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen ns->prefix_len > 0)
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen mail_namespace_destroy(ns);
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen }
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen}
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen{
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen (void)mail_user_try_home_expand(user, &path);
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen return path;
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen}
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainenstatic int mail_user_userdb_lookup_home(struct mail_user *user)
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen{
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen struct auth_user_info info;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen struct auth_user_reply reply;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen pool_t userdb_pool;
9f10cc61ec303351b43e54155c86699ef53cb8beTimo Sirainen const char *username, *const *fields;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen int ret;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen i_assert(!user->home_looked_up);
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen memset(&info, 0, sizeof(info));
5736aef6d0abe6796e57c2eda68f5c25db677918Timo Sirainen info.service = user->service;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen if (user->local_ip != NULL)
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen info.local_ip = *user->local_ip;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen if (user->remote_ip != NULL)
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen info.remote_ip = *user->remote_ip;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
5e751dbaecf7c337abc149f328c4a13ee5c15134Timo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 2048);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ret = auth_master_user_lookup(mail_user_auth_master_conn,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->username, &info, userdb_pool,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen &username, &fields);
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen if (ret > 0) {
9f10cc61ec303351b43e54155c86699ef53cb8beTimo Sirainen auth_user_fields_parse(fields, userdb_pool, &reply);
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen user->_home = p_strdup(user->pool, reply.home);
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen }
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen pool_unref(&userdb_pool);
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen return ret;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen}
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen{
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen int ret;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen if (user->home_looked_up) {
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen *home_r = user->_home;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen return user->_home != NULL ? 1 : 0;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen }
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen if (mail_user_auth_master_conn == NULL) {
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen /* no userdb connection. we can only use mail_home setting. */
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen user->_home = user->set->mail_home;
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen } else if ((ret = mail_user_userdb_lookup_home(user)) < 0) {
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen /* userdb lookup failed */
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen return -1;
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen } else if (ret == 0) {
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen /* user doesn't exist */
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen user->nonexistent = TRUE;
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen } else if (user->_home == NULL && *user->set->mail_home != '\0') {
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen /* no home returned by userdb lookup, fallback to mail_home
117a55d4260651770705ecb96f68be2dab03b99bTimo Sirainen setting. */
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen user->_home = user->set->mail_home;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen }
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen user->home_looked_up = TRUE;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen *home_r = user->_home;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen return user->_home != NULL ? 1 : 0;
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen}
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainenbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen{
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen const char *const *plugins;
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen bool ret;
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen T_BEGIN {
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen ret = str_array_find(plugins, module_get_plugin_name(module));
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen } T_END;
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen return ret;
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen}
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return mail_user_set_plugin_getenv(user->set, name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *name)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen{
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const char *const *envs;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int i, count;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!array_is_created(&set->plugin_envs))
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return NULL;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen envs = array_get(&set->plugin_envs, &count);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (i = 0; i < count; i += 2) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (strcmp(envs[i], name) == 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return envs[i+1];
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen }
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return NULL;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen}
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainenint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen{
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen const char *home, *path = *pathp;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
08a33e7c0cf5ab2c4a0c96a55056cc3251d14c5eTimo Sirainen if (*path != '~') {
cb17980a661554ebb3fd099c77e92a5be4d304ecTimo Sirainen /* no need to expand home */
cb17980a661554ebb3fd099c77e92a5be4d304ecTimo Sirainen return 0;
cb17980a661554ebb3fd099c77e92a5be4d304ecTimo Sirainen }
cb17980a661554ebb3fd099c77e92a5be4d304ecTimo Sirainen
d2d5871fa9e7226df694ff7a4be511167b35b305Timo Sirainen if (mail_user_get_home(user, &home) <= 0)
d2c853636ec2d99c9f96da877ff520a3b86a18baTimo Sirainen return -1;
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainen path = home_expand_tilde(path, home);
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainen if (path == NULL)
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainen return -1;
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainen *pathp = path;
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen return 0;
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen}
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainenvoid mail_user_set_get_temp_prefix(string_t *dest,
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainen const struct mail_user_settings *set)
b16ee3cbbcd18cb86f2f73b5cc163ebfb995ffafTimo Sirainen{
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainen str_append(dest, set->mail_temp_dir);
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainen str_append(dest, "/dovecot.");
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainen str_append(dest, master_service_get_name(master_service));
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainen str_append_c(dest, '.');
b16ee3cbbcd18cb86f2f73b5cc163ebfb995ffafTimo Sirainen}
b16ee3cbbcd18cb86f2f73b5cc163ebfb995ffafTimo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainenconst char *mail_user_get_anvil_userip_ident(struct mail_user *user)
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen{
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen if (user->remote_ip == NULL)
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen return NULL;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen return t_strconcat(net_ip2addr(user->remote_ip), "/",
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen str_tabescape(user->username), NULL);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen}
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainenbool mail_user_is_path_mounted(struct mail_user *user, const char *path,
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen const char **error_r)
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen{
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen struct mountpoint_list_rec *rec;
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen const char *mounts_path;
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen *error_r = NULL;
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen if (user->mountpoints == NULL) {
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen user->set->base_dir);
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen user->mountpoints = mountpoint_list_init_readonly(mounts_path);
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen } else {
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen (void)mountpoint_list_refresh(user->mountpoints);
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen }
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen rec = mountpoint_list_find(user->mountpoints, path);
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) {
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen /* we don't have any knowledge of this path's mountpoint.
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen assume it's fine. */
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen return TRUE;
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen }
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen /* record exists for this mountpoint. see if it's mounted */
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen if (mountpoint_list_update_mounted(user->mountpoints) == 0 &&
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen !rec->mounted) {
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen *error_r = t_strdup_printf("Mountpoint %s isn't mounted. "
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen "Mount it or remove it with doveadm mount remove",
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen rec->mount_path);
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen return FALSE;
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen }
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen return TRUE;
318ef3683d67683173f1b552cf5f9af4375b3017Timo Sirainen}
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainenstatic void
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainenmail_user_try_load_class_plugin(struct mail_user *user, const char *name)
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen{
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen struct module_dir_load_settings mod_set;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen struct module *module;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen unsigned int name_len = strlen(name);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen memset(&mod_set, 0, sizeof(mod_set));
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mod_set.abi_version = DOVECOT_ABI_VERSION;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mod_set.binary_name = master_service_get_name(master_service);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mod_set.setting_name = "<built-in storage lookup>";
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mod_set.require_init_funcs = TRUE;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mod_set.debug = user->mail_debug;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mail_storage_service_modules =
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen module_dir_load_missing(mail_storage_service_modules,
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen user->set->mail_plugin_dir,
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen name, &mod_set);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen /* initialize the module (and only this module!) immediately so that
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen the class gets registered */
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen for (module = mail_storage_service_modules; module != NULL; module = module->next) {
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen if (strncmp(module->name, name, name_len) == 0 &&
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen strcmp(module->name + name_len, "_plugin") == 0) {
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen if (!module->initialized) {
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen module->initialized = TRUE;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen module->init(module);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen }
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen break;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen }
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen }
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen}
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainenstruct mail_storage *
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainenmail_user_get_storage_class(struct mail_user *user, const char *name)
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen{
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen struct mail_storage *storage;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen storage = mail_storage_find_class(name);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen if (storage == NULL || storage->v.alloc != NULL)
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen return storage;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen /* it's implemented by a plugin. load it and check again. */
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen mail_user_try_load_class_plugin(user, name);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen storage = mail_storage_find_class(name);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen if (storage != NULL && storage->v.alloc == NULL) {
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen i_error("Storage driver '%s' exists as a stub, "
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen "but its plugin couldn't be loaded", name);
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen return NULL;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen }
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen return storage;
87ca4b209c10954826b878da165d303d9b4dc5a2Timo Sirainen}
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainenstruct mail_user *mail_user_dup(struct mail_user *user)
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen{
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen struct mail_user *user2;
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2 = mail_user_alloc(user->username, user->set_info,
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user->unexpanded_set);
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen if (user->_home != NULL)
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen mail_user_set_home(user2, user->_home);
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen mail_user_set_vars(user2, user->service,
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user->local_ip, user->remote_ip);
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->uid = user->uid;
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->gid = user->gid;
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->anonymous = user->anonymous;
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->admin = user->admin;
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->auth_token = p_strdup(user2->pool, user->auth_token);
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->auth_user = p_strdup(user2->pool, user->auth_user);
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen user2->session_id = p_strdup(user2->pool, user->session_id);
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen return user2;
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen}