mail-user.c revision f182955da33263be83a8d45af4aab0253f8f274f
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2008-2014 Dovecot authors, see the included COPYING file */
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenstruct auth_master_connection *mail_user_auth_master_conn;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainenstruct mail_user *mail_user_alloc(const char *username,
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen pool = pool_alloconly_create(MEMPOOL_GROWING"mail user", 16*1024);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen user->unexpanded_set = settings_dup(set_info, set, pool);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen user->set = settings_dup(set_info, set, pool);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen user->service = master_service_get_name(master_service);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen user->default_normalizer = uni_utf8_to_decomposed_titlecase;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen /* check settings so that the duplicated structure will again
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen contain the parsed fields */
c69a255a68103a50fa3f04a527281a169075403fTimo Sirainen if (!settings_check(set_info, pool, user->set, &error))
c69a255a68103a50fa3f04a527281a169075403fTimo Sirainen i_panic("Settings check unexpectedly failed: %s", error);
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenmail_user_expand_plugins_envs(struct mail_user *user)
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen unsigned int i, count;
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen if (!array_is_created(&user->set->plugin_envs))
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen "userdb didn't return a home directory, "
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen "but plugin setting %s used it (%%h): %s",
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen settings_vars_have_key(user->set_info, user->set,
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainen /* expand mail_home setting before calling mail_user_get_home() */
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen settings_var_expand(user->set_info, user->set,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen user->pool, mail_user_var_expand_table(user));
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen "userdb didn't return a home directory, "
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen /* autocreated users for shared mailboxes need to be fully initialized
dabb4cec4cf9bdb34013de682b08f1284cfb670fTimo Sirainen if they don't exist, since they're going to be used anyway */
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen if (user->error == NULL || user->nonexistent) {
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen mail_set = mail_user_set_get_storage_set(user);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen /* call deinit() with refcount=1, otherwise we may assert-crash in
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen mail_user_ref() that is called by some deinit() handler. */
0ce8f754204c7eeb33805993807393f74faf2cd3Timo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
e1b83f64e62cc3e8967c75fcc3f9b5dbb243d3b3Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
b516a7812b9acc04522869fead3aa6d2787dcdc6Timo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenvoid mail_user_set_vars(struct mail_user *user, const char *service,
e1b83f64e62cc3e8967c75fcc3f9b5dbb243d3b3Timo Sirainen user->service = p_strdup(user->pool, service);
e1b83f64e62cc3e8967c75fcc3f9b5dbb243d3b3Timo Sirainen if (local_ip != NULL && local_ip->family != 0) {
e1b83f64e62cc3e8967c75fcc3f9b5dbb243d3b3Timo Sirainen user->local_ip = p_new(user->pool, struct ip_addr, 1);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (remote_ip != NULL && remote_ip->family != 0) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen user->remote_ip = p_new(user->pool, struct ip_addr, 1);
62394a19cba1a8df01cad66eaa9331a70464441eTimo Sirainenmail_user_var_expand_table(struct mail_user *user)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen static struct var_expand_table static_tab[] = {
2e0fa95785f9b41c1c6aaf541245579a49f94841Timo Sirainen /* use a cached table, unless home directory has been set afterwards */
2e0fa95785f9b41c1c6aaf541245579a49f94841Timo Sirainen user->var_expand_table[4].value == user->_home)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen tab[4].value = user->_home; /* don't look it up unless we need it */
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen tab[5].value = user->local_ip == NULL ? NULL :
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen p_strdup(user->pool, net_ip2addr(user->local_ip));
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainen tab[6].value = user->remote_ip == NULL ? NULL :
87506860556bf42f656b13f4b14cf81b75261e95Timo Sirainen p_strdup(user->pool, net_ip2addr(user->remote_ip));
87506860556bf42f656b13f4b14cf81b75261e95Timo Sirainen tab[8].value = p_strdup(user->pool, dec2str(user->uid));
87506860556bf42f656b13f4b14cf81b75261e95Timo Sirainen tab[9].value = p_strdup(user->pool, dec2str(user->gid));
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainen tab[12].value = t_strcut(user->auth_user, '@');
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenvoid mail_user_add_namespace(struct mail_user *user,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct mail_namespace **tmp, *next, *ns = *namespaces;
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
e4f1a5fdad77884e1de516521504c15dc936fa9dTimo Sirainen /* drop all autocreated unusable (typically shared) namespaces.
e4f1a5fdad77884e1de516521504c15dc936fa9dTimo Sirainen don't drop the autocreated prefix="" namespace that we explicitly
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainen created for being the fallback namespace. */
e4f1a5fdad77884e1de516521504c15dc936fa9dTimo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0 &&
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
e619ecbbc00cba9e6e1e8322caa59776507fac02Timo Sirainenstatic int mail_user_userdb_lookup_home(struct mail_user *user)
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 2048);
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainen ret = auth_master_user_lookup(mail_user_auth_master_conn,
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen auth_user_fields_parse(fields, userdb_pool, &reply);
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen user->_home = p_strdup(user->pool, reply.home);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen /* no userdb connection. we can only use mail_home setting. */
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen } else if ((ret = mail_user_userdb_lookup_home(user)) < 0) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen /* userdb lookup failed */
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen } else if (ret == 0) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen /* user doesn't exist */
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen } else if (user->_home == NULL && *user->set->mail_home != '\0') {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen /* no home returned by userdb lookup, fallback to mail_home
f335accff54f408a8bbb328f8098ad458f2ff58eTimo Sirainenbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen const char *const *plugins;
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainen plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
9ae664e94e6eeb5c1f900bb90642052633031832Timo Sirainen ret = str_array_find(plugins, module_get_plugin_name(module));
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainenconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainen return mail_user_set_plugin_getenv(user->set, name);
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainenconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
const char *const *envs;
unsigned int i, count;
return NULL;
return NULL;
return NULL;
const char **error_r)
const char *mounts_path;
return TRUE;
return FALSE;
return TRUE;
struct mail_storage *
return storage;
return NULL;
return storage;
return user2;