bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainenmail_user_find_attribute_namespace(struct mail_user *user)
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen ns = mail_namespace_find_inbox(user->namespaces);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainenindex_storage_get_user_dict(struct mail_storage *err_storage,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen ns = mail_user_find_attribute_namespace(user);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* probably never happens? */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen mail_storage_set_error(err_storage, MAIL_ERROR_NOTPOSSIBLE,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen "Mailbox attributes not available for this mailbox");
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen attr_storage = mail_namespace_get_default_storage(ns);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen if (*attr_storage->set->mail_attribute_dict == '\0') {
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen mail_storage_set_error(err_storage, MAIL_ERROR_NOTPOSSIBLE,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen "Mailbox attributes not enabled");
20e04227229970d148801c507946666e2a9bd838Timo Sirainen if (dict_init(attr_storage->set->mail_attribute_dict, &dict_set,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen "mail_attribute_dict: dict_init(%s) failed: %s",
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen attr_storage->set->mail_attribute_dict, error);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainenindex_storage_get_dict(struct mailbox *box, enum mail_attribute_type type,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen struct dict **dict_r, const char **mailbox_prefix_r)
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0)
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen *mailbox_prefix_r = guid_128_to_string(metadata.guid);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* private attributes are stored in user's own dict */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen return index_storage_get_user_dict(storage, storage->user, dict_r);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* user owns the mailbox. shared attributes are stored in
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen the same dict. */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen return index_storage_get_user_dict(storage, storage->user, dict_r);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* accessing shared attribute of a shared mailbox.
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen use the owner's dict. */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen return index_storage_get_user_dict(storage, ns->owner, dict_r);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* accessing shared attributes of a public mailbox. no user owns it,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen so use the storage's dict. */
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen if (*storage->set->mail_attribute_dict == '\0') {
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen mail_storage_set_error(storage, MAIL_ERROR_NOTPOSSIBLE,
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen "Mailbox attributes not enabled");
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen if (mail_user_get_home(storage->user, &set.home_dir) <= 0)
20e04227229970d148801c507946666e2a9bd838Timo Sirainen if (dict_init(storage->set->mail_attribute_dict, &set,
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen "mail_attribute_dict: dict_init(%s) failed: %s",
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainenstatic const char *
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainenkey_get_prefixed(enum mail_attribute_type type, const char *mailbox_prefix,
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen const char *key)
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen return t_strconcat(DICT_PATH_PRIVATE, mailbox_prefix, "/",
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen return t_strconcat(DICT_PATH_SHARED, mailbox_prefix, "/",
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainenindex_storage_attribute_get_dict_trans(struct mailbox_transaction_context *t,
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen struct dict_transaction_context **dtransp = NULL;
4a9bbf81af2eba25653bbc4f744cc35e7bc9bb34Timo Sirainen /* transaction already created */
668f92ab0ef7aa42445716d653c5673ed874ab65Timo Sirainen if (mailbox_get_metadata(t->box, MAILBOX_METADATA_GUID,
668f92ab0ef7aa42445716d653c5673ed874ab65Timo Sirainen *mailbox_prefix_r = guid_128_to_string(metadata.guid);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (index_storage_get_dict(t->box, type, &dict, mailbox_prefix_r) < 0)
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen *dtransp = *dtrans_r = dict_transaction_begin(dict);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainenint index_storage_attribute_set(struct mailbox_transaction_context *t,
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen enum mail_attribute_type type, const char *key,
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek const struct mail_attribute_value *value)
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen bool pvt = type == MAIL_ATTRIBUTE_TYPE_PRIVATE;
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen time_t ts = value->last_change != 0 ? value->last_change : ioloop_time;
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (index_storage_attribute_get_dict_trans(t, type, &dtrans,
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen if (mailbox_attribute_value_to_string(t->box->storage, value,
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen mail_index_attribute_unset(t->itrans, pvt, key, ts);
9f37ef2a9192e7d47e3d7ac959080fd01120f2e9Aki Tuomiint index_storage_attribute_get(struct mailbox *box,
9c32eb25e7b90e753e0cd7b30f7a70e8ca9121d9Timo Sirainen enum mail_attribute_type type, const char *key,
9f37ef2a9192e7d47e3d7ac959080fd01120f2e9Aki Tuomi if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen ret = dict_lookup(dict, pool_datastack_create(),
b5052fbfdbc2678cc8f12899afe55c998f43b740Timo Sirainen "Failed to set attribute %s: %s", key, error);
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainenindex_storage_attribute_iter_init(struct mailbox *box,
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen iter = i_new(struct index_storage_attribute_iter, 1);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0) {
ed157532dafb9dc25f98fda89bc1e324c3926898Timo Sirainen if (mailbox_get_last_mail_error(box) == MAIL_ERROR_NOTPOSSIBLE)
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen iter->prefix = i_strdup(key_get_prefixed(type, mailbox_prefix,
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen iter->diter = dict_iterate_init(dict, iter->prefix,
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainenindex_storage_attribute_iter_next(struct mailbox_attribute_iter *_iter)
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen if (iter->diter == NULL || !dict_iterate(iter->diter, &key, &value))
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainen i_assert(strncmp(key, iter->prefix, iter->prefix_len) == 0);
8bad545017a5c2b69cf6fa06a50763b3b68fb161Timo Sirainenint index_storage_attribute_iter_deinit(struct mailbox_attribute_iter *_iter)
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainen if ((ret = dict_iterate_deinit(&iter->diter, &error)) < 0) {
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainen "dict_iterate(%s) failed: %s",