dovecot-1.1: ACL plugin was listing mailboxes directly from dove...
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 4 23:47:45 EEST 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/036d06b57bd1
changeset: 7496:036d06b57bd1
user: Timo Sirainen <tss at iki.fi>
date: Sun May 04 23:47:40 2008 +0300
description:
ACL plugin was listing mailboxes directly from dovecot-acl-list. It was
supposed to be used only as an optimization to avoid looking into all
mailboxes to see which ones contained dovecot-acl files.
diffstat:
1 file changed, 71 insertions(+), 48 deletions(-)
src/plugins/acl/acl-mailbox-list.c | 119 +++++++++++++++++++++---------------
diffs (234 lines):
diff -r 7f7003bcf422 -r 036d06b57bd1 src/plugins/acl/acl-mailbox-list.c
--- a/src/plugins/acl/acl-mailbox-list.c Sun May 04 23:45:42 2008 +0300
+++ b/src/plugins/acl/acl-mailbox-list.c Sun May 04 23:47:40 2008 +0300
@@ -29,7 +29,6 @@ struct acl_mailbox_list_iterate_context
struct mailbox_list_iterate_context *super_ctx;
struct mailbox_tree_context *tree;
- struct mailbox_tree_iterate_context *tree_iter;
struct mailbox_info info;
};
@@ -63,7 +62,7 @@ acl_mailbox_list_have_right(struct acl_m
can_see_r);
}
-static bool
+static void
acl_mailbox_try_list_fast(struct acl_mailbox_list_iterate_context *ctx,
const char *const *patterns)
{
@@ -73,19 +72,20 @@ acl_mailbox_try_list_fast(struct acl_mai
alist->rights.acl_storage_right_idx + ACL_STORAGE_RIGHT_LOOKUP;
const struct acl_mask *acl_mask;
struct acl_mailbox_list_context *nonowner_list_ctx;
- struct imap_match_glob *glob;
struct mail_namespace *ns = ctx->ctx.list->ns;
+ struct mailbox_list_iter_update_context update_ctx;
const char *name;
string_t *vname;
char sep;
int try, ret;
- if ((ctx->ctx.flags & MAILBOX_LIST_ITER_RAW_LIST) != 0)
- return FALSE;
+ if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_RAW_LIST |
+ MAILBOX_LIST_ITER_SELECT_SUBSCRIBED)) != 0)
+ return;
if (acl_backend_get_default_rights(backend, &acl_mask) < 0 ||
acl_cache_mask_isset(acl_mask, *idxp))
- return FALSE;
+ return;
/* default is to not list mailboxes. we can optimize this. */
if ((ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0) {
@@ -95,13 +95,19 @@ acl_mailbox_try_list_fast(struct acl_mai
sep = ns->real_sep;
vname = NULL;
}
- glob = imap_match_init_multiple(pool_datastack_create(), patterns,
- TRUE, sep);
+
+ memset(&update_ctx, 0, sizeof(update_ctx));
+ update_ctx.iter_ctx = &ctx->ctx;
+ update_ctx.glob =
+ imap_match_init_multiple(pool_datastack_create(), patterns,
+ TRUE, sep);;
+ update_ctx.match_parents = TRUE;
for (try = 0; try < 2; try++) {
nonowner_list_ctx =
acl_backend_nonowner_lookups_iter_init(backend);
ctx->tree = mailbox_tree_init(sep);
+ update_ctx.tree_ctx = ctx->tree;
while ((ret = acl_backend_nonowner_lookups_iter_next(
nonowner_list_ctx, &name)) > 0) {
@@ -109,8 +115,7 @@ acl_mailbox_try_list_fast(struct acl_mai
name = mail_namespace_get_vname(ns, vname,
name);
}
- mailbox_list_iter_update(&ctx->ctx, ctx->tree,
- glob, FALSE, TRUE, name);
+ mailbox_list_iter_update(&update_ctx, name);
}
acl_backend_nonowner_lookups_iter_deinit(&nonowner_list_ctx);
@@ -120,12 +125,6 @@ acl_mailbox_try_list_fast(struct acl_mai
/* try again */
mailbox_tree_deinit(&ctx->tree);
}
- if (ret < 0)
- return FALSE;
-
- ctx->tree_iter = mailbox_tree_iterate_init(ctx->tree, NULL,
- MAILBOX_FLAG_MATCHED);
- return TRUE;
}
static struct mailbox_list_iterate_context *
@@ -135,19 +134,16 @@ acl_mailbox_list_iter_init(struct mailbo
{
struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list);
struct acl_mailbox_list_iterate_context *ctx;
- bool ret;
ctx = i_new(struct acl_mailbox_list_iterate_context, 1);
ctx->ctx.list = list;
ctx->ctx.flags = flags;
T_BEGIN {
- ret = acl_mailbox_try_list_fast(ctx, patterns);
+ acl_mailbox_try_list_fast(ctx, patterns);
} T_END;
- if (!ret) {
- ctx->super_ctx = alist->module_ctx.super.
- iter_init(list, patterns, flags);
- }
+ ctx->super_ctx = alist->module_ctx.super.
+ iter_init(list, patterns, flags);
return &ctx->ctx;
}
@@ -155,16 +151,34 @@ acl_mailbox_list_iter_next_info(struct a
acl_mailbox_list_iter_next_info(struct acl_mailbox_list_iterate_context *ctx)
{
struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(ctx->ctx.list);
- struct mailbox_node *node;
-
- if (ctx->tree_iter == NULL)
- return alist->module_ctx.super.iter_next(ctx->super_ctx);
-
- node = mailbox_tree_iterate_next(ctx->tree_iter, &ctx->info.name);
- if (node == NULL)
- return NULL;
- ctx->info.flags = node->flags;
- return &ctx->info;
+ const struct mailbox_info *info;
+
+ do {
+ info = alist->module_ctx.super.iter_next(ctx->super_ctx);
+ if (info == NULL)
+ return NULL;
+ /* if the mailbox isn't in shared mailboxes list, it's not
+ visible to us. */
+ } while (ctx->tree != NULL &&
+ mailbox_tree_lookup(ctx->tree, info->name) == NULL);
+
+ return info;
+}
+
+static const char *
+acl_mailbox_list_iter_get_name(struct mailbox_list_iterate_context *ctx,
+ const char *name)
+{
+ struct mail_namespace *ns = ctx->list->ns;
+
+ if ((ctx->flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) == 0)
+ return name;
+
+ /* Mailbox names contain namespace prefix,
+ except when listing INBOX. */
+ if (strncmp(name, ns->prefix, ns->prefix_len) == 0)
+ name += ns->prefix_len;
+ return mail_namespace_fix_sep(ns, name);
}
static int
@@ -172,7 +186,6 @@ acl_mailbox_list_info_is_visible(struct
const struct mailbox_info *info)
{
struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(ctx->ctx.list);
- struct mail_namespace *ns = ctx->ctx.list->ns;
const char *acl_name;
int ret;
@@ -181,15 +194,7 @@ acl_mailbox_list_info_is_visible(struct
return 1;
}
- acl_name = info->name;
- if ((ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0) {
- /* Mailbox names contain namespace prefix,
- except when listing INBOX. */
- if (strncmp(acl_name, ns->prefix, ns->prefix_len) == 0)
- acl_name += ns->prefix_len;
- acl_name = mail_namespace_fix_sep(ns, acl_name);
- }
-
+ acl_name = acl_mailbox_list_iter_get_name(&ctx->ctx, info->name);
ret = acl_mailbox_list_have_right(alist, acl_name,
ACL_STORAGE_RIGHT_LOOKUP,
NULL);
@@ -234,6 +239,27 @@ acl_mailbox_list_iter_next(struct mailbo
}
static int
+acl_mailbox_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx,
+ const char *dir, const char *fname,
+ const char *mailbox_name,
+ enum mailbox_list_file_type type,
+ enum mailbox_info_flags *flags_r)
+{
+ struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(ctx->list);
+ int ret;
+
+ ret = alist->module_ctx.super.iter_is_mailbox(ctx, dir, fname,
+ mailbox_name,
+ type, flags_r);
+ if (ret <= 0 || (ctx->flags & MAILBOX_LIST_ITER_RAW_LIST) != 0)
+ return ret;
+
+ mailbox_name = acl_mailbox_list_iter_get_name(ctx, mailbox_name);
+ return acl_mailbox_list_have_right(alist, mailbox_name,
+ ACL_STORAGE_RIGHT_LOOKUP, NULL);
+}
+
+static int
acl_mailbox_list_iter_deinit(struct mailbox_list_iterate_context *_ctx)
{
struct acl_mailbox_list_iterate_context *ctx =
@@ -241,12 +267,8 @@ acl_mailbox_list_iter_deinit(struct mail
struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(_ctx->list);
int ret = ctx->ctx.failed ? -1 : 0;
- if (ctx->super_ctx != NULL) {
- if (alist->module_ctx.super.iter_deinit(ctx->super_ctx) < 0)
- ret = -1;
- }
- if (ctx->tree_iter != NULL)
- mailbox_tree_iterate_deinit(&ctx->tree_iter);
+ if (alist->module_ctx.super.iter_deinit(ctx->super_ctx) < 0)
+ ret = -1;
if (ctx->tree != NULL)
mailbox_tree_deinit(&ctx->tree);
@@ -430,6 +452,7 @@ void acl_mailbox_list_created(struct mai
list->v.iter_init = acl_mailbox_list_iter_init;
list->v.iter_next = acl_mailbox_list_iter_next;
list->v.iter_deinit = acl_mailbox_list_iter_deinit;
+ list->v.iter_is_mailbox = acl_mailbox_list_iter_is_mailbox;
list->v.get_mailbox_name_status = acl_get_mailbox_name_status;
list->v.delete_mailbox = acl_mailbox_list_delete;
list->v.rename_mailbox = acl_mailbox_list_rename;
More information about the dovecot-cvs
mailing list