changeset 12629:02370eda76f8

lib-storage: Mailbox virtual names are now in UTF-8 format, not IMAP mUTF-7. Plugins that use mailbox names in configuration now take them also as UTF-8 rather than mUTF-7.
author Timo Sirainen <tss@iki.fi>
date Tue, 01 Feb 2011 20:41:54 +0200
parents 49f487b435bd
children 82f984d7a241
files src/doveadm/doveadm-mail-fetch.c src/doveadm/doveadm-mail-mailbox-status.c src/doveadm/doveadm-mail-mailbox.c src/doveadm/doveadm-mail.c src/doveadm/doveadm-mail.h src/imap/cmd-list.c src/imap/cmd-subscribe.c src/imap/imap-commands-util.c src/imap/imap-fetch.c src/lda/main.c src/lib-lda/mail-deliver.c src/lib-storage/mail-search-register-human.c src/lib-storage/mail-search-register-imap.c src/lib-storage/mail-storage.c src/lib-storage/mailbox-list.c src/plugins/autocreate/autocreate-plugin.c src/plugins/snarf/snarf-plugin.c src/plugins/trash/trash-plugin.c src/plugins/virtual/virtual-config.c
diffstat 19 files changed, 157 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-mail-fetch.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/doveadm/doveadm-mail-fetch.c	Tue Feb 01 20:41:54 2011 +0200
@@ -6,7 +6,6 @@
 #include "ostream.h"
 #include "str.h"
 #include "message-size.h"
-#include "imap-utf7.h"
 #include "imap-util.h"
 #include "mail-user.h"
 #include "mail-storage.h"
@@ -47,17 +46,11 @@
 static int fetch_mailbox(struct fetch_cmd_context *ctx)
 {
 	const char *value;
-	string_t *str = t_str_new(128);
 
 	if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
 		return -1;
 
-	if (imap_utf7_to_utf8(value, str) == 0)
-		doveadm_print(str_c(str));
-	else {
-		/* not a valid mUTF-7 name, fallback to showing it as-is */
-		doveadm_print(value);
-	}
+	doveadm_print(value);
 	return 0;
 }
 
--- a/src/doveadm/doveadm-mail-mailbox-status.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/doveadm/doveadm-mail-mailbox-status.c	Tue Feb 01 20:41:54 2011 +0200
@@ -4,7 +4,6 @@
 #include "str.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
-#include "imap-utf7.h"
 #include "doveadm-print.h"
 #include "doveadm-mail.h"
 #include "doveadm-mail-list-iter.h"
@@ -80,16 +79,8 @@
 			  const struct mailbox_status *status,
 			  const struct mailbox_metadata *metadata)
 {
-	string_t *name;
-
-	if (box != NULL) {
-		name = t_str_new(128);
-		if (imap_utf7_to_utf8(mailbox_get_vname(box), name) < 0) {
-			str_truncate(name, 0);
-			str_append(name, mailbox_get_vname(box));
-		}
-		doveadm_print(str_c(name));
-	}
+	if (box != NULL)
+		doveadm_print(mailbox_get_vname(box));
 
 	if ((ctx->status_items & STATUS_MESSAGES) != 0)
 		doveadm_print_num(status->messages);
@@ -128,14 +119,8 @@
 	struct mailbox *box;
 	struct mailbox_status status;
 	struct mailbox_metadata metadata;
-	string_t *mailbox_name = t_str_new(128);
 
-	if (imap_utf7_to_utf8(info->name, mailbox_name) < 0) {
-		str_truncate(mailbox_name, 0);
-		str_append(mailbox_name, info->name);
-	}
-
-	box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, str_c(mailbox_name));
+	box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, info->name);
 	if (mailbox_get_status(box, ctx->status_items, &status) < 0 ||
 	    mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) {
 		ctx->ctx.failed = TRUE;
--- a/src/doveadm/doveadm-mail-mailbox.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/doveadm/doveadm-mail-mailbox.c	Tue Feb 01 20:41:54 2011 +0200
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "array.h"
 #include "str.h"
+#include "unichar.h"
 #include "imap-utf7.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
@@ -34,24 +35,14 @@
 	bool mutf7;
 };
 
-const char *const *doveadm_mailbox_args_to_mutf7(const char *const args[])
+void doveadm_mailbox_args_check(const char *const args[])
 {
-	ARRAY_TYPE(const_string) dest;
-	string_t *str;
-	const char *mutf7;
 	unsigned int i;
 
-	str = t_str_new(128);
-	t_array_init(&dest, 8);
 	for (i = 0; args[i] != NULL; i++) {
-		str_truncate(str, 0);
-		if (imap_utf8_to_utf7(args[i], str) < 0)
+		if (!uni_utf8_str_is_valid(args[i]))
 			i_fatal("Mailbox name not valid UTF-8: %s", args[i]);
-		mutf7 = t_strdup(str_c(str));
-		array_append(&dest, &mutf7, 1);
 	}
-	(void)array_append_space(&dest);
-	return array_idx(&dest, 0);
 }
 
 static bool cmd_mailbox_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
@@ -122,11 +113,14 @@
 	iter = doveadm_mail_list_iter_full_init(user, ctx->search_args,
 						iter_flags);
 	while ((info = doveadm_mail_list_iter_next(iter)) != NULL) {
-		str_truncate(str, 0);
-		if (ctx->mutf7 || imap_utf7_to_utf8(info->name, str) < 0)
+		if (!ctx->mutf7)
 			doveadm_print(info->name);
-		else
+		else {
+			str_truncate(str, 0);
+			if (imap_utf8_to_utf7(info->name, str) < 0)
+				i_unreached();
 			doveadm_print(str_c(str));
+		}
 	}
 	doveadm_mail_list_iter_deinit(&iter);
 }
@@ -138,7 +132,7 @@
 	struct mail_search_arg *arg;
 	unsigned int i;
 
-	args = doveadm_mailbox_args_to_mutf7(args);
+	doveadm_mailbox_args_check(args);
 	search_args = mail_search_build_init();
 	for (i = 0; args[i] != NULL; i++) {
 		arg = mail_search_build_add(search_args, SEARCH_MAILBOX_GLOB);
@@ -227,7 +221,7 @@
 
 	if (args[0] == NULL)
 		doveadm_mail_help_name("mailbox create");
-	args = doveadm_mailbox_args_to_mutf7(args);
+	doveadm_mailbox_args_check(args);
 
 	for (i = 0; args[i] != NULL; i++) {
 		name = p_strdup(ctx->ctx.ctx.pool, args[i]);
@@ -288,7 +282,7 @@
 
 	if (args[0] == NULL)
 		doveadm_mail_help_name("mailbox delete");
-	args = doveadm_mailbox_args_to_mutf7(args);
+	doveadm_mailbox_args_check(args);
 
 	for (i = 0; args[i] != NULL; i++) {
 		name = p_strdup(ctx->ctx.ctx.pool, args[i]);
@@ -352,7 +346,7 @@
 
 	if (str_array_length(args) != 2)
 		doveadm_mail_help_name("mailbox rename");
-	args = doveadm_mailbox_args_to_mutf7(args);
+	doveadm_mailbox_args_check(args);
 
 	ctx->oldname = p_strdup(ctx->ctx.ctx.pool, args[0]);
 	ctx->newname = p_strdup(ctx->ctx.ctx.pool, args[1]);
@@ -407,7 +401,7 @@
 				       "mailbox subscribe" :
 				       "mailbox unsubscribe");
 	}
-	args = doveadm_mailbox_args_to_mutf7(args);
+	doveadm_mailbox_args_check(args);
 
 	for (i = 0; args[i] != NULL; i++) {
 		name = p_strdup(ctx->ctx.ctx.pool, args[i]);
--- a/src/doveadm/doveadm-mail.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/doveadm/doveadm-mail.c	Tue Feb 01 20:41:54 2011 +0200
@@ -5,10 +5,10 @@
 #include "lib-signals.h"
 #include "ioloop.h"
 #include "str.h"
+#include "unichar.h"
 #include "module-dir.h"
 #include "wildcard-match.h"
 #include "master-service.h"
-#include "imap-utf7.h"
 #include "mail-user.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
@@ -75,12 +75,9 @@
 doveadm_mailbox_find(struct mail_user *user, const char *mailbox)
 {
 	struct mail_namespace *ns;
-	string_t *str;
 
-	str = t_str_new(128);
-	if (imap_utf8_to_utf7(mailbox, str) < 0)
+	if (!uni_utf8_str_is_valid(mailbox))
 		i_fatal("Mailbox name not valid UTF-8: %s", mailbox);
-	mailbox = str_c(str);
 
 	ns = mail_namespace_find(user->namespaces, mailbox);
 	if (ns == NULL)
--- a/src/doveadm/doveadm-mail.h	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/doveadm/doveadm-mail.h	Tue Feb 01 20:41:54 2011 +0200
@@ -95,7 +95,7 @@
 				  struct mailbox **box_r);
 struct mail_search_args *
 doveadm_mail_build_search_args(const char *const args[]);
-const char *const *doveadm_mailbox_args_to_mutf7(const char *const args[]);
+void doveadm_mailbox_args_check(const char *const args[]);
 struct mail_search_args *
 doveadm_mail_mailbox_search_args_build(const char *const args[]);
 
--- a/src/imap/cmd-list.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/imap/cmd-list.c	Tue Feb 01 20:41:54 2011 +0200
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "str.h"
 #include "strescape.h"
+#include "imap-utf7.h"
 #include "imap-quote.h"
 #include "imap-match.h"
 #include "imap-status.h"
@@ -383,11 +384,12 @@
 	const struct mailbox_info *info;
 	struct mail_namespace *ns;
 	enum mailbox_info_flags flags;
-	string_t *str;
+	string_t *str, *mutf7_name;
 	const char *name;
 	int ret = 0;
 
 	str = t_str_new(256);
+	mutf7_name = t_str_new(128);
 	while ((info = mailbox_list_iter_next(ctx->list_iter)) != NULL) {
 		name = info->name;
 		flags = info->flags;
@@ -438,6 +440,10 @@
 			continue;
 		}
 
+		str_truncate(mutf7_name, 0);
+		if (imap_utf8_to_utf7(name, mutf7_name) < 0)
+			i_panic("LIST: Mailbox name not UTF-8: %s", name);
+
 		str_truncate(str, 0);
 		str_printfa(str, "* %s (", ctx->lsub ? "LSUB" : "LIST");
 		mailbox_flags2str(ctx, str, flags);
@@ -445,7 +451,7 @@
 		list_reply_append_ns_sep_param(str,
 			mail_namespace_get_sep(ctx->ns));
 		str_append_c(str, ' ');
-		imap_quote_append_string(str, name, FALSE);
+		imap_quote_append_string(str, str_c(mutf7_name), FALSE);
 		mailbox_childinfo2str(ctx, str, flags);
 
 		ret = client_send_line(ctx->cmd->client, str_c(str));
--- a/src/imap/cmd-subscribe.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/imap/cmd-subscribe.c	Tue Feb 01 20:41:54 2011 +0200
@@ -1,6 +1,7 @@
 /* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
 
 #include "imap-common.h"
+#include "imap-utf7.h"
 #include "imap-commands.h"
 #include "mail-namespace.h"
 
@@ -22,12 +23,20 @@
 	return TRUE;
 }
 
+static bool str_ends_with_char(const char *str, char c)
+{
+	unsigned int len = strlen(str);
+
+	return len > 0 && str[len-1] == c;
+}
+
 bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe)
 {
 	struct mail_namespace *ns;
 	struct mailbox *box, *box2;
 	const char *mailbox, *orig_mailbox;
 	bool unsubscribed_mailbox2;
+	char sep;
 
 	/* <mailbox> */
 	if (!client_read_string_args(cmd, 1, &mailbox))
@@ -46,10 +55,14 @@
 		}
 	}
 
+	sep = mail_namespace_get_sep(ns);
 	unsubscribed_mailbox2 = FALSE;
-	if (!subscribe && mailbox != orig_mailbox) {
+	if (!subscribe &&
+	    str_ends_with_char(orig_mailbox, sep) &&
+	    !str_ends_with_char(mailbox, sep)) {
 		/* try to unsubscribe both "box" and "box/" */
-		box2 = mailbox_alloc(ns->list, orig_mailbox, 0);
+		const char *name2 = t_strdup_printf("%s%c", mailbox, sep);
+		box2 = mailbox_alloc(ns->list, name2, 0);
 		if (mailbox_set_subscribed(box2, FALSE) == 0)
 			unsubscribed_mailbox2 = TRUE;
 		mailbox_free(&box2);
--- a/src/imap/imap-commands-util.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/imap/imap-commands-util.c	Tue Feb 01 20:41:54 2011 +0200
@@ -8,6 +8,7 @@
 #include "imap-resp-code.h"
 #include "imap-parser.h"
 #include "imap-sync.h"
+#include "imap-utf7.h"
 #include "imap-util.h"
 #include "mail-storage.h"
 #include "mail-namespace.h"
@@ -19,6 +20,7 @@
 	struct mail_namespace *namespaces = cmd->client->user->namespaces;
 	struct mail_namespace *ns;
 	unsigned int name_len;
+	string_t *utf8_name;
 
 	ns = mail_namespace_find(namespaces, *mailbox);
 	if (ns == NULL) {
@@ -37,6 +39,13 @@
 		/* drop the extra trailing hierarchy separator */
 		*mailbox = t_strndup(*mailbox, name_len-1);
 	}
+
+	utf8_name = t_str_new(64);
+	if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) {
+		client_send_tagline(cmd, "NO Mailbox name is not valid mUTF-7");
+		return NULL;
+	}
+	*mailbox = str_c(utf8_name);
 	return ns;
 }
 
--- a/src/imap/imap-fetch.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/imap/imap-fetch.c	Tue Feb 01 20:41:54 2011 +0200
@@ -9,6 +9,7 @@
 #include "message-send.h"
 #include "message-size.h"
 #include "imap-date.h"
+#include "imap-utf7.h"
 #include "mail-search-build.h"
 #include "imap-commands.h"
 #include "imap-quote.h"
@@ -797,12 +798,18 @@
 static int fetch_x_mailbox(struct imap_fetch_context *ctx, struct mail *mail,
 			   void *context ATTR_UNUSED)
 {
-	const char *str;
+	const char *name;
+	string_t *mutf7_name;
+
+	if (mail_get_special(mail, MAIL_FETCH_MAILBOX_NAME, &name) < 0)
+		i_panic("mailbox name not returned");
 
-	if (mail_get_special(mail, MAIL_FETCH_MAILBOX_NAME, &str) < 0)
-		i_panic("mailbox name not returned");
+	mutf7_name = t_str_new(strlen(name)*2);
+	if (imap_utf8_to_utf7(name, mutf7_name) < 0)
+		i_panic("FETCH: Mailbox name not UTF-8: %s", name);
+
 	str_append(ctx->cur_str, "X-MAILBOX ");
-	imap_quote_append_string(ctx->cur_str, str, FALSE);
+	imap_quote_append_string(ctx->cur_str, str_c(mutf7_name), FALSE);
 	str_append_c(ctx->cur_str, ' ');
 	return 1;
 }
--- a/src/lda/main.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/lda/main.c	Tue Feb 01 20:41:54 2011 +0200
@@ -17,7 +17,6 @@
 #include "unichar.h"
 #include "rfc822-parser.h"
 #include "message-address.h"
-#include "imap-utf7.h"
 #include "settings-parser.h"
 #include "master-service.h"
 #include "master-service-settings.h"
--- a/src/lib-lda/mail-deliver.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/lib-lda/mail-deliver.c	Tue Feb 01 20:41:54 2011 +0200
@@ -5,9 +5,9 @@
 #include "array.h"
 #include "str.h"
 #include "str-sanitize.h"
+#include "unichar.h"
 #include "var-expand.h"
 #include "message-address.h"
-#include "imap-utf7.h"
 #include "lda-settings.h"
 #include "mail-storage.h"
 #include "mail-namespace.h"
@@ -116,16 +116,6 @@
 	va_end(args);
 }
 
-static const char *mailbox_name_to_mutf7(const char *mailbox_utf8)
-{
-	string_t *str = t_str_new(128);
-
-	if (imap_utf8_to_utf7(mailbox_utf8, str) < 0)
-		return mailbox_utf8;
-	else
-		return str_c(str);
-}
-
 int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
 			   const char *name, struct mailbox **box_r,
 			   enum mail_error *error_r, const char **error_str_r)
@@ -140,7 +130,12 @@
 	*error_r = MAIL_ERROR_NONE;
 	*error_str_r = NULL;
 
-	name = mailbox_name_to_mutf7(name);
+	if (!uni_utf8_str_is_valid(name)) {
+		*error_str_r = "Mailbox name not valid UTF-8";
+		*error_r = MAIL_ERROR_PARAMS;
+		return -1;
+	}
+
 	ns = mail_namespace_find(ctx->user->namespaces, name);
 	if (ns == NULL) {
 		*error_str_r = "Unknown namespace";
--- a/src/lib-storage/mail-search-register-human.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/lib-storage/mail-search-register-human.c	Tue Feb 01 20:41:54 2011 +0200
@@ -4,7 +4,7 @@
 #include "ioloop.h"
 #include "array.h"
 #include "str.h"
-#include "imap-utf7.h"
+#include "unichar.h"
 #include "settings-parser.h"
 #include "imap-date.h"
 #include "mail-search-register.h"
@@ -135,25 +135,15 @@
 human_search_mailbox(struct mail_search_build_context *ctx)
 {
 	struct mail_search_arg *sarg;
-	const char *value;
 
 	sarg = mail_search_build_str(ctx, SEARCH_MAILBOX_GLOB);
 	if (sarg == NULL)
 		return NULL;
 
-	value = sarg->value.str;
-
-	T_BEGIN {
-		string_t *str = t_str_new(128);
-
-		if (imap_utf8_to_utf7(value, str) < 0)
-			sarg->value.str = NULL;
-		else
-			sarg->value.str = p_strdup(ctx->pool, str_c(str));
-	} T_END;
-	if (sarg->value.str == NULL) {
+	if (!uni_utf8_str_is_valid(sarg->value.str)) {
 		ctx->_error = p_strconcat(ctx->pool,
-			"Mailbox name not valid UTF-8: ", value, NULL);
+			"Mailbox name not valid UTF-8: ",
+			sarg->value.str, NULL);
 		return NULL;
 	}
 	return sarg;
--- a/src/lib-storage/mail-search-register-imap.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/lib-storage/mail-search-register-imap.c	Tue Feb 01 20:41:54 2011 +0200
@@ -3,8 +3,10 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "array.h"
+#include "str.h"
 #include "imap-date.h"
 #include "imap-seqset.h"
+#include "imap-utf7.h"
 #include "imap-util.h"
 #include "mail-search-register.h"
 #include "mail-search-parser.h"
@@ -430,7 +432,25 @@
 }
 
 CALLBACK_STR(x_guid, SEARCH_GUID);
-CALLBACK_STR(x_mailbox, SEARCH_MAILBOX_GLOB);
+
+static struct mail_search_arg *
+imap_search_x_mailbox(struct mail_search_build_context *ctx)
+{
+	struct mail_search_arg *sarg;
+	string_t *utf8_name;
+
+	sarg = mail_search_build_str(ctx, SEARCH_MAILBOX_GLOB);
+	if (sarg == NULL)
+		return NULL;
+
+	utf8_name = t_str_new(strlen(sarg->value.str));
+	if (imap_utf7_to_utf8(sarg->value.str, utf8_name) < 0) {
+		ctx->_error = "X-MAILBOX name not mUTF-7";
+		return NULL;
+	}
+	sarg->value.str = p_strdup(ctx->pool, str_c(utf8_name));
+	return sarg;
+}
 
 const struct mail_search_register_arg imap_register_args[] = {
 	/* argument set operations */
--- a/src/lib-storage/mail-storage.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/lib-storage/mail-storage.c	Tue Feb 01 20:41:54 2011 +0200
@@ -4,6 +4,7 @@
 #include "ioloop.h"
 #include "array.h"
 #include "llist.h"
+#include "unichar.h"
 #include "istream.h"
 #include "eacces-error.h"
 #include "mkdir-parents.h"
@@ -570,6 +571,8 @@
 	struct mail_storage *storage;
 	struct mailbox *box;
 
+	i_assert(uni_utf8_str_is_valid(vname));
+
 	if (mailbox_list_get_storage(&new_list, vname, &storage) < 0) {
 		/* just use the first storage. FIXME: does this break? */
 		storage = list->ns->storage;
--- a/src/lib-storage/mailbox-list.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/lib-storage/mailbox-list.c	Tue Feb 01 20:41:54 2011 +0200
@@ -350,37 +350,45 @@
 {
 	struct mail_namespace *ns = list->ns;
 	unsigned int prefix_len = strlen(ns->prefix);
+	const char *storage_name = vname;
+	string_t *str;
 	char list_sep, ns_sep, *ret, *p;
 
-	if (strcasecmp(vname, "INBOX") == 0)
-		vname = "INBOX";
+	if (strcasecmp(storage_name, "INBOX") == 0)
+		storage_name = "INBOX";
 
 	if (prefix_len > 0) {
 		/* skip namespace prefix, except if this is INBOX */
-		if (strncmp(ns->prefix, vname, prefix_len) == 0)
-			vname += prefix_len;
-		else if (strncmp(ns->prefix, vname, prefix_len-1) == 0 &&
+		if (strncmp(ns->prefix, storage_name, prefix_len) == 0)
+			storage_name += prefix_len;
+		else if (strncmp(ns->prefix, storage_name, prefix_len-1) == 0 &&
 			 ns->prefix[prefix_len-1] == mail_namespace_get_sep(ns)) {
 			/* trying to access the namespace prefix itself */
-			vname = "";
+			storage_name = "";
 		} else {
-			i_assert(strcmp(vname, "INBOX") == 0);
+			i_assert(strcmp(storage_name, "INBOX") == 0);
 		}
 	}
 
+	/* UTF-8 -> mUTF-7 conversion */
+	str = t_str_new(strlen(storage_name)*2);
+	if (imap_utf8_to_utf7(storage_name, str) < 0)
+		i_panic("Mailbox name not UTF-8: %s", vname);
+	storage_name = str_c(str);
+
 	list_sep = mailbox_list_get_hierarchy_sep(list);
 	ns_sep = mail_namespace_get_sep(ns);
 
 	if (list_sep == ns_sep)
-		return vname;
+		return storage_name;
 	if (ns->type == NAMESPACE_SHARED &&
 	    (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) {
 		/* shared namespace root. the backend storage's hierarchy
 		   separator isn't known yet, so do nothing. */
-		return vname;
+		return storage_name;
 	}
 
-	ret = p_strdup(unsafe_data_stack_pool, vname);
+	ret = p_strdup(unsafe_data_stack_pool, storage_name);
 	for (p = ret; *p != '\0'; p++) {
 		if (*p == ns_sep)
 			*p = list_sep;
@@ -398,15 +406,16 @@
 					   const char *storage_name)
 {
 	unsigned int i, prefix_len, name_len;
+	const char *vname = storage_name;
 	char list_sep, ns_sep, *ret;
 
 	if ((list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 &&
-	    strcasecmp(storage_name, "INBOX") == 0 &&
+	    strcasecmp(vname, "INBOX") == 0 &&
 	    list->ns->user == list->ns->owner) {
 		/* user's INBOX - use as-is */
 		return "INBOX";
 	}
-	if (*storage_name == '\0') {
+	if (*vname == '\0') {
 		/* return namespace prefix without the separator */
 		if (list->ns->prefix_len == 0)
 			return list->ns->prefix;
@@ -414,6 +423,11 @@
 			return t_strndup(list->ns->prefix,
 					 list->ns->prefix_len - 1);
 		}
+	} else {
+		/* mUTF-7 -> UTF-8 conversion */
+		string_t *str = t_str_new(strlen(vname));
+		if (imap_utf7_to_utf8(vname, str) == 0)
+			vname = str_c(str);
 	}
 
 	prefix_len = strlen(list->ns->prefix);
@@ -421,15 +435,15 @@
 	ns_sep = mail_namespace_get_sep(list->ns);
 
 	if (list_sep == ns_sep && prefix_len == 0)
-		return storage_name;
+		return vname;
 
 	/* @UNSAFE */
-	name_len = strlen(storage_name);
+	name_len = strlen(vname);
 	ret = t_malloc(prefix_len + name_len + 1);
 	memcpy(ret, list->ns->prefix, prefix_len);
 	for (i = 0; i < name_len; i++) {
-		ret[i + prefix_len] = storage_name[i] == list_sep ? ns_sep :
-			storage_name[i];
+		ret[i + prefix_len] =
+			vname[i] == list_sep ? ns_sep : vname[i];
 	}
 	ret[i + prefix_len] = '\0';
 	return ret;
--- a/src/plugins/autocreate/autocreate-plugin.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/plugins/autocreate/autocreate-plugin.c	Tue Feb 01 20:41:54 2011 +0200
@@ -1,6 +1,7 @@
 /* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "unichar.h"
 #include "mail-storage.h"
 #include "mail-storage-hooks.h"
 #include "mail-namespace.h"
@@ -18,6 +19,11 @@
 	const char *str;
 	enum mail_error error;
 
+	if (!uni_utf8_str_is_valid(name)) {
+		i_error("autocreate: Mailbox name isn't valid UTF-8: %s", name);
+		return;
+	}
+
 	ns = mail_namespace_find(namespaces, name);
 	if (ns == NULL) {
 		if (namespaces->mail_set->mail_debug)
@@ -61,6 +67,11 @@
 	const char *str;
 	enum mail_error error;
 
+	if (!uni_utf8_str_is_valid(name)) {
+		i_error("autocreate: Mailbox name isn't valid UTF-8: %s", name);
+		return;
+	}
+
 	ns = mail_namespace_find_subscribable(namespaces, name);
 	if (ns == NULL) {
 		if (namespaces->mail_set->mail_debug)
--- a/src/plugins/snarf/snarf-plugin.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/plugins/snarf/snarf-plugin.c	Tue Feb 01 20:41:54 2011 +0200
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "unichar.h"
 #include "mail-namespace.h"
 #include "mail-search-build.h"
 #include "mail-storage-private.h"
@@ -124,6 +125,10 @@
 	snarf_name = mail_user_plugin_getenv(user, "snarf");
 	if (snarf_name == NULL)
 		return FALSE;
+	if (!uni_utf8_str_is_valid(snarf_name)) {
+		i_error("snarf: Mailbox name not UTF-8: %s", snarf_name);
+		return FALSE;
+	}
 
 	snarf_ns = mail_namespace_find(user->namespaces, snarf_name);
 	if (snarf_ns == NULL) {
--- a/src/plugins/trash/trash-plugin.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/plugins/trash/trash-plugin.c	Tue Feb 01 20:41:54 2011 +0200
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "unichar.h"
 #include "istream.h"
 #include "mail-namespace.h"
 #include "mail-search-build.h"
@@ -273,6 +274,11 @@
 			ret = -1;
 		}
 
+		if (!uni_utf8_str_is_valid(trash->name)) {
+			i_error("trash: Mailbox name not UTF-8: %s",
+				trash->name);
+			ret = -1;
+		}
 		if (!trash_find_storage(user, trash)) {
 			i_error("trash: Namespace not found for mailbox '%s'",
 				trash->name);
--- a/src/plugins/virtual/virtual-config.c	Tue Feb 01 20:37:17 2011 +0200
+++ b/src/plugins/virtual/virtual-config.c	Tue Feb 01 20:41:54 2011 +0200
@@ -5,6 +5,7 @@
 #include "crc32.h"
 #include "istream.h"
 #include "str.h"
+#include "unichar.h"
 #include "imap-parser.h"
 #include "imap-match.h"
 #include "mail-namespace.h"
@@ -136,6 +137,11 @@
 	bbox->ns = strcasecmp(line, "INBOX") == 0 ?
 		mail_namespace_find_inbox(user->namespaces) :
 		mail_namespace_find(user->namespaces, line);
+	if (!uni_utf8_str_is_valid(bbox->name)) {
+		*error_r = t_strdup_printf("Mailbox name not UTF-8: %s",
+					   bbox->name);
+		return -1;
+	}
 	if (bbox->ns == NULL) {
 		*error_r = t_strdup_printf("Namespace not found for %s",
 					   bbox->name);