/* Copyright (c) 2006-2018 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"
struct acl_transaction_context {
};
{
}
{
int ret;
if (abox->skip_acl_checks)
return 1;
if (ret > 0)
return 1;
if (ret < 0) {
return -1;
}
return 0;
}
{
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
}
{
}
{
/* don't copy global ACL rights. */
}
/* FIXME: Add error handling */
}
static int
bool directory)
{
int ret;
if (!mailbox_is_autocreated(box)) {
/* we're looking up CREATE permission from our parent's rights */
} else {
/* mailbox is autocreated, so we need to treat it as if it
already exists. ignore the "create" ACL here. */
ret = 1;
}
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;
}
}
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
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;
}
}
{
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
{
return -1;
return -1;
}
static bool
{
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;
}
{
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;
}
{
/* ACLs disabled */
return;
}
/* this is the root shared namespace, which itself doesn't
have any existing mailboxes. */
ignore_acls = TRUE;
}
/* aclobj can be used for setting ACLs, even when mailbox is opened
with IGNORE_ACLS flag */
v->free = acl_mailbox_free;
if (!ignore_acls) {
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)
{
return FALSE;
return TRUE;
break;
}
return acl_object_list_deinit(&iter) >= 0;
}
const struct acl_rights_update *update)
{
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;
}