mail-user.c revision 7b64db32b95286235612eebb5d37d296a49306f7
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2008-2013 Dovecot authors, see the included COPYING file */
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschstruct mail_user_module_register mail_user_module_register = { 0 };
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschstruct auth_master_connection *mail_user_auth_master_conn;
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschstatic void mail_user_deinit_base(struct mail_user *user)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschstruct mail_user *mail_user_alloc(const char *username,
833bed942977673526c72e79bccc09314fc57104Phil Carmody pool = pool_alloconly_create("mail user", 16*1024);
e9228a3918aa0243eff4aae1ff5462bd3198417fTimo Sirainen user->unexpanded_set = settings_dup(set_info, set, pool);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch user->set = settings_dup(set_info, set, pool);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch user->service = master_service_get_name(master_service);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch user->default_normalizer = uni_utf8_to_decomposed_titlecase;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch /* check settings so that the duplicated structure will again
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch contain the parsed fields */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (!settings_check(set_info, pool, user->set, &error))
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_panic("Settings check unexpectedly failed: %s", error);
1e9296de32c9ddda40f33c06556cd568ddadf71fTimo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschmail_user_expand_plugins_envs(struct mail_user *user)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch unsigned int i, count;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (!array_is_created(&user->set->plugin_envs))
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch envs = array_get_modifiable(&user->set->plugin_envs, &count);
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen "userdb didn't return a home directory, "
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen "but plugin setting %s used it (%%h): %s",
ee2633056e67353157bfbce4d9e0d1c3ceaa627aStephan Bosch var_expand(str, envs[i+1], mail_user_var_expand_table(user));
ee2633056e67353157bfbce4d9e0d1c3ceaa627aStephan Boschint mail_user_init(struct mail_user *user, const char **error_r)
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen settings_vars_have_key(user->set_info, user->set,
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen /* expand mail_home setting before calling mail_user_get_home() */
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen settings_var_expand(user->set_info, user->set,
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen user->pool, mail_user_var_expand_table(user));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch "userdb didn't return a home directory, "
ee2633056e67353157bfbce4d9e0d1c3ceaa627aStephan Bosch /* autocreated users for shared mailboxes need to be fully initialized
ee2633056e67353157bfbce4d9e0d1c3ceaa627aStephan Bosch if they don't exist, since they're going to be used anyway */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (user->error == NULL || user->nonexistent) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_set = mail_user_set_get_storage_set(user);
ee2633056e67353157bfbce4d9e0d1c3ceaa627aStephan Bosch /* call deinit() with refcount=1, otherwise we may assert-crash in
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_user_ref() that is called by some deinit() handler. */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (ns = user->namespaces; ns != NULL; ns = ns->next) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_user_set_vars(struct mail_user *user, const char *service,
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainen user->service = p_strdup(user->pool, service);
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainen if (local_ip != NULL && local_ip->family != 0) {
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch user->local_ip = p_new(user->pool, struct ip_addr, 1);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (remote_ip != NULL && remote_ip->family != 0) {
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch user->remote_ip = p_new(user->pool, struct ip_addr, 1);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschmail_user_var_expand_table(struct mail_user *user)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch static struct var_expand_table static_tab[] = {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch /* use a cached table, unless home directory has been set afterwards */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch user->var_expand_table[4].value == user->_home)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab = p_malloc(user->pool, sizeof(static_tab));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab[1].value = p_strdup(user->pool, t_strcut(user->username, '@'));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab[4].value = user->_home; /* don't look it up unless we need it */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab[5].value = user->local_ip == NULL ? NULL :
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch p_strdup(user->pool, net_ip2addr(user->local_ip));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab[6].value = user->remote_ip == NULL ? NULL :
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch p_strdup(user->pool, net_ip2addr(user->remote_ip));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab[8].value = p_strdup(user->pool, dec2str(user->uid));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch tab[9].value = p_strdup(user->pool, dec2str(user->gid));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_user_set_home(struct mail_user *user, const char *home)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_user_add_namespace(struct mail_user *user,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct mail_namespace **tmp, *next, *ns = *namespaces;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (strlen(ns->prefix) < strlen((*tmp)->prefix))
833bed942977673526c72e79bccc09314fc57104Phil Carmodyvoid mail_user_drop_useless_namespaces(struct mail_user *user)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch /* drop all autocreated unusable (typically shared) namespaces.
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch don't drop the autocreated prefix="" namespace that we explicitly
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch created for being the fallback namespace. */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (ns = user->namespaces; ns != NULL; ns = next) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0 &&
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
711e8e4c5c5d702dfa062f42a1ede5de14c151c9Stephan Boschstatic int mail_user_userdb_lookup_home(struct mail_user *user)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch userdb_pool = pool_alloconly_create("userdb lookup", 2048);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch ret = auth_master_user_lookup(mail_user_auth_master_conn,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch auth_user_fields_parse(fields, userdb_pool, &reply);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch user->_home = p_strdup(user->pool, reply.home);
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen /* no userdb connection. we can only use mail_home setting. */
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen } else if ((ret = mail_user_userdb_lookup_home(user)) < 0) {
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen /* userdb lookup failed */
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen } else if (ret == 0) {
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen /* user doesn't exist */
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch } else if (user->_home == NULL && *user->set->mail_home != '\0') {
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch /* no home returned by userdb lookup, fallback to mail_home
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschbool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch const char *const *plugins;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch ret = str_array_find(plugins, module_get_plugin_name(module));
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschconst char *mail_user_plugin_getenv(struct mail_user *user, const char *name)
const char *name)
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;