Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8450:f532e962f05d HEAD
acl: Don't break mailbox visibility checks if the name has "*" characters.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 19 Nov 2008 19:10:26 +0200 |
parents | 9dbb98d029e7 |
children | e14aabe52d8e |
files | src/plugins/acl/acl-mailbox-list.c |
diffstat | 1 files changed, 24 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/acl/acl-mailbox-list.c Wed Nov 19 19:04:55 2008 +0200 +++ b/src/plugins/acl/acl-mailbox-list.c Wed Nov 19 19:10:26 2008 +0200 @@ -217,8 +217,10 @@ struct mailbox_list_iterate_context *iter; const struct mailbox_info *info; enum mailbox_list_iter_flags flags; - const char *pattern; - bool ret = FALSE; + string_t *pattern; + const char *prefix; + unsigned int i, prefix_len; + bool stars = FALSE, ret = FALSE; /* do we have child mailboxes with LOOKUP right that don't match the list pattern? */ @@ -234,10 +236,26 @@ return FALSE; } - pattern = t_strdup_printf("%s%c*", ctx->info.name, ctx->sep); + /* if mailbox name has '*' characters in it, they'll conflict with the + LIST wildcard. replace then with '%' and verify later that all + results have the correct prefix. */ + pattern = t_str_new(128); + for (i = 0; ctx->info.name[i] != '\0'; i++) { + if (ctx->info.name[i] != '*') + str_append_c(pattern, ctx->info.name[i]); + else { + stars = TRUE; + str_append_c(pattern, '%'); + } + } + str_append_c(pattern, ctx->sep); + str_append_c(pattern, '*'); + prefix = str_c(pattern); + prefix_len = str_len(pattern) - 1; + flags = (ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - iter = mailbox_list_iter_init(ctx->ctx.list, pattern, flags); + iter = mailbox_list_iter_init(ctx->ctx.list, str_c(pattern), flags); while ((info = mailbox_list_iter_next(iter)) != NULL) { if (imap_match(ctx->glob, info->name) == IMAP_MATCH_YES) { /* at least one child matches also the original list @@ -245,7 +263,8 @@ ret = FALSE; break; } - ret = TRUE; + if (!stars || strncmp(info->name, prefix, prefix_len) == 0) + ret = TRUE; } (void)mailbox_list_iter_deinit(&iter); return ret;