mail-user.c revision b06633c63fde22b6c8837ae70b2f95fe60075b0a
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik/* Copyright (c) 2008-2013 Dovecot authors, see the included COPYING file */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "lib.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "array.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "hostpid.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "net.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "module-dir.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "home-expand.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "safe-mkstemp.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "str.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "strescape.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "var-expand.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "settings-parser.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "auth-master.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "master-service.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mountpoint-list.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "dict.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mail-storage-settings.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mail-storage-private.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mail-storage-service.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mail-namespace.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mail-storage.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include "mail-user.h"
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik#include <stdlib.h>
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
b6bc67f3272d8a45fb6b5c01c8a3f8e74010eb71Lukas Slebodnikstruct mail_user_module_register mail_user_module_register = { 0 };
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstruct auth_master_connection *mail_user_auth_master_conn;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstatic void mail_user_deinit_base(struct mail_user *user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->_attr_dict != NULL) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik (void)dict_wait(user->_attr_dict);
1ba26271952de1beeb9e041bedf87d720d3f5680Lukas Slebodnik dict_deinit(&user->_attr_dict);
b6bc67f3272d8a45fb6b5c01c8a3f8e74010eb71Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_namespaces_deinit(&user->namespaces);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->mountpoints != NULL)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mountpoint_list_deinit(&user->mountpoints);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstruct mail_user *mail_user_alloc(const char *username,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const struct setting_parser_info *set_info,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const struct mail_user_settings *set)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_user *user;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *error;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik pool_t pool;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(username != NULL);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(*username != '\0');
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik pool = pool_alloconly_create("mail user", 16*1024);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user = p_new(pool, struct mail_user, 1);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->pool = pool;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->refcount = 1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->username = p_strdup(pool, username);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->set_info = set_info;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->unexpanded_set = settings_dup(set_info, set, pool);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->set = settings_dup(set_info, set, pool);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->service = master_service_get_name(master_service);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->default_normalizer = uni_utf8_to_decomposed_titlecase;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* check settings so that the duplicated structure will again
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik contain the parsed fields */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (!settings_check(set_info, pool, user->set, &error))
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_panic("Settings check unexpectedly failed: %s", error);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->v.deinit = mail_user_deinit_base;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik p_array_init(&user->module_contexts, user->pool, 5);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return user;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstatic int
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikmail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char **envs, *home;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik string_t *str;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik unsigned int i, count;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (!array_is_created(&user->set->plugin_envs))
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str = t_str_new(256);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik envs = array_get_modifiable(&user->set->plugin_envs, &count);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert((count % 2) == 0);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (i = 0; i < count; i += 2) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->_home == NULL &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik var_has_key(envs[i+1], 'h', "home") &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_user_get_home(user, &home) <= 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *error_r = t_strdup_printf(
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik "userdb didn't return a home directory, "
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik "but plugin setting %s used it (%%h): %s",
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik envs[i], envs[i+1]);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str_truncate(str, 0);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik var_expand(str, envs[i+1], mail_user_var_expand_table(user));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik envs[i+1] = p_strdup(user->pool, str_c(str));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikint mail_user_init(struct mail_user *user, const char **error_r)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const struct mail_storage_settings *mail_set;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *home, *key, *value;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik bool need_home_dir;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik need_home_dir = user->_home == NULL &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik settings_vars_have_key(user->set_info, user->set,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik 'h', "home", &key, &value);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* expand mail_home setting before calling mail_user_get_home() */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik settings_var_expand(user->set_info, user->set,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->pool, mail_user_var_expand_table(user));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *error_r = t_strdup_printf(
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik "userdb didn't return a home directory, "
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik "but %s used it (%%h): %s", key, value);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (mail_user_expand_plugins_envs(user, error_r) < 0)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_set = mail_user_set_get_storage_set(user);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->mail_debug = mail_set->mail_debug;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->initialized = TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik hook_mail_user_created(user);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->error != NULL) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *error_r = t_strdup(user->error);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikvoid mail_user_ref(struct mail_user *user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(user->refcount > 0);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->refcount++;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikvoid mail_user_unref(struct mail_user **_user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_user *user = *_user;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(user->refcount > 0);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *_user = NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->refcount > 1) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->refcount--;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* call deinit() with refcount=1, otherwise we may assert-crash in
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_user_ref() that is called by some deinit() handler. */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->v.deinit(user);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(user->refcount == 1);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik pool_unref(&user->pool);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_namespace *ns;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (ns = user->namespaces; ns != NULL; ns = ns->next) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return ns->owner;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikvoid mail_user_set_vars(struct mail_user *user, const char *service,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const struct ip_addr *local_ip,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const struct ip_addr *remote_ip)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(service != NULL);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->service = p_strdup(user->pool, service);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (local_ip != NULL && local_ip->family != 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->local_ip = p_new(user->pool, struct ip_addr, 1);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *user->local_ip = *local_ip;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (remote_ip != NULL && remote_ip->family != 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->remote_ip = p_new(user->pool, struct ip_addr, 1);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *user->remote_ip = *remote_ip;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikconst struct var_expand_table *
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikmail_user_var_expand_table(struct mail_user *user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik static struct var_expand_table static_tab[] = {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'u', NULL, "user" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'n', NULL, "username" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'd', NULL, "domain" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 's', NULL, "service" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'h', NULL, "home" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'l', NULL, "lip" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'r', NULL, "rip" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'p', NULL, "pid" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { 'i', NULL, "uid" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { '\0', NULL, "gid" },
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik { '\0', NULL, NULL }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik };
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct var_expand_table *tab;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* use a cached table, unless home directory has been set afterwards */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->var_expand_table != NULL &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->var_expand_table[4].value == user->_home)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return user->var_expand_table;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab = p_malloc(user->pool, sizeof(static_tab));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik memcpy(tab, static_tab, sizeof(static_tab));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[0].value = user->username;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[2].value = strchr(user->username, '@');
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (tab[2].value != NULL) tab[2].value++;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[3].value = user->service;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[4].value = user->_home; /* don't look it up unless we need it */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[5].value = user->local_ip == NULL ? NULL :
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik p_strdup(user->pool, net_ip2addr(user->local_ip));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[6].value = user->remote_ip == NULL ? NULL :
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik p_strdup(user->pool, net_ip2addr(user->remote_ip));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[7].value = my_pid;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[8].value = p_strdup(user->pool, dec2str(user->uid));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tab[9].value = p_strdup(user->pool, dec2str(user->gid));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->var_expand_table = tab;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return user->var_expand_table;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikvoid mail_user_set_home(struct mail_user *user, const char *home)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->_home = p_strdup(user->pool, home);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->home_looked_up = TRUE;
e59b73366d3067c576e39a214a34ace2f9a84878Lukas Slebodnik}
e59b73366d3067c576e39a214a34ace2f9a84878Lukas Slebodnik
e59b73366d3067c576e39a214a34ace2f9a84878Lukas Slebodnikvoid mail_user_add_namespace(struct mail_user *user,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_namespace **namespaces)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_namespace **tmp, *next, *ns = *namespaces;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (; ns != NULL; ns = next) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik next = ns->next;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik tmp = &user->namespaces;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (; *tmp != NULL; tmp = &(*tmp)->next) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (strlen(ns->prefix) < strlen((*tmp)->prefix))
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik break;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik ns->next = *tmp;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *tmp = ns;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *namespaces = user->namespaces;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikvoid mail_user_drop_useless_namespaces(struct mail_user *user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_namespace *ns, *next;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* drop all autocreated unusable (typically shared) namespaces.
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik don't drop the autocreated prefix="" namespace that we explicitly
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik created for being the fallback namespace. */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (ns = user->namespaces; ns != NULL; ns = next) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik next = ns->next;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0 &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik ns->prefix_len > 0)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_namespace_destroy(ns);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikconst char *mail_user_home_expand(struct mail_user *user, const char *path)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik (void)mail_user_try_home_expand(user, &path);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return path;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstatic int mail_user_userdb_lookup_home(struct mail_user *user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct auth_user_info info;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct auth_user_reply reply;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik pool_t userdb_pool;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *username, *const *fields;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik int ret;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_assert(!user->home_looked_up);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik memset(&info, 0, sizeof(info));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik info.service = user->service;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->local_ip != NULL)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik info.local_ip = *user->local_ip;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->remote_ip != NULL)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik info.remote_ip = *user->remote_ip;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik userdb_pool = pool_alloconly_create("userdb lookup", 2048);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik ret = auth_master_user_lookup(mail_user_auth_master_conn,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->username, &info, userdb_pool,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik &username, &fields);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (ret > 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik auth_user_fields_parse(fields, userdb_pool, &reply);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->_home = p_strdup(user->pool, reply.home);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik pool_unref(&userdb_pool);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return ret;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikint mail_user_get_home(struct mail_user *user, const char **home_r)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik int ret;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->home_looked_up) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *home_r = user->_home;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return user->_home != NULL ? 1 : 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (mail_user_auth_master_conn == NULL) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* no userdb connection. we can only use mail_home setting. */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->_home = user->set->mail_home;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik } else if ((ret = mail_user_userdb_lookup_home(user)) < 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* userdb lookup failed */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik } else if (ret == 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* user doesn't exist */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->nonexistent = TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik } else if (user->_home == NULL && *user->set->mail_home != '\0') {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* no home returned by userdb lookup, fallback to mail_home
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik setting. */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->_home = user->set->mail_home;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->home_looked_up = TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *home_r = user->_home;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return user->_home != NULL ? 1 : 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *const *plugins;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik bool ret;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik T_BEGIN {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik ret = str_array_find(plugins, module_get_plugin_name(module));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik } T_END;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return ret;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return mail_user_set_plugin_getenv(user->set, name);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *name)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *const *envs;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik unsigned int i, count;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (!array_is_created(&set->plugin_envs))
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik envs = array_get(&set->plugin_envs, &count);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (i = 0; i < count; i += 2) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (strcmp(envs[i], name) == 0)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return envs[i+1];
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *home, *path = *pathp;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (*path != '~') {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* no need to expand home */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (mail_user_get_home(user, &home) <= 0)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik path = home_expand_tilde(path, home);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (path == NULL)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return -1;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *pathp = path;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return 0;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikvoid mail_user_set_get_temp_prefix(string_t *dest,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const struct mail_user_settings *set)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str_append(dest, set->mail_temp_dir);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str_append(dest, "/dovecot.");
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str_append(dest, master_service_get_name(master_service));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str_append_c(dest, '.');
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikconst char *mail_user_get_anvil_userip_ident(struct mail_user *user)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->remote_ip == NULL)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return t_strconcat(net_ip2addr(user->remote_ip), "/",
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik str_tabescape(user->username), NULL);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikbool mail_user_is_path_mounted(struct mail_user *user, const char *path,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char **error_r)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mountpoint_list_rec *rec;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik const char *mounts_path;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *error_r = NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (user->mountpoints == NULL) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->set->base_dir);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->mountpoints = mountpoint_list_init_readonly(mounts_path);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik } else {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik (void)mountpoint_list_refresh(user->mountpoints);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik rec = mountpoint_list_find(user->mountpoints, path);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* we don't have any knowledge of this path's mountpoint.
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik assume it's fine. */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* record exists for this mountpoint. see if it's mounted */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (mountpoint_list_update_mounted(user->mountpoints) == 0 &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik !rec->mounted) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik *error_r = t_strdup_printf("Mountpoint %s isn't mounted. "
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik "Mount it or remove it with doveadm mount remove",
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik rec->mount_path);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return FALSE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstatic void
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikmail_user_try_load_class_plugin(struct mail_user *user, const char *name)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct module_dir_load_settings mod_set;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct module *module;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik unsigned int name_len = strlen(name);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik memset(&mod_set, 0, sizeof(mod_set));
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mod_set.abi_version = DOVECOT_ABI_VERSION;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mod_set.binary_name = master_service_get_name(master_service);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mod_set.setting_name = "<built-in storage lookup>";
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mod_set.require_init_funcs = TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mod_set.debug = user->mail_debug;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_storage_service_modules =
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik module_dir_load_missing(mail_storage_service_modules,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik user->set->mail_plugin_dir,
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik name, &mod_set);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* initialize the module (and only this module!) immediately so that
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik the class gets registered */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik for (module = mail_storage_service_modules; module != NULL; module = module->next) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (strncmp(module->name, name, name_len) == 0 &&
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik strcmp(module->name + name_len, "_plugin") == 0) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (!module->initialized) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik module->initialized = TRUE;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik module->init(module);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik break;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikstruct mail_storage *
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnikmail_user_get_storage_class(struct mail_user *user, const char *name)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik{
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik struct mail_storage *storage;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik storage = mail_storage_find_class(name);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (storage == NULL || storage->v.alloc != NULL)
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return storage;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik /* it's implemented by a plugin. load it and check again. */
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik mail_user_try_load_class_plugin(user, name);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik storage = mail_storage_find_class(name);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik if (storage != NULL && storage->v.alloc == NULL) {
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik i_error("Storage driver '%s' exists as a stub, "
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik "but its plugin couldn't be loaded", name);
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return NULL;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik }
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik return storage;
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik}
49a5412cbc98e630de17359c29cb8d6ce0e16168Lukas Slebodnik