dovecot-1.2: virtual mailboxes: Detect loops in virtual mailbox ...

dovecot at dovecot.org dovecot at dovecot.org
Sat Aug 9 00:16:14 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/0d5fba71cb93
changeset: 8081:0d5fba71cb93
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Aug 08 17:16:07 2008 -0400
description:
virtual mailboxes: Detect loops in virtual mailbox definitions.

diffstat:

2 files changed, 40 insertions(+), 5 deletions(-)
src/plugins/virtual/virtual-storage.c |   41 ++++++++++++++++++++++++++++-----
src/plugins/virtual/virtual-storage.h |    4 +++

diffs (94 lines):

diff -r 3aec087609f0 -r 0d5fba71cb93 src/plugins/virtual/virtual-storage.c
--- a/src/plugins/virtual/virtual-storage.c	Fri Aug 08 16:50:39 2008 -0400
+++ b/src/plugins/virtual/virtual-storage.c	Fri Aug 08 17:16:07 2008 -0400
@@ -72,6 +72,7 @@ static struct mail_storage *virtual_allo
 	storage = p_new(pool, struct virtual_storage, 1);
 	storage->storage = virtual_storage;
 	storage->storage.pool = pool;
+	p_array_init(&storage->open_stack, pool, 8);
 
 	return &storage->storage;
 }
@@ -151,6 +152,20 @@ virtual_backend_box_lookup(struct virtua
 	return NULL;
 }
 
+static bool virtual_mailbox_is_in_open_stack(struct virtual_storage *storage,
+					     const char *name)
+{
+	const char *const *names;
+	unsigned int i, count;
+
+	names = array_get(&storage->open_stack, &count);
+	for (i = 0; i < count; i++) {
+		if (strcmp(names[i], name) == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
 static int virtual_mailboxes_open(struct virtual_mailbox *mbox,
 				  enum mailbox_open_flags open_flags)
 {
@@ -168,10 +183,15 @@ static int virtual_mailboxes_open(struct
 		ns = mail_namespace_find(virtual_all_namespaces, &mailbox);
 		bboxes[i]->box = mailbox_open(ns->storage, mailbox,
 					      NULL, open_flags);
+
 		if (bboxes[i]->box == NULL) {
-			str = mail_storage_get_last_error(ns->storage, &error);
-			mail_storage_set_error(mbox->ibox.box.storage,
-					       error, str);
+			if (ns->storage != mbox->ibox.box.storage) {
+				/* copy the error */
+				str = mail_storage_get_last_error(ns->storage,
+								  &error);
+				mail_storage_set_error(mbox->ibox.box.storage,
+						       error, str);
+			}
 			break;
 		}
 		i_array_init(&bboxes[i]->uids, 64);
@@ -198,6 +218,13 @@ virtual_open(struct virtual_storage *sto
 	struct mail_index *index;
 	const char *path;
 	pool_t pool;
+	bool failed;
+
+	if (virtual_mailbox_is_in_open_stack(storage, name)) {
+		mail_storage_set_critical(_storage,
+					  "Virtual mailbox loops: %s", name);
+		return NULL;
+	}
 
 	path = mailbox_list_get_path(_storage->list, name,
 				     MAILBOX_LIST_PATH_TYPE_MAILBOX);
@@ -223,8 +250,12 @@ virtual_open(struct virtual_storage *sto
 			sizeof(struct virtual_mail_index_record),
 			sizeof(uint32_t));
 
-	if (virtual_config_read(mbox) < 0 ||
-	    virtual_mailboxes_open(mbox, flags) < 0) {
+	array_append(&storage->open_stack, &name, 1);
+	failed = virtual_config_read(mbox) < 0 ||
+		virtual_mailboxes_open(mbox, flags) < 0;
+	array_delete(&storage->open_stack,
+		     array_count(&storage->open_stack)-1, 1);
+	if (failed) {
 		virtual_config_free(mbox);
 		pool_unref(&pool);
 		return NULL;
diff -r 3aec087609f0 -r 0d5fba71cb93 src/plugins/virtual/virtual-storage.h
--- a/src/plugins/virtual/virtual-storage.h	Fri Aug 08 16:50:39 2008 -0400
+++ b/src/plugins/virtual/virtual-storage.h	Fri Aug 08 17:16:07 2008 -0400
@@ -43,6 +43,10 @@ struct virtual_storage {
 struct virtual_storage {
 	struct mail_storage storage;
 	union mailbox_list_module_context list_module_ctx;
+
+	/* List of mailboxes while a virtual mailbox is being opened.
+	   Used to track loops. */
+	ARRAY_TYPE(const_string) open_stack;
 };
 
 struct virtual_backend_uidmap {


More information about the dovecot-cvs mailing list