From 52c305a3c71f66f26742c764eb8fc79f70b07f6e Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 28 Oct 2014 00:54:15 +0100 Subject: [PATCH] doveadm-sieve: Fixed timeout leaks occuring while running doveadm. This was caused by a circular reference. --- src/lib-sieve/sieve-script.c | 6 +- src/lib-sieve/sieve-storage-private.h | 12 +-- src/lib-sieve/sieve-storage-sync.c | 148 +++++++++++++++----------- src/lib-sieve/sieve-storage.c | 6 +- 4 files changed, 99 insertions(+), 73 deletions(-) diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index 3af517002..d8bebacc2 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -478,7 +478,7 @@ int sieve_script_rename /* rename INBOX mailbox attribute */ if ( ret >= 0 && oldname != NULL ) - sieve_storage_sync_script_rename(storage, oldname, newname); + (void)sieve_storage_sync_script_rename(storage, oldname, newname); return ret; } @@ -504,7 +504,7 @@ int sieve_script_delete(struct sieve_script **_script) /* unset INBOX mailbox attribute */ if ( ret >= 0 ) - sieve_storage_sync_script_delete(storage, script->name); + (void)sieve_storage_sync_script_delete(storage, script->name); /* Always deinitialize the script object */ sieve_script_unref(_script); @@ -531,7 +531,7 @@ int sieve_script_activate(struct sieve_script *script, time_t mtime) if (ret >= 0) { sieve_storage_set_modified(storage, mtime); - sieve_storage_sync_script_activate(storage); + (void)sieve_storage_sync_script_activate(storage); } return ret; diff --git a/src/lib-sieve/sieve-storage-private.h b/src/lib-sieve/sieve-storage-private.h index d032c7f2c..78e65ee5a 100644 --- a/src/lib-sieve/sieve-storage-private.h +++ b/src/lib-sieve/sieve-storage-private.h @@ -109,7 +109,7 @@ struct sieve_storage { const char *script_name; const char *bin_dir; - struct mailbox *sync_inbox; + struct mail_namespace *sync_inbox_ns; enum sieve_storage_flags flags; @@ -235,17 +235,17 @@ int sieve_storage_sync_init void sieve_storage_sync_deinit (struct sieve_storage *storage); -void sieve_storage_sync_script_save +int sieve_storage_sync_script_save (struct sieve_storage *storage, const char *name); -void sieve_storage_sync_script_rename +int sieve_storage_sync_script_rename (struct sieve_storage *storage, const char *oldname, const char *newname); -void sieve_storage_sync_script_delete +int sieve_storage_sync_script_delete (struct sieve_storage *storage, const char *name); -void sieve_storage_sync_script_activate +int sieve_storage_sync_script_activate (struct sieve_storage *storage); -void sieve_storage_sync_deactivate +int sieve_storage_sync_deactivate (struct sieve_storage *storage); diff --git a/src/lib-sieve/sieve-storage-sync.c b/src/lib-sieve/sieve-storage-sync.c index 6b0c8cd1d..37b24a38f 100644 --- a/src/lib-sieve/sieve-storage-sync.c +++ b/src/lib-sieve/sieve-storage-sync.c @@ -24,11 +24,7 @@ int sieve_storage_sync_init (struct sieve_storage *storage, struct mail_user *user) { - struct mail_namespace *ns; - struct mailbox *box; enum sieve_storage_flags sflags = storage->flags; - enum mailbox_flags mflags = MAILBOX_FLAG_IGNORE_ACLS; - enum mail_error error; if ( (sflags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 && (sflags & SIEVE_STORAGE_FLAG_READWRITE) == 0 ) @@ -41,126 +37,156 @@ int sieve_storage_sync_init } sieve_storage_sys_debug(storage, "sync: " - "Opening INBOX for attribute modifications"); - - ns = mail_namespace_find_inbox(user->namespaces); - storage->sync_inbox = box = mailbox_alloc(ns->list, "INBOX", mflags); - if (mailbox_open(box) == 0) - return 0; + "Synchronization active"); - sieve_storage_sys_warning(storage, "sync: " - "Failed to open user INBOX for attribute modifications: %s", - mailbox_get_last_error(box, &error)); - return -1; + storage->sync_inbox_ns = mail_namespace_find_inbox(user->namespaces); + return 0; } void sieve_storage_sync_deinit -(struct sieve_storage *storage) +(struct sieve_storage *storage ATTR_UNUSED) { - if (storage->sync_inbox != NULL) - mailbox_free(&storage->sync_inbox); + /* nothing */ } /* * Sync attributes */ -static void sieve_storage_sync_transaction_finish -(struct sieve_storage *storage, struct mailbox_transaction_context **t) +static int sieve_storage_sync_transaction_begin +(struct sieve_storage *storage, struct mailbox_transaction_context **trans_r) { - struct mailbox *inbox = storage->sync_inbox; + enum mailbox_flags mflags = MAILBOX_FLAG_IGNORE_ACLS; + struct mail_namespace *ns = storage->sync_inbox_ns; + struct mailbox *inbox; + enum mail_error error; - i_assert( storage->sync_inbox != NULL ); + if (ns == NULL) + return 0; + + inbox = mailbox_alloc(ns->list, "INBOX", mflags); + if (mailbox_open(inbox) < 0) { + sieve_storage_sys_warning(storage, "sync: " + "Failed to open user INBOX for attribute modifications: %s", + mailbox_get_last_error(inbox, &error)); + return -1; + } + + *trans_r = mailbox_transaction_begin(inbox, 0); + return 1; +} - if (mailbox_transaction_commit(t) < 0) { +static int sieve_storage_sync_transaction_finish +(struct sieve_storage *storage, struct mailbox_transaction_context **trans) +{ + struct mailbox *inbox; + int ret; + + inbox = mailbox_transaction_get_mailbox(*trans); + + if ((ret=mailbox_transaction_commit(trans)) < 0) { enum mail_error error; sieve_storage_sys_warning(storage, "sync: " "Failed to update INBOX attributes: %s", mail_storage_get_last_error(mailbox_get_storage(inbox), &error)); } + + mailbox_free(&inbox); + return ret; } -void sieve_storage_sync_script_save +int sieve_storage_sync_script_save (struct sieve_storage *storage, const char *name) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; const char *key; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; key = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL); - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_set(t->itrans, TRUE, key, ioloop_time, 0); - sieve_storage_sync_transaction_finish(storage, &t); + + mail_index_attribute_set(trans->itrans, TRUE, key, ioloop_time, 0); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_script_rename +int sieve_storage_sync_script_rename (struct sieve_storage *storage, const char *oldname, const char *newname) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; const char *oldkey, *newkey; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; oldkey = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, oldname, NULL); newkey = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, newname, NULL); - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_unset(t->itrans, TRUE, oldkey, ioloop_time); - mail_index_attribute_set(t->itrans, TRUE, newkey, ioloop_time, 0); - sieve_storage_sync_transaction_finish(storage, &t); + mail_index_attribute_unset(trans->itrans, TRUE, oldkey, ioloop_time); + mail_index_attribute_set(trans->itrans, TRUE, newkey, ioloop_time, 0); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_script_delete +int sieve_storage_sync_script_delete (struct sieve_storage *storage, const char *name) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; const char *key; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; key = t_strconcat (MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL); - - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_unset(t->itrans, TRUE, key, ioloop_time); - sieve_storage_sync_transaction_finish(storage, &t); + + mail_index_attribute_unset(trans->itrans, TRUE, key, ioloop_time); + + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_script_activate +int sieve_storage_sync_script_activate (struct sieve_storage *storage) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; + int ret; + + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; - if (storage->sync_inbox == NULL) - return; + mail_index_attribute_set(trans->itrans, + TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time, 0); - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_set - (t->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time, 0); - sieve_storage_sync_transaction_finish(storage, &t); + return sieve_storage_sync_transaction_finish(storage, &trans); } -void sieve_storage_sync_deactivate +int sieve_storage_sync_deactivate (struct sieve_storage *storage) { - struct mailbox_transaction_context *t; + struct mailbox_transaction_context *trans; + int ret; - if (storage->sync_inbox == NULL) - return; + if ((ret=sieve_storage_sync_transaction_begin + (storage, &trans)) <= 0) + return ret; - t = mailbox_transaction_begin(storage->sync_inbox, 0); - mail_index_attribute_unset - (t->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time); - sieve_storage_sync_transaction_finish(storage, &t); + mail_index_attribute_unset(trans->itrans, + TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time); + + return sieve_storage_sync_transaction_finish(storage, &trans); } diff --git a/src/lib-sieve/sieve-storage.c b/src/lib-sieve/sieve-storage.c index f61178761..c057f4af8 100644 --- a/src/lib-sieve/sieve-storage.c +++ b/src/lib-sieve/sieve-storage.c @@ -482,7 +482,7 @@ void sieve_storage_unref(struct sieve_storage **_storage) if (--storage->refcount != 0) return; - (void)sieve_storage_sync_deinit(storage); + sieve_storage_sync_deinit(storage); if ( storage->v.destroy != NULL ) storage->v.destroy(storage); @@ -673,7 +673,7 @@ int sieve_storage_deactivate if (ret >= 0) { sieve_storage_set_modified(storage, mtime); - sieve_storage_sync_deactivate(storage); + (void)sieve_storage_sync_deactivate(storage); } return ret; @@ -865,7 +865,7 @@ int sieve_storage_save_commit(struct sieve_storage_save_context **_sctx) /* set INBOX mailbox attribute */ if ( ret >= 0 ) - sieve_storage_sync_script_save(storage, scriptname); + (void)sieve_storage_sync_script_save(storage, scriptname); return ret; } -- GitLab