mail-user.c revision 39993536eaef0a23954105e41040dcf88afd2e7e
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "array.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "hostpid.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "network.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "module-dir.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "home-expand.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "str.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "strescape.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "var-expand.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "settings-parser.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-master.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "master-service.h"
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen#include "mountpoint-list.h"
40ef82c46f6652412b068ebcdac7c3e74840a284Timo Sirainen#include "mail-storage-settings.h"
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#include "mail-storage-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-namespace.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-user.h"
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen#include <stdlib.h>
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen
56f45b3f3ae20e5c933701f4657dda5ef1916855Timo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstruct auth_master_connection *mail_user_auth_master_conn;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mail_namespaces_deinit(&user->namespaces);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen if (user->mountpoints != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mountpoint_list_deinit(&user->mountpoints);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainenstruct mail_user *mail_user_alloc(const char *username,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen const struct setting_parser_info *set_info,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen const struct mail_user_settings *set)
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_user *user;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *error;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool_t pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen i_assert(username != NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(*username != '\0');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen pool = pool_alloconly_create("mail user", 16*1024);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user = p_new(pool, struct mail_user, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->pool = pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->refcount = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->username = p_strdup(pool, username);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->set_info = set_info;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->unexpanded_set = settings_dup(set_info, set, pool);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->set = settings_dup(set_info, set, pool);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->service = master_service_get_name(master_service);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* check settings so that the duplicated structure will again
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen contain the parsed fields */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!settings_check(set_info, pool, user->set, &error))
659fe5d24825b160cae512538088020d97a60239Timo Sirainen i_panic("Settings check unexpectedly failed: %s", error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->v.deinit = mail_user_deinit_base;
232d5bef3c709e90e24f0874a36854b92187bb6cTimo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return user;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainenstatic int
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenmail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen{
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen const char **envs, *home;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen string_t *str;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!array_is_created(&user->set->plugin_envs))
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen return 0;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen str = t_str_new(256);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen i_assert((count % 2) == 0);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen for (i = 0; i < count; i += 2) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (user->_home == NULL &&
a928e7efabb1672b1476e597106d4b4b81ac6f3cTimo Sirainen var_has_key(envs[i+1], 'h', "home") &&
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_user_get_home(user, &home) <= 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen *error_r = t_strdup_printf(
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen "userdb didn't return a home directory, "
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen "but plugin setting %s used it (%%h): %s",
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen envs[i], envs[i+1]);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_truncate(str, 0);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen envs[i+1] = p_strdup(user->pool, str_c(str));
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const struct mail_storage_settings *mail_set;
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen const char *home, *key, *value;
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen bool need_home_dir;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen need_home_dir = user->_home == NULL &&
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen settings_vars_have_key(user->set_info, user->set,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen 'h', "home", &key, &value);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* expand mail_home setting before calling mail_user_get_home() */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen settings_var_expand(user->set_info, user->set,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen user->pool, mail_user_var_expand_table(user));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen *error_r = t_strdup_printf(
a928e7efabb1672b1476e597106d4b4b81ac6f3cTimo Sirainen "userdb didn't return a home directory, "
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen "but %s used it (%%h): %s", key, value);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen return -1;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (mail_user_expand_plugins_envs(user, error_r) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_set = mail_user_set_get_storage_set(user);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen user->mail_debug = mail_set->mail_debug;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen user->initialized = TRUE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen hook_mail_user_created(user);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen if (user->error != NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *error_r = t_strdup(user->error);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen return 0;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen}
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_user_ref(struct mail_user *user)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(user->refcount > 0);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen user->refcount++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_user_unref(struct mail_user **_user)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_user *user = *_user;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(user->refcount > 0);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *_user = NULL;
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen if (user->refcount > 1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->refcount--;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* call deinit() with refcount=1, otherwise we may assert-crash in
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen mail_user_ref() that is called by some deinit() handler. */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen user->v.deinit(user);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen i_assert(user->refcount == 1);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen pool_unref(&user->pool);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen}
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
c680a6b35b459045e92814778908da5a93922107Timo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
c680a6b35b459045e92814778908da5a93922107Timo Sirainen{
c680a6b35b459045e92814778908da5a93922107Timo Sirainen struct mail_namespace *ns;
c680a6b35b459045e92814778908da5a93922107Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ns->owner;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen}
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainenvoid mail_user_set_vars(struct mail_user *user, const char *service,
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen const struct ip_addr *local_ip,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct ip_addr *remote_ip)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(service != NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo 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);
c9c24293550541307f1bb41bba4a0fdfe2fa59e0Timo Sirainen *user->local_ip = *local_ip;
c9c24293550541307f1bb41bba4a0fdfe2fa59e0Timo 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;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenconst struct var_expand_table *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_user_var_expand_table(struct mail_user *user)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen static struct var_expand_table static_tab[] = {
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen { 'u', NULL, "user" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'n', NULL, "username" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'd', NULL, "domain" },
8a3d609fdd84f5938c82e8e7eeb84a24ab41b317Timo Sirainen { 's', NULL, "service" },
8a3d609fdd84f5938c82e8e7eeb84a24ab41b317Timo Sirainen { 'h', NULL, "home" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'l', NULL, "lip" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'r', NULL, "rip" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'p', NULL, "pid" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'i', NULL, "uid" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { '\0', NULL, "gid" },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { '\0', NULL, NULL }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen };
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct var_expand_table *tab;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (user->var_expand_table != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return user->var_expand_table;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen tab[0].value = user->username;
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen tab[2].value = strchr(user->username, '@');
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen if (tab[2].value != NULL) tab[2].value++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen tab[3].value = user->service;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen tab[4].value = user->_home; /* don't look it up unless we need it */
tab[5].value = user->local_ip == NULL ? NULL :
p_strdup(user->pool, net_ip2addr(user->local_ip));
tab[6].value = user->remote_ip == NULL ? NULL :
p_strdup(user->pool, net_ip2addr(user->remote_ip));
tab[7].value = my_pid;
tab[8].value = p_strdup(user->pool, dec2str(user->uid));
tab[9].value = p_strdup(user->pool, dec2str(user->gid));
user->var_expand_table = tab;
return user->var_expand_table;
}
void mail_user_set_home(struct mail_user *user, const char *home)
{
user->_home = p_strdup(user->pool, home);
user->home_looked_up = TRUE;
}
void mail_user_add_namespace(struct mail_user *user,
struct mail_namespace **namespaces)
{
struct mail_namespace **tmp, *next, *ns = *namespaces;
for (; ns != NULL; ns = next) {
next = ns->next;
tmp = &user->namespaces;
for (; *tmp != NULL; tmp = &(*tmp)->next) {
if (strlen(ns->prefix) < strlen((*tmp)->prefix))
break;
}
ns->next = *tmp;
*tmp = ns;
}
*namespaces = user->namespaces;
}
void mail_user_drop_useless_namespaces(struct mail_user *user)
{
struct mail_namespace *ns, *next;
for (ns = user->namespaces; ns != NULL; ns = next) {
next = ns->next;
if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
(ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0)
mail_namespace_destroy(ns);
}
}
const char *mail_user_home_expand(struct mail_user *user, const char *path)
{
(void)mail_user_try_home_expand(user, &path);
return path;
}
static int mail_user_userdb_lookup_home(struct mail_user *user)
{
struct auth_user_info info;
struct auth_user_reply reply;
pool_t userdb_pool;
const char *username, *const *fields;
int ret;
i_assert(!user->home_looked_up);
memset(&info, 0, sizeof(info));
info.service = user->service;
if (user->local_ip != NULL)
info.local_ip = *user->local_ip;
if (user->remote_ip != NULL)
info.remote_ip = *user->remote_ip;
if (mail_user_auth_master_conn == NULL)
return 0;
userdb_pool = pool_alloconly_create("userdb lookup", 2048);
ret = auth_master_user_lookup(mail_user_auth_master_conn,
user->username, &info, userdb_pool,
&username, &fields);
if (ret > 0) {
auth_user_fields_parse(fields, userdb_pool, &reply);
user->_home = p_strdup(user->pool, reply.home);
}
pool_unref(&userdb_pool);
return ret;
}
int mail_user_get_home(struct mail_user *user, const char **home_r)
{
int ret;
if (user->home_looked_up) {
*home_r = user->_home;
return user->_home != NULL ? 1 : 0;
}
ret = mail_user_userdb_lookup_home(user);
if (ret < 0)
return -1;
if (ret > 0 && user->_home == NULL && *user->set->mail_home != '\0') {
/* no home in userdb, fallback to mail_home setting */
user->_home = user->set->mail_home;
}
user->home_looked_up = TRUE;
*home_r = user->_home;
return user->_home != NULL ? 1 : 0;
}
bool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
{
const char *const *plugins;
bool ret;
T_BEGIN {
plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
ret = str_array_find(plugins, module_get_plugin_name(module));
} T_END;
return ret;
}
const char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
{
return mail_user_set_plugin_getenv(user->set, name);
}
const char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
const char *name)
{
const char *const *envs;
unsigned int i, count;
if (!array_is_created(&set->plugin_envs))
return NULL;
envs = array_get(&set->plugin_envs, &count);
for (i = 0; i < count; i += 2) {
if (strcmp(envs[i], name) == 0)
return envs[i+1];
}
return NULL;
}
int mail_user_try_home_expand(struct mail_user *user, const char **pathp)
{
const char *home, *path = *pathp;
if (*path != '~') {
/* no need to expand home */
return 0;
}
if (mail_user_get_home(user, &home) <= 0)
return -1;
path = home_expand_tilde(path, home);
if (path == NULL)
return -1;
*pathp = path;
return 0;
}
void mail_user_set_get_temp_prefix(string_t *dest,
const struct mail_user_settings *set)
{
str_append(dest, set->mail_temp_dir);
str_append(dest, "/dovecot.");
str_append(dest, master_service_get_name(master_service));
str_append_c(dest, '.');
}
const char *mail_user_get_anvil_userip_ident(struct mail_user *user)
{
if (user->remote_ip == NULL)
return NULL;
return t_strconcat(net_ip2addr(user->remote_ip), "/",
str_tabescape(user->username), NULL);
}
bool mail_user_is_path_mounted(struct mail_user *user, const char *path,
const char **error_r)
{
struct mountpoint_list_rec *rec;
const char *mounts_path;
*error_r = NULL;
if (user->mountpoints == NULL) {
mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
user->set->base_dir);
user->mountpoints = mountpoint_list_init_readonly(mounts_path);
} else {
(void)mountpoint_list_refresh(user->mountpoints);
}
rec = mountpoint_list_find(user->mountpoints, path);
if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) {
/* we don't have any knowledge of this path's mountpoint.
assume it's fine. */
return TRUE;
}
/* record exists for this mountpoint. see if it's mounted */
if (mountpoint_list_update_mounted(user->mountpoints) == 0 &&
!rec->mounted) {
*error_r = t_strdup_printf("Mountpoint %s isn't mounted. "
"Mount it or remove it with doveadm mount remove",
rec->mount_path);
return FALSE;
}
return TRUE;
}