bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen/* FIXME: If we don't have permission to change flags/keywords, the changes
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen should still be stored temporarily for this session. However most clients
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen don't care and it's a huge job, so I currently this isn't done. The same
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen problem actually exists when opening read-only mailboxes. */
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen#include "lib.h"
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen#include "array.h"
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen#include "ioloop.h"
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen#include "istream.h"
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include "mailbox-list-private.h"
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen#include "acl-api-private.h"
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen#include "acl-plugin.h"
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen#include <sys/stat.h>
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define ACL_MAIL_CONTEXT(obj) \
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi MODULE_CONTEXT_REQUIRE(obj, acl_mail_module)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstruct acl_transaction_context {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen union mailbox_transaction_module_context module_ctx;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen};
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
f428ea9564d72894c18b8f3876bfaaf677ce19aaTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(acl_mail_module, &mail_module_register);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic struct acl_transaction_context acl_transaction_failure;
f428ea9564d72894c18b8f3876bfaaf677ce19aaTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstruct acl_object *acl_mailbox_get_aclobj(struct mailbox *box)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return abox->aclobj;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenint acl_mailbox_right_lookup(struct mailbox *box, unsigned int right_idx)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen int ret;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (abox->skip_acl_checks)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return 1;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
5e10e813a3f0c0f568cf642dbdf440a40b183ae6Aki Tuomi struct acl_mailbox_list *alist = ACL_LIST_CONTEXT_REQUIRE(box->list);
5e10e813a3f0c0f568cf642dbdf440a40b183ae6Aki Tuomi
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen ret = acl_object_have_right(abox->aclobj,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen alist->rights.acl_storage_right_idx[right_idx]);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (ret > 0)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return 1;
e7ca5f820d6a1a8fe549a2966ac707a60e055ef4Timo Sirainen if (ret < 0) {
e7ca5f820d6a1a8fe549a2966ac707a60e055ef4Timo Sirainen mail_storage_set_internal_error(box->storage);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return -1;
e7ca5f820d6a1a8fe549a2966ac707a60e055ef4Timo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen MAIL_ERRSTR_NO_PERMISSION);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return 0;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainenstatic bool acl_is_readonly(struct mailbox *box)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen enum acl_storage_rights save_right;
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen if (abox->module_ctx.super.is_readonly(box))
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return TRUE;
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen save_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen if (acl_mailbox_right_lookup(box, save_right) > 0)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return FALSE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_EXPUNGE) > 0)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return FALSE;
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) > 0)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return FALSE;
026be738ed56c8be10d048ef7b684ef5e05e5beaTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED) > 0)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return FALSE;
026be738ed56c8be10d048ef7b684ef5e05e5beaTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) > 0)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return FALSE;
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen return TRUE;
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen}
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainenstatic void acl_mailbox_free(struct mailbox *box)
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen acl_object_deinit(&abox->aclobj);
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen abox->module_ctx.super.free(box);
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen}
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainen
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainenstatic void acl_mailbox_copy_acls_from_parent(struct mailbox *box)
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
5e10e813a3f0c0f568cf642dbdf440a40b183ae6Aki Tuomi struct acl_mailbox_list *alist = ACL_LIST_CONTEXT_REQUIRE(box->list);
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen struct acl_object *parent_aclobj;
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen struct acl_object_list_iter *iter;
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen struct acl_rights_update update;
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update);
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen update.modify_mode = ACL_MODIFY_MODE_REPLACE;
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE;
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen parent_aclobj = acl_object_init_from_parent(alist->rights.backend,
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen box->name);
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen iter = acl_object_list_init(parent_aclobj);
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi while (acl_object_list_next(iter, &update.rights)) {
4264d75117668afed3c3602116dcf159463644e6Timo Sirainen /* don't copy global ACL rights. */
4264d75117668afed3c3602116dcf159463644e6Timo Sirainen if (!update.rights.global)
4264d75117668afed3c3602116dcf159463644e6Timo Sirainen (void)acl_object_update(abox->aclobj, &update);
4264d75117668afed3c3602116dcf159463644e6Timo Sirainen }
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi /* FIXME: Add error handling */
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen acl_object_list_deinit(&iter);
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen acl_object_deinit(&parent_aclobj);
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen}
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenstatic int
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenacl_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen bool directory)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen int ret;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen if (!mailbox_is_autocreated(box)) {
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen /* we're looking up CREATE permission from our parent's rights */
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen ret = acl_mailbox_list_have_right(box->list, box->name, TRUE,
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen ACL_STORAGE_RIGHT_CREATE, NULL);
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen } else {
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen /* mailbox is autocreated, so we need to treat it as if it
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen already exists. ignore the "create" ACL here. */
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen ret = 1;
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen }
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen if (ret <= 0) {
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen if (ret < 0) {
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen mail_storage_set_internal_error(box->storage);
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen return -1;
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen }
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen /* Note that if user didn't have LOOKUP permission to parent
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen mailbox, this may reveal the mailbox's existence to user.
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen Can't help it. */
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen MAIL_ERRSTR_NO_PERMISSION);
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen return -1;
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen }
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen /* ignore ACLs in this mailbox until creation is complete, because
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen super.create() may call e.g. mailbox_open() which will fail since
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen we haven't yet copied ACLs to this mailbox. */
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen abox->skip_acl_checks = TRUE;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen ret = abox->module_ctx.super.create_box(box, update, directory);
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen abox->skip_acl_checks = FALSE;
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen if (ret == 0)
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen acl_mailbox_copy_acls_from_parent(box);
b53bec99f804caa67f85c3523435ba9f4502c2d7Timo Sirainen return ret;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen}
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenstatic int
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenacl_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen int ret;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_ADMIN);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (ret <= 0)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen return -1;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen return abox->module_ctx.super.update_box(box, update);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen}
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenstatic void acl_mailbox_fail_not_found(struct mailbox *box)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen{
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen int ret;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret > 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen MAIL_ERRSTR_NO_PERMISSION);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen } else if (ret == 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
bdb026e2dc8a7c77585ed5ba489f0056df8074d4Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname));
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen }
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen}
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenstatic int
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenacl_mailbox_delete(struct mailbox *box)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen int ret;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_DELETE);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret <= 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret == 0)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen acl_mailbox_fail_not_found(box);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return -1;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen }
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
fca5548c51bf3887a202089549b9f87cf94cf212Timo Sirainen return abox->module_ctx.super.delete_box(box);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen}
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainenstatic int
71e88fae3be360e9a93b3398e743f99a6f05d2edTimo Sirainenacl_mailbox_rename(struct mailbox *src, struct mailbox *dest)
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(src);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen int ret;
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen /* renaming requires rights to delete the old mailbox */
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen ret = acl_mailbox_right_lookup(src, ACL_STORAGE_RIGHT_DELETE);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen if (ret <= 0) {
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen if (ret == 0)
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen acl_mailbox_fail_not_found(src);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen return -1;
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen }
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen /* and create the new one under the parent mailbox */
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen T_BEGIN {
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen ret = acl_mailbox_list_have_right(dest->list, dest->name, TRUE,
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen ACL_STORAGE_RIGHT_CREATE, NULL);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen } T_END;
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen if (ret <= 0) {
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen if (ret == 0) {
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen /* Note that if the mailbox didn't have LOOKUP
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen permission, this now reveals to user the mailbox's
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen existence. Can't help it. */
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen mail_storage_set_error(src->storage, MAIL_ERROR_PERM,
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen MAIL_ERRSTR_NO_PERMISSION);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen } else {
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen mail_storage_set_internal_error(src->storage);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen }
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen return -1;
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen }
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen return abox->module_ctx.super.rename_box(src, dest);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen}
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenstatic int
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenacl_get_write_rights(struct mailbox *box,
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen bool *flags_r, bool *flag_seen_r, bool *flag_del_r)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen int ret;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (ret < 0)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return -1;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen *flags_r = ret > 0;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (ret < 0)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return -1;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen *flag_seen_r = ret > 0;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (ret < 0)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return -1;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen *flag_del_r = ret > 0;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen return 0;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void acl_transaction_set_failure(struct mailbox_transaction_context *t)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen MODULE_CONTEXT_SET(t, acl_storage_module,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen &acl_transaction_failure);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenacl_mail_update_flags(struct mail *_mail, enum modify_type modify_type,
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen enum mail_flags flags)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail = ACL_MAIL_CONTEXT(mail);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen bool acl_flags, acl_flag_seen, acl_flag_del;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen if (acl_get_write_rights(_mail->box, &acl_flags, &acl_flag_seen,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen &acl_flag_del) < 0) {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen acl_transaction_set_failure(_mail->transaction);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (modify_type != MODIFY_REPLACE) {
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* adding/removing flags. just remove the disallowed
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen flags from the mask. */
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (!acl_flags)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen flags &= MAIL_SEEN | MAIL_DELETED;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (!acl_flag_seen)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen flags &= ~MAIL_SEEN;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (!acl_flag_del)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen flags &= ~MAIL_DELETED;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen } else if (!acl_flags || !acl_flag_seen || !acl_flag_del) {
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* we don't have permission to replace all the flags. */
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (!acl_flags && !acl_flag_seen && !acl_flag_del) {
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* no flag changes allowed. ignore silently. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* handle this by first removing the allowed flags and
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen then adding the allowed flags */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen acl_mail_update_flags(_mail, MODIFY_REMOVE, ~flags);
103106f0227b8487abc1e2c6ad63b84cdc51388eTimo Sirainen if (flags != 0)
103106f0227b8487abc1e2c6ad63b84cdc51388eTimo Sirainen acl_mail_update_flags(_mail, MODIFY_ADD, flags);
103106f0227b8487abc1e2c6ad63b84cdc51388eTimo Sirainen return;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen amail->super.update_flags(_mail, modify_type, flags);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenacl_mail_update_keywords(struct mail *_mail, enum modify_type modify_type,
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_keywords *keywords)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail = ACL_MAIL_CONTEXT(mail);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen int ret;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(_mail->box, ACL_STORAGE_RIGHT_WRITE);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (ret <= 0) {
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* if we don't have permission, just silently return success. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (ret < 0)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen acl_transaction_set_failure(_mail->transaction);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen amail->super.update_keywords(_mail, modify_type, keywords);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void acl_mail_expunge(struct mail *_mail)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail = ACL_MAIL_CONTEXT(mail);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen int ret;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(_mail->box, ACL_STORAGE_RIGHT_EXPUNGE);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen if (ret <= 0) {
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* if we don't have permission, silently return success so
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen users won't see annoying error messages in case their
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen clients try automatic expunging. */
742230f6ea54caf4dc2fdf365396da2e26f2f8e3Timo Sirainen acl_transaction_set_failure(_mail->transaction);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen amail->super.expunge(_mail);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainenvoid acl_mail_allocated(struct mail *_mail)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct acl_mailbox *abox = ACL_CONTEXT(_mail->box);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mail_vfuncs *v = mail->vlast;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen if (abox == NULL || !abox->acl_enabled)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen amail = p_new(mail->pool, union mail_module_context, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen amail->super = *v;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen mail->vlast = &amail->super;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->update_flags = acl_mail_update_flags;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->update_keywords = acl_mail_update_keywords;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->expunge = acl_mail_expunge;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET_SELF(mail, acl_mail_module, amail);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainenstatic int
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainenacl_save_get_flags(struct mailbox *box, enum mail_flags *flags,
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen enum mail_flags *pvt_flags, struct mail_keywords **keywords)
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen{
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen bool acl_flags, acl_flag_seen, acl_flag_del;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen if (acl_get_write_rights(box, &acl_flags, &acl_flag_seen,
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen &acl_flag_del) < 0)
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen return -1;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen if (!acl_flag_seen) {
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen *flags &= ~MAIL_SEEN;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen *pvt_flags &= ~MAIL_SEEN;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen }
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen if (!acl_flag_del) {
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen *flags &= ~MAIL_DELETED;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen *pvt_flags &= ~MAIL_DELETED;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen }
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen if (!acl_flags) {
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen *flags &= MAIL_SEEN | MAIL_DELETED;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen *pvt_flags &= MAIL_SEEN | MAIL_DELETED;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen *keywords = NULL;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen }
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen return 0;
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen}
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenstatic int
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainenacl_save_begin(struct mail_save_context *ctx, struct istream *input)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen struct mailbox *box = ctx->transaction->box;
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen enum acl_storage_rights save_right;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen save_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen if (acl_mailbox_right_lookup(box, save_right) <= 0)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen return -1;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen if (acl_save_get_flags(box, &ctx->data.flags,
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen &ctx->data.pvt_flags, &ctx->data.keywords) < 0)
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen return -1;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen return abox->module_ctx.super.save_begin(ctx, input);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainenstatic bool
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainenacl_copy_has_rights(struct mail_save_context *ctx, struct mail *mail)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen struct mailbox *destbox = ctx->transaction->box;
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen enum acl_storage_rights save_right;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
7ada346a0fb1540ae8c26433a6a12166c27daf22Timo Sirainen if (ctx->moving) {
7ada346a0fb1540ae8c26433a6a12166c27daf22Timo Sirainen if (acl_mailbox_right_lookup(mail->box,
7ada346a0fb1540ae8c26433a6a12166c27daf22Timo Sirainen ACL_STORAGE_RIGHT_EXPUNGE) <= 0)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen return FALSE;
7ada346a0fb1540ae8c26433a6a12166c27daf22Timo Sirainen }
7ada346a0fb1540ae8c26433a6a12166c27daf22Timo Sirainen
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen save_right = (destbox->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen if (acl_mailbox_right_lookup(destbox, save_right) <= 0)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen return FALSE;
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen if (acl_save_get_flags(destbox, &ctx->data.flags,
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen &ctx->data.pvt_flags, &ctx->data.keywords) < 0)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen return FALSE;
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen return TRUE;
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen}
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainenstatic int
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainenacl_copy(struct mail_save_context *ctx, struct mail *mail)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen{
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen struct mailbox_transaction_context *t = ctx->transaction;
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(t->box);
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen if (!acl_copy_has_rights(ctx, mail)) {
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen mailbox_save_cancel(&ctx);
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen return -1;
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen return abox->module_ctx.super.copy(ctx, mail);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic int
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenacl_transaction_commit(struct mailbox_transaction_context *ctx,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct mail_transaction_commit_changes *changes_r)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
b8a3be58d25a5b9113a70b848f53e664edd63761Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(ctx->box);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen void *at = ACL_CONTEXT(ctx);
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen int ret;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (at != NULL) {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen abox->module_ctx.super.transaction_rollback(ctx);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return -1;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen ret = abox->module_ctx.super.transaction_commit(ctx, changes_r);
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen if (abox->no_read_right) {
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen /* don't allow IMAP client to see what UIDs the messages got */
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen changes_r->no_read_perm = TRUE;
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen }
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen return ret;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
ef3f582fdf2d007838bba693f8c2629d079668deTimo Sirainen
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainenstatic int acl_mailbox_exists(struct mailbox *box, bool auto_boxes,
c29216637957d4b3126c6929ac5ba98138256ce1Timo Sirainen enum mailbox_existence *existence_r)
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen const char *const *rights;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen unsigned int i;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen if (acl_object_get_my_rights(abox->aclobj, pool_datastack_create(),
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen &rights) < 0)
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen return -1;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen /* for now this is used only by IMAP SUBSCRIBE. we'll intentionally
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen violate RFC 4314 here, because it says SUBSCRIBE should succeed only
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen when mailbox has 'l' right. But there's no point in not allowing
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen a subscribe for a mailbox that can be selected anyway. Just the
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen opposite: subscribing to such mailboxes is a very useful feature. */
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen for (i = 0; rights[i] != NULL; i++) {
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen if (strcmp(rights[i], MAIL_ACL_LOOKUP) == 0 ||
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen strcmp(rights[i], MAIL_ACL_READ) == 0 ||
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen strcmp(rights[i], MAIL_ACL_INSERT) == 0)
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen return abox->module_ctx.super.exists(box, auto_boxes,
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen existence_r);
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen }
c29216637957d4b3126c6929ac5ba98138256ce1Timo Sirainen *existence_r = MAILBOX_EXISTENCE_NONE;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen return 0;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen}
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int acl_mailbox_open_check_acl(struct mailbox *box)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
5e10e813a3f0c0f568cf642dbdf440a40b183ae6Aki Tuomi struct acl_mailbox_list *alist = ACL_LIST_CONTEXT_REQUIRE(box->list);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen const unsigned int *idx_arr = alist->rights.acl_storage_right_idx;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen enum acl_storage_rights open_right;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen int ret;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen /* mailbox can be opened either for reading or appending new messages */
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if ((box->flags & MAILBOX_FLAG_IGNORE_ACLS) != 0 ||
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen (box->list->ns->flags & NAMESPACE_FLAG_NOACL) != 0 ||
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen abox->skip_acl_checks)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return 0;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if ((box->flags & MAILBOX_FLAG_SAVEONLY) != 0) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen open_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
fca5548c51bf3887a202089549b9f87cf94cf212Timo Sirainen } else if (box->deleting) {
fca5548c51bf3887a202089549b9f87cf94cf212Timo Sirainen open_right = ACL_STORAGE_RIGHT_DELETE;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen } else {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen open_right = ACL_STORAGE_RIGHT_READ;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen ret = acl_object_have_right(abox->aclobj, idx_arr[open_right]);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret <= 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret == 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen /* no access. */
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen acl_mailbox_fail_not_found(box);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen if (open_right != ACL_STORAGE_RIGHT_READ) {
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen ret = acl_object_have_right(abox->aclobj,
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen idx_arr[ACL_STORAGE_RIGHT_READ]);
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen if (ret < 0)
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen return -1;
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen if (ret == 0)
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen abox->no_read_right = TRUE;
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen }
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return 0;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int acl_mailbox_open(struct mailbox *box)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (acl_mailbox_open_check_acl(box) < 0)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return abox->module_ctx.super.open(box);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainenstatic int acl_mailbox_get_status(struct mailbox *box,
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen enum mailbox_status_items items,
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen struct mailbox_status *status_r)
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen{
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if (abox->module_ctx.super.get_status(box, items, status_r) < 0)
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen return -1;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if ((items & STATUS_PERMANENT_FLAGS) != 0) {
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) <= 0) {
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen status_r->permanent_flags &= MAIL_DELETED|MAIL_SEEN;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen status_r->permanent_keywords = FALSE;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen status_r->allow_new_keywords = FALSE;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen }
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED) <= 0)
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen status_r->permanent_flags &= ~MAIL_DELETED;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) <= 0)
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen status_r->permanent_flags &= ~MAIL_SEEN;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen }
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen return 0;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen}
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainenvoid acl_mailbox_allocated(struct mailbox *box)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen{
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mailbox_vfuncs *v = box->vlast;
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct acl_mailbox *abox;
7d6d78822fea744b86892b4faa04a5bf5137896fTimo Sirainen bool ignore_acls = (box->flags & MAILBOX_FLAG_IGNORE_ACLS) != 0;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen if (alist == NULL) {
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen /* ACLs disabled */
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen return;
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen }
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen
14b551180cb4ac7acac8b048d8d6d7278541d1f6Timo Sirainen if (mail_namespace_is_shared_user_root(box->list->ns)) {
a9dbce68b8bf10026e05721fdf3206279d64cb8aTimo Sirainen /* this is the root shared namespace, which itself doesn't
a9dbce68b8bf10026e05721fdf3206279d64cb8aTimo Sirainen have any existing mailboxes. */
7d6d78822fea744b86892b4faa04a5bf5137896fTimo Sirainen ignore_acls = TRUE;
a9dbce68b8bf10026e05721fdf3206279d64cb8aTimo Sirainen }
a9dbce68b8bf10026e05721fdf3206279d64cb8aTimo Sirainen
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen abox = p_new(box->pool, struct acl_mailbox, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen abox->module_ctx.super = *v;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen box->vlast = &abox->module_ctx.super;
dd350fbefc91e6450dcd01f0cda5db6ea2242736Timo Sirainen /* aclobj can be used for setting ACLs, even when mailbox is opened
dd350fbefc91e6450dcd01f0cda5db6ea2242736Timo Sirainen with IGNORE_ACLS flag */
dd350fbefc91e6450dcd01f0cda5db6ea2242736Timo Sirainen abox->aclobj = acl_object_init_from_name(alist->rights.backend,
dd350fbefc91e6450dcd01f0cda5db6ea2242736Timo Sirainen mailbox_get_name(box));
db9f053331a7bb144d32a2331e666cb1d2be5766Timo Sirainen
dd350fbefc91e6450dcd01f0cda5db6ea2242736Timo Sirainen v->free = acl_mailbox_free;
8d834fd1016ccba47ae8df74877a2a757c3e9f21Timo Sirainen if (!ignore_acls) {
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen abox->acl_enabled = TRUE;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->is_readonly = acl_is_readonly;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen v->exists = acl_mailbox_exists;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->open = acl_mailbox_open;
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen v->get_status = acl_mailbox_get_status;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen v->create_box = acl_mailbox_create;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen v->update_box = acl_mailbox_update;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen v->delete_box = acl_mailbox_delete;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen v->rename_box = acl_mailbox_rename;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->save_begin = acl_save_begin;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->copy = acl_copy;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->transaction_commit = acl_transaction_commit;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen v->attribute_set = acl_attribute_set;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen v->attribute_get = acl_attribute_get;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen v->attribute_iter_init = acl_attribute_iter_init;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen v->attribute_iter_next = acl_attribute_iter_next;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen v->attribute_iter_deinit = acl_attribute_iter_deinit;
db9f053331a7bb144d32a2331e666cb1d2be5766Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET(box, acl_storage_module, abox);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen}
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenstatic bool
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenacl_mailbox_update_removed_id(struct acl_object *aclobj,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen const struct acl_rights_update *update)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen{
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen struct acl_object_list_iter *iter;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen struct acl_rights rights;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (update->modify_mode != ACL_MODIFY_MODE_CLEAR &&
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen update->neg_modify_mode != ACL_MODIFY_MODE_CLEAR)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return FALSE;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (update->modify_mode == ACL_MODIFY_MODE_CLEAR &&
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen update->neg_modify_mode == ACL_MODIFY_MODE_CLEAR)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return TRUE;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen /* mixed clear/non-clear. see if the identifier exists anymore */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen iter = acl_object_list_init(aclobj);
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi while (acl_object_list_next(iter, &rights)) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (rights.id_type == update->rights.id_type &&
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen null_strcmp(rights.identifier, update->rights.identifier) == 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen break;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen }
bbc7e2c2e726cf84da49f4062d05b0c35a9377bdAki Tuomi return acl_object_list_deinit(&iter) >= 0;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen}
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenint acl_mailbox_update_acl(struct mailbox_transaction_context *t,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen const struct acl_rights_update *update)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen{
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen struct acl_object *aclobj;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen const char *key;
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen time_t ts = update->last_change != 0 ?
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen update->last_change : ioloop_time;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen key = t_strdup_printf(MAILBOX_ATTRIBUTE_PREFIX_ACL"%s",
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen acl_rights_get_id(&update->rights));
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen aclobj = acl_mailbox_get_aclobj(t->box);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_object_update(aclobj, update) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(t->box, "Failed to set ACL");
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return -1;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen }
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen /* FIXME: figure out some value lengths, so maybe some day
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen quota could apply to ACLs as well. */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (acl_mailbox_update_removed_id(aclobj, update))
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen mail_index_attribute_unset(t->itrans, FALSE, key, ts);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen else
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen mail_index_attribute_set(t->itrans, FALSE, key, ts, 0);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return 0;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen}