acl-mailbox.c revision a8c5a86d183db25a57bf193c06b41e092ec2e151
/* Copyright (c) 2006-2014 Dovecot authors, see the included COPYING file */
should still be stored temporarily for this session. However most clients
don't care and it's a huge job, so I currently this isn't done. The same
problem actually exists when opening read-only mailboxes. */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "istream.h"
#include "mailbox-list-private.h"
#include "acl-api-private.h"
#include "acl-plugin.h"
#define ACL_MAIL_CONTEXT(obj) \
struct acl_transaction_context {
};
static struct acl_transaction_context acl_transaction_failure;
{
}
{
int ret;
if (abox->skip_acl_checks)
return 1;
if (ret > 0)
return 1;
if (ret < 0) {
return -1;
}
return 0;
}
{
enum acl_storage_rights save_right;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
}
{
}
{
struct acl_object *parent_aclobj;
struct acl_object_list_iter *iter;
struct acl_rights_update update;
/* don't copy global ACL rights. */
}
}
static int
bool directory)
{
int ret;
/* we're looking up CREATE permission from our parent's rights */
if (ret <= 0) {
if (ret < 0) {
return -1;
}
/* Note that if user didn't have LOOKUP permission to parent
mailbox, this may reveal the mailbox's existence to user.
Can't help it. */
return -1;
}
/* ignore ACLs in this mailbox until creation is complete, because
super.create() may call e.g. mailbox_open() which will fail since
we haven't yet copied ACLs to this mailbox. */
if (ret == 0)
return ret;
}
static int
{
int ret;
if (ret <= 0)
return -1;
}
{
int ret;
if (ret > 0) {
} else if (ret == 0) {
}
}
static int
{
int ret;
if (ret <= 0) {
if (ret == 0)
return -1;
}
/* deletion might internally open the mailbox. let it succeed even if
we don't have READ permission. */
return ret;
}
static int
{
int ret;
/* renaming requires rights to delete the old mailbox */
if (ret <= 0) {
if (ret == 0)
return -1;
}
/* and create the new one under the parent mailbox */
T_BEGIN {
} T_END;
if (ret <= 0) {
if (ret == 0) {
/* Note that if the mailbox didn't have LOOKUP
permission, this now reveals to user the mailbox's
existence. Can't help it. */
} else {
}
return -1;
}
}
static int
{
int ret;
if (ret < 0)
return -1;
if (ret < 0)
return -1;
*flag_seen_r = ret > 0;
if (ret < 0)
return -1;
*flag_del_r = ret > 0;
return 0;
}
static void acl_transaction_set_failure(struct mailbox_transaction_context *t)
{
}
static void
enum mail_flags flags)
{
&acl_flag_del) < 0) {
return;
}
if (modify_type != MODIFY_REPLACE) {
flags from the mask. */
if (!acl_flags)
if (!acl_flag_seen)
if (!acl_flag_del)
flags &= ~MAIL_DELETED;
/* we don't have permission to replace all the flags. */
/* no flag changes allowed. ignore silently. */
return;
}
/* handle this by first removing the allowed flags and
then adding the allowed flags */
if (flags != 0)
return;
}
}
static void
struct mail_keywords *keywords)
{
int ret;
if (ret <= 0) {
/* if we don't have permission, just silently return success. */
if (ret < 0)
return;
}
}
{
int ret;
if (ret <= 0) {
/* if we don't have permission, silently return success so
users won't see annoying error messages in case their
clients try automatic expunging. */
return;
}
}
{
union mail_module_context *amail;
return;
v->expunge = acl_mail_expunge;
}
static int
{
&acl_flag_del) < 0)
return -1;
if (!acl_flag_seen) {
}
if (!acl_flag_del) {
*flags &= ~MAIL_DELETED;
*pvt_flags &= ~MAIL_DELETED;
}
if (!acl_flags) {
}
return 0;
}
static int
{
enum acl_storage_rights save_right;
return -1;
return -1;
}
static bool
{
enum acl_storage_rights save_right;
ACL_STORAGE_RIGHT_EXPUNGE) <= 0)
return FALSE;
}
return FALSE;
return FALSE;
return TRUE;
}
static int
{
return -1;
}
}
static int
struct mail_transaction_commit_changes *changes_r)
{
int ret;
return -1;
}
if (abox->no_read_right) {
/* don't allow IMAP client to see what UIDs the messages got */
}
return ret;
}
enum mailbox_existence *existence_r)
{
const char *const *rights;
unsigned int i;
&rights) < 0)
return -1;
/* for now this is used only by IMAP SUBSCRIBE. we'll intentionally
violate RFC 4314 here, because it says SUBSCRIBE should succeed only
when mailbox has 'l' right. But there's no point in not allowing
a subscribe for a mailbox that can be selected anyway. Just the
opposite: subscribing to such mailboxes is a very useful feature. */
}
return 0;
}
{
enum acl_storage_rights open_right;
int ret;
/* mailbox can be opened either for reading or appending new messages */
return 0;
} else {
}
if (ret <= 0) {
if (ret == 0) {
/* no access. */
}
return -1;
}
if (open_right != ACL_STORAGE_RIGHT_READ) {
if (ret < 0)
return -1;
if (ret == 0)
}
return 0;
}
{
if (acl_mailbox_open_check_acl(box) < 0)
return -1;
}
enum mailbox_status_items items,
struct mailbox_status *status_r)
{
return -1;
if ((items & STATUS_PERMANENT_FLAGS) != 0) {
}
}
return 0;
}
{
struct acl_mailbox *abox;
/* ACLs disabled */
return;
}
/* this is the root shared namespace, which itself doesn't
have any existing mailboxes. */
return;
}
/* aclobj can be used for setting ACLs, even when mailbox is opened
with IGNORE_ACLS flag */
v->free = acl_mailbox_free;
v->is_readonly = acl_is_readonly;
v->exists = acl_mailbox_exists;
v->open = acl_mailbox_open;
v->create_box = acl_mailbox_create;
v->update_box = acl_mailbox_update;
v->delete_box = acl_mailbox_delete;
v->rename_box = acl_mailbox_rename;
v->save_begin = acl_save_begin;
}
}
static bool
const struct acl_rights_update *update)
{
struct acl_object_list_iter *iter;
struct acl_rights rights;
int ret;
return FALSE;
return TRUE;
break;
}
return ret == 0;
}
int acl_mailbox_update_acl(struct mailbox_transaction_context *t,
const struct acl_rights_update *update)
{
struct acl_object *aclobj;
const char *key;
return -1;
}
/* FIXME: figure out some value lengths, so maybe some day
quota could apply to ACLs as well. */
else
return 0;
}