Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8081:0d5fba71cb93 HEAD
virtual mailboxes: Detect loops in virtual mailbox definitions.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 08 Aug 2008 17:16:07 -0400 |
parents | 3aec087609f0 |
children | db66611fd195 |
files | src/plugins/virtual/virtual-storage.c src/plugins/virtual/virtual-storage.h |
diffstat | 2 files changed, 40 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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;
--- 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 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 {