mail-user.c revision 013a8a91c83c6ea24bc75322b81235f19e26fa8f
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "array.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "hostpid.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "network.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "module-dir.h"
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen#include "home-expand.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "str.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "strescape.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "var-expand.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "settings-parser.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "auth-master.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "master-service.h"
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen#include "mountpoint-list.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mail-storage-settings.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mail-storage-private.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mail-namespace.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mail-storage.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mail-user.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include <stdlib.h>
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct auth_master_connection *mail_user_auth_master_conn;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_namespaces_deinit(&user->namespaces);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (user->mountpoints != NULL)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mountpoint_list_deinit(&user->mountpoints);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct mail_user *mail_user_alloc(const char *username,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const struct setting_parser_info *set_info,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const struct mail_user_settings *set)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_user *user;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char *error;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen pool_t pool;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(username != NULL);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(*username != '\0');
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen pool = pool_alloconly_create("mail user", 16*1024);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user = p_new(pool, struct mail_user, 1);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->pool = pool;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->refcount = 1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->username = p_strdup(pool, username);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->set_info = set_info;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->unexpanded_set = settings_dup(set_info, set, pool);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->set = settings_dup(set_info, set, pool);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->service = master_service_get_name(master_service);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* check settings so that the duplicated structure will again
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen contain the parsed fields */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (!settings_check(set_info, pool, user->set, &error))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_panic("Settings check unexpectedly failed: %s", error);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->v.deinit = mail_user_deinit_base;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return user;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char **envs, *home;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen string_t *str;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen unsigned int i, count;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (!array_is_created(&user->set->plugin_envs))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen str = t_str_new(256);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert((count % 2) == 0);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen for (i = 0; i < count; i += 2) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (user->_home == NULL &&
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen var_has_key(envs[i+1], 'h', "home") &&
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_user_get_home(user, &home) <= 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen *error_r = t_strdup_printf(
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "userdb didn't return a home directory, "
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "but plugin setting %s used it (%%h): %s",
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen envs[i], envs[i+1]);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen str_truncate(str, 0);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen envs[i+1] = p_strdup(user->pool, str_c(str));
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const struct mail_storage_settings *mail_set;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char *home, *key, *value;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (user->_home == NULL &&
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen settings_vars_have_key(user->set_info, user->set,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen 'h', "home", &key, &value) &&
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_user_get_home(user, &home) <= 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen *error_r = t_strdup_printf(
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "userdb didn't return a home directory, "
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "but %s used it (%%h): %s", key, value);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen settings_var_expand(user->set_info, user->set,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->pool, mail_user_var_expand_table(user));
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (mail_user_expand_plugins_envs(user, error_r) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_set = mail_user_set_get_storage_set(user);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->mail_debug = mail_set->mail_debug;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->initialized = TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen hook_mail_user_created(user);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (user->error != NULL) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen *error_r = t_strdup(user->error);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_user_ref(struct mail_user *user)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(user->refcount > 0);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->refcount++;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_user_unref(struct mail_user **_user)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_user *user = *_user;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(user->refcount > 0);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen *_user = NULL;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (user->refcount > 1) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->refcount--;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* call deinit() with refcount=1, otherwise we may assert-crash in
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_user_ref() that is called by some deinit() handler. */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->v.deinit(user);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(user->refcount == 1);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen pool_unref(&user->pool);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_namespace *ns;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return ns->owner;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return NULL;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_user_set_vars(struct mail_user *user, const char *service,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const struct ip_addr *local_ip,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const struct ip_addr *remote_ip)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(service != NULL);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen user->service = p_strdup(user->pool, service);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (local_ip != NULL && local_ip->family != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->local_ip = p_new(user->pool, struct ip_addr, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *user->local_ip = *local_ip;
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (remote_ip != NULL && remote_ip->family != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->remote_ip = p_new(user->pool, struct ip_addr, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *user->remote_ip = *remote_ip;
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen }
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst struct var_expand_table *
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenmail_user_var_expand_table(struct mail_user *user)
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen static struct var_expand_table static_tab[] = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'u', NULL, "user" },
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen { 'n', NULL, "username" },
2abfef71398a61e5ed97c23a1ceb71461933ccb8Timo Sirainen { 'd', NULL, "domain" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 's', NULL, "service" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'h', NULL, "home" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'l', NULL, "lip" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'r', NULL, "rip" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'p', NULL, "pid" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'i', NULL, "uid" },
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen { '\0', NULL, "gid" },
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen { '\0', NULL, NULL }
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen };
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen struct var_expand_table *tab;
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen if (user->var_expand_table != NULL)
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen return user->var_expand_table;
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
b9b48aaaebf6f72dfab567cda073cde8a7b26598Timo Sirainen
b9b48aaaebf6f72dfab567cda073cde8a7b26598Timo Sirainen tab[0].value = user->username;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen tab[2].value = strchr(user->username, '@');
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen if (tab[2].value != NULL) tab[2].value++;
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[3].value = user->service;
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[4].value = user->_home; /* don't look it up unless we need it */
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[5].value = user->local_ip == NULL ? NULL :
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen p_strdup(user->pool, net_ip2addr(user->local_ip));
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[6].value = user->remote_ip == NULL ? NULL :
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen p_strdup(user->pool, net_ip2addr(user->remote_ip));
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[7].value = my_pid;
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[8].value = p_strdup(user->pool, dec2str(user->uid));
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[9].value = p_strdup(user->pool, dec2str(user->gid));
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->var_expand_table = tab;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen return user->var_expand_table;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen{
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen user->_home = p_strdup(user->pool, home);
d4dcb9c30dba354cff7af6d303ecef7698194c55Timo Sirainen user->home_looked_up = TRUE;
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen}
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainenvoid mail_user_add_namespace(struct mail_user *user,
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen struct mail_namespace **namespaces)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_namespace **tmp, *next, *ns = *namespaces;
9c7e765845357342923e16351181091028e5930fTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen for (; ns != NULL; ns = next) {
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen next = ns->next;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen tmp = &user->namespaces;
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen for (; *tmp != NULL; tmp = &(*tmp)->next) {
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen break;
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen }
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen ns->next = *tmp;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen *tmp = ns;
b00787191c3c31bebb939c3d00f1fcdb67356c69Timo Sirainen }
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen *namespaces = user->namespaces;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen}
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
d22301419109ed4a38351715e6760011421dadecTimo Sirainen{
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen struct mail_namespace *ns, *next;
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen next = ns->next;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0)
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen mail_namespace_destroy(ns);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen }
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (void)mail_user_try_home_expand(user, &path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return path;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen{
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen struct auth_user_info info;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen struct auth_user_reply reply;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen pool_t userdb_pool;
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainen const char *username, *const *fields;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(&info, 0, sizeof(info));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.service = user->service;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (user->local_ip != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.local_ip = *user->local_ip;
aa62d8779ce53900c2f09bf2ff6fa790bc9f6a89Timo Sirainen if (user->remote_ip != NULL)
ea9fd7f876643e985946a2563140359064819b8eTimo Sirainen info.remote_ip = *user->remote_ip;
ea9fd7f876643e985946a2563140359064819b8eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (user->home_looked_up) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *home_r = user->_home;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen return user->_home != NULL ? 1 : 0;
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *home_r = NULL;
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (mail_user_auth_master_conn == NULL)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 2048);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen ret = auth_master_user_lookup(mail_user_auth_master_conn,
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen user->username, &info, userdb_pool,
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen &username, &fields);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (ret >= 0) {
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen auth_user_fields_parse(fields, userdb_pool, &reply);
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen user->_home = ret == 0 ? NULL :
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen p_strdup(user->pool, reply.home);
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen user->home_looked_up = TRUE;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen ret = user->_home != NULL ? 1 : 0;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen *home_r = user->_home;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen }
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen pool_unref(&userdb_pool);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return ret;
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen}
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen{
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen const char *const *plugins;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen bool ret;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen T_BEGIN {
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen ret = str_array_find(plugins, module_get_plugin_name(module));
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen } T_END;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen return ret;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen}
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainenconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen{
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return mail_user_set_plugin_getenv(user->set, name);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen}
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen const char *name)
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen{
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen const char *const *envs;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen unsigned int i, count;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen if (!array_is_created(&set->plugin_envs))
538303a216166f3526c0ae9658c9978275cfa100Timo Sirainen return NULL;
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen envs = array_get(&set->plugin_envs, &count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < count; i += 2) {
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (strcmp(envs[i], name) == 0)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return envs[i+1];
a87e5f15283e057c7dc26dd9db7b616268c95ca7Timo Sirainen }
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return NULL;
c93cd163f9c1d4b0ca29f49cbfdbf474caeef5bfTimo Sirainen}
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen const char *home, *path = *pathp;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_user_get_home(user, &home) <= 0)
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen return -1;
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen path = home_expand_tilde(path, home);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (path == NULL)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return -1;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen *pathp = path;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return 0;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen}
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenvoid mail_user_set_get_temp_prefix(string_t *dest,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen const struct mail_user_settings *set)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen{
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen str_append(dest, set->mail_temp_dir);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen str_append(dest, "/dovecot.");
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen str_append(dest, master_service_get_name(master_service));
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen str_append_c(dest, '.');
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainenconst char *mail_user_get_anvil_userip_ident(struct mail_user *user)
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen{
38df0cacce475112991e60d796f8f2105c616f01Timo Sirainen if (user->remote_ip == NULL)
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen return NULL;
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen return t_strconcat(net_ip2addr(user->remote_ip), "/",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_tabescape(user->username), NULL);
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen}
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool mail_user_is_path_mounted(struct mail_user *user, const char *path,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **error_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct mountpoint_list_rec *rec;
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen const char *mounts_path;
43955c82f9f52c969c777b3da00bc170183dfdf2Timo Sirainen
43955c82f9f52c969c777b3da00bc170183dfdf2Timo Sirainen *error_r = NULL;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen if (user->mountpoints == NULL) {
d3eff05aaa4c2bc0a7580ee87a54f6693f4a8241Timo Sirainen mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen user->set->base_dir);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen user->mountpoints = mountpoint_list_init_readonly(mounts_path);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen } else {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen (void)mountpoint_list_refresh(user->mountpoints);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen rec = mountpoint_list_find(user->mountpoints, path);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) {
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen /* we don't have any knowledge of this path's mountpoint.
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen assume it's fine. */
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen return TRUE;
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen }
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen /* record exists for this mountpoint. see if it's mounted */
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen if (mountpoint_list_update_mounted(user->mountpoints) == 0 &&
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen !rec->mounted) {
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen *error_r = t_strdup_printf("Mountpoint %s isn't mounted. "
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen "Mount it or remove it with doveadm mount remove",
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen rec->mount_path);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return FALSE;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return TRUE;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen}
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen