acl-lookup-dict.c revision 20e04227229970d148801c507946666e2a9bd838
/* Copyright (c) 2008-2016 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "dict.h"
#include "mail-user.h"
#include "mail-namespace.h"
#include "acl-api-private.h"
#include "acl-storage.h"
#include "acl-plugin.h"
#include "acl-lookup-dict.h"
#define DICT_SHARED_BOXES_PATH "shared-boxes/"
struct acl_lookup_dict {
};
struct acl_lookup_dict_iter {
struct acl_lookup_dict *dict;
unsigned int iter_idx, iter_value_idx;
unsigned int failed:1;
};
{
struct acl_lookup_dict *dict;
struct dict_settings dict_set;
} else if (user->mail_debug) {
i_debug("acl: No acl_shared_dict setting - "
"shared mailbox listing is disabled");
}
return dict;
}
{
}
{
}
static void
{
case ACL_ID_ANYONE:
case ACL_ID_AUTHENTICATED:
/* don't bother separating these */
break;
case ACL_ID_USER:
break;
case ACL_ID_GROUP:
case ACL_ID_GROUP_OVERRIDE:
break;
case ACL_ID_OWNER:
case ACL_ID_TYPE_COUNT:
i_unreached();
}
}
static bool
{
}
{
struct acl_backend *backend;
struct acl_mailbox_list_context *ctx;
struct acl_object *aclobj;
struct acl_object_list_iter *iter;
struct acl_rights rights;
return 0;
/* avoid pointless user -> user entries,
which some clients do */
str_truncate(id, 0);
}
}
if (ret < 0)
ret2 = -1;
}
}
static int
bool no_removes)
{
struct dict_iterate_context *iter;
struct dict_transaction_context *dt;
unsigned int prefix_len;
int ret;
/* get all existing identifiers for the user. we might be able to
sync identifiers also for other users whose shared namespaces we
have, but it's possible that the other users have other namespaces
that aren't visible to us, so we don't want to remove anything
that could break them. */
/* prefix/$type/$dest/$source */
key += prefix_len;
}
}
if (dict_iterate_deinit(&iter) < 0) {
i_error("acl: dict iteration failed, can't update dict");
return -1;
}
/* sort the existing identifiers */
/* sync the identifiers */
if (ret == 0) {
} else if (ret < 0) {
/* new identifier, add it */
newi++;
} else if (!no_removes) {
/* old identifier removed */
oldi++;
}
}
if (dict_transaction_commit(&dt) < 0) {
i_error("acl: dict commit failed");
return -1;
}
return 0;
}
{
struct mail_namespace *ns;
const char **ids;
int ret = 0;
return 0;
/* get all ACL identifiers with a positive lookup right */
ret = -1;
}
/* sort identifiers and remove duplicates */
if (++dest != i)
}
}
/* if lookup failed at some point we can still add new ids,
but we can't remove any existing ones */
ret = -1;
return ret;
}
{
struct dict_iterate_context *dict_iter;
unsigned int prefix_len;
iter->iter_value_idx = 0;
/* read all of it to memory. at least currently dict-proxy can support
only one iteration at a time, but the acl code can end up rebuilding
the dict, which opens another iteration. */
}
if (dict_iterate_deinit(&dict_iter) < 0)
}
struct acl_lookup_dict_iter *
{
struct acl_lookup_dict_iter *iter;
const char *id;
unsigned int i;
id = "anyone";
/* get all groups we belong to */
NULL);
}
}
/* iterate through all identifiers that match us, start with the
first one */
else
return iter;
}
const char *
{
const char *const *keys;
unsigned int count;
/* get to the next iterator */
return acl_lookup_dict_iterate_visible_next(iter);
}
return NULL;
}
{
return ret;
}