dovecot-2.2: acl: Hide non-listable mailboxes from a shared subs...

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 22 03:40:27 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/1cf67db75455
changeset: 16810:1cf67db75455
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Sep 22 03:40:14 2013 +0300
description:
acl: Hide non-listable mailboxes from a shared subscriptions file.

diffstat:

 src/plugins/acl/acl-mailbox-list.c |  31 +++++++++++++++++++++++++++----
 1 files changed, 27 insertions(+), 4 deletions(-)

diffs (87 lines):

diff -r d400c1a673cf -r 1cf67db75455 src/plugins/acl/acl-mailbox-list.c
--- a/src/plugins/acl/acl-mailbox-list.c	Sun Sep 22 03:17:12 2013 +0300
+++ b/src/plugins/acl/acl-mailbox-list.c	Sun Sep 22 03:40:14 2013 +0300
@@ -22,6 +22,7 @@
 	struct mailbox_info info;
 
 	char sep;
+	unsigned int hide_nonlistable_subscriptions:1;
 	unsigned int simple_star_glob:1;
 };
 
@@ -172,6 +173,14 @@
 	ctx->ctx.list = list;
 	ctx->ctx.flags = flags;
 
+	if (list->ns->type != MAIL_NAMESPACE_TYPE_PRIVATE &&
+	    (list->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0) {
+		/* non-private namespace with subscriptions=yes. this could be
+		   a site-global subscriptions file, so hide subscriptions for
+		   mailboxes the user doesn't see. */
+		ctx->hide_nonlistable_subscriptions = TRUE;
+	}
+
 	inboxcase = (list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0;
 	ctx->sep = mail_namespace_get_sep(list->ns);
 	ctx->ctx.glob = imap_match_init_multiple(pool, patterns,
@@ -253,7 +262,7 @@
 
 static bool
 iter_mailbox_has_visible_children(struct acl_mailbox_list_iterate_context *ctx,
-				  bool only_nonpatterns)
+				  bool only_nonpatterns, bool subscribed)
 {
 	struct mailbox_list_iterate_context *iter;
 	const struct mailbox_info *info;
@@ -295,6 +304,8 @@
 	prefix_len = str_len(pattern) - 1;
 
 	iter = mailbox_list_iter_init(ctx->ctx.list, str_c(pattern),
+				      (!subscribed ? 0 :
+				       MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) |
 				      MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
 	while ((info = mailbox_list_iter_next(iter)) != NULL) {
 		if (only_nonpatterns &&
@@ -325,7 +336,8 @@
 	}
 
 	if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 &&
-	    (ctx->ctx.flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) != 0) {
+	    (ctx->ctx.flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) != 0 &&
+	    !ctx->hide_nonlistable_subscriptions) {
 		/* don't waste time doing an ACL check. we're going to list
 		   all subscriptions anyway. */
 		info->flags &= MAILBOX_SUBSCRIBED | MAILBOX_CHILD_SUBSCRIBED;
@@ -342,7 +354,7 @@
 			   children, but also don't return incorrect flags */
 			info->flags &= ~MAILBOX_CHILDREN;
 		} else if ((info->flags & MAILBOX_CHILDREN) != 0 &&
-			   !iter_mailbox_has_visible_children(ctx, FALSE)) {
+			   !iter_mailbox_has_visible_children(ctx, FALSE, FALSE)) {
 			info->flags &= ~MAILBOX_CHILDREN;
 			info->flags |= MAILBOX_NOCHILDREN;
 		}
@@ -357,11 +369,22 @@
 		i_assert((info->flags & PRESERVE_MAILBOX_FLAGS) != 0);
 		info->flags = MAILBOX_NONEXISTENT |
 			(info->flags & PRESERVE_MAILBOX_FLAGS);
+		if (ctx->hide_nonlistable_subscriptions) {
+			/* global subscriptions file. hide this entry if there
+			   are no visible subscribed children or if we're going
+			   to list the subscribed children anyway. */
+			if ((info->flags & MAILBOX_CHILD_SUBSCRIBED) == 0)
+				return 0;
+			if (iter_is_listing_all_children(ctx) ||
+			    !iter_mailbox_has_visible_children(ctx, TRUE, TRUE))
+				return 0;
+			/* e.g. LSUB "" % with visible subscribed children */
+		}
 		return 1;
 	}
 
 	if (!iter_is_listing_all_children(ctx) &&
-	    iter_mailbox_has_visible_children(ctx, TRUE)) {
+	    iter_mailbox_has_visible_children(ctx, TRUE, FALSE)) {
 		/* no child mailboxes match the list pattern(s), but mailbox
 		   has visible children. we'll need to show this as
 		   non-existent. */


More information about the dovecot-cvs mailing list