mail-user.c revision 7afde4b6c600f86ef6f742ea3b01640075ce16a2
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "lib.h"
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen#include "array.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "hostpid.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "network.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "str.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "strescape.h"
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen#include "var-expand.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "settings-parser.h"
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen#include "auth-master.h"
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen#include "master-service.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "mail-storage-settings.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mail-storage-private.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mail-namespace.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mail-storage.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "mail-user.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen#include <stdlib.h>
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
b624773984e35dd894db8dff976c1a2114c70782Timo Sirainenvoid (*hook_mail_user_created)(struct mail_user *user) = NULL;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen
b624773984e35dd894db8dff976c1a2114c70782Timo Sirainenstatic struct auth_master_connection *auth_master_conn;
12d38e76ba7f70d6219c89ec7416fea0d5de7e02Timo Sirainen
b624773984e35dd894db8dff976c1a2114c70782Timo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_namespaces_deinit(&user->namespaces);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen pool_unref(&user->pool);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstruct mail_user *mail_user_alloc(const char *username,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct mail_user_settings *set)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
3a7113e3e2dac0e333e1a3f62af7d682896f59c6Timo Sirainen struct mail_user *user;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen pool_t pool;
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen i_assert(username != NULL);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen i_assert(*username != '\0');
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen pool = pool_alloconly_create("mail user", 8192);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen user = p_new(pool, struct mail_user, 1);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->pool = pool;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->refcount = 1;
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen user->username = p_strdup(pool, username);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->unexpanded_set =
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen settings_dup(&mail_user_setting_parser_info, set, pool);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->set = settings_dup(&mail_user_setting_parser_info, set, pool);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->v.deinit = mail_user_deinit_base;
788a0754cfd38dcfec1902844b085e4e84cfe7e6Timo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen return user;
788a0754cfd38dcfec1902844b085e4e84cfe7e6Timo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic int
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenmail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen{
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen const char **envs, *home;
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen string_t *str;
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen unsigned int i, count;
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen if (!array_is_created(&user->set->plugin_envs))
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen return 0;
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen str = t_str_new(256);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen i_assert((count % 2) == 0);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen for (i = 0; i < count; i += 2) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (user->_home == NULL &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen var_has_key(envs[i+1], 'h', "home") &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_user_get_home(user, &home) <= 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen *error_r = t_strdup_printf(
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "userdb didn't return a home directory, "
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "but plugin setting %s used it (%%h): %s",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen envs[i], envs[i+1]);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return -1;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_truncate(str, 0);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen envs[i+1] = p_strdup(user->pool, str_c(str));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return 0;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct mail_storage_settings *mail_set;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen const char *home, *key, *value;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (user->_home == NULL &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen settings_vars_have_key(&mail_user_setting_parser_info, user->set,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen 'h', "home", &key, &value) &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_user_get_home(user, &home) <= 0) {
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen *error_r = t_strdup_printf(
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen "userdb didn't return a home directory, "
83d2e37f065eabe38dc92db485c5ca39ee43ce05Timo Sirainen "but %s used it (%%h): %s", key, value);
83d2e37f065eabe38dc92db485c5ca39ee43ce05Timo Sirainen return -1;
83d2e37f065eabe38dc92db485c5ca39ee43ce05Timo Sirainen }
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen settings_var_expand(&mail_user_setting_parser_info, user->set,
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen user->pool, mail_user_var_expand_table(user));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (mail_user_expand_plugins_envs(user, error_r) < 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return -1;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_set = mail_user_set_get_storage_set(user->set);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen user->mail_debug = mail_set->mail_debug;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen user->initialized = TRUE;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen if (hook_mail_user_created != NULL)
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen hook_mail_user_created(user);
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen return 0;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen}
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainenvoid mail_user_ref(struct mail_user *user)
3a7113e3e2dac0e333e1a3f62af7d682896f59c6Timo Sirainen{
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen i_assert(user->refcount > 0);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen user->refcount++;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen}
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainenvoid mail_user_unref(struct mail_user **_user)
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen{
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen struct mail_user *user = *_user;
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen i_assert(user->refcount > 0);
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen *_user = NULL;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen if (--user->refcount == 0)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen user->v.deinit(user);
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen}
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen{
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen struct mail_namespace *ns;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen return ns->owner;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen }
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen return NULL;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen}
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainenvoid mail_user_set_vars(struct mail_user *user, uid_t uid, const char *service,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct ip_addr *local_ip,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct ip_addr *remote_ip)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen user->uid = uid;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen user->service = p_strdup(user->pool, service);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (local_ip != NULL && local_ip->family != 0) {
31633d676642b83305b8d46da495d9bb4e2d1ff8Timo Sirainen user->local_ip = p_new(user->pool, struct ip_addr, 1);
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen *user->local_ip = *local_ip;
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen }
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen if (remote_ip != NULL && remote_ip->family != 0) {
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen user->remote_ip = p_new(user->pool, struct ip_addr, 1);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen *user->remote_ip = *remote_ip;
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen }
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen}
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainenconst struct var_expand_table *
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainenmail_user_var_expand_table(struct mail_user *user)
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen{
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen static struct var_expand_table static_tab[] = {
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen { 'u', NULL, "user" },
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen { 'n', NULL, "username" },
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen { 'd', NULL, "domain" },
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen { 's', NULL, "service" },
5d4855d7b4dcffb6975ed8e3c9c376dac74e5c8aTimo Sirainen { 'h', NULL, "home" },
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen { 'l', NULL, "lip" },
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen { 'r', NULL, "rip" },
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen { 'p', NULL, "pid" },
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen { 'i', NULL, "uid" },
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen { '\0', NULL, NULL }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen };
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct var_expand_table *tab;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen if (user->var_expand_table != NULL)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return user->var_expand_table;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen tab[0].value = user->username;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen tab[2].value = strchr(user->username, '@');
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (tab[2].value != NULL) tab[2].value++;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen tab[3].value = user->service;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen tab[4].value = user->_home; /* don't look it up unless we need it */
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen tab[5].value = user->local_ip == NULL ? NULL :
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen p_strdup(user->pool, net_ip2addr(user->local_ip));
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen tab[6].value = user->remote_ip == NULL ? NULL :
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen p_strdup(user->pool, net_ip2addr(user->remote_ip));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen tab[7].value = my_pid;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen tab[8].value = p_strdup(user->pool, dec2str(user->uid));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen user->var_expand_table = tab;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return user->var_expand_table;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen}
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen{
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen user->_home = p_strdup(user->pool, home);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen user->home_looked_up = TRUE;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen}
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainenvoid mail_user_add_namespace(struct mail_user *user,
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen struct mail_namespace **namespaces)
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen{
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen struct mail_namespace **tmp, *next, *ns = *namespaces;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen for (; ns != NULL; ns = next) {
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen next = ns->next;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen tmp = &user->namespaces;
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen for (; *tmp != NULL; tmp = &(*tmp)->next) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen break;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen ns->next = *tmp;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen *tmp = ns;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen }
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen *namespaces = user->namespaces;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen}
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen struct mail_namespace *ns, *next;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen next = ns->next;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen mail_namespace_destroy(ns);
31633d676642b83305b8d46da495d9bb4e2d1ff8Timo Sirainen }
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen}
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen{
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen (void)mail_user_try_home_expand(user, &path);
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen return path;
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen}
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen{
3db05c8c00faca6ab9ac8391e1d6977365f4d1b3Timo Sirainen struct auth_user_info info;
3db05c8c00faca6ab9ac8391e1d6977365f4d1b3Timo Sirainen struct auth_user_reply reply;
3db05c8c00faca6ab9ac8391e1d6977365f4d1b3Timo Sirainen pool_t userdb_pool;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const char *username, *const *fields;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen int ret;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen memset(&info, 0, sizeof(info));
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen info.service = "lib-storage";
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen if (user->local_ip != NULL)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen info.local_ip = *user->local_ip;
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen if (user->remote_ip != NULL)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen info.remote_ip = *user->remote_ip;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (user->home_looked_up) {
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen *home_r = user->_home;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return user->_home != NULL ? 1 : 0;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (auth_master_conn == NULL)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen return 0;
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 512);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen ret = auth_master_user_lookup(auth_master_conn, user->username,
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen &info, userdb_pool, &username, &fields);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (ret < 0)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen *home_r = NULL;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen else {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_user_fields_parse(fields, userdb_pool, &reply);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen user->_home = ret == 0 ? NULL :
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen p_strdup(user->pool, reply.home);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen user->home_looked_up = TRUE;
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen ret = user->_home != NULL ? 1 : 0;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen *home_r = user->_home;
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen }
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen pool_unref(&userdb_pool);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return ret;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen}
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainenconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen return mail_user_set_plugin_getenv(user->set, name);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen}
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen const char *name)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen const char *const *envs;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen unsigned int i, count;
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen if (!array_is_created(&set->plugin_envs))
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen return NULL;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen envs = array_get(&set->plugin_envs, &count);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen for (i = 0; i < count; i += 2) {
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen if (strcmp(envs[i], name) == 0)
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen return envs[i+1];
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen }
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen return NULL;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainenint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
484e12acec34f16e5a8adc001e23ae48f1dda8c7Timo Sirainen{
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen const char *home, *path = *pathp;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (mail_user_get_home(user, &home) < 0)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return -1;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) {
484e12acec34f16e5a8adc001e23ae48f1dda8c7Timo Sirainen if (home == NULL)
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen return -1;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen *pathp = t_strconcat(home, path + 1, NULL);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen }
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return 0;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainenconst char *mail_user_get_temp_prefix(struct mail_user *user)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen{
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen struct mail_namespace *ns;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen const char *dir;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (user->_home != NULL) {
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen return t_strconcat(user->_home, "/.temp.", my_hostname, ".",
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen my_pid, ".", NULL);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen }
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen ns = mail_namespace_find_inbox(user->namespaces);
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen if (ns == NULL)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen ns = user->namespaces;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (ns->storage->temp_path_prefix != NULL)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen return ns->storage->temp_path_prefix;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen dir = mailbox_list_get_path(ns->list, NULL,
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen return t_strconcat(dir, "/",
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen mailbox_list_get_temp_prefix(ns->list), NULL);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainenconst char *mail_user_get_anvil_userip_ident(struct mail_user *user)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen{
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (user->remote_ip == NULL)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return NULL;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen return t_strconcat(net_ip2addr(user->remote_ip), "/",
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen str_tabescape(user->username), NULL);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainenvoid mail_users_init(const char *auth_socket_path, bool debug)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen{
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen auth_master_conn = auth_socket_path == NULL ? NULL :
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen auth_master_init(auth_socket_path, debug);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainenvoid mail_users_deinit(void)
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (auth_master_conn != NULL)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_master_deinit(&auth_master_conn);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen