mail-user.c revision 013a8a91c83c6ea24bc75322b81235f19e26fa8f
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct auth_master_connection *mail_user_auth_master_conn;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct mail_user *mail_user_alloc(const char *username,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen pool = pool_alloconly_create("mail user", 16*1024);
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 /* 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 p_array_init(&user->module_contexts, user->pool, 5);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen unsigned int i, count;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (!array_is_created(&user->set->plugin_envs))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "userdb didn't return a home directory, "
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "but plugin setting %s used it (%%h): %s",
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen settings_vars_have_key(user->set_info, user->set,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "userdb didn't return a home directory, "
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 mail_set = mail_user_set_get_storage_set(user);
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 Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_user_set_vars(struct mail_user *user, const char *service,
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 if (remote_ip != NULL && remote_ip->family != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->remote_ip = p_new(user->pool, struct ip_addr, 1);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenmail_user_var_expand_table(struct mail_user *user)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen static struct var_expand_table static_tab[] = {
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
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[8].value = p_strdup(user->pool, dec2str(user->uid));
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen tab[9].value = p_strdup(user->pool, dec2str(user->gid));
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainenvoid mail_user_add_namespace(struct mail_user *user,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_namespace **tmp, *next, *ns = *namespaces;
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0)
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 2048);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen ret = auth_master_user_lookup(mail_user_auth_master_conn,
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen auth_user_fields_parse(fields, userdb_pool, &reply);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen const char *const *plugins;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen ret = str_array_find(plugins, module_get_plugin_name(module));
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainenconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return mail_user_set_plugin_getenv(user->set, name);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen const char *const *envs;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen unsigned int i, count;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenvoid mail_user_set_get_temp_prefix(string_t *dest,
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen str_append(dest, master_service_get_name(master_service));
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainenconst char *mail_user_get_anvil_userip_ident(struct mail_user *user)
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen return t_strconcat(net_ip2addr(user->remote_ip), "/",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool mail_user_is_path_mounted(struct mail_user *user, const char *path,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **error_r)
d3eff05aaa4c2bc0a7580ee87a54f6693f4a8241Timo Sirainen mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen user->mountpoints = mountpoint_list_init_readonly(mounts_path);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen (void)mountpoint_list_refresh(user->mountpoints);
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 /* record exists for this mountpoint. see if it's mounted */
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen if (mountpoint_list_update_mounted(user->mountpoints) == 0 &&
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen *error_r = t_strdup_printf("Mountpoint %s isn't mounted. "
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen "Mount it or remove it with doveadm mount remove",