mail-user.c revision bdd36cfdba3ff66d25570a9ff568d69e1eb543cf
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct auth_master_connection *mail_user_auth_master_conn;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_user *mail_user_alloc(const char *username,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool = pool_alloconly_create("mail user", 16*1024);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen user->unexpanded_set = settings_dup(set_info, set, pool);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen user->set = settings_dup(set_info, set, pool);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->service = master_service_get_name(master_service);
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen user->default_normalizer = uni_utf8_to_decomposed_titlecase;
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))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_panic("Settings check unexpectedly failed: %s", error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_user_expand_plugins_envs(struct mail_user *user, const char **error_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!array_is_created(&user->set->plugin_envs))
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen envs = array_get_modifiable(&user->set->plugin_envs, &count);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen "userdb didn't return a home directory, "
d2475500ee2a5f3c07eb22886797cef0e11ce7c4Timo Sirainen "but plugin setting %s used it (%%h): %s",
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen var_expand(str, envs[i+1], mail_user_var_expand_table(user));
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenint mail_user_init(struct mail_user *user, const char **error_r)
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen settings_vars_have_key(user->set_info, user->set,
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* expand mail_home setting before calling mail_user_get_home() */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen settings_var_expand(user->set_info, user->set,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->pool, mail_user_var_expand_table(user));
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen "userdb didn't return a home directory, "
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen if (mail_user_expand_plugins_envs(user, error_r) < 0)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen mail_set = mail_user_set_get_storage_set(user);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* call deinit() with refcount=1, otherwise we may assert-crash in
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen mail_user_ref() that is called by some deinit() handler. */
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_user_set_vars(struct mail_user *user, const char *service,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->service = p_strdup(user->pool, service);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (local_ip != NULL && local_ip->family != 0) {
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo 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);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenmail_user_var_expand_table(struct mail_user *user)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen static struct var_expand_table static_tab[] = {
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen /* use a cached table, unless home directory has been set afterwards */
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen user->var_expand_table[4].value == user->_home)
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen tab = p_malloc(user->pool, sizeof(static_tab));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen tab[4].value = user->_home; /* don't look it up unless we need it */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen tab[5].value = user->local_ip == NULL ? NULL :
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen p_strdup(user->pool, net_ip2addr(user->local_ip));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen tab[6].value = user->remote_ip == NULL ? NULL :
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen p_strdup(user->pool, net_ip2addr(user->remote_ip));
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen tab[8].value = p_strdup(user->pool, dec2str(user->uid));
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen tab[9].value = p_strdup(user->pool, dec2str(user->gid));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_user_add_namespace(struct mail_user *user,
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen struct mail_namespace **tmp, *next, *ns = *namespaces;
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
685393de106e55b61f754d420e378d05bd462ebbTimo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenstatic int mail_user_userdb_lookup_home(struct mail_user *user)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 2048);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = auth_master_user_lookup(mail_user_auth_master_conn,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_user_fields_parse(fields, userdb_pool, &reply);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen user->_home = p_strdup(user->pool, reply.home);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen if (ret > 0 && user->_home == NULL && *user->set->mail_home != '\0') {
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen /* no home in userdb, fallback to mail_home setting */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen const char *const *plugins;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ret = str_array_find(plugins, module_get_plugin_name(module));
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return mail_user_set_plugin_getenv(user->set, name);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenconst char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen const char *const *envs;
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen /* no need to expand home */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_user_set_get_temp_prefix(string_t *dest,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen str_append(dest, master_service_get_name(master_service));
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenconst char *mail_user_get_anvil_userip_ident(struct mail_user *user)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen return t_strconcat(net_ip2addr(user->remote_ip), "/",
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenbool mail_user_is_path_mounted(struct mail_user *user, const char *path,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen const char **error_r)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen user->mountpoints = mountpoint_list_init_readonly(mounts_path);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen (void)mountpoint_list_refresh(user->mountpoints);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen rec = mountpoint_list_find(user->mountpoints, path);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we don't have any knowledge of this path's mountpoint.
return TRUE;
return FALSE;
return TRUE;