bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
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. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen union mailbox_transaction_module_context module_ctx;
f428ea9564d72894c18b8f3876bfaaf677ce19aaTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(acl_mail_module, &mail_module_register);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic struct acl_transaction_context acl_transaction_failure;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstruct acl_object *acl_mailbox_get_aclobj(struct mailbox *box)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenint acl_mailbox_right_lookup(struct mailbox *box, unsigned int right_idx)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
5e10e813a3f0c0f568cf642dbdf440a40b183ae6Aki Tuomi struct acl_mailbox_list *alist = ACL_LIST_CONTEXT_REQUIRE(box->list);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen alist->rights.acl_storage_right_idx[right_idx]);
e7ca5f820d6a1a8fe549a2966ac707a60e055ef4Timo Sirainen mail_storage_set_internal_error(box->storage);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
11fec79522fc0cebe7321d1a9206568d22ddc1c0Timo Sirainenstatic bool acl_is_readonly(struct mailbox *box)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
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)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_EXPUNGE) > 0)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) > 0)
026be738ed56c8be10d048ef7b684ef5e05e5beaTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED) > 0)
026be738ed56c8be10d048ef7b684ef5e05e5beaTimo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) > 0)
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainenstatic void acl_mailbox_free(struct mailbox *box)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainenstatic void acl_mailbox_copy_acls_from_parent(struct mailbox *box)
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 update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE;
36b7bef6b3106dae2586bad95c5db4dc71f8ad2fTimo Sirainen parent_aclobj = acl_object_init_from_parent(alist->rights.backend,
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi while (acl_object_list_next(iter, &update.rights)) {
4264d75117668afed3c3602116dcf159463644e6Timo Sirainen /* don't copy global ACL rights. */
4264d75117668afed3c3602116dcf159463644e6Timo Sirainen (void)acl_object_update(abox->aclobj, &update);
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi /* FIXME: Add error handling */
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenacl_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(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 /* mailbox is autocreated, so we need to treat it as if it
8c6884ab66c38f87d2198b840662a5546ca5d024Timo Sirainen already exists. ignore the "create" ACL here. */
9199a1680a57988eacccce07f457c4fac6a108b4Timo Sirainen mail_storage_set_internal_error(box->storage);
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 /* 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. */
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen ret = abox->module_ctx.super.create_box(box, update, directory);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenacl_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_ADMIN);
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen return abox->module_ctx.super.update_box(box, update);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenstatic void acl_mailbox_fail_not_found(struct mailbox *box)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen } else if (ret == 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_DELETE);
fca5548c51bf3887a202089549b9f87cf94cf212Timo Sirainen return abox->module_ctx.super.delete_box(box);
71e88fae3be360e9a93b3398e743f99a6f05d2edTimo Sirainenacl_mailbox_rename(struct mailbox *src, struct mailbox *dest)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(src);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen /* renaming requires rights to delete the old mailbox */
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen ret = acl_mailbox_right_lookup(src, ACL_STORAGE_RIGHT_DELETE);
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen /* and create the new one under the parent mailbox */
206ac4273fa102500fa017f0c21a4fd72e94665aTimo Sirainen ret = acl_mailbox_list_have_right(dest->list, dest->name, TRUE,
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_storage_set_internal_error(src->storage);
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen return abox->module_ctx.super.rename_box(src, dest);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen bool *flags_r, bool *flag_seen_r, bool *flag_del_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void acl_transaction_set_failure(struct mailbox_transaction_context *t)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenacl_mail_update_flags(struct mail *_mail, enum modify_type modify_type,
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail = ACL_MAIL_CONTEXT(mail);
12ef7b394dfdf4d53d432ac576f6bfcd20ebad6dTimo Sirainen if (acl_get_write_rights(_mail->box, &acl_flags, &acl_flag_seen,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen acl_transaction_set_failure(_mail->transaction);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* adding/removing flags. just remove the disallowed
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen flags from the mask. */
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. */
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 acl_mail_update_flags(_mail, MODIFY_ADD, flags);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen amail->super.update_flags(_mail, modify_type, flags);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainenacl_mail_update_keywords(struct mail *_mail, enum modify_type modify_type,
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail = ACL_MAIL_CONTEXT(mail);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(_mail->box, ACL_STORAGE_RIGHT_WRITE);
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen /* if we don't have permission, just silently return success. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen acl_transaction_set_failure(_mail->transaction);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen amail->super.update_keywords(_mail, modify_type, keywords);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void acl_mail_expunge(struct mail *_mail)
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mail_module_context *amail = ACL_MAIL_CONTEXT(mail);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = acl_mailbox_right_lookup(_mail->box, ACL_STORAGE_RIGHT_EXPUNGE);
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);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct acl_mailbox *abox = ACL_CONTEXT(_mail->box);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen amail = p_new(mail->pool, union mail_module_context, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->update_keywords = acl_mail_update_keywords;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET_SELF(mail, acl_mail_module, amail);
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 if (acl_get_write_rights(box, &acl_flags, &acl_flag_seen,
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainenacl_save_begin(struct mail_save_context *ctx, struct istream *input)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
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)
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen &ctx->data.pvt_flags, &ctx->data.keywords) < 0)
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen return abox->module_ctx.super.save_begin(ctx, input);
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainenacl_copy_has_rights(struct mail_save_context *ctx, struct mail *mail)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen struct mailbox *destbox = ctx->transaction->box;
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 if (acl_save_get_flags(destbox, &ctx->data.flags,
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen &ctx->data.pvt_flags, &ctx->data.keywords) < 0)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainenacl_copy(struct mail_save_context *ctx, struct mail *mail)
6695fbfc493422a810eb5d950bfd6f41990626a9Timo Sirainen struct mailbox_transaction_context *t = ctx->transaction;
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(t->box);
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen return abox->module_ctx.super.copy(ctx, mail);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenacl_transaction_commit(struct mailbox_transaction_context *ctx,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct mail_transaction_commit_changes *changes_r)
b8a3be58d25a5b9113a70b848f53e664edd63761Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(ctx->box);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen abox->module_ctx.super.transaction_rollback(ctx);
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen ret = abox->module_ctx.super.transaction_commit(ctx, changes_r);
1973c7c4f46abec48e1015823a304f17da35b2f6Timo Sirainen /* don't allow IMAP client to see what UIDs the messages got */
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainenstatic int acl_mailbox_exists(struct mailbox *box, bool auto_boxes,
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen unsigned int i;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen if (acl_object_get_my_rights(abox->aclobj, pool_datastack_create(),
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 if (strcmp(rights[i], MAIL_ACL_LOOKUP) == 0 ||
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen return abox->module_ctx.super.exists(box, auto_boxes,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int acl_mailbox_open_check_acl(struct mailbox *box)
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 /* 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 ||
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;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen ret = acl_object_have_right(abox->aclobj, idx_arr[open_right]);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen /* no access. */
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int acl_mailbox_open(struct mailbox *box)
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainenstatic int acl_mailbox_get_status(struct mailbox *box,
3131b3878de3245db7552234e66d437e8fde9351Aki Tuomi struct acl_mailbox *abox = ACL_CONTEXT_REQUIRE(box);
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if (abox->module_ctx.super.get_status(box, items, status_r) < 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 if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED) <= 0)
b59960aed0923004f21f2a00bc1c945084d2f851Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) <= 0)
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainenvoid acl_mailbox_allocated(struct mailbox *box)
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
7d6d78822fea744b86892b4faa04a5bf5137896fTimo Sirainen bool ignore_acls = (box->flags & MAILBOX_FLAG_IGNORE_ACLS) != 0;
ea9d9d99948cff5f9b881f79b28fa3b80da0f2a7Timo Sirainen /* ACLs disabled */
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. */
7fb70daba4e571eab5b64f496d20b9e37e31141bTimo Sirainen abox = p_new(box->pool, struct acl_mailbox, 1);
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,
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->transaction_commit = acl_transaction_commit;
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;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET(box, acl_storage_module, abox);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenacl_mailbox_update_removed_id(struct acl_object *aclobj,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (update->modify_mode != ACL_MODIFY_MODE_CLEAR &&
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen update->neg_modify_mode != ACL_MODIFY_MODE_CLEAR)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (update->modify_mode == ACL_MODIFY_MODE_CLEAR &&
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen update->neg_modify_mode == ACL_MODIFY_MODE_CLEAR)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen /* mixed clear/non-clear. see if the identifier exists anymore */
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (rights.id_type == update->rights.id_type &&
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen null_strcmp(rights.identifier, update->rights.identifier) == 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenint acl_mailbox_update_acl(struct mailbox_transaction_context *t,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen key = t_strdup_printf(MAILBOX_ATTRIBUTE_PREFIX_ACL"%s",
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(t->box, "Failed to set ACL");
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);