bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainenacl_attribute_update_acl(struct mailbox_transaction_context *t, const char *key,
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen const char *value_str, *id, *const *rights, *error;
10ccd0e45768923d69be459e87ef6cd2574cec60Timo Sirainen /* for now allow only dsync to update ACLs this way.
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if this check is removed, it should be replaced by a setting, since
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen some admins may still have configured Dovecot using dovecot-acl
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen files directly that they don't want users to update. and in any case
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen ACL_STORAGE_RIGHT_ADMIN must be checked then. */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_error(t->box->storage, MAIL_ERROR_PERM,
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen if (mailbox_attribute_value_to_string(t->box->storage, value,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL);
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen rights = value_str == NULL ? NULL : t_strsplit(value_str, " ");
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_rights_update_import(&update, id, rights, &error) < 0) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, error);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen /* FIXME: this should actually be done only at commit().. */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenstatic int acl_attribute_get_acl(struct mailbox *box, const char *key,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen struct acl_object *aclobj = acl_mailbox_get_aclobj(box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen /* set last_change for all ACL objects, even if they don't exist
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen (because they could have been removed by the last change, and dsync
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen can use this information) */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen (void)acl_object_last_changed(aclobj, &value_r->last_change);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_identifier_parse(id, &wanted_rights) < 0) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen null_strcmp(rights.identifier, wanted_rights.identifier) == 0) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_internal_error(box->storage);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenstatic int acl_have_attribute_rights(struct mailbox *box)
fca5548c51bf3887a202089549b9f87cf94cf212Timo Sirainen /* deleting attributes during mailbox deletion */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen When the ACL extension [RFC4314] is present, users can only set and
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen retrieve private or shared mailbox annotations on a mailbox on which
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen they have the "l" right and any one of the "r", "s", "w", "i", or "p"
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_READ) > 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) > 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) > 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_INSERT) > 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_POST) > 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenint acl_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)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(t->box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_ACL,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return acl_attribute_update_acl(t, key, value);
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek return abox->module_ctx.super.attribute_set(t, type, key, value);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen enum mail_attribute_type type, const char *key,
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_ACL,
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek return abox->module_ctx.super.attribute_get(box, type, key, value_r);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenacl_attribute_iter_init(struct mailbox *box, enum mail_attribute_type type,
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen aiter = i_new(struct acl_mailbox_attribute_iter, 1);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen aiter->acl_iter = acl_object_list_init(abox->aclobj);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen str_append(aiter->acl_name, MAILBOX_ATTRIBUTE_PREFIX_ACL);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenstatic const char *
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenacl_attribute_iter_next_acl(struct acl_mailbox_attribute_iter *aiter)
37c72fa0cd3f1d74d79b64afb3fb6da5ffd4fe3aAki Tuomi while (acl_object_list_next(aiter->acl_iter, &rights)) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen str_truncate(aiter->acl_name, strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL));
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen acl_rights_write_id(aiter->acl_name, &rights);
37c72fa0cd3f1d74d79b64afb3fb6da5ffd4fe3aAki Tuomi if (acl_object_list_deinit(&aiter->acl_iter) < 0) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen mail_storage_set_internal_error(aiter->iter.box->storage);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenconst char *acl_attribute_iter_next(struct mailbox_attribute_iter *iter)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(iter->box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if ((key = acl_attribute_iter_next_acl(aiter)) != NULL)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return abox->module_ctx.super.attribute_iter_next(aiter->super);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenint acl_attribute_iter_deinit(struct mailbox_attribute_iter *iter)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(iter->box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (abox->module_ctx.super.attribute_iter_deinit(aiter->super) < 0)
b607b432d14af662bbd20d3a894a8315d25a0fddAki Tuomi if (aiter->acl_iter != NULL && acl_object_list_deinit(&aiter->acl_iter) < 0) {