From dovecot at dovecot.org Thu Oct 1 09:28:31 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:28:31 +0000 Subject: dovecot-2.2: push-notification: Fix distinguishing between IMAP ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/39ae1789ba74 changeset: 19260:39ae1789ba74 user: Michael Slusarz date: Wed Sep 30 17:43:20 2015 -0600 description: push-notification: Fix distinguishing between IMAP APPEND and MTA deliveries diffstat: src/plugins/push-notification/push-notification-plugin.c | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diffs (32 lines): diff -r 2ceca0becf8e -r 39ae1789ba74 src/plugins/push-notification/push-notification-plugin.c --- a/src/plugins/push-notification/push-notification-plugin.c Wed Sep 30 18:50:09 2015 +0300 +++ b/src/plugins/push-notification/push-notification-plugin.c Wed Sep 30 17:43:20 2015 -0600 @@ -141,13 +141,13 @@ static void push_notification_mail_save(void *txn, struct mail *mail) { - struct push_notification_txn *ptxn = (struct push_notification_txn *)txn; + struct push_notification_txn *ptxn = txn; - /* External means a COPY or APPEND IMAP action. */ - if (ptxn->t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) { + /* POST_SESSION means MTA delivery. */ + if (mail->box->flags & MAILBOX_FLAG_POST_SESSION) { + push_notification_trigger_msg_save_new(ptxn, mail, NULL); + } else { push_notification_trigger_msg_save_append(ptxn, mail, NULL); - } else { - push_notification_trigger_msg_save_new(ptxn, mail, NULL); } } @@ -155,8 +155,7 @@ struct mail *src ATTR_UNUSED, struct mail *dest) { - push_notification_trigger_msg_save_append( - (struct push_notification_txn *)txn, dest, NULL); + push_notification_mail_save(txn, dest); } static void push_notification_mail_expunge(void *txn, struct mail *mail) From dovecot at dovecot.org Thu Oct 1 09:28:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:28:32 +0000 Subject: dovecot-2.2: push-notification: If other drivers triggered a non... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/160eae376b44 changeset: 19261:160eae376b44 user: Michael Slusarz date: Wed Sep 30 17:45:49 2015 -0600 description: push-notification: If other drivers triggered a non-MessageNew successful event, don't assert diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (20 lines): diff -r 39ae1789ba74 -r 160eae376b44 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Wed Sep 30 17:43:20 2015 -0600 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Wed Sep 30 17:45:49 2015 -0600 @@ -266,11 +266,13 @@ (struct push_notification_driver_ox_txn *)dtxn->context; struct mail_user *user = dtxn->ptxn->muser; + messagenew = push_notification_txn_msg_get_eventdata(msg, "MessageNew"); + if (messagenew == NULL) { + return; + } + push_notification_driver_ox_init_global(user); - messagenew = push_notification_txn_msg_get_eventdata(msg, "MessageNew"); - i_assert(messagenew != NULL); - http_req = http_client_request_url(ox_global->http_client, "PUT", dconfig->http_url, push_notification_driver_ox_http_callback, From dovecot at dovecot.org Thu Oct 1 09:28:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:28:32 +0000 Subject: dovecot-2.2: push-notification: Fix infinite recursive loop in O... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/fe5890ba0618 changeset: 19262:fe5890ba0618 user: Michael Slusarz date: Wed Sep 30 17:49:24 2015 -0600 description: push-notification: Fix infinite recursive loop in OX driver diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 27 ++++++++---- 1 files changed, 18 insertions(+), 9 deletions(-) diffs (55 lines): diff -r 160eae376b44 -r fe5890ba0618 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Wed Sep 30 17:45:49 2015 -0600 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Wed Sep 30 17:49:24 2015 -0600 @@ -101,18 +101,25 @@ struct mailbox *inbox; struct mailbox_transaction_context *mctx = NULL; struct mail_namespace *ns; - bool success = FALSE; + bool success = FALSE, use_existing_txn = FALSE; int ret; /* Get canonical INBOX, where private server-level metadata is stored. * See imap/cmd-getmetadata.c */ - ns = mail_namespace_find_inbox(dtxn->ptxn->muser->namespaces); - inbox = mailbox_alloc(ns->list, "INBOX", MAILBOX_FLAG_READONLY); - if (mailbox_open(inbox) < 0) { - i_error(OX_LOG_LABEL "Skipped because unable to open INBOX: %s", - mailbox_get_last_error(inbox, NULL)); + if ((dtxn->ptxn->t != NULL) && dtxn->ptxn->mbox->inbox_user) { + /* Use the currently open transaction. */ + inbox = dtxn->ptxn->mbox; + mctx = dtxn->ptxn->t; + use_existing_txn = TRUE; } else { - mctx = mailbox_transaction_begin(inbox, 0); + ns = mail_namespace_find_inbox(dtxn->ptxn->muser->namespaces); + inbox = mailbox_alloc(ns->list, "INBOX", MAILBOX_FLAG_READONLY); + if (mailbox_open(inbox) < 0) { + i_error(OX_LOG_LABEL "Skipped because unable to open INBOX: %s", + mailbox_get_last_error(inbox, NULL)); + } else { + mctx = mailbox_transaction_begin(inbox, 0); + } } if (mctx != NULL) { @@ -128,14 +135,16 @@ success = TRUE; } - if (mailbox_transaction_commit(&mctx) < 0) { + if (!use_existing_txn && (mailbox_transaction_commit(&mctx) < 0)) { i_error(OX_LOG_LABEL "Transaction commit failed: %s", mailbox_get_last_error(inbox, NULL)); /* the commit doesn't matter though. */ } } - mailbox_free(&inbox); + if (!use_existing_txn) { + mailbox_free(&inbox); + } return (success == TRUE) ? attr.value : NULL; } From dovecot at dovecot.org Thu Oct 1 09:28:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:28:32 +0000 Subject: dovecot-2.2: push-notification: On-demand initialization of tran... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6f86db8428e6 changeset: 19263:6f86db8428e6 user: Michael Slusarz date: Wed Sep 30 17:59:07 2015 -0600 description: push-notification: On-demand initialization of transaction data diffstat: src/plugins/push-notification/push-notification-drivers.h | 1 + src/plugins/push-notification/push-notification-plugin.c | 81 +++++++++----- 2 files changed, 53 insertions(+), 29 deletions(-) diffs (153 lines): diff -r fe5890ba0618 -r 6f86db8428e6 src/plugins/push-notification/push-notification-drivers.h --- a/src/plugins/push-notification/push-notification-drivers.h Wed Sep 30 17:49:24 2015 -0600 +++ b/src/plugins/push-notification/push-notification-drivers.h Wed Sep 30 17:59:07 2015 -0600 @@ -85,6 +85,7 @@ struct mailbox *mbox; struct mail_user *muser; struct push_notification_user *puser; + bool initialized; enum push_notification_event_trigger trigger; struct push_notification_trigger_ctx *trigger_ctx; diff -r fe5890ba0618 -r 6f86db8428e6 src/plugins/push-notification/push-notification-plugin.c --- a/src/plugins/push-notification/push-notification-plugin.c Wed Sep 30 17:49:24 2015 -0600 +++ b/src/plugins/push-notification/push-notification-plugin.c Wed Sep 30 17:59:07 2015 -0600 @@ -29,12 +29,42 @@ static struct push_notification_user *puser = NULL; +static void +push_notification_transaction_init(struct push_notification_txn *ptxn) +{ + struct push_notification_driver_txn *dtxn; + struct push_notification_driver_user **duser; + struct mail_storage *storage; + + if (ptxn->initialized) { + return; + } + + ptxn->initialized = TRUE; + + storage = mailbox_get_storage(ptxn->mbox); + if (storage->user->autocreated && + (strcmp(storage->name, "raw") == 0)) { + /* no notifications for autocreated raw users */ + return; + } + + array_foreach_modifiable(&ptxn->puser->drivers, duser) { + dtxn = p_new(ptxn->pool, struct push_notification_driver_txn, 1); + dtxn->duser = *duser; + dtxn->ptxn = ptxn; + + if ((dtxn->duser->driver->v.begin_txn == NULL) || + dtxn->duser->driver->v.begin_txn(dtxn)) { + array_append(&ptxn->drivers, &dtxn, 1); + } + } +} + static struct push_notification_txn * push_notification_transaction_create(struct mailbox *box, struct mailbox_transaction_context *t) { - struct push_notification_driver_txn *dtxn; - struct push_notification_driver_user **duser; pool_t pool; struct push_notification_txn *ptxn; struct mail_storage *storage; @@ -52,23 +82,6 @@ p_array_init(&ptxn->drivers, pool, 4); - if (storage->user->autocreated && - (strcmp(storage->name, "raw") == 0)) { - /* no notifications for autocreated raw users */ - return ptxn; - } - - array_foreach_modifiable(&ptxn->puser->drivers, duser) { - dtxn = p_new(pool, struct push_notification_driver_txn, 1); - dtxn->duser = *duser; - dtxn->ptxn = ptxn; - - if ((dtxn->duser->driver->v.begin_txn == NULL) || - dtxn->duser->driver->v.begin_txn(dtxn)) { - array_append(&ptxn->drivers, &dtxn, 1); - } - } - return ptxn; } @@ -77,9 +90,11 @@ { struct push_notification_driver_txn **dtxn; - array_foreach_modifiable(&ptxn->drivers, dtxn) { - if ((*dtxn)->duser->driver->v.end_txn != NULL) { - (*dtxn)->duser->driver->v.end_txn(*dtxn, success); + if (ptxn->initialized) { + array_foreach_modifiable(&ptxn->drivers, dtxn) { + if ((*dtxn)->duser->driver->v.end_txn != NULL) { + (*dtxn)->duser->driver->v.end_txn(*dtxn, success); + } } } @@ -143,6 +158,8 @@ { struct push_notification_txn *ptxn = txn; + push_notification_transaction_init(ptxn); + /* POST_SESSION means MTA delivery. */ if (mail->box->flags & MAILBOX_FLAG_POST_SESSION) { push_notification_trigger_msg_save_new(ptxn, mail, NULL); @@ -160,24 +177,30 @@ static void push_notification_mail_expunge(void *txn, struct mail *mail) { - push_notification_trigger_msg_save_expunge( - (struct push_notification_txn *)txn, mail, NULL); + struct push_notification_txn *ptxn = txn; + + push_notification_transaction_init(ptxn); + push_notification_trigger_msg_save_expunge(txn, mail, NULL); } static void push_notification_mail_update_flags(void *txn, struct mail *mail, enum mail_flags old_flags) { - push_notification_trigger_msg_flag_change( - (struct push_notification_txn *) txn, mail, NULL, old_flags); + struct push_notification_txn *ptxn = txn; + + push_notification_transaction_init(ptxn); + push_notification_trigger_msg_flag_change(txn, mail, NULL, old_flags); } static void push_notification_mail_update_keywords(void *txn, struct mail *mail, const char *const *old_keywords) { - push_notification_trigger_msg_keyword_change( - (struct push_notification_txn *) txn, mail, NULL, old_keywords); + struct push_notification_txn *ptxn = txn; + + push_notification_transaction_init(ptxn); + push_notification_trigger_msg_keyword_change(txn, mail, NULL, old_keywords); } static void * @@ -188,7 +211,7 @@ static void push_notification_transaction_rollback(void *txn) { - struct push_notification_txn *ptxn = (struct push_notification_txn *)txn; + struct push_notification_txn *ptxn = txn; push_notification_transaction_end(ptxn, FALSE); } From dovecot at dovecot.org Thu Oct 1 09:28:37 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:28:37 +0000 Subject: dovecot-2.2: push-notification: Improved struct naming of driver... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e309b27f02ea changeset: 19264:e309b27f02ea user: Michael Slusarz date: Wed Sep 30 18:22:52 2015 -0600 description: push-notification: Improved struct naming of driver list data diffstat: src/plugins/push-notification/push-notification-drivers.h | 8 +- src/plugins/push-notification/push-notification-plugin.c | 48 ++++++++------ 2 files changed, 32 insertions(+), 24 deletions(-) diffs (140 lines): diff -r 6f86db8428e6 -r e309b27f02ea src/plugins/push-notification/push-notification-drivers.h --- a/src/plugins/push-notification/push-notification-drivers.h Wed Sep 30 17:59:07 2015 -0600 +++ b/src/plugins/push-notification/push-notification-drivers.h Wed Sep 30 18:22:52 2015 -0600 @@ -68,10 +68,14 @@ void *context; }; +struct push_notification_driver_list { + ARRAY(struct push_notification_driver_user *) drivers; + pool_t pool; +}; + struct push_notification_user { union mail_user_module_context module_ctx; - ARRAY(struct push_notification_driver_user *) drivers; - pool_t pool; + struct push_notification_driver_list *driverlist; }; struct push_notification_trigger_ctx { diff -r 6f86db8428e6 -r e309b27f02ea src/plugins/push-notification/push-notification-plugin.c --- a/src/plugins/push-notification/push-notification-plugin.c Wed Sep 30 17:59:07 2015 -0600 +++ b/src/plugins/push-notification/push-notification-plugin.c Wed Sep 30 18:22:52 2015 -0600 @@ -26,7 +26,7 @@ &mail_user_module_register); -static struct push_notification_user *puser = NULL; +static struct push_notification_driver_list *dlist = NULL; static void @@ -49,7 +49,7 @@ return; } - array_foreach_modifiable(&ptxn->puser->drivers, duser) { + array_foreach_modifiable(&ptxn->puser->driverlist->drivers, duser) { dtxn = p_new(ptxn->pool, struct push_notification_driver_txn, 1); dtxn->duser = *duser; dtxn->ptxn = ptxn; @@ -217,9 +217,9 @@ } static void -push_notification_user_created_init_config(const char *config_name, +push_notification_config_init(const char *config_name, struct mail_user *user, - struct push_notification_user *puser) + struct push_notification_driver_list *dlist) { struct push_notification_driver_user *duser; const char *env; @@ -235,46 +235,50 @@ break; } - if (push_notification_driver_init(user, env, puser->pool, &duser) < 0) { + if (push_notification_driver_init(user, env, dlist->pool, &duser) < 0) { break; } // Add driver. - array_append(&puser->drivers, &duser, 1); + array_append(&dlist->drivers, &duser, 1); str_truncate(root_name, strlen(config_name)); str_printfa(root_name, "%d", i); } } -static void push_notification_user_created_init(struct mail_user *user) +static void push_notification_driver_list_init(struct mail_user *user) { pool_t pool; pool = pool_alloconly_create("push notification plugin", 1024); - puser = p_new(pool, struct push_notification_user, 1); - puser->pool = pool; + dlist = p_new(pool, struct push_notification_driver_list, 1); + dlist->pool = pool; - p_array_init(&puser->drivers, pool, 4); + p_array_init(&dlist->drivers, pool, 4); - push_notification_user_created_init_config(PUSH_NOTIFICATION_CONFIG, user, - puser); + push_notification_config_init(PUSH_NOTIFICATION_CONFIG, user, dlist); - if (array_is_empty(&puser->drivers)) { + if (array_is_empty(&dlist->drivers)) { /* Support old configuration (it was available at time initial OX - * driver was first released. */ - push_notification_user_created_init_config(PUSH_NOTIFICATION_CONFIG_OLD, - user, puser); + * driver was first released). */ + push_notification_config_init(PUSH_NOTIFICATION_CONFIG_OLD, user, + dlist); } } static void push_notification_user_created(struct mail_user *user) { - if (puser == NULL) { - push_notification_user_created_init(user); + struct push_notification_user *puser; + + if (dlist == NULL) { + push_notification_driver_list_init(user); } + puser = p_new(user->pool, struct push_notification_user, 1); + puser->driverlist = dlist; + MODULE_CONTEXT_SET(user, push_notification_user_module, puser); } @@ -326,8 +330,8 @@ { struct push_notification_driver_user **duser; - if (puser != NULL) { - array_foreach_modifiable(&puser->drivers, duser) { + if (dlist != NULL) { + array_foreach_modifiable(&dlist->drivers, duser) { if ((*duser)->driver->v.deinit != NULL) { (*duser)->driver->v.deinit(*duser); } @@ -337,8 +341,8 @@ } } - array_free(&puser->drivers); - pool_unref(&puser->pool); + array_free(&dlist->drivers); + pool_unref(&dlist->pool); } push_notification_driver_unregister(&push_notification_driver_dlog); From dovecot at dovecot.org Thu Oct 1 09:36:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:36:12 +0000 Subject: dovecot-2.2: push-notification: Don't crash at ox driver cleanup... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a67e667f38a9 changeset: 19265:a67e667f38a9 user: Timo Sirainen date: Thu Oct 01 12:34:43 2015 +0300 description: push-notification: Don't crash at ox driver cleanup if init() hadn't been called. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (16 lines): diff -r e309b27f02ea -r a67e667f38a9 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Wed Sep 30 18:22:52 2015 -0600 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 12:34:43 2015 +0300 @@ -334,8 +334,10 @@ static void push_notification_driver_ox_cleanup(void) { if ((ox_global != NULL) && (ox_global->refcount <= 0)) { - http_client_wait(ox_global->http_client); - http_client_deinit(&ox_global->http_client); + if (ox_global->http_client != NULL) { + http_client_wait(ox_global->http_client); + http_client_deinit(&ox_global->http_client); + } i_free_and_null(ox_global); } } From dovecot at dovecot.org Thu Oct 1 09:50:53 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 09:50:53 +0000 Subject: dovecot-2.2: push-notification: Cache the metadata lookup in OX ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7cbb955a3d44 changeset: 19266:7cbb955a3d44 user: Timo Sirainen date: Thu Oct 01 12:49:25 2015 +0300 description: push-notification: Cache the metadata lookup in OX driver. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (38 lines): diff -r a67e667f38a9 -r 7cbb955a3d44 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 12:34:43 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 12:49:25 2015 +0300 @@ -37,6 +37,7 @@ /* This is data specific to an OX driver. */ struct push_notification_driver_ox_config { struct http_url *http_url; + const char *cached_ox_metadata; }; /* This is data specific to an OX driver transaction. */ @@ -97,6 +98,7 @@ static const char *push_notification_driver_ox_get_metadata (struct push_notification_driver_txn *dtxn) { + struct push_notification_driver_ox_config *dconfig = dtxn->duser->context; struct mail_attribute_value attr; struct mailbox *inbox; struct mailbox_transaction_context *mctx = NULL; @@ -104,6 +106,9 @@ bool success = FALSE, use_existing_txn = FALSE; int ret; + if (dconfig->cached_ox_metadata != NULL) + return dconfig->cached_ox_metadata; + /* Get canonical INBOX, where private server-level metadata is stored. * See imap/cmd-getmetadata.c */ if ((dtxn->ptxn->t != NULL) && dtxn->ptxn->mbox->inbox_user) { @@ -146,6 +151,8 @@ mailbox_free(&inbox); } + dconfig->cached_ox_metadata = + p_strdup(dtxn->ptxn->puser->driverlist->pool, attr.value); return (success == TRUE) ? attr.value : NULL; } From dovecot at dovecot.org Thu Oct 1 10:49:55 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 10:49:55 +0000 Subject: dovecot-2.2: push-notification: Allow OX driver to use "user" fr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/af0ae8ab2be4 changeset: 19267:af0ae8ab2be4 user: Timo Sirainen date: Thu Oct 01 13:45:17 2015 +0300 description: push-notification: Allow OX driver to use "user" from METADATA only if user_from_metadata is set. Otherwise users could send push-notifications to each others' if imap_metadata=yes. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 14 ++++++++---- 1 files changed, 9 insertions(+), 5 deletions(-) diffs (57 lines): diff -r 7cbb955a3d44 -r af0ae8ab2be4 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 12:49:25 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 13:45:17 2015 +0300 @@ -38,11 +38,12 @@ struct push_notification_driver_ox_config { struct http_url *http_url; const char *cached_ox_metadata; + bool use_unsafe_username; }; /* This is data specific to an OX driver transaction. */ struct push_notification_driver_ox_txn { - const char *user; + const char *unsafe_user; }; static void @@ -81,6 +82,8 @@ url, error); return -1; } + dconfig->use_unsafe_username = + hash_table_lookup(config->config, (const char *)"user_from_metadata") != NULL; push_notification_driver_debug(OX_LOG_LABEL, user, "Using URL %s", url); @@ -210,17 +213,17 @@ if (value != NULL) { key = t_strdup_until(key, value++); if (strcmp(key, "user") == 0) { - txn->user = p_strdup(dtxn->ptxn->pool, value); + txn->unsafe_user = p_strdup(dtxn->ptxn->pool, value); } } } - if (txn->user == NULL) { + if (txn->unsafe_user == NULL) { i_error(OX_LOG_LABEL "No user provided in config"); return FALSE; } - push_notification_driver_debug(OX_LOG_LABEL, user, "User (%s)", txn->user); + push_notification_driver_debug(OX_LOG_LABEL, user, "User (%s)", txn->unsafe_user); for (; *events != NULL; events++) { if (strcmp(*events, "MessageNew") == 0) { @@ -299,7 +302,8 @@ str = str_new(default_pool, 256); str_append(str, "{\"user\":\""); - json_append_escaped(str, txn->user); + json_append_escaped(str, dconfig->use_unsafe_username ? + txn->unsafe_user : user->username); str_append(str, "\",\"event\":\"messageNew\",\"folder\":\""); json_append_escaped(str, msg->mailbox); str_printfa(str, "\",\"imap-uidvalidity\":%u,\"imap-uid\":%u", From dovecot at dovecot.org Thu Oct 1 10:49:58 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Oct 2015 10:49:58 +0000 Subject: dovecot-2.2: push-notification: Free all events at plugin deinit. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5f883bc3f380 changeset: 19268:5f883bc3f380 user: Timo Sirainen date: Thu Oct 01 13:48:24 2015 +0300 description: push-notification: Free all events at plugin deinit. diffstat: src/plugins/push-notification/push-notification-events-rfc5423.c | 36 ++++++--- src/plugins/push-notification/push-notification-events-rfc5423.h | 1 + src/plugins/push-notification/push-notification-plugin.c | 1 + 3 files changed, 26 insertions(+), 12 deletions(-) diffs (69 lines): diff -r af0ae8ab2be4 -r 5f883bc3f380 src/plugins/push-notification/push-notification-events-rfc5423.c --- a/src/plugins/push-notification/push-notification-events-rfc5423.c Thu Oct 01 13:45:17 2015 +0300 +++ b/src/plugins/push-notification/push-notification-events-rfc5423.c Thu Oct 01 13:48:24 2015 +0300 @@ -28,19 +28,31 @@ extern struct push_notification_event push_notification_event_messageread; extern struct push_notification_event push_notification_event_messagetrash; +static struct push_notification_event *rfc5423_events[] = { + &push_notification_event_flagsclear, + &push_notification_event_flagsset, + &push_notification_event_mailboxcreate, + &push_notification_event_mailboxdelete, + &push_notification_event_mailboxrename, + &push_notification_event_mailboxsubscribe, + &push_notification_event_mailboxunsubscribe, + &push_notification_event_messageappend, + &push_notification_event_messageexpunge, + &push_notification_event_messagenew, + &push_notification_event_messageread, + &push_notification_event_messagetrash +}; void push_notification_event_register_rfc5423_events(void) { - push_notification_event_register(&push_notification_event_flagsclear); - push_notification_event_register(&push_notification_event_flagsset); - push_notification_event_register(&push_notification_event_mailboxcreate); - push_notification_event_register(&push_notification_event_mailboxdelete); - push_notification_event_register(&push_notification_event_mailboxrename); - push_notification_event_register(&push_notification_event_mailboxsubscribe); - push_notification_event_register(&push_notification_event_mailboxunsubscribe); - push_notification_event_register(&push_notification_event_messageappend); - push_notification_event_register(&push_notification_event_messageexpunge); - push_notification_event_register(&push_notification_event_messagenew); - push_notification_event_register(&push_notification_event_messageread); - push_notification_event_register(&push_notification_event_messagetrash); + unsigned int i; + for (i = 0; i < N_ELEMENTS(rfc5423_events); i++) + push_notification_event_register(rfc5423_events[i]); } + +void push_notification_event_unregister_rfc5423_events(void) +{ + unsigned int i; + for (i = 0; i < N_ELEMENTS(rfc5423_events); i++) + push_notification_event_unregister(rfc5423_events[i]); +} diff -r af0ae8ab2be4 -r 5f883bc3f380 src/plugins/push-notification/push-notification-events-rfc5423.h --- a/src/plugins/push-notification/push-notification-events-rfc5423.h Thu Oct 01 13:45:17 2015 +0300 +++ b/src/plugins/push-notification/push-notification-events-rfc5423.h Thu Oct 01 13:48:24 2015 +0300 @@ -5,6 +5,7 @@ void push_notification_event_register_rfc5423_events(void); +void push_notification_event_unregister_rfc5423_events(void); #endif /* PUSH_NOTIFICATION_EVENTS_H */ diff -r af0ae8ab2be4 -r 5f883bc3f380 src/plugins/push-notification/push-notification-plugin.c --- a/src/plugins/push-notification/push-notification-plugin.c Thu Oct 01 13:45:17 2015 +0300 +++ b/src/plugins/push-notification/push-notification-plugin.c Thu Oct 01 13:48:24 2015 +0300 @@ -348,6 +348,7 @@ push_notification_driver_unregister(&push_notification_driver_dlog); push_notification_driver_unregister(&push_notification_driver_ox); + push_notification_event_unregister_rfc5423_events(); mail_storage_hooks_remove(&push_notification_storage_hooks); notify_unregister(push_notification_ctx); } From dovecot at dovecot.org Fri Oct 2 09:12:13 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:13 +0000 Subject: dovecot-2.2: push-notification: Removed optimization to init dri... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cb7b0ad2836a changeset: 19269:cb7b0ad2836a user: Timo Sirainen date: Fri Oct 02 11:13:14 2015 +0300 description: push-notification: Removed optimization to init drivers only once. Different users may have different drivers. And the previous metadata-caching change especially isn't working without this change. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 2 +- src/plugins/push-notification/push-notification-drivers.h | 1 - src/plugins/push-notification/push-notification-plugin.c | 64 ++++++------ 3 files changed, 31 insertions(+), 36 deletions(-) diffs (134 lines): diff -r 5f883bc3f380 -r cb7b0ad2836a src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 13:48:24 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 11:13:14 2015 +0300 @@ -155,7 +155,7 @@ } dconfig->cached_ox_metadata = - p_strdup(dtxn->ptxn->puser->driverlist->pool, attr.value); + p_strdup(dtxn->ptxn->muser->pool, attr.value); return (success == TRUE) ? attr.value : NULL; } diff -r 5f883bc3f380 -r cb7b0ad2836a src/plugins/push-notification/push-notification-drivers.h --- a/src/plugins/push-notification/push-notification-drivers.h Thu Oct 01 13:48:24 2015 +0300 +++ b/src/plugins/push-notification/push-notification-drivers.h Fri Oct 02 11:13:14 2015 +0300 @@ -70,7 +70,6 @@ struct push_notification_driver_list { ARRAY(struct push_notification_driver_user *) drivers; - pool_t pool; }; struct push_notification_user { diff -r 5f883bc3f380 -r cb7b0ad2836a src/plugins/push-notification/push-notification-plugin.c --- a/src/plugins/push-notification/push-notification-plugin.c Thu Oct 01 13:48:24 2015 +0300 +++ b/src/plugins/push-notification/push-notification-plugin.c Fri Oct 02 11:13:14 2015 +0300 @@ -26,9 +26,6 @@ &mail_user_module_register); -static struct push_notification_driver_list *dlist = NULL; - - static void push_notification_transaction_init(struct push_notification_txn *ptxn) { @@ -235,7 +232,7 @@ break; } - if (push_notification_driver_init(user, env, dlist->pool, &duser) < 0) { + if (push_notification_driver_init(user, env, user->pool, &duser) < 0) { break; } @@ -247,16 +244,13 @@ } } -static void push_notification_driver_list_init(struct mail_user *user) +static struct push_notification_driver_list * +push_notification_driver_list_init(struct mail_user *user) { - pool_t pool; + struct push_notification_driver_list *dlist; - pool = pool_alloconly_create("push notification plugin", 1024); - - dlist = p_new(pool, struct push_notification_driver_list, 1); - dlist->pool = pool; - - p_array_init(&dlist->drivers, pool, 4); + dlist = p_new(user->pool, struct push_notification_driver_list, 1); + p_array_init(&dlist->drivers, user->pool, 4); push_notification_config_init(PUSH_NOTIFICATION_CONFIG, user, dlist); @@ -266,18 +260,37 @@ push_notification_config_init(PUSH_NOTIFICATION_CONFIG_OLD, user, dlist); } + return dlist; +} + +static void push_notification_user_deinit(struct mail_user *user) +{ + struct push_notification_user *puser = PUSH_NOTIFICATION_USER_CONTEXT(user); + struct push_notification_driver_list *dlist = puser->driverlist; + struct push_notification_driver_user **duser; + + array_foreach_modifiable(&dlist->drivers, duser) { + if ((*duser)->driver->v.deinit != NULL) { + (*duser)->driver->v.deinit(*duser); + } + + if ((*duser)->driver->v.cleanup != NULL) { + (*duser)->driver->v.cleanup(); + } + } + puser->module_ctx.super.deinit(user); } static void push_notification_user_created(struct mail_user *user) { + struct mail_user_vfuncs *v = user->vlast; struct push_notification_user *puser; - if (dlist == NULL) { - push_notification_driver_list_init(user); - } - puser = p_new(user->pool, struct push_notification_user, 1); - puser->driverlist = dlist; + puser->module_ctx.super = *v; + user->vlast = &puser->module_ctx.super; + v->deinit = push_notification_user_deinit; + puser->driverlist = push_notification_driver_list_init(user); MODULE_CONTEXT_SET(user, push_notification_user_module, puser); } @@ -328,23 +341,6 @@ void push_notification_plugin_deinit(void) { - struct push_notification_driver_user **duser; - - if (dlist != NULL) { - array_foreach_modifiable(&dlist->drivers, duser) { - if ((*duser)->driver->v.deinit != NULL) { - (*duser)->driver->v.deinit(*duser); - } - - if ((*duser)->driver->v.cleanup != NULL) { - (*duser)->driver->v.cleanup(); - } - } - - array_free(&dlist->drivers); - pool_unref(&dlist->pool); - } - push_notification_driver_unregister(&push_notification_driver_dlog); push_notification_driver_unregister(&push_notification_driver_ox); From dovecot at dovecot.org Fri Oct 2 09:12:21 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:21 +0000 Subject: dovecot-2.2: push-notification: Add cache lifetime config parame... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/990030864e16 changeset: 19271:990030864e16 user: Michael Slusarz date: Thu Oct 01 21:02:55 2015 -0600 description: push-notification: Add cache lifetime config parameter to OX driver diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 33 +++++++++--- 1 files changed, 25 insertions(+), 8 deletions(-) diffs (86 lines): diff -r 6c001f36f1ed -r 990030864e16 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 20:49:20 2015 -0600 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 21:02:55 2015 -0600 @@ -25,6 +25,7 @@ /* Default values. */ static const char *const default_events[] = { "MessageNew", NULL }; static const char *const default_mboxes[] = { "INBOX", NULL }; +#define DEFAULT_CACHE_LIFETIME 60 /* This is data that is shared by all plugin users. */ @@ -38,6 +39,8 @@ struct push_notification_driver_ox_config { struct http_url *http_url; const char *cached_ox_metadata; + unsigned int cached_ox_metadata_lifetime; + time_t cached_ox_metadata_timestamp; bool use_unsafe_username; }; @@ -65,27 +68,37 @@ void **context, const char **error_r) { struct push_notification_driver_ox_config *dconfig; - const char *error, *url; + const char *error, *tmp; - /* Valid config keys: url */ - url = hash_table_lookup(config->config, (const char *)"url"); - if (url == NULL) { + /* Valid config keys: cache_lifetime, url */ + tmp = hash_table_lookup(config->config, (const char *)"url"); + if (tmp == NULL) { *error_r = OX_LOG_LABEL "Driver requires the url parameter"; return -1; } dconfig = p_new(pool, struct push_notification_driver_ox_config, 1); - if (http_url_parse(url, NULL, HTTP_URL_ALLOW_USERINFO_PART, pool, + if (http_url_parse(tmp, NULL, HTTP_URL_ALLOW_USERINFO_PART, pool, &dconfig->http_url, &error) < 0) { *error_r = t_strdup_printf(OX_LOG_LABEL "Failed to parse OX REST URL %s: %s", - url, error); + tmp, error); return -1; } dconfig->use_unsafe_username = hash_table_lookup(config->config, (const char *)"user_from_metadata") != NULL; - push_notification_driver_debug(OX_LOG_LABEL, user, "Using URL %s", url); + push_notification_driver_debug(OX_LOG_LABEL, user, "Using URL %s", tmp); + + tmp = hash_table_lookup(config->config, (const char *)"cache_lifetime"); + if ((tmp == NULL) || + (str_to_uint(tmp, &dconfig->cached_ox_metadata_lifetime) < 0)) { + dconfig->cached_ox_metadata_lifetime = DEFAULT_CACHE_LIFETIME; + } + + push_notification_driver_debug(OX_LOG_LABEL, user, + "Using cache lifetime: %u", + dconfig->cached_ox_metadata_lifetime); if (ox_global == NULL) { ox_global = i_new(struct push_notification_driver_ox_global, 1); @@ -109,8 +122,10 @@ bool success = FALSE, use_existing_txn = FALSE; int ret; - if (dconfig->cached_ox_metadata != NULL) + if ((dconfig->cached_ox_metadata != NULL) && + ((dconfig->cached_ox_metadata_timestamp + dconfig->cached_ox_metadata_lifetime) > ioloop_time)) { return dconfig->cached_ox_metadata; + } /* Get canonical INBOX, where private server-level metadata is stored. * See imap/cmd-getmetadata.c */ @@ -156,6 +171,8 @@ dconfig->cached_ox_metadata = p_strdup(dtxn->ptxn->muser->pool, attr.value); + dconfig->cached_ox_metadata_timestamp = ioloop_time; + return (success == TRUE) ? attr.value : NULL; } From dovecot at dovecot.org Fri Oct 2 09:12:14 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:14 +0000 Subject: dovecot-2.2: push-notification: OCD fix for lining up function p... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6c001f36f1ed changeset: 19270:6c001f36f1ed user: Michael Slusarz date: Thu Oct 01 20:49:20 2015 -0600 description: push-notification: OCD fix for lining up function parameters diffstat: src/plugins/push-notification/push-notification-plugin.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r cb7b0ad2836a -r 6c001f36f1ed src/plugins/push-notification/push-notification-plugin.c --- a/src/plugins/push-notification/push-notification-plugin.c Fri Oct 02 11:13:14 2015 +0300 +++ b/src/plugins/push-notification/push-notification-plugin.c Thu Oct 01 20:49:20 2015 -0600 @@ -215,8 +215,8 @@ static void push_notification_config_init(const char *config_name, - struct mail_user *user, - struct push_notification_driver_list *dlist) + struct mail_user *user, + struct push_notification_driver_list *dlist) { struct push_notification_driver_user *duser; const char *env; From dovecot at dovecot.org Fri Oct 2 09:12:21 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:21 +0000 Subject: dovecot-2.2: push-notification: OX driver error handling fix - g... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/012d11e9cb67 changeset: 19272:012d11e9cb67 user: Timo Sirainen date: Fri Oct 02 11:17:53 2015 +0300 description: push-notification: OX driver error handling fix - garbage metadata was returned on failure. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (19 lines): diff -r 990030864e16 -r 012d11e9cb67 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Thu Oct 01 21:02:55 2015 -0600 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 11:17:53 2015 +0300 @@ -168,12 +168,14 @@ if (!use_existing_txn) { mailbox_free(&inbox); } + if (!success) + return NULL; dconfig->cached_ox_metadata = p_strdup(dtxn->ptxn->muser->pool, attr.value); dconfig->cached_ox_metadata_timestamp = ioloop_time; - return (success == TRUE) ? attr.value : NULL; + return dconfig->cached_ox_metadata; } static bool push_notification_driver_ox_begin_txn From dovecot at dovecot.org Fri Oct 2 09:12:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:32 +0000 Subject: dovecot-2.2: push-notification: Added timeout_msecs and max_retr... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5a64d5ea81e2 changeset: 19274:5a64d5ea81e2 user: Timo Sirainen date: Fri Oct 02 12:09:30 2015 +0300 description: push-notification: Added timeout_msecs and max_retries parameters to OX driver. For configuring HTTP lookups. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 30 ++++++++++-- 1 files changed, 25 insertions(+), 5 deletions(-) diffs (76 lines): diff -r 5e667cce0842 -r 5a64d5ea81e2 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 11:46:30 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 12:09:30 2015 +0300 @@ -26,7 +26,8 @@ static const char *const default_events[] = { "MessageNew", NULL }; static const char *const default_mboxes[] = { "INBOX", NULL }; #define DEFAULT_CACHE_LIFETIME 60 - +#define DEFAULT_TIMEOUT_MSECS 2000 +#define DEFAULT_RETRY_COUNT 1 /* This is data that is shared by all plugin users. */ struct push_notification_driver_ox_global { @@ -38,10 +39,13 @@ /* This is data specific to an OX driver. */ struct push_notification_driver_ox_config { struct http_url *http_url; + unsigned int cached_ox_metadata_lifetime; + bool use_unsafe_username; + unsigned int http_max_retries; + unsigned int http_timeout_msecs; + char *cached_ox_metadata; - unsigned int cached_ox_metadata_lifetime; time_t cached_ox_metadata_timestamp; - bool use_unsafe_username; }; /* This is data specific to an OX driver transaction. */ @@ -50,13 +54,18 @@ }; static void -push_notification_driver_ox_init_global(struct mail_user *user) +push_notification_driver_ox_init_global(struct mail_user *user, + struct push_notification_driver_ox_config *config) { struct http_client_settings http_set; if (ox_global->http_client == NULL) { + /* this is going to use the first user's settings, but these are + unlikely to change between users so it shouldn't matter much. */ memset(&http_set, 0, sizeof(http_set)); http_set.debug = user->mail_debug; + http_set.max_attempts = config->http_max_retries+1; + http_set.request_timeout_msecs = config->http_timeout_msecs; ox_global->http_client = http_client_init(&http_set); } @@ -96,6 +105,17 @@ dconfig->cached_ox_metadata_lifetime = DEFAULT_CACHE_LIFETIME; } + tmp = hash_table_lookup(config->config, (const char *)"max_retries"); + if ((tmp == NULL) || + (str_to_uint(tmp, &dconfig->http_max_retries) < 0)) { + dconfig->http_max_retries = DEFAULT_RETRY_COUNT; + } + tmp = hash_table_lookup(config->config, (const char *)"timeout_msecs"); + if ((tmp == NULL) || + (str_to_uint(tmp, &dconfig->http_timeout_msecs) < 0)) { + dconfig->http_timeout_msecs = DEFAULT_TIMEOUT_MSECS; + } + push_notification_driver_debug(OX_LOG_LABEL, user, "Using cache lifetime: %u", dconfig->cached_ox_metadata_lifetime); @@ -309,7 +329,7 @@ return; } - push_notification_driver_ox_init_global(user); + push_notification_driver_ox_init_global(user, dconfig); http_req = http_client_request_url(ox_global->http_client, "PUT", dconfig->http_url, From dovecot at dovecot.org Fri Oct 2 09:12:26 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:26 +0000 Subject: dovecot-2.2: push-notification: Don't allocate cached metadata f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5e667cce0842 changeset: 19273:5e667cce0842 user: Timo Sirainen date: Fri Oct 02 11:46:30 2015 +0300 description: push-notification: Don't allocate cached metadata from memory pool in OX driver. It slowly keeps increasing memory usage over time. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (33 lines): diff -r 012d11e9cb67 -r 5e667cce0842 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 11:17:53 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 11:46:30 2015 +0300 @@ -38,7 +38,7 @@ /* This is data specific to an OX driver. */ struct push_notification_driver_ox_config { struct http_url *http_url; - const char *cached_ox_metadata; + char *cached_ox_metadata; unsigned int cached_ox_metadata_lifetime; time_t cached_ox_metadata_timestamp; bool use_unsafe_username; @@ -171,8 +171,8 @@ if (!success) return NULL; - dconfig->cached_ox_metadata = - p_strdup(dtxn->ptxn->muser->pool, attr.value); + i_free(dconfig->cached_ox_metadata); + dconfig->cached_ox_metadata = i_strdup(attr.value); dconfig->cached_ox_metadata_timestamp = ioloop_time; return dconfig->cached_ox_metadata; @@ -355,6 +355,9 @@ static void push_notification_driver_ox_deinit (struct push_notification_driver_user *duser ATTR_UNUSED) { + struct push_notification_driver_ox_config *dconfig = duser->context; + + i_free(dconfig->cached_ox_metadata); if (ox_global != NULL) { i_assert(ox_global->refcount > 0); --ox_global->refcount; From dovecot at dovecot.org Fri Oct 2 09:12:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:12:32 +0000 Subject: dovecot-2.2: push-notification: Allow drivers to set only "key" ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/67996a17e857 changeset: 19275:67996a17e857 user: Timo Sirainen date: Fri Oct 02 12:10:41 2015 +0300 description: push-notification: Allow drivers to set only "key" without "=value" to parameters. diffstat: src/plugins/push-notification/push-notification-drivers.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (19 lines): diff -r 5a64d5ea81e2 -r 67996a17e857 src/plugins/push-notification/push-notification-drivers.c --- a/src/plugins/push-notification/push-notification-drivers.c Fri Oct 02 12:09:30 2015 +0300 +++ b/src/plugins/push-notification/push-notification-drivers.c Fri Oct 02 12:10:41 2015 +0300 @@ -66,9 +66,12 @@ p2 = strchr(*args, '='); if (p2 != NULL) { key = t_strdup_until(*args, p2); - value = t_strdup(p2 + 1); - hash_table_insert(config->config, key, value); - } + value = t_strdup(p2 + 1); + } else { + key = *args; + value = ""; + } + hash_table_insert(config->config, key, value); } return config; From dovecot at dovecot.org Fri Oct 2 09:17:45 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:17:45 +0000 Subject: dovecot-2.2: push-notification: Compiler warning fix. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cac0c21f5746 changeset: 19276:cac0c21f5746 user: Timo Sirainen date: Fri Oct 02 12:16:11 2015 +0300 description: push-notification: Compiler warning fix. diffstat: src/plugins/push-notification/push-notification-driver-ox.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 67996a17e857 -r cac0c21f5746 src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 12:10:41 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 12:16:11 2015 +0300 @@ -143,7 +143,7 @@ int ret; if ((dconfig->cached_ox_metadata != NULL) && - ((dconfig->cached_ox_metadata_timestamp + dconfig->cached_ox_metadata_lifetime) > ioloop_time)) { + ((dconfig->cached_ox_metadata_timestamp + (time_t)dconfig->cached_ox_metadata_lifetime) > ioloop_time)) { return dconfig->cached_ox_metadata; } From dovecot at dovecot.org Fri Oct 2 09:24:54 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 09:24:54 +0000 Subject: dovecot-2.2: push-notification: Use setting_get_time() parsing f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7a7111a5ce5e changeset: 19277:7a7111a5ce5e user: Timo Sirainen date: Fri Oct 02 12:23:22 2015 +0300 description: push-notification: Use setting_get_time() parsing for cache_lifetime OX driver setting. diffstat: src/plugins/push-notification/Makefile.am | 1 + src/plugins/push-notification/push-notification-driver-ox.c | 19 ++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diffs (74 lines): diff -r cac0c21f5746 -r 7a7111a5ce5e src/plugins/push-notification/Makefile.am --- a/src/plugins/push-notification/Makefile.am Fri Oct 02 12:16:11 2015 +0300 +++ b/src/plugins/push-notification/Makefile.am Fri Oct 02 12:23:22 2015 +0300 @@ -1,5 +1,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-http \ -I$(top_srcdir)/src/lib-index \ -I$(top_srcdir)/src/lib-mail \ diff -r cac0c21f5746 -r 7a7111a5ce5e src/plugins/push-notification/push-notification-driver-ox.c --- a/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 12:16:11 2015 +0300 +++ b/src/plugins/push-notification/push-notification-driver-ox.c Fri Oct 02 12:23:22 2015 +0300 @@ -6,6 +6,7 @@ #include "http-url.h" #include "ioloop.h" #include "istream.h" +#include "settings-parser.h" #include "json-parser.h" #include "mailbox-attribute.h" #include "mail-storage-private.h" @@ -25,7 +26,7 @@ /* Default values. */ static const char *const default_events[] = { "MessageNew", NULL }; static const char *const default_mboxes[] = { "INBOX", NULL }; -#define DEFAULT_CACHE_LIFETIME 60 +#define DEFAULT_CACHE_LIFETIME_SECS 60 #define DEFAULT_TIMEOUT_MSECS 2000 #define DEFAULT_RETRY_COUNT 1 @@ -39,7 +40,7 @@ /* This is data specific to an OX driver. */ struct push_notification_driver_ox_config { struct http_url *http_url; - unsigned int cached_ox_metadata_lifetime; + unsigned int cached_ox_metadata_lifetime_secs; bool use_unsafe_username; unsigned int http_max_retries; unsigned int http_timeout_msecs; @@ -100,9 +101,12 @@ push_notification_driver_debug(OX_LOG_LABEL, user, "Using URL %s", tmp); tmp = hash_table_lookup(config->config, (const char *)"cache_lifetime"); - if ((tmp == NULL) || - (str_to_uint(tmp, &dconfig->cached_ox_metadata_lifetime) < 0)) { - dconfig->cached_ox_metadata_lifetime = DEFAULT_CACHE_LIFETIME; + if (tmp == NULL) + dconfig->cached_ox_metadata_lifetime_secs = DEFAULT_CACHE_LIFETIME_SECS; + else if (settings_get_time(tmp, &dconfig->cached_ox_metadata_lifetime_secs, &error) < 0) { + *error_r = t_strdup_printf(OX_LOG_LABEL "Failed to parse OX cache_lifetime %s: %s", + tmp, error); + return -1; } tmp = hash_table_lookup(config->config, (const char *)"max_retries"); @@ -118,7 +122,7 @@ push_notification_driver_debug(OX_LOG_LABEL, user, "Using cache lifetime: %u", - dconfig->cached_ox_metadata_lifetime); + dconfig->cached_ox_metadata_lifetime_secs); if (ox_global == NULL) { ox_global = i_new(struct push_notification_driver_ox_global, 1); @@ -143,7 +147,8 @@ int ret; if ((dconfig->cached_ox_metadata != NULL) && - ((dconfig->cached_ox_metadata_timestamp + (time_t)dconfig->cached_ox_metadata_lifetime) > ioloop_time)) { + ((dconfig->cached_ox_metadata_timestamp + + (time_t)dconfig->cached_ox_metadata_lifetime_secs) > ioloop_time)) { return dconfig->cached_ox_metadata; } From dovecot at dovecot.org Fri Oct 2 15:32:29 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 15:32:29 +0000 Subject: dovecot-2.2: pop3: Fixed buffer overflow with handling pop3_dele... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/05e0700daea3 changeset: 19278:05e0700daea3 user: Timo Sirainen date: Fri Oct 02 18:30:22 2015 +0300 description: pop3: Fixed buffer overflow with handling pop3_deleted_flag setting. This has been broken since v2.2.10, although the setting wasn't working completely correctly before that version either. Afterwards it should have become obvious quickly enough that the setting is broken, because it started crashing POP3 sessions in normal use quite soon. So I doubt there are any installations that are accidentally exploitable. diffstat: src/pop3/pop3-client.c | 2 ++ src/pop3/pop3-client.h | 1 + src/pop3/pop3-commands.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletions(-) diffs (43 lines): diff -r 7a7111a5ce5e -r 05e0700daea3 src/pop3/pop3-client.c --- a/src/pop3/pop3-client.c Fri Oct 02 12:23:22 2015 +0300 +++ b/src/pop3/pop3-client.c Fri Oct 02 18:30:22 2015 +0300 @@ -193,6 +193,8 @@ if ((mail_get_flags(mail) & MAIL_SEEN) != 0) client->last_seen_pop3_msn = msgnum + 1; client->total_size += size; + if (client->highest_seq < mail->seq) + client->highest_seq = mail->seq; array_append(&message_sizes, &size, 1); msgnum++; diff -r 7a7111a5ce5e -r 05e0700daea3 src/pop3/pop3-client.h --- a/src/pop3/pop3-client.h Fri Oct 02 12:23:22 2015 +0300 +++ b/src/pop3/pop3-client.h Fri Oct 02 18:30:22 2015 +0300 @@ -69,6 +69,7 @@ /* All sequences currently visible in the mailbox. */ ARRAY_TYPE(seq_range) all_seqs; + uint32_t highest_seq; /* [msgnum] contains mail seq. anything after it has seq = msgnum+1 */ uint32_t *msgnum_to_seq_map; diff -r 7a7111a5ce5e -r 05e0700daea3 src/pop3/pop3-commands.c --- a/src/pop3/pop3-commands.c Fri Oct 02 12:23:22 2015 +0300 +++ b/src/pop3/pop3-commands.c Fri Oct 02 18:30:22 2015 +0300 @@ -796,7 +796,7 @@ client->uidl_pool = pool_alloconly_create("message uidls", 1024); /* first read all the UIDLs into a temporary [seq] array */ - seq_uidls = i_new(const char *, client->messages_count); + seq_uidls = i_new(const char *, client->highest_seq); str = t_str_new(128); while (mailbox_search_next(search_ctx, &mail)) { str_truncate(str, 0); @@ -811,6 +811,7 @@ if (client->set->pop3_save_uidl && !permanent_uidl) mail_update_pop3_uidl(mail, uidl); + i_assert(mail->seq <= client->highest_seq); seq_uidls[mail->seq-1] = uidl; if (uidl_duplicates_rename) hash_table_insert(prev_uidls, uidl, POINTER_CAST(1)); From pigeonhole at rename-it.nl Fri Oct 2 15:43:43 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 02 Oct 2015 17:43:43 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Use mailbox_save_using_mail()... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/4e83dca6b75d changeset: 2113:4e83dca6b75d user: Stephan Bosch date: Fri Oct 02 17:43:37 2015 +0200 description: lib-sieve: Use mailbox_save_using_mail() instead of mailbox_copy() for delivering messages. This makes sure that the resulting mail storage events are of the correct type for logging/notification. diffstat: src/lib-sieve/sieve-actions.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 47e8e82c98d3 -r 4e83dca6b75d src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Thu Oct 01 00:11:04 2015 +0200 +++ b/src/lib-sieve/sieve-actions.c Fri Oct 02 17:43:37 2015 +0200 @@ -581,7 +581,7 @@ mailbox_save_copy_flags(save_ctx, mail); } - if ( mailbox_copy(&save_ctx, mail) < 0 ) { + if ( mailbox_save_using_mail(&save_ctx, mail) < 0 ) { sieve_act_store_get_storage_error(aenv, trans); status = ( trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE ); From dovecot at dovecot.org Fri Oct 2 16:15:01 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 16:15:01 +0000 Subject: dovecot-2.2: Released v2.2.19. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d7e14d388a7e changeset: 19279:d7e14d388a7e user: Timo Sirainen date: Fri Oct 02 19:02:42 2015 +0300 description: Released v2.2.19. diffstat: NEWS | 9 +++++++-- configure.ac | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diffs (28 lines): diff -r 05e0700daea3 -r d7e14d388a7e NEWS --- a/NEWS Fri Oct 02 18:30:22 2015 +0300 +++ b/NEWS Fri Oct 02 19:02:42 2015 +0300 @@ -1,5 +1,10 @@ -v2.2.19 2015-09-xx Timo Sirainen - +v2.2.19 2015-10-02 Timo Sirainen + + * pop3_deleted_flag has been broken since v2.2.10. Using it would + cause buffer overflows, which could be exploitable. However, this + bug would have become visible quite soon after users had deleted + some POP3 mails, because the pop3 processes would have started + crashing all the time even in normal use. * "doveadm director flush" command has a changed meaning now: It safely moves users to their wanted backends, instead of simply forgetting the mapping entirely and leaving the existing connections diff -r 05e0700daea3 -r d7e14d388a7e configure.ac --- a/configure.ac Fri Oct 02 18:30:22 2015 +0300 +++ b/configure.ac Fri Oct 02 19:02:42 2015 +0300 @@ -2,7 +2,7 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.19.rc2],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.2.19],[dovecot at dovecot.org]) AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv19($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) From dovecot at dovecot.org Fri Oct 2 16:15:02 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 16:15:02 +0000 Subject: dovecot-2.2: Added tag 2.2.19 for changeset d7e14d388a7e Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0818b2fb5148 changeset: 19280:0818b2fb5148 user: Timo Sirainen date: Fri Oct 02 19:02:43 2015 +0300 description: Added tag 2.2.19 for changeset d7e14d388a7e diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r d7e14d388a7e -r 0818b2fb5148 .hgtags --- a/.hgtags Fri Oct 02 19:02:42 2015 +0300 +++ b/.hgtags Fri Oct 02 19:02:43 2015 +0300 @@ -129,3 +129,4 @@ 917d027836d0f9d7d4b740dc33ae48cc5beead6f 2.2.18 60057d955db325d1af199098ff4cfd57f237645c 2.2.19.rc1 7a5726201e40ac299b677cebd73326ec92b8fdd8 2.2.19.rc2 +d7e14d388a7ee6090daec2fadbc11325f67dc0cc 2.2.19 From dovecot at dovecot.org Fri Oct 2 16:15:02 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Oct 2015 16:15:02 +0000 Subject: dovecot-2.2: Added signature for changeset d7e14d388a7e Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b483fba06083 changeset: 19281:b483fba06083 user: Timo Sirainen date: Fri Oct 02 19:02:47 2015 +0300 description: Added signature for changeset d7e14d388a7e diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 0818b2fb5148 -r b483fba06083 .hgsigs --- a/.hgsigs Fri Oct 02 19:02:43 2015 +0300 +++ b/.hgsigs Fri Oct 02 19:02:47 2015 +0300 @@ -92,3 +92,4 @@ 917d027836d0f9d7d4b740dc33ae48cc5beead6f 0 iEYEABECAAYFAlVV0mIACgkQyUhSUUBVismFtwCeIVNrGFguuXIhDoCSUm86Q4uTpQUAnAi6UfVL9/+QWC5LpR7jvY97QH0c 60057d955db325d1af199098ff4cfd57f237645c 0 iEYEABECAAYFAlYCpMAACgkQyUhSUUBVismRDwCeIE5jzDFBEBFuIf2JgRMsvgErSmkAniUiUmQ8clnWBSqu7fEY7A2ZbHia 7a5726201e40ac299b677cebd73326ec92b8fdd8 0 iEYEABECAAYFAlYJTfgACgkQyUhSUUBVislrewCfZRDY+7eAKD4vPigNVUlVU/fU1CUAoIbplWaRSdUFByC4A4tb1OdU1uWc +d7e14d388a7ee6090daec2fadbc11325f67dc0cc 0 iEYEABECAAYFAlYOqqMACgkQyUhSUUBVism9LgCgjrrzr2NKJbpK0+UJmRqKgBXkpCoAmwRpnWSYcx9s9fiSB2t1mEMNFybU From pigeonhole at rename-it.nl Fri Oct 2 19:37:32 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 02 Oct 2015 21:37:32 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: file storage: Added assert to... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/357ac0a0e68b changeset: 2114:357ac0a0e68b user: Stephan Bosch date: Fri Oct 02 21:37:28 2015 +0200 description: lib-sieve: file storage: Added assert to make Coverity happier. diffstat: src/lib-sieve/storage/file/sieve-file-storage.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 4e83dca6b75d -r 357ac0a0e68b src/lib-sieve/storage/file/sieve-file-storage.c --- a/src/lib-sieve/storage/file/sieve-file-storage.c Fri Oct 02 17:43:37 2015 +0200 +++ b/src/lib-sieve/storage/file/sieve-file-storage.c Fri Oct 02 21:37:28 2015 +0200 @@ -377,6 +377,8 @@ storage_path = active_path; } + i_assert(storage_path != NULL); + /* Prepare for write access */ if ( (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ) { From dovecot at dovecot.org Sun Oct 4 18:54:11 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 04 Oct 2015 18:54:11 +0000 Subject: dovecot-2.2: lib-index: When writing new index, rotate the log f... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8322fc090a57 changeset: 19282:8322fc090a57 user: Timo Sirainen date: Sun Oct 04 21:49:08 2015 +0300 description: lib-index: When writing new index, rotate the log file first before writing it. This way the index contains the new log's seq+offset instead of having to recreate the index almost immediately afterwards. diffstat: src/lib-index/mail-index-write.c | 23 +++++++++++++++++------ 1 files changed, 17 insertions(+), 6 deletions(-) diffs (44 lines): diff -r b483fba06083 -r 8322fc090a57 src/lib-index/mail-index-write.c --- a/src/lib-index/mail-index-write.c Fri Oct 02 19:02:47 2015 +0300 +++ b/src/lib-index/mail-index-write.c Sun Oct 04 21:49:08 2015 +0300 @@ -118,13 +118,29 @@ void mail_index_write(struct mail_index *index, bool want_rotate) { struct mail_index_map *map = index->map; - const struct mail_index_header *hdr = &map->hdr; + struct mail_index_header *hdr = &map->hdr; i_assert(index->log_sync_locked); if (index->readonly) return; + /* rotate the .log before writing index, so the index will point to + the latest log. */ + if (want_rotate && + hdr->log_file_seq == index->log->head->hdr.file_seq && + hdr->log_file_tail_offset == hdr->log_file_head_offset) { + if (mail_transaction_log_rotate(index->log, FALSE) == 0) { + struct mail_transaction_log_file *file = + index->log->head; + i_assert(file->hdr.prev_file_seq == hdr->log_file_seq); + i_assert(file->hdr.prev_file_offset == hdr->log_file_head_offset); + hdr->log_file_seq = file->hdr.file_seq; + hdr->log_file_head_offset = + hdr->log_file_tail_offset = file->hdr.hdr_size; + } + } + if (!MAIL_INDEX_IS_IN_MEMORY(index)) { if (mail_index_recreate(index) < 0) { (void)mail_index_move_to_memory(index); @@ -135,9 +151,4 @@ index->last_read_log_file_seq = hdr->log_file_seq; index->last_read_log_file_head_offset = hdr->log_file_head_offset; index->last_read_log_file_tail_offset = hdr->log_file_tail_offset; - - if (want_rotate && - hdr->log_file_seq == index->log->head->hdr.file_seq && - hdr->log_file_tail_offset == hdr->log_file_head_offset) - (void)mail_transaction_log_rotate(index->log, FALSE); } From dovecot at dovecot.org Sun Oct 4 18:54:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 04 Oct 2015 18:54:12 +0000 Subject: dovecot-2.2: lib-index: Fixed checking when we want to update do... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9e3d7e83a075 changeset: 19283:9e3d7e83a075 user: Timo Sirainen date: Sun Oct 04 21:51:55 2015 +0300 description: lib-index: Fixed checking when we want to update dovecot.index This has been broken since 76f576fc28dc. After that dovecot.index was usually updated only when dovecot.index.log was being rotated. diffstat: src/lib-index/mail-index-sync.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (19 lines): diff -r 8322fc090a57 -r 9e3d7e83a075 src/lib-index/mail-index-sync.c --- a/src/lib-index/mail-index-sync.c Sun Oct 04 21:49:08 2015 +0300 +++ b/src/lib-index/mail-index-sync.c Sun Oct 04 21:51:55 2015 +0300 @@ -797,9 +797,12 @@ { uint32_t log_diff; - if (index->last_read_log_file_seq != index->map->hdr.log_file_seq) { - /* we recently just rotated the log and rewrote index */ - return FALSE; + if (index->last_read_log_file_seq != 0 && + index->last_read_log_file_seq != index->map->hdr.log_file_seq) { + /* dovecot.index points to an old .log file. we were supposed + to rewrite the dovecot.index when rotating the log, so + we shouldn't usually get here. */ + return TRUE; } log_diff = index->map->hdr.log_file_tail_offset - From dovecot at dovecot.org Sun Oct 4 18:54:13 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 04 Oct 2015 18:54:13 +0000 Subject: dovecot-2.2: lib-index: Removed some unnecessary fields. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ef458c0a98b1 changeset: 19284:ef458c0a98b1 user: Timo Sirainen date: Sun Oct 04 21:52:29 2015 +0300 description: lib-index: Removed some unnecessary fields. diffstat: src/lib-index/mail-index-map-read.c | 3 --- src/lib-index/mail-index-private.h | 5 +---- src/lib-index/mail-index-write.c | 1 - 3 files changed, 1 insertions(+), 8 deletions(-) diffs (42 lines): diff -r 9e3d7e83a075 -r ef458c0a98b1 src/lib-index/mail-index-map-read.c --- a/src/lib-index/mail-index-map-read.c Sun Oct 04 21:51:55 2015 +0300 +++ b/src/lib-index/mail-index-map-read.c Sun Oct 04 21:52:29 2015 +0300 @@ -385,11 +385,8 @@ i_assert(new_map->rec_map->records != NULL); index->last_read_log_file_seq = new_map->hdr.log_file_seq; - index->last_read_log_file_head_offset = - new_map->hdr.log_file_head_offset; index->last_read_log_file_tail_offset = new_map->hdr.log_file_tail_offset; - index->last_read_stat = st; mail_index_unmap(&index->map); index->map = new_map; diff -r 9e3d7e83a075 -r ef458c0a98b1 src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Sun Oct 04 21:51:55 2015 +0300 +++ b/src/lib-index/mail-index-private.h Sun Oct 04 21:52:29 2015 +0300 @@ -188,12 +188,9 @@ /* last_read_log_file_* contains the seq/offsets we last read from the main index file's headers. these are used to figure out when - the main index file should be updated, and if we can update it - by writing on top of it or if we need to recreate it. */ + the main index file should be updated. */ uint32_t last_read_log_file_seq; - uint32_t last_read_log_file_head_offset; uint32_t last_read_log_file_tail_offset; - struct stat last_read_stat; /* transaction log head seq/offset when we last fscked */ uint32_t fsck_log_head_file_seq; diff -r 9e3d7e83a075 -r ef458c0a98b1 src/lib-index/mail-index-write.c --- a/src/lib-index/mail-index-write.c Sun Oct 04 21:51:55 2015 +0300 +++ b/src/lib-index/mail-index-write.c Sun Oct 04 21:52:29 2015 +0300 @@ -149,6 +149,5 @@ } index->last_read_log_file_seq = hdr->log_file_seq; - index->last_read_log_file_head_offset = hdr->log_file_head_offset; index->last_read_log_file_tail_offset = hdr->log_file_tail_offset; } From pigeonhole at rename-it.nl Sun Oct 4 21:14:31 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 04 Oct 2015 23:14:31 +0200 Subject: dovecot-2.2-pigeonhole: Released v0.4.9 for Dovecot v2.2.19. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/8cdb8b90e7a3 changeset: 2115:8cdb8b90e7a3 user: Stephan Bosch date: Sun Oct 04 23:13:50 2015 +0200 description: Released v0.4.9 for Dovecot v2.2.19. diffstat: NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (27 lines): diff -r 357ac0a0e68b -r 8cdb8b90e7a3 NEWS --- a/NEWS Fri Oct 02 21:37:28 2015 +0200 +++ b/NEWS Sun Oct 04 23:13:50 2015 +0200 @@ -1,4 +1,4 @@ -v0.4.9 xx-10-2015 Stephan Bosch +v0.4.9 04-10-2015 Stephan Bosch * Properly implemented checking of ABI version for Sieve interpreter plugins, much like Dovecot itself does for plugins. This will prevent plugin ABI @@ -21,7 +21,7 @@ keep when there is an explicit default destination folder. This caused message duplication. - lib-sieve: Fixed bug in RFC5322 header folding. Words longer than the - optimal line length caused empty lines in the output, which would break the + optimal line length caused empty lines in the output, which would break the resulting message header. This surfaced in References: headers with very long message IDs. diff -r 357ac0a0e68b -r 8cdb8b90e7a3 configure.ac --- a/configure.ac Fri Oct 02 21:37:28 2015 +0200 +++ b/configure.ac Sun Oct 04 23:13:50 2015 +0200 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.4.9.rc1], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) +AC_INIT([Pigeonhole], [0.4.9], [dovecot at dovecot.org], [dovecot-2.2-pigeonhole]) AC_DEFINE_UNQUOTED([PIGEONHOLE_ABI_VERSION], "0.4.ABIv1($PACKAGE_VERSION)", [Pigeonhole ABI version]) AC_CONFIG_AUX_DIR([.]) From pigeonhole at rename-it.nl Sun Oct 4 21:14:31 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 04 Oct 2015 23:14:31 +0200 Subject: dovecot-2.2-pigeonhole: Added tag 0.4.9 for changeset 8cdb8b90e7a3 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/004035889945 changeset: 2116:004035889945 user: Stephan Bosch date: Sun Oct 04 23:14:08 2015 +0200 description: Added tag 0.4.9 for changeset 8cdb8b90e7a3 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 8cdb8b90e7a3 -r 004035889945 .hgtags --- a/.hgtags Sun Oct 04 23:13:50 2015 +0200 +++ b/.hgtags Sun Oct 04 23:14:08 2015 +0200 @@ -32,3 +32,4 @@ 7b154d69394fcdbbc0b066978d864e551b736ce9 0.4.8.rc3 baa15dd77f9e2a1b7794771ce7deb6f961ed0360 0.4.8 b2d5b1a5fa25766eb09d5a823b5d79b37b8ecefc 0.4.9.rc1 +8cdb8b90e7a3d1c5c68ee30041522ebf90b0afaa 0.4.9 From pigeonhole at rename-it.nl Sun Oct 4 21:16:21 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sun, 04 Oct 2015 23:16:21 +0200 Subject: dovecot-2.2-pigeonhole: Added signature for changeset 8cdb8b90e7a3 Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/2dc6dda47ae7 changeset: 2117:2dc6dda47ae7 user: Stephan Bosch date: Sun Oct 04 23:18:29 2015 +0200 description: Added signature for changeset 8cdb8b90e7a3 diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 004035889945 -r 2dc6dda47ae7 .hgsigs --- a/.hgsigs Sun Oct 04 23:14:08 2015 +0200 +++ b/.hgsigs Sun Oct 04 23:18:29 2015 +0200 @@ -26,3 +26,4 @@ 7b154d69394fcdbbc0b066978d864e551b736ce9 0 iQEcBAABAgAGBQJVU7n1AAoJEATWKx49+7T0sOYH/jL46oo70cwImQN5pyAHudSarM9Mtls8//vX7JmJ/b8OPftwwx4ExBNYmvHSv315CPjq6ntMA7GMZ1tAd9lHk+ZB2WFL/Y7MQZUGgowo6K/F36MW1Z6tGN2rtnooqglyamKUPqrLIurs5Hc9444VrGMcdeMecGn9mEpxULy1jsMmo0AVVsyf50PHbYRwSgq960onz93lKhTcaD7/Sc76FPbJenqstP9iPQBuXugVxv/p9gN31Xx/V8RlxmHIjeHljx33m76sTGQ/8ca2XKvBwft8dZU4lTsrSmcvt+0wxATurjtfJ+aqPlH5pPXmqydbsEe6F3fjZTblwexc4kFNDsQ= baa15dd77f9e2a1b7794771ce7deb6f961ed0360 0 iQEcBAABAgAGBQJVVkC/AAoJEATWKx49+7T0nhoIAInNseUHHa4TUCeKH5NOr4f8d5Sj1arnxr1IGPuNlhz/Naeu2999cyVLHWGfOyWN7/B3SCmbJ/Vb/41lJLikC7Ma01IEskMDIcvJca/Nx8ZR5mcDxwpxma7k0III+gxf0pP2HWvqYXOZD+JXEGmvjCXSJyMAYPkEUEO/aVH83fNQVaPAqvvrl3cZz53TF8U9l01DecduRwLm+od2zHiFByB4bJuKhIvcAq2ksrjiHyfLJv9MXLZnhSbTLbWr4SXHs8bctzgBg6TXl6Fgp6ehOR3UQTR+k3xFOfXJY2GBfNPzBUi+rY8g8DgirNDDYjSwrc1W1+QRD5d9ANwmppeDDzg= b2d5b1a5fa25766eb09d5a823b5d79b37b8ecefc 0 iQEcBAABAgAGBQJWBHLBAAoJEATWKx49+7T0MmwH/A6QURy8nLougjKBPzdISMhk75frCr9XlKwBz5DxxPU3ed1dD2I/Bgb6xoW+KIlvf5SO1zPhhkeD9MInImKXZuQbT47Ain0Q8mMJE7jXQbx8lkMpPbOtlsthjcxMnnIYQhE0wWSe40xtFRy217ry9NCWqByNyZrNOjKLOF27rO3h538xD31xflkAslqSY1enMVeJJsAzT7tGxithEufESDW4toBgPLFlgSmaKS5c9VxMWCQ04YWJVkO9IeIac8vK5crRpzCVUjd8lu5ucucAV5PoCNGunKCu0svsDkCL5X6wzZAglZHxfs5pM3LBDOerT4DnOMXQHOzdsKl9o5HDkXg= +8cdb8b90e7a3d1c5c68ee30041522ebf90b0afaa 0 iQEcBAABAgAGBQJWEZegAAoJEATWKx49+7T0CywH/R6wMmdkNJi7/HQydWFuYXIUwbCaYbVKC5cWFkTKQkrwhPL34kNc81pksyS3aTxN8UMSwks9D0pLQnBBnOtbHvtVsZt2hBUwu6uT/LoKu+GI5g1GJoQXIEJlFwx+/3WpI2AA8JeA5RlwCdzRGJhaNBxKngStyEss6eoUto1GuAc7ldJElyazBxPZfrOmheraQ2eIjOVpi1Yi9EwB1m76XrQ6tVfqLwNA9Hb7omZJd7cMg0N9Uryh03+yikxPY3w6e7g0le8QA+4kDqMLBbty1orIaIeTavfnb2qq7CeXRXnYQxR2nIijcyWHQsrIcgzYz5dPdLU8+ukHDgA2oqTtsns= From dovecot at dovecot.org Tue Oct 6 15:15:40 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 06 Oct 2015 15:15:40 +0000 Subject: dovecot-2.2: lib-http: client: Fixed handling of response timout... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/279c156c90e2 changeset: 19285:279c156c90e2 user: Stephan Bosch date: Tue Oct 06 18:14:05 2015 +0300 description: lib-http: client: Fixed handling of response timout if there is no payload going to the server. diffstat: src/lib-http/http-client-request.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r ef458c0a98b1 -r 279c156c90e2 src/lib-http/http-client-request.c --- a/src/lib-http/http-client-request.c Sun Oct 04 21:52:29 2015 +0300 +++ b/src/lib-http/http-client-request.c Tue Oct 06 18:14:05 2015 +0300 @@ -916,6 +916,7 @@ } } else { req->state = HTTP_REQUEST_STATE_WAITING; + http_client_connection_start_request_timeout(req->conn); conn->output_locked = FALSE; } if (ret >= 0 && o_stream_flush(output) < 0) { From dovecot at dovecot.org Tue Oct 6 15:19:24 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 06 Oct 2015 15:19:24 +0000 Subject: dovecot-2.2: lib-http: Minor improvement to "disconnected during... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9d2dd826ae7e changeset: 19286:9d2dd826ae7e user: Timo Sirainen date: Tue Oct 06 18:17:45 2015 +0300 description: lib-http: Minor improvement to "disconnected during payload read" error message. The same error is also used for http-server for parsing client input, so the message shouldn't say anything about reading the input from server. diffstat: src/lib-http/http-message-parser.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 279c156c90e2 -r 9d2dd826ae7e src/lib-http/http-message-parser.c --- a/src/lib-http/http-message-parser.c Tue Oct 06 18:14:05 2015 +0300 +++ b/src/lib-http/http-message-parser.c Tue Oct 06 18:17:45 2015 +0300 @@ -392,7 +392,7 @@ i_assert(data->eof); i_assert(data->v_offset + data->new_bytes < data->wanted_size); - return t_strdup_printf("Disconnected from server at offset %"PRIuUOFF_T + return t_strdup_printf("Disconnected while reading response payload at offset %"PRIuUOFF_T " (wanted %"PRIuUOFF_T"): %s", data->v_offset + data->new_bytes, data->wanted_size, io_stream_get_disconnect_reason(input, NULL)); } From dovecot at dovecot.org Sat Oct 10 15:34:34 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Oct 2015 15:34:34 +0000 Subject: dovecot-2.2: director: Don't become desynced if two directors ch... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0f9d4f1a083d changeset: 19287:0f9d4f1a083d user: Timo Sirainen date: Sat Oct 10 18:32:06 2015 +0300 description: director: Don't become desynced if two directors change the same backend in incompatible ways. This would have caused "User hash .. is being redirected to two hosts" errors, which wouldn't easily go away as the directors have a different view of what hosts currently exist. diffstat: src/director/director-connection.c | 20 +++++++++++++++++++- src/director/director.c | 3 +++ src/director/mail-host.c | 8 ++++++++ src/director/mail-host.h | 4 ++++ 4 files changed, 34 insertions(+), 1 deletions(-) diffs (103 lines): diff -r 9d2dd826ae7e -r 0f9d4f1a083d src/director/director-connection.c --- a/src/director/director-connection.c Tue Oct 06 18:17:45 2015 +0300 +++ b/src/director/director-connection.c Sat Oct 10 18:32:06 2015 +0300 @@ -842,6 +842,7 @@ director_cmd_host_int(struct director_connection *conn, const char *const *args, struct director_host *dir_host) { + struct director_host *src_host = conn->host; struct mail_host *host; struct ip_addr ip; const char *tag = ""; @@ -889,6 +890,23 @@ mail_host_set_tag(host, tag); update = TRUE; } + if (update && host->desynced) { + vhost_count = I_MIN(vhost_count, host->vhost_count); + if (host->down != down) { + if (host->last_updown_change <= last_updown_change) + down = host->last_updown_change; + } + last_updown_change = I_MAX(last_updown_change, + host->last_updown_change); + i_warning("director(%s): Host %s is being updated before previous update had finished - " + "setting to state=%s vhosts=%u", + conn->name, net_ip2addr(&host->ip), + down ? "down" : "up", vhost_count); + /* make the change appear to come from us, so it + reaches the full ring */ + dir_host = NULL; + src_host = conn->dir->self_host; + } } if (update) { @@ -896,7 +914,7 @@ down, last_updown_change); mail_host_set_vhost_count(conn->dir->mail_hosts, host, vhost_count); - director_update_host(conn->dir, conn->host, dir_host, host); + director_update_host(conn->dir, src_host, dir_host, host); } return TRUE; } diff -r 9d2dd826ae7e -r 0f9d4f1a083d src/director/director.c --- a/src/director/director.c Tue Oct 06 18:17:45 2015 +0300 +++ b/src/director/director.c Sat Oct 10 18:32:06 2015 +0300 @@ -314,6 +314,7 @@ timeout_remove(&dir->to_sync); dir->ring_synced = TRUE; dir->ring_last_sync_time = ioloop_time; + mail_hosts_set_synced(dir->mail_hosts); director_set_state_changed(dir); } @@ -548,6 +549,8 @@ } str_append_c(str, '\n'); director_update_send(dir, src, str_c(str)); + + host->desynced = TRUE; director_sync(dir); } diff -r 9d2dd826ae7e -r 0f9d4f1a083d src/director/mail-host.c --- a/src/director/mail-host.c Tue Oct 06 18:17:45 2015 +0300 +++ b/src/director/mail-host.c Sat Oct 10 18:32:06 2015 +0300 @@ -388,6 +388,14 @@ return mail_host_get_by_hash_direct(list, hash, tag); } +void mail_hosts_set_synced(struct mail_host_list *list) +{ + struct mail_host *const *hostp; + + array_foreach(&list->hosts, hostp) + (*hostp)->desynced = FALSE; +} + bool mail_hosts_have_usable(struct mail_host_list *list) { if (list->hosts_unsorted) diff -r 9d2dd826ae7e -r 0f9d4f1a083d src/director/mail-host.h --- a/src/director/mail-host.h Tue Oct 06 18:17:45 2015 +0300 +++ b/src/director/mail-host.h Sat Oct 10 18:32:06 2015 +0300 @@ -15,6 +15,9 @@ struct ip_addr ip; char *tag; + + /* host was recently changed and ring hasn't synced yet since */ + unsigned int desynced:1; }; ARRAY_DEFINE_TYPE(mail_host, struct mail_host *); @@ -37,6 +40,7 @@ unsigned int vhost_count); void mail_host_remove(struct mail_host_list *list, struct mail_host *host); +void mail_hosts_set_synced(struct mail_host_list *list); bool mail_hosts_have_usable(struct mail_host_list *list); const ARRAY_TYPE(mail_host) *mail_hosts_get(struct mail_host_list *list); From dovecot at dovecot.org Sat Oct 10 15:34:34 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Oct 2015 15:34:34 +0000 Subject: dovecot-2.2: director: Don't allow doveadm to update backend's s... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5939512ff017 changeset: 19288:5939512ff017 user: Timo Sirainen date: Sat Oct 10 18:32:56 2015 +0300 description: director: Don't allow doveadm to update backend's state if the state is already being changed. diffstat: src/director/doveadm-connection.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (29 lines): diff -r 0f9d4f1a083d -r 5939512ff017 src/director/doveadm-connection.c --- a/src/director/doveadm-connection.c Sat Oct 10 18:32:06 2015 +0300 +++ b/src/director/doveadm-connection.c Sat Oct 10 18:32:56 2015 +0300 @@ -282,6 +282,10 @@ return TRUE; } host = mail_host_add_ip(dir->mail_hosts, &ip, tag); + } else if (host->desynced) { + o_stream_nsend_str(conn->output, + "host is already being updated - try again later\n"); + return TRUE; } if (vhost_count != UINT_MAX) mail_host_set_vhost_count(dir->mail_hosts, host, vhost_count); @@ -323,7 +327,13 @@ o_stream_nsend_str(conn->output, "NOTFOUND\n"); return TRUE; } - if (host->down != down) { + if (host->down == down) + ; + else if (host->desynced) { + o_stream_nsend_str(conn->output, + "host is already being updated - try again later\n"); + return TRUE; + } else { mail_host_set_down(conn->dir->mail_hosts, host, down, ioloop_time); director_update_host(conn->dir, conn->dir->self_host, From dovecot at dovecot.org Sun Oct 11 15:47:36 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 11 Oct 2015 15:47:36 +0000 Subject: dovecot-2.2: director: Small code cleanup - make it easier to ad... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4e0c9df36a78 changeset: 19289:4e0c9df36a78 user: Timo Sirainen date: Sun Oct 11 18:45:58 2015 +0300 description: director: Small code cleanup - make it easier to add parameters to SYNC diffstat: src/director/director-connection.c | 21 ++++++++++----------- 1 files changed, 10 insertions(+), 11 deletions(-) diffs (37 lines): diff -r 5939512ff017 -r 4e0c9df36a78 src/director/director-connection.c --- a/src/director/director-connection.c Sat Oct 10 18:32:56 2015 +0300 +++ b/src/director/director-connection.c Sun Oct 11 18:45:58 2015 +0300 @@ -1320,23 +1320,22 @@ struct director_host *host; struct ip_addr ip; in_port_t port; - unsigned int seq, minor_version = 0, timestamp = ioloop_time; + unsigned int arg_count, seq, minor_version = 0, timestamp = ioloop_time; - if (str_array_length(args) < 3 || + arg_count = str_array_length(args); + if (arg_count < 3 || !director_args_parse_ip_port(conn, args, &ip, &port) || str_to_uint(args[2], &seq) < 0) { director_cmd_error(conn, "Invalid parameters"); return FALSE; } - if (args[3] != NULL) { - if (str_to_uint(args[3], &minor_version) < 0) { - director_cmd_error(conn, "Invalid parameters"); - return FALSE; - } - if (args[4] != NULL && str_to_uint(args[4], ×tamp) < 0) { - director_cmd_error(conn, "Invalid parameters"); - return FALSE; - } + if (arg_count >= 4 && str_to_uint(args[3], &minor_version) < 0) { + director_cmd_error(conn, "Invalid parameters"); + return FALSE; + } + if (arg_count >= 5 && str_to_uint(args[4], ×tamp) < 0) { + director_cmd_error(conn, "Invalid parameters"); + return FALSE; } /* find the originating director. if we don't see it, it was already From dovecot at dovecot.org Mon Oct 12 12:43:44 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Oct 2015 12:43:44 +0000 Subject: dovecot-2.2: director: Added mail_hosts_hash(), which identifies... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/eb9b9519db7a changeset: 19291:eb9b9519db7a user: Timo Sirainen date: Mon Oct 12 15:41:25 2015 +0300 description: director: Added mail_hosts_hash(), which identifies the current mail_hosts configuration. diffstat: src/director/mail-host.c | 24 ++++++++++++++++++++++++ src/director/mail-host.h | 1 + 2 files changed, 25 insertions(+), 0 deletions(-) diffs (70 lines): diff -r c4fa1bf6da57 -r eb9b9519db7a src/director/mail-host.c --- a/src/director/mail-host.c Mon Oct 12 15:39:36 2015 +0300 +++ b/src/director/mail-host.c Mon Oct 12 15:41:25 2015 +0300 @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "bsearch-insert-pos.h" +#include "crc32.h" #include "md5.h" #include "mail-host.h" @@ -16,6 +17,7 @@ struct mail_host_list { ARRAY_TYPE(mail_host) hosts; ARRAY(struct mail_vhost) vhosts; + unsigned int hosts_hash; bool hosts_unsorted; bool consistent_hashing; }; @@ -114,10 +116,23 @@ static void mail_hosts_sort(struct mail_host_list *list) { + struct mail_host *const *hostp; + uint32_t num; + if (list->consistent_hashing) mail_hosts_sort_ring(list); else mail_hosts_sort_direct(list); + + list->hosts_hash = 0; + array_foreach(&list->hosts, hostp) { + num = ((*hostp)->down ? 1 : 0) ^ (*hostp)->vhost_count; + list->hosts_hash = crc32_data_more(list->hosts_hash, + &num, sizeof(num)); + num = net_ip_hash(&(*hostp)->ip); + list->hosts_hash = crc32_data_more(list->hosts_hash, + &num, sizeof(num)); + } } struct mail_host * @@ -396,6 +411,15 @@ (*hostp)->desynced = FALSE; } +unsigned int mail_hosts_hash(struct mail_host_list *list) +{ + if (list->hosts_unsorted) + mail_hosts_sort(list); + /* don't retun 0 as hash, since we're using it as "doesn't exist" in + some places. */ + return list->hosts_hash == 0 ? 1 : list->hosts_hash; +} + bool mail_hosts_have_usable(struct mail_host_list *list) { if (list->hosts_unsorted) diff -r c4fa1bf6da57 -r eb9b9519db7a src/director/mail-host.h --- a/src/director/mail-host.h Mon Oct 12 15:39:36 2015 +0300 +++ b/src/director/mail-host.h Mon Oct 12 15:41:25 2015 +0300 @@ -41,6 +41,7 @@ void mail_host_remove(struct mail_host_list *list, struct mail_host *host); void mail_hosts_set_synced(struct mail_host_list *list); +unsigned int mail_hosts_hash(struct mail_host_list *list); bool mail_hosts_have_usable(struct mail_host_list *list); const ARRAY_TYPE(mail_host) *mail_hosts_get(struct mail_host_list *list); From dovecot at dovecot.org Mon Oct 12 12:43:43 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Oct 2015 12:43:43 +0000 Subject: dovecot-2.2: director: Added another debug log message. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c4fa1bf6da57 changeset: 19290:c4fa1bf6da57 user: Timo Sirainen date: Mon Oct 12 15:39:36 2015 +0300 description: director: Added another debug log message. diffstat: src/director/director-request.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 4e0c9df36a78 -r c4fa1bf6da57 src/director/director-request.c --- a/src/director/director-request.c Sun Oct 11 18:45:58 2015 +0300 +++ b/src/director/director-request.c Mon Oct 12 15:39:36 2015 +0300 @@ -219,6 +219,7 @@ if (user->host == host) { /* doesn't matter, other directors would assign the user the same way regardless */ + dir_debug("request: %u would be weak, but host doesn't change", request->username_hash); return TRUE; } From dovecot at dovecot.org Mon Oct 12 12:43:44 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Oct 2015 12:43:44 +0000 Subject: dovecot-2.2: director: Use mail_hosts_hash() to improve debug lo... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/bae8efd8b5b3 changeset: 19292:bae8efd8b5b3 user: Timo Sirainen date: Mon Oct 12 15:41:55 2015 +0300 description: director: Use mail_hosts_hash() to improve debug log messages. diffstat: src/director/director-connection.c | 13 ++++++++++--- src/director/director-request.c | 5 +++-- src/director/director.c | 11 +++++++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diffs (80 lines): diff -r eb9b9519db7a -r bae8efd8b5b3 src/director/director-connection.c --- a/src/director/director-connection.c Mon Oct 12 15:41:25 2015 +0300 +++ b/src/director/director-connection.c Mon Oct 12 15:41:55 2015 +0300 @@ -882,7 +882,7 @@ update = host->vhost_count != vhost_count || host->down != down || host->last_updown_change != last_updown_change; -; + if (strcmp(tag, host->tag) != 0) { i_error("director(%s): Host %s changed tag from '%s' to '%s'", conn->name, net_ip2addr(&host->ip), @@ -915,6 +915,12 @@ mail_host_set_vhost_count(conn->dir->mail_hosts, host, vhost_count); director_update_host(conn->dir, src_host, dir_host, host); + } else { + dir_debug("Ignoring host %s update vhost_count=%u " + "down=%d last_updown_change=%ld (hosts_hash=%u)", + net_ip2addr(&ip), vhost_count, down, + (long)last_updown_change, + mail_hosts_hash(conn->dir->mail_hosts)); } return TRUE; } @@ -1263,8 +1269,9 @@ /* duplicate SYNC (which was sent just in case the previous one got lost) */ } else { - dir_debug("Ring is synced (%s sent seq=%u)", - conn->name, seq); + dir_debug("Ring is synced (%s sent seq=%u, hosts_hash=%u)", + conn->name, seq, + mail_hosts_hash(dir->mail_hosts)); director_set_ring_synced(dir); } } else { diff -r eb9b9519db7a -r bae8efd8b5b3 src/director/director-request.c --- a/src/director/director-request.c Mon Oct 12 15:41:25 2015 +0300 +++ b/src/director/director-request.c Mon Oct 12 15:41:55 2015 +0300 @@ -308,8 +308,9 @@ } user = user_directory_add(dir->users, request->username_hash, host, ioloop_time); - dir_debug("request: %u added timeout to %u", - request->username_hash, user->timestamp); + dir_debug("request: %u added timeout to %u (hosts_hash=%u)", + request->username_hash, user->timestamp, + mail_hosts_hash(dir->mail_hosts)); } i_assert(!user->weak); diff -r eb9b9519db7a -r bae8efd8b5b3 src/director/director.c --- a/src/director/director.c Mon Oct 12 15:41:25 2015 +0300 +++ b/src/director/director.c Mon Oct 12 15:41:55 2015 +0300 @@ -289,8 +289,9 @@ timeout_remove(&dir->to_handshake_warning); if (dir->ring_handshake_warning_sent) { i_warning("Ring is synced, continuing delayed requests " - "(syncing took %d secs)", - (int)(ioloop_time - dir->ring_last_sync_time)); + "(syncing took %d secs, hosts_hash=%u)", + (int)(ioloop_time - dir->ring_last_sync_time), + mail_hosts_hash(dir->mail_hosts)); dir->ring_handshake_warning_sent = FALSE; } @@ -523,6 +524,12 @@ /* update state in case this is the first mail host being added */ director_set_state_changed(dir); + dir_debug("Updating host %s vhost_count=%u " + "down=%d last_updown_change=%ld (hosts_hash=%u)", + net_ip2addr(&host->ip), host->vhost_count, host->down, + (long)host->last_updown_change, + mail_hosts_hash(dir->mail_hosts)); + if (orig_src == NULL) { orig_src = dir->self_host; orig_src->last_seq++; From dovecot at dovecot.org Mon Oct 12 12:49:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Oct 2015 12:49:32 +0000 Subject: dovecot-2.2: director: Detect if directors' hosts have become de... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8f225e43e6e3 changeset: 19293:8f225e43e6e3 user: Timo Sirainen date: Mon Oct 12 15:47:46 2015 +0300 description: director: Detect if directors' hosts have become desynced by sending hosts_hash in SYNC parameter. Also fix up such a situation by resending all HOSTs. diffstat: src/director/director-connection.c | 47 ++++++++++++++++++++++++++++++++-- src/director/director-host.h | 4 ++ src/director/director.c | 51 ++++++++++++++++++++++++++----------- src/director/director.h | 3 +- 4 files changed, 84 insertions(+), 21 deletions(-) diffs (234 lines): diff -r bae8efd8b5b3 -r 8f225e43e6e3 src/director/director-connection.c --- a/src/director/director-connection.c Mon Oct 12 15:41:55 2015 +0300 +++ b/src/director/director-connection.c Mon Oct 12 15:47:46 2015 +0300 @@ -228,7 +228,8 @@ dir->sync_seq++; director_set_ring_unsynced(dir); director_sync_send(dir, dir->self_host, dir->sync_seq, - DIRECTOR_VERSION_MINOR, ioloop_time); + DIRECTOR_VERSION_MINOR, ioloop_time, + mail_hosts_hash(dir->mail_hosts)); } director_connection_set_ping_timeout(conn); } @@ -1243,7 +1244,7 @@ director_connection_sync_host(struct director_connection *conn, struct director_host *host, uint32_t seq, unsigned int minor_version, - unsigned int timestamp) + unsigned int timestamp, unsigned int hosts_hash) { struct director *dir = conn->dir; @@ -1261,6 +1262,16 @@ successfully connected to both directions */ i_assert(dir->left != NULL && dir->right != NULL); + if (hosts_hash != 0 && + hosts_hash != mail_hosts_hash(conn->dir->mail_hosts)) { + i_error("director(%s): Hosts unexpectedly changed during SYNC reply - resending" + "(seq=%u, old hosts_hash=%u, new hosts_hash=%u)", + conn->name, seq, hosts_hash, + mail_hosts_hash(dir->mail_hosts)); + (void)director_resend_sync(dir); + return FALSE; + } + dir->ring_min_version = minor_version; if (!dir->ring_handshaked) { /* the ring is handshaked */ @@ -1311,10 +1322,32 @@ return FALSE; } + if (hosts_hash != 0 && + hosts_hash != mail_hosts_hash(conn->dir->mail_hosts)) { + if (host->desynced_hosts_hash != hosts_hash) { + dir_debug("Ignore director %s stale SYNC request whose hosts don't match us " + "(seq=%u, remote hosts_hash=%u, my hosts_hash=%u)", + net_ip2addr(&host->ip), seq, hosts_hash, + mail_hosts_hash(dir->mail_hosts)); + host->desynced_hosts_hash = hosts_hash; + return FALSE; + } + /* we'll get here only if we received a SYNC twice + with the same wrong hosts_hash. FIXME: this gets + triggered unnecessarily sometimes if hosts are + changing rapidly. */ + i_error("director(%s): Director %s SYNC request hosts don't match us - resending hosts " + "(seq=%u, remote hosts_hash=%u, my hosts_hash=%u)", + conn->name, net_ip2addr(&host->ip), seq, + hosts_hash, mail_hosts_hash(dir->mail_hosts)); + director_resend_hosts(dir); + return FALSE; + } + host->desynced_hosts_hash = 0; if (dir->right != NULL) { /* forward it to the connection on right */ director_sync_send(dir, host, seq, minor_version, - timestamp); + timestamp, hosts_hash); } } return TRUE; @@ -1328,6 +1361,7 @@ struct ip_addr ip; in_port_t port; unsigned int arg_count, seq, minor_version = 0, timestamp = ioloop_time; + unsigned int hosts_hash = 0; arg_count = str_array_length(args); if (arg_count < 3 || @@ -1344,13 +1378,18 @@ director_cmd_error(conn, "Invalid parameters"); return FALSE; } + if (arg_count >= 6 && str_to_uint(args[5], &hosts_hash) < 0) { + director_cmd_error(conn, "Invalid parameters"); + return FALSE; + } /* find the originating director. if we don't see it, it was already removed and we can ignore this sync. */ host = director_host_lookup(dir, &ip, port); if (host != NULL) { if (!director_connection_sync_host(conn, host, seq, - minor_version, timestamp)) + minor_version, timestamp, + hosts_hash)) return TRUE; } diff -r bae8efd8b5b3 -r 8f225e43e6e3 src/director/director-host.h --- a/src/director/director-host.h Mon Oct 12 15:41:55 2015 +0300 +++ b/src/director/director-host.h Mon Oct 12 15:47:46 2015 +0300 @@ -23,6 +23,10 @@ /* use these to avoid infinitely sending SYNCs for directors that aren't connected in the ring. */ unsigned int last_sync_seq, last_sync_seq_counter, last_sync_timestamp; + /* whenever we receive a SYNC with stale hosts_hash, set this. if it's + already set and equals the current hosts_hash, re-send our hosts to + everybody in case they somehow got out of sync. */ + unsigned int desynced_hosts_hash; /* Last time host was detected to be down */ time_t last_network_failure; time_t last_protocol_failure; diff -r bae8efd8b5b3 -r 8f225e43e6e3 src/director/director.c --- a/src/director/director.c Mon Oct 12 15:41:55 2015 +0300 +++ b/src/director/director.c Mon Oct 12 15:47:46 2015 +0300 @@ -321,7 +321,7 @@ void director_sync_send(struct director *dir, struct director_host *host, uint32_t seq, unsigned int minor_version, - unsigned int timestamp) + unsigned int timestamp, unsigned int hosts_hash) { string_t *str; @@ -331,7 +331,8 @@ if (minor_version > 0 && director_connection_get_minor_version(dir->right) > 0) { /* only minor_version>0 supports extra parameters */ - str_printfa(str, "\t%u\t%u", minor_version, timestamp); + str_printfa(str, "\t%u\t%u\t%u", minor_version, + timestamp, hosts_hash); } str_append_c(str, '\n'); director_connection_send(dir->right, str_c(str)); @@ -349,7 +350,8 @@ /* send a new SYNC in case the previous one got dropped */ dir->self_host->last_sync_timestamp = ioloop_time; director_sync_send(dir, dir->self_host, dir->sync_seq, - DIRECTOR_VERSION_MINOR, ioloop_time); + DIRECTOR_VERSION_MINOR, ioloop_time, + mail_hosts_hash(dir->mail_hosts)); if (dir->to_sync != NULL) timeout_reset(dir->to_sync); return TRUE; @@ -412,7 +414,8 @@ director_connection_set_synced(dir->left, FALSE); director_connection_set_synced(dir->right, FALSE); director_sync_send(dir, dir->self_host, dir->sync_seq, - DIRECTOR_VERSION_MINOR, ioloop_time); + DIRECTOR_VERSION_MINOR, ioloop_time, + mail_hosts_hash(dir->mail_hosts)); } void director_sync_freeze(struct director *dir) @@ -515,21 +518,13 @@ DIRECTOR_VERSION_RING_REMOVE, cmd); } -void director_update_host(struct director *dir, struct director_host *src, - struct director_host *orig_src, - struct mail_host *host) +static void +director_send_host(struct director *dir, struct director_host *src, + struct director_host *orig_src, + struct mail_host *host) { string_t *str; - /* update state in case this is the first mail host being added */ - director_set_state_changed(dir); - - dir_debug("Updating host %s vhost_count=%u " - "down=%d last_updown_change=%ld (hosts_hash=%u)", - net_ip2addr(&host->ip), host->vhost_count, host->down, - (long)host->last_updown_change, - mail_hosts_hash(dir->mail_hosts)); - if (orig_src == NULL) { orig_src = dir->self_host; orig_src->last_seq++; @@ -556,6 +551,30 @@ } str_append_c(str, '\n'); director_update_send(dir, src, str_c(str)); +} + +void director_resend_hosts(struct director *dir) +{ + struct mail_host *const *hostp; + + array_foreach(mail_hosts_get(dir->mail_hosts), hostp) + director_send_host(dir, dir->self_host, NULL, *hostp); +} + +void director_update_host(struct director *dir, struct director_host *src, + struct director_host *orig_src, + struct mail_host *host) +{ + /* update state in case this is the first mail host being added */ + director_set_state_changed(dir); + + dir_debug("Updating host %s vhost_count=%u " + "down=%d last_updown_change=%ld (hosts_hash=%u)", + net_ip2addr(&host->ip), host->vhost_count, host->down, + (long)host->last_updown_change, + mail_hosts_hash(dir->mail_hosts)); + + director_send_host(dir, src, orig_src, host); host->desynced = TRUE; director_sync(dir); diff -r bae8efd8b5b3 -r 8f225e43e6e3 src/director/director.h --- a/src/director/director.h Mon Oct 12 15:41:55 2015 +0300 +++ b/src/director/director.h Mon Oct 12 15:47:46 2015 +0300 @@ -115,7 +115,7 @@ void director_set_state_changed(struct director *dir); void director_sync_send(struct director *dir, struct director_host *host, uint32_t seq, unsigned int minor_version, - unsigned int timestamp); + unsigned int timestamp, unsigned int hosts_hash); bool director_resend_sync(struct director *dir); void director_notify_ring_added(struct director_host *added_host, @@ -126,6 +126,7 @@ void director_update_host(struct director *dir, struct director_host *src, struct director_host *orig_src, struct mail_host *host) ATTR_NULL(3); +void director_resend_hosts(struct director *dir); void director_remove_host(struct director *dir, struct director_host *src, struct director_host *orig_src, struct mail_host *host) ATTR_NULL(2, 3); From dovecot at dovecot.org Mon Oct 12 12:59:21 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Oct 2015 12:59:21 +0000 Subject: dovecot-2.2: director: Log a warning if directors' clocks are to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d96595e2363b changeset: 19294:d96595e2363b user: Timo Sirainen date: Mon Oct 12 15:57:42 2015 +0300 description: director: Log a warning if directors' clocks are too much out of sync. diffstat: src/director/director-connection.c | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diffs (47 lines): diff -r 8f225e43e6e3 -r d96595e2363b src/director/director-connection.c --- a/src/director/director-connection.c Mon Oct 12 15:47:46 2015 +0300 +++ b/src/director/director-connection.c Mon Oct 12 15:57:42 2015 +0300 @@ -78,6 +78,7 @@ valid received SYNC timestamp, assume that we lost the director's restart notification and reset the last_sync_seq */ #define DIRECTOR_SYNC_STALE_TIMESTAMP_RESET_SECS (60*2) +#define DIRECTOR_MAX_CLOCK_DIFF_WARN_SECS 1 #if DIRECTOR_CONNECTION_DONE_TIMEOUT_MSECS <= DIRECTOR_CONNECTION_PING_TIMEOUT_MSECS # error DIRECTOR_CONNECTION_DONE_TIMEOUT_MSECS is too low @@ -388,6 +389,22 @@ } conn->me_received = TRUE; + if (args[2] != NULL) { + time_t remote_time; + int diff; + + if (str_to_time(args[2], &remote_time) < 0) { + director_cmd_error(conn, "Invalid ME timestamp"); + return FALSE; + } + diff = ioloop_time - remote_time; + if (diff > DIRECTOR_MAX_CLOCK_DIFF_WARN_SECS || + (diff < 0 && -diff > DIRECTOR_MAX_CLOCK_DIFF_WARN_SECS)) { + i_warning("Director %s clock differs from ours by %d secs", + conn->name, diff); + } + } + timeout_remove(&conn->to_ping); conn->to_ping = timeout_add(DIRECTOR_CONNECTION_DONE_TIMEOUT_MSECS, director_connection_init_timeout, conn); @@ -1799,9 +1816,10 @@ { director_connection_send(conn, t_strdup_printf( "VERSION\t"DIRECTOR_VERSION_NAME"\t%u\t%u\n" - "ME\t%s\t%u\n", + "ME\t%s\t%u\t%lld\n", DIRECTOR_VERSION_MAJOR, DIRECTOR_VERSION_MINOR, - net_ip2addr(&conn->dir->self_ip), conn->dir->self_port)); + net_ip2addr(&conn->dir->self_ip), conn->dir->self_port, + (long long)time(NULL))); } struct director_connection * From dovecot at dovecot.org Mon Oct 12 14:14:21 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Oct 2015 14:14:21 +0000 Subject: dovecot-2.2: fs-dict: Implemented hex-encoding for values. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/719e7f8fd70b changeset: 19295:719e7f8fd70b user: Timo Sirainen date: Mon Oct 12 17:12:17 2015 +0300 description: fs-dict: Implemented hex-encoding for values. diffstat: src/lib-fs/fs-dict.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diffs (42 lines): diff -r d96595e2363b -r 719e7f8fd70b src/lib-fs/fs-dict.c --- a/src/lib-fs/fs-dict.c Mon Oct 12 15:57:42 2015 +0300 +++ b/src/lib-fs/fs-dict.c Mon Oct 12 17:12:17 2015 +0300 @@ -4,6 +4,7 @@ #include "buffer.h" #include "str.h" #include "guid.h" +#include "hex-binary.h" #include "base64.h" #include "istream.h" #include "ostream.h" @@ -12,6 +13,7 @@ enum fs_dict_value_encoding { FS_DICT_VALUE_ENCODING_RAW, + FS_DICT_VALUE_ENCODING_HEX, FS_DICT_VALUE_ENCODING_BASE64 }; @@ -58,6 +60,8 @@ encoding_str = t_strdup_until(args, p++); if (strcmp(encoding_str, "raw") == 0) fs->encoding = FS_DICT_VALUE_ENCODING_RAW; + else if (strcmp(encoding_str, "hex") == 0) + fs->encoding = FS_DICT_VALUE_ENCODING_HEX; else if (strcmp(encoding_str, "base64") == 0) fs->encoding = FS_DICT_VALUE_ENCODING_BASE64; else { @@ -196,6 +200,13 @@ case FS_DICT_VALUE_ENCODING_RAW: dict_set(trans, file->key, str_c(file->write_buffer)); break; + case FS_DICT_VALUE_ENCODING_HEX: { + string_t *hex = t_str_new(file->write_buffer->used * 2 + 1); + binary_to_hex_append(hex, file->write_buffer->data, + file->write_buffer->used); + dict_set(trans, file->key, str_c(hex)); + break; + } case FS_DICT_VALUE_ENCODING_BASE64: { const unsigned int base64_size = MAX_BASE64_ENCODED_SIZE(file->write_buffer->used); From dovecot at dovecot.org Tue Oct 13 10:46:30 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 10:46:30 +0000 Subject: dovecot-2.2: auth: passwd-file now stat()s the file max once per... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dce5ee506cc8 changeset: 19296:dce5ee506cc8 user: Timo Sirainen date: Tue Oct 13 13:44:48 2015 +0300 description: auth: passwd-file now stat()s the file max once per second. It's quite unnecessary to do it more often. diffstat: src/auth/db-passwd-file.c | 5 +++++ src/auth/db-passwd-file.h | 1 + 2 files changed, 6 insertions(+), 0 deletions(-) diffs (33 lines): diff -r 719e7f8fd70b -r dce5ee506cc8 src/auth/db-passwd-file.c --- a/src/auth/db-passwd-file.c Mon Oct 12 17:12:17 2015 +0300 +++ b/src/auth/db-passwd-file.c Tue Oct 13 13:44:48 2015 +0300 @@ -13,6 +13,7 @@ #include "hash.h" #include "str.h" #include "eacces-error.h" +#include "ioloop.h" #include #include @@ -261,6 +262,10 @@ struct stat st; const char *error; + if (pw->last_sync_time == ioloop_time) + return 0; + pw->last_sync_time = ioloop_time; + if (stat(pw->path, &st) < 0) { /* with variables don't give hard errors, or errors about nonexistent files */ diff -r 719e7f8fd70b -r dce5ee506cc8 src/auth/db-passwd-file.h --- a/src/auth/db-passwd-file.h Mon Oct 12 17:12:17 2015 +0300 +++ b/src/auth/db-passwd-file.h Tue Oct 13 13:44:48 2015 +0300 @@ -20,6 +20,7 @@ pool_t pool; int refcount; + time_t last_sync_time; char *path; time_t stamp; off_t size; From dovecot at dovecot.org Tue Oct 13 17:43:28 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 17:43:28 +0000 Subject: dovecot-2.2: dict-sql: Added support for value_type field, which... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/6bb60a869c71 changeset: 19298:6bb60a869c71 user: Timo Sirainen date: Tue Oct 13 20:40:38 2015 +0300 description: dict-sql: Added support for value_type field, which deprecates value_hexblob. value_type=string|hexblob|uint are supported now. diffstat: src/lib-dict/dict-sql-settings.c | 7 +++++++ src/lib-dict/dict-sql-settings.h | 1 + src/lib-dict/dict-sql.c | 27 ++++++++++++++++++++------- 3 files changed, 28 insertions(+), 7 deletions(-) diffs (90 lines): diff -r c854e1b3e419 -r 6bb60a869c71 src/lib-dict/dict-sql-settings.c --- a/src/lib-dict/dict-sql-settings.c Tue Oct 13 20:39:50 2015 +0300 +++ b/src/lib-dict/dict-sql-settings.c Tue Oct 13 20:40:38 2015 +0300 @@ -36,6 +36,7 @@ DEF_STR(table), DEF_STR(username_field), DEF_STR(value_field), + DEF_STR(value_type), DEF_BOOL(value_hexblob), { 0, NULL, 0 } @@ -129,6 +130,12 @@ return "Missing setting: table"; if (ctx->cur_map.value_field == NULL) return "Missing setting: value_field"; + if (ctx->cur_map.value_type != NULL) { + if (strcmp(ctx->cur_map.value_type, "string") != 0 && + strcmp(ctx->cur_map.value_type, "hexblob") != 0 && + strcmp(ctx->cur_map.value_type, "uint") != 0) + return "Invalid value in value_type"; + } if (ctx->cur_map.username_field == NULL) { /* not all queries require this */ diff -r c854e1b3e419 -r 6bb60a869c71 src/lib-dict/dict-sql-settings.h --- a/src/lib-dict/dict-sql-settings.h Tue Oct 13 20:39:50 2015 +0300 +++ b/src/lib-dict/dict-sql-settings.h Tue Oct 13 20:40:38 2015 +0300 @@ -19,6 +19,7 @@ const char *table; const char *username_field; const char *value_field; + const char *value_type; bool value_hexblob; ARRAY(struct dict_sql_field) sql_fields; diff -r c854e1b3e419 -r 6bb60a869c71 src/lib-dict/dict-sql.c --- a/src/lib-dict/dict-sql.c Tue Oct 13 20:39:50 2015 +0300 +++ b/src/lib-dict/dict-sql.c Tue Oct 13 20:40:38 2015 +0300 @@ -380,13 +380,26 @@ return str_c(str); } +static enum dict_sql_type +sql_dict_map_type(const struct dict_sql_map *map) +{ + if (map->value_type != NULL) { + if (strcmp(map->value_type, "string") == 0) + return DICT_SQL_TYPE_STRING; + if (strcmp(map->value_type, "hexblob") == 0) + return DICT_SQL_TYPE_HEXBLOB; + if (strcmp(map->value_type, "uint") == 0) + return DICT_SQL_TYPE_UINT; + i_unreached(); /* should have checked already at parsing */ + } + return map->value_hexblob ? DICT_SQL_TYPE_HEXBLOB : DICT_SQL_TYPE_STRING; +} + static const char * sql_dict_result_unescape_value(const struct dict_sql_map *map, pool_t pool, struct sql_result *result) { - enum dict_sql_type value_type = map->value_hexblob ? - DICT_SQL_TYPE_HEXBLOB : DICT_SQL_TYPE_STRING; - return sql_dict_result_unescape(value_type, pool, result, 0); + return sql_dict_result_unescape(sql_dict_map_type(map), pool, result, 0); } static const char * @@ -876,8 +889,8 @@ if (build->inc) str_append(suffix, fields[i].value); else { - enum dict_sql_type value_type = fields[i].map->value_hexblob ? - DICT_SQL_TYPE_HEXBLOB : DICT_SQL_TYPE_STRING; + enum dict_sql_type value_type = + sql_dict_map_type(fields[i].map); if (sql_dict_value_escape(suffix, dict, value_type, "value", fields[i].value, "", error_r) < 0) return -1; @@ -919,8 +932,8 @@ fields[i].map->value_field, fields[i].value); } else { - enum dict_sql_type value_type = fields[i].map->value_hexblob ? - DICT_SQL_TYPE_HEXBLOB : DICT_SQL_TYPE_STRING; + enum dict_sql_type value_type = + sql_dict_map_type(fields[i].map); if (sql_dict_value_escape(prefix, dict, value_type, "value", fields[i].value, "", error_r) < 0) return -1; From dovecot at dovecot.org Tue Oct 13 17:43:21 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 17:43:21 +0000 Subject: dovecot-2.2: cassandra: Added support for returning "int" type v... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c854e1b3e419 changeset: 19297:c854e1b3e419 user: Timo Sirainen date: Tue Oct 13 20:39:50 2015 +0300 description: cassandra: Added support for returning "int" type values. It looks like we need to explicitly convert all types to strings. diffstat: src/lib-sql/driver-cassandra.c | 23 +++++++++++++++++++++-- 1 files changed, 21 insertions(+), 2 deletions(-) diffs (41 lines): diff -r dce5ee506cc8 -r c854e1b3e419 src/lib-sql/driver-cassandra.c --- a/src/lib-sql/driver-cassandra.c Tue Oct 13 13:44:48 2015 +0300 +++ b/src/lib-sql/driver-cassandra.c Tue Oct 13 20:39:50 2015 +0300 @@ -723,16 +723,35 @@ void *output_dup; size_t output_size; CassError rc; + const char *type; if (cass_value_is_null(value)) { *str_r = NULL; return 0; } - rc = cass_value_get_bytes(value, &output, &output_size); + switch (cass_data_type_type(cass_value_data_type(value))) { + case CASS_VALUE_TYPE_INT: { + cass_int32_t num; + + rc = cass_value_get_int32(value, &num); + if (rc == CASS_OK) { + const char *str = t_strdup_printf("%d", num); + output_size = strlen(str); + output = (const void *)str; + } + type = "int32"; + break; + } + default: + rc = cass_value_get_bytes(value, &output, &output_size); + type = "bytes"; + break; + } if (rc != CASS_OK) { i_free(result->error); - result->error = i_strdup_printf("Couldn't get value as string (code=%d)", rc); + result->error = i_strdup_printf("Couldn't get value as %s: %s", + type, cass_error_desc(rc)); return -1; } output_dup = p_malloc(result->row_pool, output_size + 1); From dovecot at dovecot.org Tue Oct 13 17:43:28 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 17:43:28 +0000 Subject: dovecot-2.2: lib: uri_parser_init() wasn't using pool parameter ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/b0545670fd99 changeset: 19299:b0545670fd99 user: Timo Sirainen date: Tue Oct 13 20:41:36 2015 +0300 description: lib: uri_parser_init() wasn't using pool parameter for anything. Now everything is allocated from it instead of from data stack. diffstat: src/lib/uri-util.c | 30 ++++++++++++++++-------------- 1 files changed, 16 insertions(+), 14 deletions(-) diffs (135 lines): diff -r 6bb60a869c71 -r b0545670fd99 src/lib/uri-util.c --- a/src/lib/uri-util.c Tue Oct 13 20:40:38 2015 +0300 +++ b/src/lib/uri-util.c Tue Oct 13 20:41:36 2015 +0300 @@ -103,7 +103,7 @@ } if ((value = _decode_hex_digit(**p)) < 0) { - parser->error = t_strdup_printf( + parser->error = p_strdup_printf(parser->pool, "Expecting hex digit after '%%', but found '%c'", **p); return -1; } @@ -112,7 +112,7 @@ *p += 1; if ((value = _decode_hex_digit(**p)) < 0) { - parser->error = t_strdup_printf( + parser->error = p_strdup_printf(parser->pool, "Expecting hex digit after '%%%c', but found '%c'", *((*p)-1), **p); return -1; } @@ -207,7 +207,7 @@ } if (decoded_r != NULL) - *decoded_r = t_strdup(str_c(decoded)); + *decoded_r = p_strdup(parser->pool, str_c(decoded)); return TRUE; } @@ -252,6 +252,8 @@ return 0; parser->cur = (const unsigned char *)p; + if (!parser->pool->datastack_pool) + *scheme_r = p_strdup(parser->pool, *scheme_r); return 1; } @@ -400,12 +402,12 @@ return -1; } if (*address == 'v') { - parser->error = t_strdup_printf( + parser->error = p_strdup_printf(parser->pool, "Future IP host address '%s' not supported", address); return -1; } if ((ret = inet_pton(AF_INET6, address, &ip6)) <= 0) { - parser->error = t_strdup_printf( + parser->error = p_strdup_printf(parser->pool, "Invalid IPv6 host address '%s'", address); return -1; } @@ -439,7 +441,7 @@ return -1; if (auth != NULL) { - auth->host_literal = t_strdup(str_c(literal)); + auth->host_literal = p_strdup(parser->pool, str_c(literal)); auth->host_ip.family = AF_INET6; auth->host_ip.u.ip6 = ip6; auth->have_host_ip = TRUE; @@ -458,7 +460,7 @@ preserve = parser->cur; if ((ret = uri_parse_ipv4address(parser, literal, &ip4)) > 0) { if (auth != NULL) { - auth->host_literal = t_strdup(str_c(literal)); + auth->host_literal = p_strdup(parser->pool, str_c(literal)); auth->host_ip.family = AF_INET; auth->host_ip.u.ip4 = ip4; auth->have_host_ip = TRUE; @@ -472,7 +474,7 @@ if (uri_parse_reg_name(parser, literal) < 0) return -1; if (auth != NULL) { - auth->host_literal = t_strdup(str_c(literal)); + auth->host_literal = p_strdup(parser->pool, str_c(literal)); auth->have_host_ip = FALSE; } return 0; @@ -535,7 +537,7 @@ /* Extract userinfo */ if (p < parser->end && *p == '@') { if (auth != NULL) - auth->enc_userinfo = t_strdup_until(parser->cur, p); + auth->enc_userinfo = p_strdup_until(parser->pool, parser->cur, p); parser->cur = p+1; } @@ -605,7 +607,7 @@ return 0; if (segment_r != NULL) - *segment_r = t_strdup_until(parser->cur, p); + *segment_r = p_strdup_until(parser->pool, parser->cur, p); parser->cur = p; return 1; } @@ -622,7 +624,7 @@ count = 0; if (path_r != NULL) - t_array_init(&segments, 16); + p_array_init(&segments, parser->pool, 16); else memset(&segments, 0, sizeof(segments)); @@ -740,7 +742,7 @@ } if (query_r != NULL) - *query_r = t_strdup_until(parser->cur+1, p); + *query_r = p_strdup_until(parser->pool, parser->cur+1, p); parser->cur = p; return 1; } @@ -777,7 +779,7 @@ } if (fragment_r != NULL) - *fragment_r = t_strdup_until(parser->cur+1, p); + *fragment_r = p_strdup_until(parser->pool, parser->cur+1, p); parser->cur = p; return 1; } @@ -794,7 +796,7 @@ string_t *uri_parser_get_tmpbuf(struct uri_parser *parser, size_t size) { if (parser->tmpbuf == NULL) - parser->tmpbuf = t_str_new(size); + parser->tmpbuf = str_new(parser->pool, size); else str_truncate(parser->tmpbuf, 0); return parser->tmpbuf; From dovecot at dovecot.org Tue Oct 13 18:23:28 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 18:23:28 +0000 Subject: dovecot-2.2: auth ldap: If tls_* settings are used, pass them to... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/727acba74cbf changeset: 19300:727acba74cbf user: Timo Sirainen date: Tue Oct 13 21:21:48 2015 +0300 description: auth ldap: If tls_* settings are used, pass them to LDAP library even if tls=no Most importantly this allows using the settings for ldaps URLs. And they hopefully won't hurt anything if neither STARTTLS nor ldaps are used. diffstat: src/auth/db-ldap.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diffs (13 lines): diff -r b0545670fd99 -r 727acba74cbf src/auth/db-ldap.c --- a/src/auth/db-ldap.c Tue Oct 13 20:41:36 2015 +0300 +++ b/src/auth/db-ldap.c Tue Oct 13 21:21:48 2015 +0300 @@ -1064,9 +1064,6 @@ static void db_ldap_set_tls_options(struct ldap_connection *conn) { - if (!conn->set.tls) - return; - #ifdef OPENLDAP_TLS_OPTIONS db_ldap_set_opt_str(conn, NULL, LDAP_OPT_X_TLS_CACERTFILE, conn->set.tls_ca_cert_file, "tls_ca_cert_file"); From dovecot at dovecot.org Tue Oct 13 18:42:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 18:42:12 +0000 Subject: dovecot-2.2: imap: APPEND crashed if invalid keyword was given a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5e48c5a29ddd changeset: 19301:5e48c5a29ddd user: Timo Sirainen date: Tue Oct 13 21:40:33 2015 +0300 description: imap: APPEND crashed if invalid keyword was given as parameter. diffstat: src/imap/cmd-append.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 727acba74cbf -r 5e48c5a29ddd src/imap/cmd-append.c --- a/src/imap/cmd-append.c Tue Oct 13 21:21:48 2015 +0300 +++ b/src/imap/cmd-append.c Tue Oct 13 21:40:33 2015 +0300 @@ -534,6 +534,7 @@ /* invalid keywords - delay failure */ client_send_box_error(cmd, ctx->box); ctx->failed = TRUE; + keywords = NULL; } } From dovecot at dovecot.org Tue Oct 13 18:59:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 13 Oct 2015 18:59:12 +0000 Subject: dovecot-2.2: lib-storage: Support latest cache fields in struct ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3b1e7941542f changeset: 19302:3b1e7941542f user: Timo Sirainen date: Tue Oct 13 21:57:29 2015 +0300 description: lib-storage: Support latest cache fields in struct mailbox_metadata.precache_fields diffstat: src/lib-storage/index/index-mail.c | 3 +++ src/lib-storage/index/index-status.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletions(-) diffs (37 lines): diff -r 5e48c5a29ddd -r 3b1e7941542f src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Tue Oct 13 21:40:33 2015 +0300 +++ b/src/lib-storage/index/index-mail.c Tue Oct 13 21:57:29 2015 +0300 @@ -61,6 +61,9 @@ .type = MAIL_CACHE_FIELD_VARIABLE_SIZE }, { .name = "body.snippet", .type = MAIL_CACHE_FIELD_VARIABLE_SIZE } + /* FIXME: for now need to update get_metadata_precache_fields() in + index-status.c when adding more fields. those fields should probably + just be moved here to the same struct. */ }; static int index_mail_parse_body(struct index_mail *mail, diff -r 5e48c5a29ddd -r 3b1e7941542f src/lib-storage/index/index-status.c --- a/src/lib-storage/index/index-status.c Tue Oct 13 21:40:33 2015 +0300 +++ b/src/lib-storage/index/index-status.c Tue Oct 13 21:57:29 2015 +0300 @@ -237,8 +237,10 @@ strcmp(name, "imap.envelope") == 0) cache |= MAIL_FETCH_STREAM_HEADER; else if (strcmp(name, "mime.parts") == 0 || + strcmp(name, "binary.parts") == 0 || strcmp(name, "imap.body") == 0 || - strcmp(name, "imap.bodystructure") == 0) + strcmp(name, "imap.bodystructure") == 0 || + strcmp(name, "body.snippet") == 0) cache |= MAIL_FETCH_STREAM_BODY; else if (strcmp(name, "date.received") == 0) cache |= MAIL_FETCH_RECEIVED_DATE; @@ -250,6 +252,8 @@ cache |= MAIL_FETCH_PHYSICAL_SIZE; else if (strcmp(name, "pop3.uidl") == 0) cache |= MAIL_FETCH_UIDL_BACKEND; + else if (strcmp(name, "pop3.order") == 0) + cache |= MAIL_FETCH_POP3_ORDER; else if (strcmp(name, "guid") == 0) cache |= MAIL_FETCH_GUID; else if (strcmp(name, "flags") == 0) { From dovecot at dovecot.org Wed Oct 14 10:52:25 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Oct 2015 10:52:25 +0000 Subject: dovecot-2.2: dict-sql: dict_lookup_async() didn't call callback ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a5e47d9637c3 changeset: 19303:a5e47d9637c3 user: Timo Sirainen date: Wed Oct 14 13:32:02 2015 +0300 description: dict-sql: dict_lookup_async() didn't call callback on query build failures. diffstat: src/lib-dict/dict-sql.c | 26 ++++++++++++++++++++------ 1 files changed, 20 insertions(+), 6 deletions(-) diffs (65 lines): diff -r 3b1e7941542f -r a5e47d9637c3 src/lib-dict/dict-sql.c --- a/src/lib-dict/dict-sql.c Tue Oct 13 21:57:29 2015 +0300 +++ b/src/lib-dict/dict-sql.c Wed Oct 14 13:32:02 2015 +0300 @@ -337,7 +337,8 @@ static int sql_lookup_get_query(struct sql_dict *dict, const char *key, - string_t *query, const struct dict_sql_map **map_r) + string_t *query, const struct dict_sql_map **map_r, + const char **error_r) { const struct dict_sql_map *map; ARRAY_TYPE(const_string) values; @@ -345,14 +346,16 @@ map = *map_r = sql_dict_find_map(dict, key, &values); if (map == NULL) { - i_error("sql dict lookup: Invalid/unmapped key: %s", key); + *error_r = t_strdup_printf( + "sql dict lookup: Invalid/unmapped key: %s", key); return -1; } str_printfa(query, "SELECT %s FROM %s", map->value_field, map->table); if (sql_dict_where_build(dict, map, &values, key[0], SQL_DICT_RECURSE_NONE, query, &error) < 0) { - i_error("sql dict lookup: Failed to lookup key %s: %s", key, error); + *error_r = t_strdup_printf( + "sql dict lookup: Failed to lookup key %s: %s", key, error); return -1; } return 0; @@ -424,9 +427,12 @@ T_BEGIN { string_t *query = t_str_new(256); + const char *error; - ret = sql_lookup_get_query(dict, key, query, &map); - if (ret == 0) + ret = sql_lookup_get_query(dict, key, query, &map, &error); + if (ret < 0) + i_error("%s", error); + else result = sql_query_s(dict->db, str_c(query)); } T_END; @@ -485,8 +491,16 @@ T_BEGIN { string_t *query = t_str_new(256); + const char *error; - if (sql_lookup_get_query(dict, key, query, &map) == 0) { + if (sql_lookup_get_query(dict, key, query, &map, &error) < 0) { + struct dict_lookup_result result; + + memset(&result, 0, sizeof(result)); + result.ret = -1; + result.error = error; + callback(&result, context); + } else { ctx = i_new(struct sql_dict_lookup_context, 1); ctx->callback = callback; ctx->context = context; From dovecot at dovecot.org Wed Oct 14 11:08:20 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Oct 2015 11:08:20 +0000 Subject: dovecot-2.2: cassandra: Added read/write/delete_fallback_consist... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8f7a0201ebe3 changeset: 19304:8f7a0201ebe3 user: Timo Sirainen date: Wed Oct 14 14:06:35 2015 +0300 description: cassandra: Added read/write/delete_fallback_consistency settings. The fallback is attempted if the primary consistency can't be satisfied. One useful use case for this is to have: write_consistency=each-quorum write_fallback_consistency=local-quorum Which means that during regular operation all writes go to all data centers before they are finished, but if one of the data centers go down we'll switch to just waiting for local data center writes to finish. diffstat: src/lib-sql/driver-cassandra.c | 126 ++++++++++++++++++++++++++++++++++++++-- 1 files changed, 118 insertions(+), 8 deletions(-) diffs (242 lines): diff -r a5e47d9637c3 -r 8f7a0201ebe3 src/lib-sql/driver-cassandra.c --- a/src/lib-sql/driver-cassandra.c Wed Oct 14 13:32:02 2015 +0300 +++ b/src/lib-sql/driver-cassandra.c Wed Oct 14 14:06:35 2015 +0300 @@ -17,6 +17,10 @@ ((db)->api.state != SQL_DB_STATE_DISCONNECTED && \ (db)->api.state != SQL_DB_STATE_CONNECTING) +#define CASSANDRA_FALLBACK_WARN_INTERVAL_SECS 60 +#define CASSANDRA_FALLBACK_FIRST_RETRY_MSECS 50 +#define CASSANDRA_FALLBACK_MAX_RETRY_MSECS (1000*60) + typedef void driver_cassandra_callback_t(CassFuture *future, void *context); enum cassandra_query_type { @@ -24,6 +28,11 @@ CASSANDRA_QUERY_TYPE_WRITE, CASSANDRA_QUERY_TYPE_DELETE }; +#define CASSANDRA_QUERY_TYPE_COUNT 3 + +static const char *cassandra_query_type_names[CASSANDRA_QUERY_TYPE_COUNT] = { + "read", "write", "delete" +}; struct cassandra_callback { unsigned int id; @@ -38,6 +47,7 @@ char *hosts, *keyspace; CassConsistency read_consistency, write_consistency, delete_consistency; + CassConsistency read_fallback_consistency, write_fallback_consistency, delete_fallback_consistency; CassLogLevel log_level; unsigned int protocol_version; @@ -51,6 +61,10 @@ ARRAY(struct cassandra_result *) results; unsigned int callback_ids; + struct timeval first_fallback_sent[CASSANDRA_QUERY_TYPE_COUNT]; + time_t last_fallback_warning[CASSANDRA_QUERY_TYPE_COUNT]; + unsigned int fallback_failures[CASSANDRA_QUERY_TYPE_COUNT]; + /* for synchronous queries: */ struct ioloop *ioloop, *orig_ioloop; struct sql_result *sync_result; @@ -65,6 +79,7 @@ CassIterator *iterator; char *query; char *error; + CassConsistency consistency, fallback_consistency; enum cassandra_query_type query_type; struct timeval start_time, finish_time; unsigned int row_count; @@ -129,6 +144,7 @@ { CASS_LOG_TRACE, "trace" } }; +static void driver_cassandra_result_send_query(struct cassandra_result *result); static void driver_cassandra_send_queries(struct cassandra_db *db); static void result_finish(struct cassandra_result *result); @@ -350,6 +366,7 @@ { const char *const *args, *key, *value; string_t *hosts = t_str_new(64); + bool read_fallback_set = FALSE, write_fallback_set = FALSE, delete_fallback_set = FALSE; db->log_level = CASS_LOG_WARN; db->read_consistency = CASS_CONSISTENCY_LOCAL_QUORUM; @@ -376,12 +393,24 @@ } else if (strcmp(key, "read_consistency") == 0) { if (consistency_parse(value, &db->read_consistency) < 0) i_fatal("cassandra: Unknown read_consistency: %s", value); + } else if (strcmp(key, "read_fallback_consistency") == 0) { + if (consistency_parse(value, &db->read_fallback_consistency) < 0) + i_fatal("cassandra: Unknown read_fallback_consistency: %s", value); + read_fallback_set = TRUE; } else if (strcmp(key, "write_consistency") == 0) { if (consistency_parse(value, &db->write_consistency) < 0) i_fatal("cassandra: Unknown write_consistency: %s", value); + } else if (strcmp(key, "write_fallback_consistency") == 0) { + if (consistency_parse(value, &db->write_fallback_consistency) < 0) + i_fatal("cassandra: Unknown write_fallback_consistency: %s", value); + write_fallback_set = TRUE; } else if (strcmp(key, "delete_consistency") == 0) { if (consistency_parse(value, &db->delete_consistency) < 0) i_fatal("cassandra: Unknown delete_consistency: %s", value); + } else if (strcmp(key, "delete_fallback_consistency") == 0) { + if (consistency_parse(value, &db->delete_fallback_consistency) < 0) + i_fatal("cassandra: Unknown delete_fallback_consistency: %s", value); + delete_fallback_set = TRUE; } else if (strcmp(key, "log_level") == 0) { if (log_level_parse(value, &db->log_level) < 0) i_fatal("cassandra: Unknown log_level: %s", value); @@ -393,6 +422,13 @@ } } + if (!read_fallback_set) + db->read_fallback_consistency = db->read_consistency; + if (!write_fallback_set) + db->write_fallback_consistency = db->write_consistency; + if (!delete_fallback_set) + db->delete_fallback_consistency = db->delete_consistency; + if (str_len(hosts) == 0) i_fatal("cassandra: No hosts given in connect string"); if (db->keyspace == NULL) @@ -526,11 +562,34 @@ sql_result_unref(&result->api); } +static void query_resend_with_fallback(struct cassandra_result *result) +{ + struct cassandra_db *db = (struct cassandra_db *)result->api.db; + time_t last_warning = + ioloop_time - db->last_fallback_warning[result->query_type]; + + if (last_warning >= CASSANDRA_FALLBACK_WARN_INTERVAL_SECS) { + i_warning("%s - retrying future %s queries with consistency %s (instead of %s)", + result->error, cassandra_query_type_names[result->query_type], + cass_consistency_string(result->fallback_consistency), + cass_consistency_string(result->consistency)); + db->last_fallback_warning[result->query_type] = ioloop_time; + } + i_free_and_null(result->error); + if (db->fallback_failures[result->query_type]++ == 0) + db->first_fallback_sent[result->query_type] = ioloop_timeval; + + result->consistency = result->fallback_consistency; + driver_cassandra_result_send_query(result); +} + static void query_callback(CassFuture *future, void *context) { struct cassandra_result *result = context; + struct cassandra_db *db = (struct cassandra_db *)result->api.db; + CassError error = cass_future_error_code(future); - if (cass_future_error_code(future) != CASS_OK) { + if (error != CASS_OK) { const char *errmsg; size_t errsize; @@ -539,18 +598,64 @@ result->error = i_strdup_printf("Query '%s' failed: %.*s", result->query, (int)errsize, errmsg); + if (error == CASS_ERROR_SERVER_UNAVAILABLE && + result->fallback_consistency != result->consistency) { + /* retry with fallback consistency */ + query_resend_with_fallback(result); + return; + } result_finish(result); return; } + + if (result->fallback_consistency != result->consistency) { + /* non-fallback query finished successfully. if there had been + any fallbacks, reset them. */ + db->fallback_failures[result->query_type] = 0; + } + result->result = cass_future_get_result(future); result->iterator = cass_iterator_from_result(result->result); result_finish(result); } +static void driver_cassandra_result_send_query(struct cassandra_result *result) +{ + struct cassandra_db *db = (struct cassandra_db *)result->api.db; + CassFuture *future; + + result->statement = cass_statement_new(result->query, 0); + cass_statement_set_consistency(result->statement, result->consistency); + + future = cass_session_execute(db->session, result->statement); + driver_cassandra_set_callback(future, db, query_callback, result); +} + +static bool +driver_cassandra_want_fallback_query(struct cassandra_result *result) +{ + struct cassandra_db *db = (struct cassandra_db *)result->api.db; + unsigned int failure_count = db->fallback_failures[result->query_type]; + unsigned int i, msecs = CASSANDRA_FALLBACK_FIRST_RETRY_MSECS; + struct timeval tv; + + if (failure_count == 0) + return FALSE; + tv = db->first_fallback_sent[result->query_type]; + for (i = 1; i < failure_count; i++) { + msecs *= 2; + if (msecs >= CASSANDRA_FALLBACK_MAX_RETRY_MSECS) { + msecs = CASSANDRA_FALLBACK_FIRST_RETRY_MSECS; + break; + } + } + timeval_add_msecs(&tv, msecs); + return timeval_cmp(&ioloop_timeval, &tv) < 0; +} + static int driver_cassandra_send_query(struct cassandra_result *result) { struct cassandra_db *db = (struct cassandra_db *)result->api.db; - CassFuture *future; int ret; if (!SQL_DB_IS_READY(&db->api)) { @@ -563,20 +668,25 @@ result->start_time = ioloop_timeval; result->row_pool = pool_alloconly_create("cassandra result", 512); - result->statement = cass_statement_new(result->query, 0); switch (result->query_type) { case CASSANDRA_QUERY_TYPE_READ: - cass_statement_set_consistency(result->statement, db->read_consistency); + result->consistency = db->read_consistency; + result->fallback_consistency = db->read_fallback_consistency; break; case CASSANDRA_QUERY_TYPE_WRITE: - cass_statement_set_consistency(result->statement, db->write_consistency); + result->consistency = db->write_consistency; + result->fallback_consistency = db->write_fallback_consistency; break; case CASSANDRA_QUERY_TYPE_DELETE: - cass_statement_set_consistency(result->statement, db->delete_consistency); + result->consistency = db->delete_consistency; + result->fallback_consistency = db->delete_fallback_consistency; break; } - future = cass_session_execute(db->session, result->statement); - driver_cassandra_set_callback(future, db, query_callback, result); + + if (driver_cassandra_want_fallback_query(result)) + result->consistency = result->fallback_consistency; + + driver_cassandra_result_send_query(result); result->query_sent = TRUE; return 1; } From dovecot at dovecot.org Wed Oct 14 14:29:52 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Oct 2015 14:29:52 +0000 Subject: dovecot-2.2: imap/pop3-login: If LOGIN/USER is used with plainte... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/06908dbcee62 changeset: 19305:06908dbcee62 user: Timo Sirainen date: Wed Oct 14 17:28:11 2015 +0300 description: imap/pop3-login: If LOGIN/USER is used with plaintext auth disabled, remember the username for logging. It's still useful to see the username that was sent in the logout message. This won't work for AUTHENTICATE PLAIN, but hopefully the clients that use it understand the LOGINDISABLED capability better. diffstat: src/imap-login/client-authenticate.c | 5 ++++- src/pop3-login/client-authenticate.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diffs (32 lines): diff -r 8f7a0201ebe3 -r 06908dbcee62 src/imap-login/client-authenticate.c --- a/src/imap-login/client-authenticate.c Wed Oct 14 14:06:35 2015 +0300 +++ b/src/imap-login/client-authenticate.c Wed Oct 14 17:28:11 2015 +0300 @@ -180,8 +180,11 @@ !IMAP_ARG_IS_EOL(&args[2])) return -1; - if (!client_check_plaintext_auth(client, TRUE)) + if (!client_check_plaintext_auth(client, TRUE)) { + if (client->virtual_user == NULL) + client->virtual_user = i_strdup(user); return 1; + } /* authorization ID \0 authentication ID \0 pass */ plain_login = buffer_create_dynamic(pool_datastack_create(), 64); diff -r 8f7a0201ebe3 -r 06908dbcee62 src/pop3-login/client-authenticate.c --- a/src/pop3-login/client-authenticate.c Wed Oct 14 14:06:35 2015 +0300 +++ b/src/pop3-login/client-authenticate.c Wed Oct 14 17:28:11 2015 +0300 @@ -108,8 +108,11 @@ bool cmd_user(struct pop3_client *pop3_client, const char *args) { - if (!client_check_plaintext_auth(&pop3_client->common, FALSE)) + if (!client_check_plaintext_auth(&pop3_client->common, FALSE)) { + if (pop3_client->common.virtual_user == NULL) + pop3_client->common.virtual_user = i_strdup(args); return TRUE; + } i_free(pop3_client->last_user); pop3_client->last_user = i_strdup(args); From dovecot at dovecot.org Wed Oct 14 14:36:04 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Oct 2015 14:36:04 +0000 Subject: dovecot-2.2: dsync: If rename algorithm seems go to an infinite ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ca17b29b1720 changeset: 19306:ca17b29b1720 user: Timo Sirainen date: Wed Oct 14 17:34:23 2015 +0300 description: dsync: If rename algorithm seems go to an infinite loop, log an error and stop. Ideally we would of course fix the algorithm (especially to not require this kind of looping). diffstat: src/doveadm/dsync/dsync-mailbox-tree-sync.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diffs (35 lines): diff -r 06908dbcee62 -r ca17b29b1720 src/doveadm/dsync/dsync-mailbox-tree-sync.c --- a/src/doveadm/dsync/dsync-mailbox-tree-sync.c Wed Oct 14 17:28:11 2015 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-tree-sync.c Wed Oct 14 17:34:23 2015 +0300 @@ -15,6 +15,8 @@ #define TEMP_SUFFIX_MAX_LEN (sizeof("temp-")-1 + 8) #define TEMP_SUFFIX_FORMAT "temp-%x" +#define MAX_RENAMES 100 + struct dsync_mailbox_tree_bfs_iter { struct dsync_mailbox_tree *tree; @@ -1076,6 +1078,7 @@ static void dsync_mailbox_tree_handle_renames(struct dsync_mailbox_tree_sync_ctx *ctx) { + unsigned int count = 0; bool changed; do { @@ -1088,7 +1091,13 @@ i_debug("brain %c: -- Mailbox renamed, restart sync --", (ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN) != 0 ? 'M' : 'S'); } - } while (changed); + } while (changed && ++count <= MAX_RENAMES); + + if (changed) { + i_error("BUG: Mailbox renaming algorithm got into a potentially infinite loop, aborting"); + ctx->brain->failed = TRUE; + } + while (sync_rename_temp_mailboxes(ctx, ctx->local_tree, &ctx->local_tree->root)) ; while (sync_rename_temp_mailboxes(ctx, ctx->remote_tree, &ctx->remote_tree->root)) ; } From dovecot at dovecot.org Thu Oct 15 11:45:58 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 15 Oct 2015 11:45:58 +0000 Subject: dovecot-2.2: lib-mail: fix html2text parser Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/17aac21b303d changeset: 19307:17aac21b303d user: Phil Carmody date: Thu Oct 15 14:44:03 2015 +0300 description: lib-mail: fix html2text parser Silly typo. Fixes bug reported on dovecot list by Akash on Oct 14. Signed-off-by: Phil Carmody diffstat: src/lib-mail/mail-html2text.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ca17b29b1720 -r 17aac21b303d src/lib-mail/mail-html2text.c --- a/src/lib-mail/mail-html2text.c Wed Oct 14 17:34:23 2015 +0300 +++ b/src/lib-mail/mail-html2text.c Thu Oct 15 14:44:03 2015 +0300 @@ -192,7 +192,7 @@ if (c == '"') ht->state = HTML_STATE_TAG_DQUOTED; else if (c == '\'') - ht->state = HTML_STATE_TAG_DQUOTED; + ht->state = HTML_STATE_TAG_SQUOTED; else if (c == '>') { ht->state = HTML_STATE_TEXT; mail_html2text_add_space(output); From dovecot at dovecot.org Mon Oct 19 10:37:34 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 10:37:34 +0000 Subject: dovecot-2.2: man: Changed "pattern" to "string" in doveamd-searc... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/66be949b9bcc changeset: 19308:66be949b9bcc user: Timo Sirainen date: Mon Oct 19 13:37:25 2015 +0300 description: man: Changed "pattern" to "string" in doveamd-search-query(7) diffstat: doc/man/doveadm-search-query.7 | 36 ++++++++++++++++++------------------ 1 files changed, 18 insertions(+), 18 deletions(-) diffs (98 lines): diff -r 17aac21b303d -r 66be949b9bcc doc/man/doveadm-search-query.7 --- a/doc/man/doveadm-search-query.7 Thu Oct 15 14:44:03 2015 +0300 +++ b/doc/man/doveadm-search-query.7 Mon Oct 19 13:37:25 2015 +0300 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2015 Dovecot authors, see the included COPYING file -.TH DOVEADM\-SEARCH\-QUERY 7 "2011-11-24" "Dovecot v2.2" "Dovecot" +.TH DOVEADM\-SEARCH\-QUERY 7 "2015-10-19" "Dovecot v2.2" "Dovecot" .SH NAME doveadm\-search\-query \- Overview of search queries for doveadm mailbox \ commands @@ -100,9 +100,9 @@ Matches messages with the IMAP flag \(rsAnswered set. .\"----------------- .TP -.BI BCC\ pattern +.BI BCC\ string Matches messages, which contain -.I pattern +.I string in the BCC field of the message\(aqs IMAP envelope structure. .\"----------------- .TP @@ -111,15 +111,15 @@ .IR date\ specification . .\"----------------- .TP -.BI BODY\ pattern +.BI BODY\ string Matches messages, which contain -.I pattern +.I string in the body part. .\"----------------- .TP -.BI CC\ pattern +.BI CC\ string Matches messages, which contain -.I pattern +.I string in the CC field of the message\(aqs IMAP envelope structure. .\"----------------- .TP @@ -135,22 +135,22 @@ Matches messages with the IMAP flag \(rsFlagged set. .\"----------------- .TP -.BI FROM\ pattern +.BI FROM\ string Matches messages, which contain -.I pattern +.I string in the FROM field of the message\(aqs IMAP envelope structure. .\"----------------- .TP -\fBHEADER\fP \fIfield\fP \fIpattern\fP +\fBHEADER\fP \fIfield\fP \fIstring\fP Matches messages, which either have the named header .IR field , when empty -.I pattern +.I string was given. Or messages, where the given header .IR field \(aqs value contains the specified -.IR pattern . +.IR string . .\"----------------- .TP .BI KEYWORD\ keyword @@ -236,21 +236,21 @@ .IR size . .\"----------------- .TP -.BI SUBJECT\ pattern +.BI SUBJECT\ string Matches messages, which contain -.I pattern +.I string in the SUBJECT field of the message\(aqs IMAP envelope structure. .\"----------------- .TP -.BI TEXT\ pattern +.BI TEXT\ string Matches messages, which contain -.I pattern +.I string in the message body. .\"----------------- .TP -.BI TO\ pattern +.BI TO\ string Matches messages, which contain -.I pattern +.I string in the TO field of the message\(aqs IMAP envelope structure. .\"----------------- .TP From dovecot at dovecot.org Mon Oct 19 10:50:02 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 10:50:02 +0000 Subject: dovecot-2.2: director: Small code cleanup - make it easier to ad... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8e9cada0c8fc changeset: 19309:8e9cada0c8fc user: Timo Sirainen date: Mon Oct 19 13:40:52 2015 +0300 description: director: Small code cleanup - make it easier to add parameters to HOST diffstat: src/director/director-connection.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) diffs (40 lines): diff -r 66be949b9bcc -r 8e9cada0c8fc src/director/director-connection.c --- a/src/director/director-connection.c Mon Oct 19 13:37:25 2015 +0300 +++ b/src/director/director-connection.c Mon Oct 19 13:40:52 2015 +0300 @@ -864,26 +864,26 @@ struct mail_host *host; struct ip_addr ip; const char *tag = ""; - unsigned int vhost_count; + unsigned int arg_count, vhost_count; bool update, down = FALSE; time_t last_updown_change = 0; - if (str_array_length(args) < 2 || + arg_count = str_array_length(args); + if (arg_count < 2 || net_addr2ip(args[0], &ip) < 0 || str_to_uint(args[1], &vhost_count) < 0) { director_cmd_error(conn, "Invalid parameters"); return FALSE; } - if (args[2] != NULL) { + if (arg_count >= 3) tag = args[2]; - if (args[3] != NULL) { - if ((args[3][0] != 'D' && args[3][0] != 'U') || - str_to_time(args[3]+1, &last_updown_change) < 0) { - director_cmd_error(conn, "Invalid updown parameters"); - return FALSE; - } - down = args[3][0] == 'D'; + if (arg_count >= 4) { + if ((args[3][0] != 'D' && args[3][0] != 'U') || + str_to_time(args[3]+1, &last_updown_change) < 0) { + director_cmd_error(conn, "Invalid updown parameters"); + return FALSE; } + down = args[3][0] == 'D'; } if (conn->ignore_host_events) { /* remote is sending hosts in a handshake, but it doesn't have From dovecot at dovecot.org Mon Oct 19 10:50:03 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 10:50:03 +0000 Subject: dovecot-2.2: director: Remember backends' hostnames and send the... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/7f718c840aff changeset: 19310:7f718c840aff user: Timo Sirainen date: Mon Oct 19 13:49:54 2015 +0300 description: director: Remember backends' hostnames and send them in login reply. This allows login processes to verify the remote server's hostname in SSL certificate. diffstat: src/director/director-connection.c | 11 ++++++++--- src/director/director-request.c | 5 +++-- src/director/director-request.h | 4 ++-- src/director/director.c | 6 +++++- src/director/login-connection.c | 17 +++++++++++++---- src/director/mail-host.c | 27 ++++++++++++++++++++++----- src/director/mail-host.h | 4 ++++ 7 files changed, 57 insertions(+), 17 deletions(-) diffs (211 lines): diff -r 8e9cada0c8fc -r 7f718c840aff src/director/director-connection.c --- a/src/director/director-connection.c Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/director-connection.c Mon Oct 19 13:49:54 2015 +0300 @@ -863,7 +863,7 @@ struct director_host *src_host = conn->host; struct mail_host *host; struct ip_addr ip; - const char *tag = ""; + const char *tag = "", *hostname = NULL; unsigned int arg_count, vhost_count; bool update, down = FALSE; time_t last_updown_change = 0; @@ -885,6 +885,8 @@ } down = args[3][0] == 'D'; } + if (arg_count >= 5) + hostname = args[4]; if (conn->ignore_host_events) { /* remote is sending hosts in a handshake, but it doesn't have a completed ring and we do. */ @@ -894,7 +896,8 @@ host = mail_host_lookup(conn->dir->mail_hosts, &ip); if (host == NULL) { - host = mail_host_add_ip(conn->dir->mail_hosts, &ip, tag); + host = mail_host_add_hostname(conn->dir->mail_hosts, + hostname, &ip, tag); update = TRUE; } else { update = host->vhost_count != vhost_count || @@ -1701,8 +1704,10 @@ str_append_tabescaped(str, host->tag); } if (send_updowns) { - str_printfa(str, "\t%c%ld", host->down ? 'D' : 'U', + str_printfa(str, "\t%c%ld\t", host->down ? 'D' : 'U', (long)host->last_updown_change); + if (host->hostname != NULL) + str_append_tabescaped(str, host->hostname); } str_append_c(str, '\n'); } diff -r 8e9cada0c8fc -r 7f718c840aff src/director/director-request.c --- a/src/director/director-request.c Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/director-request.c Mon Oct 19 13:49:54 2015 +0300 @@ -111,7 +111,7 @@ array_delete(&dir->pending_requests, 0, 1); T_BEGIN { - request->callback(NULL, errormsg, request->context); + request->callback(NULL, NULL, errormsg, request->context); } T_END; director_request_free(request); } @@ -316,7 +316,8 @@ i_assert(!user->weak); director_update_user(dir, dir->self_host, user); T_BEGIN { - request->callback(&user->host->ip, NULL, request->context); + request->callback(&user->host->ip, user->host->hostname, + NULL, request->context); } T_END; director_request_free(request); return TRUE; diff -r 8e9cada0c8fc -r 7f718c840aff src/director/director-request.h --- a/src/director/director-request.h Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/director-request.h Mon Oct 19 13:49:54 2015 +0300 @@ -5,8 +5,8 @@ struct director_request; typedef void -director_request_callback(const struct ip_addr *ip, const char *errormsg, - void *context); +director_request_callback(const struct ip_addr *ip, const char *hostname, + const char *errormsg, void *context); void director_request(struct director *dir, const char *username, const char *tag, diff -r 8e9cada0c8fc -r 7f718c840aff src/director/director.c --- a/src/director/director.c Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/director.c Mon Oct 19 13:49:54 2015 +0300 @@ -546,8 +546,12 @@ return; } if (dir->ring_min_version >= DIRECTOR_VERSION_UPDOWN) { - str_printfa(str, "\t%c%ld", host->down ? 'D' : 'U', + str_printfa(str, "\t%c%ld\t", host->down ? 'D' : 'U', (long)host->last_updown_change); + /* add any further version checks here - these directors ignore + any extra unknown arguments */ + if (host->hostname != NULL) + str_append_tabescaped(str, host->hostname); } str_append_c(str, '\n'); director_update_send(dir, src, str_c(str)); diff -r 8e9cada0c8fc -r 7f718c840aff src/director/login-connection.c --- a/src/director/login-connection.c Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/login-connection.c Mon Oct 19 13:49:54 2015 +0300 @@ -3,6 +3,7 @@ #include "lib.h" #include "ioloop.h" #include "net.h" +#include "str.h" #include "istream.h" #include "ostream.h" #include "llist.h" @@ -124,8 +125,8 @@ } static void -login_host_callback(const struct ip_addr *ip, const char *errormsg, - void *context) +login_host_callback(const struct ip_addr *ip, const char *hostname, + const char *errormsg, void *context) { struct login_host_request *request = context; struct director *dir = request->conn->dir; @@ -148,9 +149,17 @@ login_host_request_is_self(request, ip)) { line = request->line; } else { + string_t *str = t_str_new(64); + secs = dir->set->director_user_expire / 2; - line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u", - request->line, net_ip2addr(ip), secs); + str_printfa(str, "%s\tproxy_refresh=%u\t", request->line, secs); + if (hostname == NULL) + str_printfa(str, "host=%s", net_ip2addr(ip)); + else { + str_printfa(str, "host=%s\thostip=%s", + hostname, net_ip2addr(ip)); + } + line = str_c(str); } login_connection_send_line(request->conn, line); diff -r 8e9cada0c8fc -r 7f718c840aff src/director/mail-host.c --- a/src/director/mail-host.c Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/mail-host.c Mon Oct 19 13:49:54 2015 +0300 @@ -153,19 +153,35 @@ return host; } +struct mail_host * +mail_host_add_hostname(struct mail_host_list *list, const char *hostname, + const struct ip_addr *ip, const char *tag) +{ + struct mail_host *host; + + host = mail_host_add_ip(list, ip, tag); + host->hostname = i_strdup(hostname); + return host; +} + static int -mail_host_add(struct mail_host_list *list, const char *host, const char *tag) +mail_host_add(struct mail_host_list *list, const char *hostname, const char *tag) { - struct ip_addr *ips; + struct ip_addr *ips, ip; unsigned int i, ips_count; - if (net_gethostbyname(host, &ips, &ips_count) < 0) { - i_error("Unknown mail host: %s", host); + if (net_addr2ip(hostname, &ip) == 0) { + (void)mail_host_add_ip(list, &ip, tag); + return 0; + } + + if (net_gethostbyname(hostname, &ips, &ips_count) < 0) { + i_error("Unknown mail host: %s", hostname); return -1; } for (i = 0; i < ips_count; i++) - (void)mail_host_add_ip(list, &ips[i], tag); + (void)mail_host_add_hostname(list, hostname, &ips[i], tag); return 0; } @@ -309,6 +325,7 @@ static void mail_host_free(struct mail_host *host) { i_free(host->tag); + i_free(host->hostname); i_free(host); } diff -r 8e9cada0c8fc -r 7f718c840aff src/director/mail-host.h --- a/src/director/mail-host.h Mon Oct 19 13:40:52 2015 +0300 +++ b/src/director/mail-host.h Mon Oct 19 13:49:54 2015 +0300 @@ -14,6 +14,7 @@ time_t last_updown_change; struct ip_addr ip; + char *hostname; char *tag; /* host was recently changed and ring hasn't synced yet since */ @@ -25,6 +26,9 @@ mail_host_add_ip(struct mail_host_list *list, const struct ip_addr *ip, const char *tag); struct mail_host * +mail_host_add_hostname(struct mail_host_list *list, const char *hostname, + const struct ip_addr *ip, const char *tag); +struct mail_host * mail_host_lookup(struct mail_host_list *list, const struct ip_addr *ip); struct mail_host * mail_host_get_by_hash(struct mail_host_list *list, unsigned int hash, From dovecot at dovecot.org Mon Oct 19 11:05:35 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 11:05:35 +0000 Subject: dovecot-2.2: director: Fix to previous change - mail_host_dup() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5876ca2d63fb changeset: 19311:5876ca2d63fb user: Timo Sirainen date: Mon Oct 19 14:04:46 2015 +0300 description: director: Fix to previous change - mail_host_dup() wasn't strdup()ing hostname. This could have caused a crash at deinit. diffstat: src/director/mail-host.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 7f718c840aff -r 5876ca2d63fb src/director/mail-host.c --- a/src/director/mail-host.c Mon Oct 19 13:49:54 2015 +0300 +++ b/src/director/mail-host.c Mon Oct 19 14:04:46 2015 +0300 @@ -483,6 +483,7 @@ dest = i_new(struct mail_host, 1); *dest = *src; dest->tag = i_strdup(src->tag); + dest->hostname = i_strdup(src->hostname); return dest; } From dovecot at dovecot.org Mon Oct 19 11:05:35 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 11:05:35 +0000 Subject: dovecot-2.2: lib: net_gethostbyname() now supports [ipv6] style ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c5c34c02fda3 changeset: 19312:c5c34c02fda3 user: Timo Sirainen date: Mon Oct 19 14:05:26 2015 +0300 description: lib: net_gethostbyname() now supports [ipv6] style bracketed addresses. diffstat: src/lib/net.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diffs (26 lines): diff -r 5876ca2d63fb -r c5c34c02fda3 src/lib/net.c --- a/src/lib/net.c Mon Oct 19 14:04:46 2015 +0300 +++ b/src/lib/net.c Mon Oct 19 14:05:26 2015 +0300 @@ -628,6 +628,7 @@ #ifdef HAVE_IPV6 union sockaddr_union *so; struct addrinfo hints, *ai, *origai; + struct ip_addr ip; int host_error; #else struct hostent *hp; @@ -638,6 +639,14 @@ *ips_count = 0; #ifdef HAVE_IPV6 + /* support [ipv6] style addresses here so they work globally */ + if (addr[0] == '[' && net_addr2ip(addr, &ip) == 0) { + *ips_count = 1; + *ips = t_new(struct ip_addr, 1); + **ips = ip; + return 0; + } + memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; From dovecot at dovecot.org Mon Oct 19 11:29:18 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 11:29:18 +0000 Subject: dovecot-2.2: imapc: Set storage's error to "internal error" if w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/56d08de919a1 changeset: 19313:56d08de919a1 user: Timo Sirainen date: Mon Oct 19 14:29:10 2015 +0300 description: imapc: Set storage's error to "internal error" if we detect mailbox state corruption. This fixes "unknown internal error" in at least syncing code when an expunged message reappears. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r c5c34c02fda3 -r 56d08de919a1 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Mon Oct 19 14:05:26 2015 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Mon Oct 19 14:29:10 2015 +0300 @@ -24,6 +24,8 @@ mbox->box.name, t_strdup_vprintf(reason, va)); va_end(va); + mail_storage_set_internal_error(&mbox->storage->storage); + if (!mbox->initial_sync_done) { /* we failed during initial sync. need to rebuild indexes if we want to get this fixed */ From dovecot at dovecot.org Mon Oct 19 21:24:20 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 21:24:20 +0000 Subject: dovecot-2.2: lib-charset: Run iconv unit tests by giving iconv()... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5bba7529d5d7 changeset: 19314:5bba7529d5d7 user: Timo Sirainen date: Tue Oct 20 00:23:56 2015 +0300 description: lib-charset: Run iconv unit tests by giving iconv() new data 1 byte at a time. diffstat: src/lib-charset/test-charset.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diffs (35 lines): diff -r 56d08de919a1 -r 5bba7529d5d7 src/lib-charset/test-charset.c --- a/src/lib-charset/test-charset.c Mon Oct 19 14:29:10 2015 +0300 +++ b/src/lib-charset/test-charset.c Tue Oct 20 00:23:56 2015 +0300 @@ -69,7 +69,9 @@ { "ISO-8859-1", "p\xE4\xE4", "p??", CHARSET_RET_OK } }; string_t *str = t_str_new(128); + struct charset_translation *trans; enum charset_result result; + size_t pos, left, limit, len; unsigned int i; test_begin("charset iconv"); @@ -79,6 +81,21 @@ tests[i].input, str, &result) == 0, i); test_assert_idx(strcmp(tests[i].output, str_c(str)) == 0, i); test_assert_idx(result == tests[i].result, i); + + str_truncate(str, 0); + test_assert_idx(charset_to_utf8_begin(tests[i].charset, NULL, &trans) == 0, i); + len = strlen(tests[i].input); + for (pos = 0, limit = 1; limit <= len; pos += left, limit++) { + left = limit - pos; + result = charset_to_utf8(trans, (const void *)(tests[i].input + pos), + &left, str); + if (result != CHARSET_RET_INCOMPLETE_INPUT && + result != CHARSET_RET_OK) + break; + } + test_assert_idx(strcmp(tests[i].output, str_c(str)) == 0, i); + test_assert_idx(result == tests[i].result, i); + charset_to_utf8_end(&trans); } /* Use //IGNORE just to force handling to be done by iconv instead of our own UTF-8 routines. */ From dovecot at dovecot.org Mon Oct 19 21:25:25 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Oct 2015 21:25:25 +0000 Subject: dovecot-2.2: lib-charset: Added UTF-7 iconv() unit test Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0f5e58361c48 changeset: 19315:0f5e58361c48 user: Timo Sirainen date: Tue Oct 20 00:25:14 2015 +0300 description: lib-charset: Added UTF-7 iconv() unit test Possibly crashes on FreeBSD? Not verified yet. But a good test in any case. diffstat: src/lib-charset/test-charset.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 5bba7529d5d7 -r 0f5e58361c48 src/lib-charset/test-charset.c --- a/src/lib-charset/test-charset.c Tue Oct 20 00:23:56 2015 +0300 +++ b/src/lib-charset/test-charset.c Tue Oct 20 00:25:14 2015 +0300 @@ -66,7 +66,9 @@ const char *output; enum charset_result result; } tests[] = { - { "ISO-8859-1", "p\xE4\xE4", "p??", CHARSET_RET_OK } + { "ISO-8859-1", "p\xE4\xE4", "p??", CHARSET_RET_OK }, + { "UTF-7", "+AOQA5AD2AOQA9gDkAPYA5AD2AOQA9gDkAPYA5AD2AOQA9gDkAPYA5AD2AOQA9gDkAPYA5AD2AOQA9gDkAPYA5AD2AOQA9gDk", + "????????????????????????????????????", CHARSET_RET_OK } }; string_t *str = t_str_new(128); struct charset_translation *trans; From dovecot at dovecot.org Tue Oct 20 10:12:35 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 10:12:35 +0000 Subject: dovecot-2.2: dict-sql: Fixed async iteration with MySQL and SQLite Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/467695fee373 changeset: 19316:467695fee373 user: Timo Sirainen date: Tue Oct 20 13:12:24 2015 +0300 description: dict-sql: Fixed async iteration with MySQL and SQLite diffstat: src/lib-dict/dict-sql.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (31 lines): diff -r 0f5e58361c48 -r 467695fee373 src/lib-dict/dict-sql.c --- a/src/lib-dict/dict-sql.c Tue Oct 20 00:25:14 2015 +0300 +++ b/src/lib-dict/dict-sql.c Tue Oct 20 13:12:24 2015 +0300 @@ -45,6 +45,7 @@ const struct dict_sql_map *map; unsigned int key_prefix_len, pattern_prefix_len, next_map_idx; unsigned int path_idx, sql_fields_start_idx; + bool synchronous_result; bool failed; }; @@ -616,7 +617,7 @@ { sql_result_ref(result); ctx->result = result; - if (ctx->ctx.async_callback != NULL) + if (ctx->ctx.async_callback != NULL && !ctx->synchronous_result) ctx->ctx.async_callback(ctx->ctx.async_context); } @@ -638,8 +639,10 @@ ctx->result = sql_query_s(dict->db, str_c(query)); } else { i_assert(ctx->result == NULL); + ctx->synchronous_result = TRUE; sql_query(dict->db, str_c(query), sql_dict_iterate_callback, ctx); + ctx->synchronous_result = FALSE; } } T_END; *error_r = t_strdup(error); From pigeonhole at rename-it.nl Tue Oct 20 11:57:53 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 20 Oct 2015 13:57:53 +0200 Subject: dovecot-2.2-pigeonhole: doveadm sieve plugin: Fixed crashes caus... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d64153bf5352 changeset: 2118:d64153bf5352 user: Stephan Bosch date: Tue Oct 20 13:57:48 2015 +0200 description: doveadm sieve plugin: Fixed crashes caused by incorrect context allocation in the command implementations. The base context struct was allocated, rather than the (larger) command-specific context. Patch by Timo Sirainen. diffstat: src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c | 10 +++++----- src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c | 11 ++++++----- src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c | 14 +++++++------- src/plugins/doveadm-sieve/doveadm-sieve-cmd-rename.c | 10 +++++----- 4 files changed, 23 insertions(+), 22 deletions(-) diffs (97 lines): diff -r 2dc6dda47ae7 -r d64153bf5352 src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c Sun Oct 04 23:18:29 2015 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c Tue Oct 20 13:57:48 2015 +0200 @@ -107,12 +107,12 @@ static struct doveadm_mail_cmd_context * cmd_sieve_activate_alloc(void) { - struct doveadm_sieve_cmd_context *ctx; + struct doveadm_sieve_activate_cmd_context *ctx; - ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_cmd_context); - ctx->ctx.v.init = cmd_sieve_activate_init; - ctx->v.run = cmd_sieve_activate_run; - return &ctx->ctx; + ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_activate_cmd_context); + ctx->ctx.ctx.v.init = cmd_sieve_activate_init; + ctx->ctx.v.run = cmd_sieve_activate_run; + return &ctx->ctx.ctx; } static struct doveadm_mail_cmd_context * diff -r 2dc6dda47ae7 -r d64153bf5352 src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c Sun Oct 04 23:18:29 2015 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c Tue Oct 20 13:57:48 2015 +0200 @@ -26,6 +26,7 @@ struct istream *input; enum sieve_error error; + return 0; script = sieve_storage_open_script (_ctx->storage, ctx->scriptname, &error); if ( script == NULL || sieve_script_get_stream @@ -60,13 +61,13 @@ static struct doveadm_mail_cmd_context * cmd_sieve_get_alloc(void) { - struct doveadm_sieve_cmd_context *ctx; + struct doveadm_sieve_get_cmd_context *ctx; - ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_cmd_context); - ctx->ctx.v.init = cmd_sieve_get_init; - ctx->v.run = cmd_sieve_get_run; + ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_get_cmd_context); + ctx->ctx.ctx.v.init = cmd_sieve_get_init; + ctx->ctx.v.run = cmd_sieve_get_run; doveadm_print_init("pager"); - return &ctx->ctx; + return &ctx->ctx.ctx; } struct doveadm_mail_cmd doveadm_sieve_cmd_get = { diff -r 2dc6dda47ae7 -r d64153bf5352 src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c Sun Oct 04 23:18:29 2015 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c Tue Oct 20 13:57:48 2015 +0200 @@ -164,14 +164,14 @@ static struct doveadm_mail_cmd_context * cmd_sieve_put_alloc(void) { - struct doveadm_sieve_cmd_context *ctx; + struct doveadm_sieve_put_cmd_context *ctx; - ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_cmd_context); - ctx->ctx.getopt_args = "a"; - ctx->ctx.v.parse_arg = cmd_sieve_put_parse_arg; - ctx->ctx.v.init = cmd_sieve_put_init; - ctx->v.run = cmd_sieve_put_run; - return &ctx->ctx; + ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_put_cmd_context); + ctx->ctx.ctx.getopt_args = "a"; + ctx->ctx.ctx.v.parse_arg = cmd_sieve_put_parse_arg; + ctx->ctx.ctx.v.init = cmd_sieve_put_init; + ctx->ctx.v.run = cmd_sieve_put_run; + return &ctx->ctx.ctx; } struct doveadm_mail_cmd doveadm_sieve_cmd_put = { diff -r 2dc6dda47ae7 -r d64153bf5352 src/plugins/doveadm-sieve/doveadm-sieve-cmd-rename.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-rename.c Sun Oct 04 23:18:29 2015 +0200 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-rename.c Tue Oct 20 13:57:48 2015 +0200 @@ -63,12 +63,12 @@ static struct doveadm_mail_cmd_context * cmd_sieve_rename_alloc(void) { - struct doveadm_sieve_cmd_context *ctx; + struct doveadm_sieve_rename_cmd_context *ctx; - ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_cmd_context); - ctx->ctx.v.init = cmd_sieve_rename_init; - ctx->v.run = cmd_sieve_rename_run; - return &ctx->ctx; + ctx = doveadm_sieve_cmd_alloc(struct doveadm_sieve_rename_cmd_context); + ctx->ctx.ctx.v.init = cmd_sieve_rename_init; + ctx->ctx.v.run = cmd_sieve_rename_run; + return &ctx->ctx.ctx; } struct doveadm_mail_cmd doveadm_sieve_cmd_rename = { From dovecot at dovecot.org Tue Oct 20 12:29:16 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 12:29:16 +0000 Subject: dovecot-2.2: lib-storage/notify: Added MAILBOX_TRANSACTION_FLAG_... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/16ff395c156e changeset: 19317:16ff395c156e user: Timo Sirainen date: Tue Oct 20 15:27:42 2015 +0300 description: lib-storage/notify: Added MAILBOX_TRANSACTION_FLAG_NO_NOTIFY This flag could potentially apply for other things as well, not just notify plugin. In general anything that could do external notifications shouldn't do anything for transactions with this flag. diffstat: src/lib-storage/mail-storage.h | 6 +++++- src/plugins/notify/notify-storage.c | 27 ++++++++++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diffs (102 lines): diff -r 467695fee373 -r 16ff395c156e src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Tue Oct 20 13:12:24 2015 +0300 +++ b/src/lib-storage/mail-storage.h Tue Oct 20 15:27:42 2015 +0300 @@ -177,7 +177,11 @@ MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC = 0x10, /* Sync transaction describes changes to mailbox that already happened to another mailbox with whom we're syncing with (dsync) */ - MAILBOX_TRANSACTION_FLAG_SYNC = 0x20 + MAILBOX_TRANSACTION_FLAG_SYNC = 0x20, + /* Don't trigger any notifications for this transaction. This + especially means the notify plugin. This would normally be used only + with _FLAG_SYNC. */ + MAILBOX_TRANSACTION_FLAG_NO_NOTIFY = 0x40 }; enum mailbox_sync_flags { diff -r 467695fee373 -r 16ff395c156e src/plugins/notify/notify-storage.c --- a/src/plugins/notify/notify-storage.c Tue Oct 20 13:12:24 2015 +0300 +++ b/src/plugins/notify/notify-storage.c Tue Oct 20 15:27:42 2015 +0300 @@ -79,6 +79,9 @@ struct mail_vfuncs *v = mail->vlast; union mail_module_context *lmail; + if ((_mail->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) != 0) + return; + lmail = p_new(mail->pool, union mail_module_context, 1); lmail->super = *v; mail->vlast = &lmail->super; @@ -98,7 +101,8 @@ NOTIFY_CONTEXT(ctx->transaction->box); int ret; - if (ctx->dest_mail == NULL) { + if (ctx->dest_mail == NULL && + (ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) { if (lt->tmp_mail == NULL) lt->tmp_mail = mail_alloc(ctx->transaction, 0, NULL); ctx->dest_mail = lt->tmp_mail; @@ -107,7 +111,9 @@ if ((ret = lbox->super.copy(ctx, mail)) < 0) return -1; - if (ctx->saving) { + if ((ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) != 0) { + /* no notifications */ + } else if (ctx->saving) { /* we came from mailbox_save_using_mail() */ notify_contexts_mail_save(ctx->dest_mail); } else { @@ -124,7 +130,8 @@ union mailbox_module_context *lbox = NOTIFY_CONTEXT(ctx->transaction->box); - if (ctx->dest_mail == NULL) { + if (ctx->dest_mail == NULL && + (ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) { if (lt->tmp_mail == NULL) lt->tmp_mail = mail_alloc(ctx->transaction, 0, NULL); ctx->dest_mail = lt->tmp_mail; @@ -141,7 +148,8 @@ if (lbox->super.save_finish(ctx) < 0) return -1; - if (dest_mail != NULL) + if (dest_mail != NULL && + (ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) notify_contexts_mail_save(dest_mail); return 0; } @@ -159,7 +167,8 @@ lt = i_new(struct notify_transaction_context, 1); MODULE_CONTEXT_SET(t, notify_storage_module, lt); - notify_contexts_mail_transaction_begin(t); + if ((t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) + notify_contexts_mail_transaction_begin(t); return t; } @@ -179,7 +188,10 @@ return -1; } - notify_contexts_mail_transaction_commit(t, changes_r); + /* FIXME: note that t is already freed at this stage. it's not actually + being dereferenced anymore though. still, a bit unsafe.. */ + if ((t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) + notify_contexts_mail_transaction_commit(t, changes_r); return 0; } @@ -193,7 +205,8 @@ mail_free(<->tmp_mail); i_free(lt); - notify_contexts_mail_transaction_rollback(t); + if ((t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) + notify_contexts_mail_transaction_rollback(t); lbox->super.transaction_rollback(t); } From dovecot at dovecot.org Tue Oct 20 12:29:16 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 12:29:16 +0000 Subject: dovecot-2.2: dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable M... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/f9a143c630a5 changeset: 19318:f9a143c630a5 user: Timo Sirainen date: Tue Oct 20 15:29:07 2015 +0300 description: dsync: Added DSYNC_BRAIN_FLAG_NO_NOTIFY to enable MAILBOX_TRANSACTION_FLAG_NO_NOTIFY It's arguable that this should be enabled by default, but people might like to keep mail_log notifications for dsync. diffstat: src/doveadm/dsync/dsync-brain-mailbox.c | 2 ++ src/doveadm/dsync/dsync-brain-private.h | 1 + src/doveadm/dsync/dsync-brain.c | 1 + src/doveadm/dsync/dsync-brain.h | 4 +++- src/doveadm/dsync/dsync-ibc-stream.c | 6 +++++- src/doveadm/dsync/dsync-mailbox-import.c | 10 +++++++--- src/doveadm/dsync/dsync-mailbox-import.h | 3 ++- 7 files changed, 21 insertions(+), 6 deletions(-) diffs (136 lines): diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-brain-mailbox.c --- a/src/doveadm/dsync/dsync-brain-mailbox.c Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-brain-mailbox.c Tue Oct 20 15:29:07 2015 +0300 @@ -216,6 +216,8 @@ if (brain->local_dsync_box.have_only_guid128 || remote_dsync_box->have_only_guid128) import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128; + if (brain->no_notify) + import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_NO_NOTIFY; brain->box_importer = brain->backup_send ? NULL : dsync_mailbox_import_init(brain->box, brain->virtual_all_box, diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-brain-private.h --- a/src/doveadm/dsync/dsync-brain-private.h Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-brain-private.h Tue Oct 20 15:29:07 2015 +0300 @@ -111,6 +111,7 @@ unsigned int changes_during_sync:1; unsigned int require_full_resync:1; unsigned int verbose_proctitle:1; + unsigned int no_notify:1; unsigned int failed:1; }; diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-brain.c --- a/src/doveadm/dsync/dsync-brain.c Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-brain.c Tue Oct 20 15:29:07 2015 +0300 @@ -142,6 +142,7 @@ (flags & DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH) != 0; brain->no_mailbox_renames = (flags & DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES) != 0; + brain->no_notify = (flags & DSYNC_BRAIN_FLAG_NO_NOTIFY) != 0; } static void diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-brain.h --- a/src/doveadm/dsync/dsync-brain.h Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-brain.h Tue Oct 20 15:29:07 2015 +0300 @@ -30,7 +30,9 @@ DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH = 0x100, /* Disable mailbox renaming logic. This is just a kludge that should be removed once the renaming logic has no more bugs.. */ - DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES = 0x200 + DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES = 0x200, + /* Add MAILBOX_TRANSACTION_FLAG_NO_NOTIFY to transactions. */ + DSYNC_BRAIN_FLAG_NO_NOTIFY = 0x400 }; enum dsync_brain_sync_type { diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-ibc-stream.c --- a/src/doveadm/dsync/dsync-ibc-stream.c Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-ibc-stream.c Tue Oct 20 15:29:07 2015 +0300 @@ -76,7 +76,7 @@ "debug sync_visible_namespaces exclude_mailboxes " "send_mail_requests backup_send backup_recv lock_timeout " "no_mail_sync no_mailbox_renames no_backup_overwrite purge_remote " - "sync_since_timestamp sync_flags virtual_all_box" + "no_notify sync_since_timestamp sync_flags virtual_all_box" }, { .name = "mailbox_state", .chr = 'S', @@ -716,6 +716,8 @@ dsync_serializer_encode_add(encoder, "no_backup_overwrite", ""); if ((set->brain_flags & DSYNC_BRAIN_FLAG_PURGE_REMOTE) != 0) dsync_serializer_encode_add(encoder, "purge_remote", ""); + if ((set->brain_flags & DSYNC_BRAIN_FLAG_NO_NOTIFY) != 0) + dsync_serializer_encode_add(encoder, "no_notify", ""); dsync_serializer_encode_finish(&encoder, str); dsync_ibc_stream_send_string(ibc, str); @@ -822,6 +824,8 @@ set->brain_flags |= DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE; if (dsync_deserializer_decode_try(decoder, "purge_remote", &value)) set->brain_flags |= DSYNC_BRAIN_FLAG_PURGE_REMOTE; + if (dsync_deserializer_decode_try(decoder, "no_notify", &value)) + set->brain_flags |= DSYNC_BRAIN_FLAG_NO_NOTIFY; *set_r = set; return DSYNC_IBC_RECV_RET_OK; diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-mailbox-import.c --- a/src/doveadm/dsync/dsync-mailbox-import.c Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Tue Oct 20 15:29:07 2015 +0300 @@ -62,6 +62,7 @@ uint32_t remote_first_recent_uid; uint64_t remote_highest_modseq, remote_highest_pvt_modseq; time_t sync_since_timestamp; + enum mailbox_transaction_flags transaction_flags; enum mail_flags sync_flag; const char *sync_keyword; @@ -170,12 +171,12 @@ dsync_mailbox_import_transaction_begin(struct dsync_mailbox_importer *importer) { const enum mailbox_transaction_flags ext_trans_flags = - MAILBOX_TRANSACTION_FLAG_SYNC | + importer->transaction_flags | MAILBOX_TRANSACTION_FLAG_EXTERNAL | MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS; importer->trans = mailbox_transaction_begin(importer->box, - MAILBOX_TRANSACTION_FLAG_SYNC); + importer->transaction_flags); importer->ext_trans = mailbox_transaction_begin(importer->box, ext_trans_flags); importer->mail = mail_alloc(importer->trans, 0, NULL); @@ -227,6 +228,9 @@ else importer->sync_keyword = p_strdup(pool, sync_flag); } + importer->transaction_flags = MAILBOX_TRANSACTION_FLAG_SYNC; + if ((flags & DSYNC_MAILBOX_IMPORT_FLAG_NO_NOTIFY) != 0) + importer->transaction_flags |= MAILBOX_TRANSACTION_FLAG_NO_NOTIFY; hash_table_create(&importer->import_guids, pool, 0, str_hash, strcmp); hash_table_create_direct(&importer->import_uids, pool, 0); @@ -2023,7 +2027,7 @@ importer->virtual_trans = mailbox_transaction_begin(importer->virtual_all_box, - MAILBOX_TRANSACTION_FLAG_SYNC); + importer->transaction_flags); search_ctx = mailbox_search_init(importer->virtual_trans, search_args, NULL, MAIL_FETCH_GUID, NULL); mail_search_args_unref(&search_args); diff -r 16ff395c156e -r f9a143c630a5 src/doveadm/dsync/dsync-mailbox-import.h --- a/src/doveadm/dsync/dsync-mailbox-import.h Tue Oct 20 15:27:42 2015 +0300 +++ b/src/doveadm/dsync/dsync-mailbox-import.h Tue Oct 20 15:29:07 2015 +0300 @@ -9,7 +9,8 @@ DSYNC_MAILBOX_IMPORT_FLAG_REVERT_LOCAL_CHANGES = 0x04, DSYNC_MAILBOX_IMPORT_FLAG_DEBUG = 0x08, DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS = 0x10, - DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128 = 0x20 + DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128 = 0x20, + DSYNC_MAILBOX_IMPORT_FLAG_NO_NOTIFY = 0x40 }; struct mailbox; From dovecot at dovecot.org Tue Oct 20 15:23:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 15:23:12 +0000 Subject: dovecot-2.2: mysql: Use the correct way of setting a connect tim... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5288c66c7d69 changeset: 19319:5288c66c7d69 user: Timo Sirainen date: Tue Oct 20 16:56:23 2015 +0300 description: mysql: Use the correct way of setting a connect timeout. I'm not sure if this didn't exist earlier, or if I just somehow missed it. diffstat: src/lib-sql/driver-mysql.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (39 lines): diff -r f9a143c630a5 -r 5288c66c7d69 src/lib-sql/driver-mysql.c --- a/src/lib-sql/driver-mysql.c Tue Oct 20 15:29:07 2015 +0300 +++ b/src/lib-sql/driver-mysql.c Tue Oct 20 16:56:23 2015 +0300 @@ -76,7 +76,8 @@ struct mysql_db *db = (struct mysql_db *)_db; const char *unix_socket, *host; unsigned long client_flags = db->client_flags; - unsigned int secs_used; + unsigned int secs_used, connect_timeout = SQL_CONNECT_TIMEOUT_SECS; + time_t start_time; bool failed; i_assert(db->api.state == SQL_DB_STATE_DISCONNECTED); @@ -96,6 +97,7 @@ db->option_file); } + mysql_options(db->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout); mysql_options(db->mysql, MYSQL_READ_DEFAULT_GROUP, db->option_group != NULL ? db->option_group : "client"); @@ -118,15 +120,15 @@ #endif } - alarm(SQL_CONNECT_TIMEOUT_SECS); #ifdef CLIENT_MULTI_RESULTS client_flags |= CLIENT_MULTI_RESULTS; #endif /* CLIENT_MULTI_RESULTS allows the use of stored procedures */ + start_time = time(NULL); failed = mysql_real_connect(db->mysql, host, db->user, db->password, db->dbname, db->port, unix_socket, client_flags) == NULL; - secs_used = SQL_CONNECT_TIMEOUT_SECS - alarm(0); + secs_used = time(NULL) - start_time; if (failed) { /* connecting could have taken a while. make sure that any timeouts that get added soon will get a refreshed From dovecot at dovecot.org Tue Oct 20 15:23:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 15:23:12 +0000 Subject: dovecot-2.2: mysql: Fixed client_flags parameter Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e9f5db1e5770 changeset: 19320:e9f5db1e5770 user: Timo Sirainen date: Tue Oct 20 16:57:34 2015 +0300 description: mysql: Fixed client_flags parameter diffstat: src/lib-sql/driver-mysql.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 5288c66c7d69 -r e9f5db1e5770 src/lib-sql/driver-mysql.c --- a/src/lib-sql/driver-mysql.c Tue Oct 20 16:56:23 2015 +0300 +++ b/src/lib-sql/driver-mysql.c Tue Oct 20 16:57:34 2015 +0300 @@ -187,7 +187,7 @@ if (net_str2port(value, &db->port) < 0) i_fatal("mysql: Invalid port number: %s", value); } else if (strcmp(name, "client_flags") == 0) { - if (str_to_uint(value, &db->client_flags) < 9) + if (str_to_uint(value, &db->client_flags) < 0) i_fatal("mysql: Invalid client flags: %s", value); } else if (strcmp(name, "ssl_cert") == 0) field = &db->ssl_cert; From dovecot at dovecot.org Tue Oct 20 15:23:18 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 15:23:18 +0000 Subject: dovecot-2.2: mysql: Added connect/read/write_timeout settings. D... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2730e603547d changeset: 19321:2730e603547d user: Timo Sirainen date: Tue Oct 20 17:07:20 2015 +0300 description: mysql: Added connect/read/write_timeout settings. Default to 30s read/write_timeout. diffstat: src/lib-sql/driver-mysql.c | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diffs (67 lines): diff -r e9f5db1e5770 -r 2730e603547d src/lib-sql/driver-mysql.c --- a/src/lib-sql/driver-mysql.c Tue Oct 20 16:57:34 2015 +0300 +++ b/src/lib-sql/driver-mysql.c Tue Oct 20 17:07:20 2015 +0300 @@ -23,6 +23,9 @@ #endif #include +#define MYSQL_DEFAULT_READ_TIMEOUT_SECS 30 +#define MYSQL_DEFAULT_WRITE_TIMEOUT_SECS 30 + struct mysql_db { struct sql_db api; @@ -33,6 +36,7 @@ const char *option_file, *option_group; in_port_t port; unsigned int client_flags; + unsigned int connect_timeout, read_timeout, write_timeout; time_t last_success; MYSQL *mysql; @@ -76,7 +80,7 @@ struct mysql_db *db = (struct mysql_db *)_db; const char *unix_socket, *host; unsigned long client_flags = db->client_flags; - unsigned int secs_used, connect_timeout = SQL_CONNECT_TIMEOUT_SECS; + unsigned int secs_used; time_t start_time; bool failed; @@ -97,7 +101,9 @@ db->option_file); } - mysql_options(db->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout); + mysql_options(db->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &db->connect_timeout); + mysql_options(db->mysql, MYSQL_OPT_READ_TIMEOUT, &db->read_timeout); + mysql_options(db->mysql, MYSQL_OPT_WRITE_TIMEOUT, &db->write_timeout); mysql_options(db->mysql, MYSQL_READ_DEFAULT_GROUP, db->option_group != NULL ? db->option_group : "client"); @@ -162,6 +168,9 @@ db->ssl_cipher = "HIGH"; db->ssl_verify_server_cert = 0; /* FIXME: change to 1 for v2.3 */ + db->connect_timeout = SQL_CONNECT_TIMEOUT_SECS; + db->read_timeout = MYSQL_DEFAULT_READ_TIMEOUT_SECS; + db->write_timeout = MYSQL_DEFAULT_WRITE_TIMEOUT_SECS; args = t_strsplit_spaces(connect_string, " "); for (; *args != NULL; args++) { @@ -189,6 +198,15 @@ } else if (strcmp(name, "client_flags") == 0) { if (str_to_uint(value, &db->client_flags) < 0) i_fatal("mysql: Invalid client flags: %s", value); + } else if (strcmp(name, "connect_timeout") == 0) { + if (str_to_uint(value, &db->connect_timeout) < 0) + i_fatal("mysql: Invalid read_timeout: %s", value); + } else if (strcmp(name, "read_timeout") == 0) { + if (str_to_uint(value, &db->read_timeout) < 0) + i_fatal("mysql: Invalid read_timeout: %s", value); + } else if (strcmp(name, "write_timeout") == 0) { + if (str_to_uint(value, &db->write_timeout) < 0) + i_fatal("mysql: Invalid read_timeout: %s", value); } else if (strcmp(name, "ssl_cert") == 0) field = &db->ssl_cert; else if (strcmp(name, "ssl_key") == 0) From dovecot at dovecot.org Tue Oct 20 15:23:23 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 15:23:23 +0000 Subject: dovecot-2.2: lib-imap-storage: Mark METADATA transactions as ext... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/89323ed80676 changeset: 19322:89323ed80676 user: Timo Sirainen date: Tue Oct 20 18:22:53 2015 +0300 description: lib-imap-storage: Mark METADATA transactions as external. We never write the metadata values to any storage backend, so they also don't need to be explicitly synced. diffstat: src/lib-imap-storage/imap-metadata.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2730e603547d -r 89323ed80676 src/lib-imap-storage/imap-metadata.c --- a/src/lib-imap-storage/imap-metadata.c Tue Oct 20 17:07:20 2015 +0300 +++ b/src/lib-imap-storage/imap-metadata.c Tue Oct 20 18:22:53 2015 +0300 @@ -121,7 +121,7 @@ if (imtrans->box == NULL || mailbox_open(imtrans->box) < 0) return -1; - imtrans->trans = mailbox_transaction_begin(imtrans->box, 0); + imtrans->trans = mailbox_transaction_begin(imtrans->box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); return 0; } From dovecot at dovecot.org Tue Oct 20 15:43:46 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 15:43:46 +0000 Subject: dovecot-2.2: lib-index: tail_offset wasn't updated as often as i... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a26d8492614e changeset: 19323:a26d8492614e user: Timo Sirainen date: Tue Oct 20 18:43:32 2015 +0300 description: lib-index: tail_offset wasn't updated as often as it should have been. ctx->last_tail_offset was being increased for every non-external transaction and at the end we checked if head was larger than it. This logic didn't really make any sense, since non-external transactions specifically were supposed to update the tail_offset. diffstat: src/lib-index/mail-index-sync.c | 30 ++++++++++-------------------- 1 files changed, 10 insertions(+), 20 deletions(-) diffs (75 lines): diff -r 89323ed80676 -r a26d8492614e src/lib-index/mail-index-sync.c --- a/src/lib-index/mail-index-sync.c Tue Oct 20 18:22:53 2015 +0300 +++ b/src/lib-index/mail-index-sync.c Tue Oct 20 18:43:32 2015 +0300 @@ -22,7 +22,6 @@ ARRAY(struct mail_index_sync_list) sync_list; uint32_t next_uid; - uint32_t last_tail_seq, last_tail_offset; unsigned int no_warning:1; unsigned int seen_nonexternal_transactions:1; @@ -164,20 +163,6 @@ } } -static void -mail_index_sync_update_mailbox_pos(struct mail_index_sync_ctx *ctx) -{ - uint32_t seq; - uoff_t offset; - - mail_transaction_log_view_get_prev_pos(ctx->view->log_view, - &seq, &offset); - - ctx->seen_nonexternal_transactions = TRUE; - ctx->last_tail_seq = seq; - ctx->last_tail_offset = offset + ctx->hdr->size + sizeof(*ctx->hdr); -} - static int mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx) { @@ -203,8 +188,14 @@ continue; T_BEGIN { - if (mail_index_sync_add_transaction(ctx)) - mail_index_sync_update_mailbox_pos(ctx); + if (mail_index_sync_add_transaction(ctx)) { + /* update tail_offset if needed */ + ctx->seen_nonexternal_transactions = TRUE; + } else { + /* this is an internal change. we don't + necessarily need to update tail_offset, so + avoid the extra write caused by it. */ + } } T_END; } @@ -436,8 +427,6 @@ ctx = i_new(struct mail_index_sync_ctx, 1); ctx->index = index; - ctx->last_tail_seq = hdr->log_file_seq; - ctx->last_tail_offset = hdr->log_file_tail_offset; ctx->flags = flags; ctx->view = mail_index_view_open(index); @@ -764,6 +753,7 @@ static void mail_index_sync_update_mailbox_offset(struct mail_index_sync_ctx *ctx) { + const struct mail_index_header *hdr = &ctx->index->map->hdr; uint32_t seq; uoff_t offset; @@ -785,7 +775,7 @@ external, because that wouldn't change effective the tail offset. except e.g. mdbox map requires this to happen, so do it optionally. */ - if ((ctx->last_tail_seq != seq || ctx->last_tail_offset < offset) && + if ((hdr->log_file_seq != seq || hdr->log_file_tail_offset < offset) && (ctx->seen_nonexternal_transactions || (ctx->flags & MAIL_INDEX_SYNC_FLAG_UPDATE_TAIL_OFFSET) != 0)) { ctx->ext_trans->log_updates = TRUE; From dovecot at dovecot.org Tue Oct 20 17:15:29 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 17:15:29 +0000 Subject: dovecot-2.2: dict: Show number of clients in process title Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/051505f9a5ae changeset: 19324:051505f9a5ae user: Timo Sirainen date: Tue Oct 20 20:15:20 2015 +0300 description: dict: Show number of clients in process title diffstat: src/dict/main.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (21 lines): diff -r a26d8492614e -r 051505f9a5ae src/dict/main.c --- a/src/dict/main.c Tue Oct 20 18:43:32 2015 +0300 +++ b/src/dict/main.c Tue Oct 20 20:15:20 2015 +0300 @@ -83,13 +83,16 @@ int main(int argc, char *argv[]) { + const enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_UPDATE_PROCTITLE; const struct setting_parser_info *set_roots[] = { &dict_setting_parser_info, NULL }; const char *error; - master_service = master_service_init("dict", 0, &argc, &argv, ""); + master_service = master_service_init("dict", service_flags, + &argc, &argv, ""); if (master_getopt(master_service) > 0) return FATAL_DEFAULT; From dovecot at dovecot.org Tue Oct 20 18:23:23 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Oct 2015 18:23:23 +0000 Subject: dovecot-2.2: doveadm fs: Log also the exact reason for "file doe... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0c2f8cb41fea changeset: 19325:0c2f8cb41fea user: Timo Sirainen date: Tue Oct 20 21:23:03 2015 +0300 description: doveadm fs: Log also the exact reason for "file doesn't exist" diffstat: src/doveadm/doveadm-fs.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diffs (53 lines): diff -r 051505f9a5ae -r 0c2f8cb41fea src/doveadm/doveadm-fs.c --- a/src/doveadm/doveadm-fs.c Tue Oct 20 20:15:20 2015 +0300 +++ b/src/doveadm/doveadm-fs.c Tue Oct 20 21:23:03 2015 +0300 @@ -72,7 +72,8 @@ } i_assert(ret == -1); if (input->stream_errno == ENOENT) { - i_error("%s doesn't exist", fs_file_path(file)); + i_error("%s doesn't exist: %s", fs_file_path(file), + fs_file_last_error(file)); doveadm_exit_code = DOVEADM_EX_NOTFOUND; } else if (input->stream_errno != 0) { i_error("read(%s) failed: %s", fs_file_path(file), @@ -165,7 +166,8 @@ dest_file = fs_file_init(fs, dest_path, FS_OPEN_MODE_REPLACE); if (fs_copy(src_file, dest_file) == 0) ; else if (errno == ENOENT) { - i_error("%s doesn't exist", src_path); + i_error("%s doesn't exist: %s", src_path, + fs_last_error(fs)); doveadm_exit_code = DOVEADM_EX_NOTFOUND; } else { i_error("fs_copy(%s, %s) failed: %s", @@ -190,7 +192,8 @@ printf("%s size=%lld\n", fs_file_path(file), (long long)st.st_size); } else if (errno == ENOENT) { - i_error("%s doesn't exist", fs_file_path(file)); + i_error("%s doesn't exist: %s", fs_file_path(file), + fs_file_last_error(file)); doveadm_exit_code = DOVEADM_EX_NOTFOUND; } else { i_error("fs_stat(%s) failed: %s", @@ -215,7 +218,8 @@ array_foreach(metadata, m) printf("%s=%s\n", m->key, m->value); } else if (errno == ENOENT) { - i_error("%s doesn't exist", fs_file_path(file)); + i_error("%s doesn't exist: %s", fs_file_path(file), + fs_file_last_error(file)); doveadm_exit_code = DOVEADM_EX_NOTFOUND; } else { i_error("fs_stat(%s) failed: %s", @@ -248,7 +252,8 @@ if (ret == 0) ret = 1; } else if (errno == ENOENT) { - i_error("%s doesn't exist", fs_file_path(ctx->files[i])); + i_error("%s doesn't exist: %s", fs_file_path(ctx->files[i]), + fs_file_last_error(ctx->files[i])); doveadm_exit_code = DOVEADM_EX_NOTFOUND; ret = -1; } else { From pigeonhole at rename-it.nl Tue Oct 20 19:55:11 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 20 Oct 2015 21:55:11 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: script storage: Sieve mailbox... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9ff5fac3f7a8 changeset: 2119:9ff5fac3f7a8 user: Stephan Bosch date: Tue Oct 20 21:54:49 2015 +0200 description: lib-sieve: script storage: Sieve mailbox attributes use an external storage, so they don't need to be synced explicitly with any mail storage backend. Patch by Timo Sirainen. diffstat: src/lib-sieve/sieve-storage-sync.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d64153bf5352 -r 9ff5fac3f7a8 src/lib-sieve/sieve-storage-sync.c --- a/src/lib-sieve/sieve-storage-sync.c Tue Oct 20 13:57:48 2015 +0200 +++ b/src/lib-sieve/sieve-storage-sync.c Tue Oct 20 21:54:49 2015 +0200 @@ -72,7 +72,7 @@ return -1; } - *trans_r = mailbox_transaction_begin(inbox, 0); + *trans_r = mailbox_transaction_begin(inbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL); return 1; } From dovecot at dovecot.org Wed Oct 21 10:33:07 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 21 Oct 2015 10:33:07 +0000 Subject: dovecot-2.2: ssl_options: Added support for no_ticket Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/098de79b89c8 changeset: 19326:098de79b89c8 user: Timo Sirainen date: Wed Oct 21 13:32:58 2015 +0300 description: ssl_options: Added support for no_ticket diffstat: src/lib-master/master-service-ssl-settings.c | 3 +++ src/lib-master/master-service-ssl-settings.h | 1 + src/lib-ssl-iostream/iostream-openssl-context.c | 4 ++++ src/lib-ssl-iostream/iostream-ssl.h | 1 + src/login-common/ssl-proxy-openssl.c | 7 +++++++ 5 files changed, 16 insertions(+), 0 deletions(-) diffs (94 lines): diff -r 0c2f8cb41fea -r 098de79b89c8 src/lib-master/master-service-ssl-settings.c --- a/src/lib-master/master-service-ssl-settings.c Tue Oct 20 21:23:03 2015 +0300 +++ b/src/lib-master/master-service-ssl-settings.c Wed Oct 21 13:32:58 2015 +0300 @@ -104,6 +104,7 @@ /* Now explode the ssl_options string into individual flags */ /* First set them all to defaults */ set->parsed_opts.compression = TRUE; + set->parsed_opts.tickets = TRUE; /* Then modify anything specified in the string */ const char **opts = t_strsplit_spaces(set->ssl_options, ", "); @@ -111,6 +112,8 @@ while ((opt = *opts++) != NULL) { if (strcasecmp(opt, "no_compression") == 0) { set->parsed_opts.compression = FALSE; + } else if (strcasecmp(opt, "no_ticket") == 0) { + set->parsed_opts.tickets = FALSE; } else { *error_r = t_strdup_printf("ssl_options: unknown flag: '%s'", opt); diff -r 0c2f8cb41fea -r 098de79b89c8 src/lib-master/master-service-ssl-settings.h --- a/src/lib-master/master-service-ssl-settings.h Tue Oct 20 21:23:03 2015 +0300 +++ b/src/lib-master/master-service-ssl-settings.h Wed Oct 21 13:32:58 2015 +0300 @@ -23,6 +23,7 @@ /* These are derived from ssl_options, not set directly */ struct { bool compression; + bool tickets; } parsed_opts; }; diff -r 0c2f8cb41fea -r 098de79b89c8 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Tue Oct 20 21:23:03 2015 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Wed Oct 21 13:32:58 2015 +0300 @@ -510,6 +510,10 @@ if (!set->compression) ssl_ops |= SSL_OP_NO_COMPRESSION; #endif +#ifdef SSL_OP_NO_TICKET + if (!set->tickets) + ssl_ops |= SSL_OP_NO_TICKET; +#endif SSL_CTX_set_options(ctx->ssl_ctx, ssl_ops); #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); diff -r 0c2f8cb41fea -r 098de79b89c8 src/lib-ssl-iostream/iostream-ssl.h --- a/src/lib-ssl-iostream/iostream-ssl.h Tue Oct 20 21:23:03 2015 +0300 +++ b/src/lib-ssl-iostream/iostream-ssl.h Wed Oct 21 13:32:58 2015 +0300 @@ -19,6 +19,7 @@ bool require_valid_cert; /* stream-only */ bool prefer_server_ciphers; bool compression; + bool tickets; }; /* Returns 0 if ok, -1 and sets error_r if failed. The returned error string diff -r 0c2f8cb41fea -r 098de79b89c8 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Tue Oct 20 21:23:03 2015 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Wed Oct 21 13:32:58 2015 +0300 @@ -103,6 +103,7 @@ bool verify_client_cert; bool prefer_server_ciphers; bool compression; + bool tickets; }; static int extdata_index; @@ -649,6 +650,7 @@ login_set->auth_ssl_username_from_cert; lookup_ctx.prefer_server_ciphers = set->ssl_prefer_server_ciphers; lookup_ctx.compression = set->parsed_opts.compression; + lookup_ctx.tickets = set->parsed_opts.tickets; ctx = hash_table_lookup(ssl_servers, &lookup_ctx); if (ctx == NULL) @@ -1029,6 +1031,10 @@ if (!set->parsed_opts.compression) ssl_ops |= SSL_OP_NO_COMPRESSION; #endif +#ifdef SSL_OP_NO_TICKET + if (!set->parsed_opts.tickets) + ssl_ops |= SSL_OP_NO_TICKET; +#endif SSL_CTX_set_options(ssl_ctx, ssl_ops); #ifdef SSL_MODE_RELEASE_BUFFERS @@ -1301,6 +1307,7 @@ login_set->auth_ssl_username_from_cert; ctx->prefer_server_ciphers = ssl_set->ssl_prefer_server_ciphers; ctx->compression = ssl_set->parsed_opts.compression; + ctx->tickets = ssl_set->parsed_opts.tickets; ctx->ctx = ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if (ssl_ctx == NULL) From dovecot at dovecot.org Wed Oct 21 12:50:43 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 21 Oct 2015 12:50:43 +0000 Subject: dovecot-2.2: login proxy: Separate admin kicks, director kicks a... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/a98aaaf55b13 changeset: 19327:a98aaaf55b13 user: Timo Sirainen date: Wed Oct 21 15:50:31 2015 +0300 description: login proxy: Separate admin kicks, director kicks and shutdowns in log messages. diffstat: src/login-common/login-proxy.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (41 lines): diff -r 098de79b89c8 -r a98aaaf55b13 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Wed Oct 21 13:32:58 2015 +0300 +++ b/src/login-common/login-proxy.c Wed Oct 21 15:50:31 2015 +0300 @@ -22,7 +22,9 @@ #define LOGIN_PROXY_DIE_IDLE_SECS 2 #define LOGIN_PROXY_IPC_PATH "ipc-proxy" #define LOGIN_PROXY_IPC_NAME "proxy" -#define KILLED_BY_ADMIN_REASON "Killed by admin" +#define KILLED_BY_ADMIN_REASON "Kicked by admin" +#define KILLED_BY_DIRECTOR_REASON "Kicked via director" +#define KILLED_BY_SHUTDOWN_REASON "Process shutting down" #define PROXY_IMMEDIATE_FAILURE_SECS 30 #define PROXY_CONNECT_RETRY_MSECS 1000 #define PROXY_DISCONNECT_INTERVAL_MSECS 100 @@ -758,7 +760,7 @@ static void proxy_kill_idle(struct login_proxy *proxy) { - login_proxy_free_reason(&proxy, KILLED_BY_ADMIN_REASON); + login_proxy_free_reason(&proxy, KILLED_BY_SHUTDOWN_REASON); } void login_proxy_kill_idle(void) @@ -843,7 +845,7 @@ if (director_username_hash(proxy->client) == hash && !net_ip_compare(&proxy->ip, &except_ip)) { - login_proxy_free_delayed(&proxy, KILLED_BY_ADMIN_REASON); + login_proxy_free_delayed(&proxy, KILLED_BY_DIRECTOR_REASON); count++; } } @@ -914,7 +916,7 @@ while (login_proxies != NULL) { proxy = login_proxies; - login_proxy_free_reason(&proxy, KILLED_BY_ADMIN_REASON); + login_proxy_free_reason(&proxy, KILLED_BY_SHUTDOWN_REASON); } while (login_proxies_disconnecting != NULL) login_proxy_free_final(login_proxies_disconnecting); From dovecot at dovecot.org Wed Oct 21 16:12:53 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 21 Oct 2015 16:12:53 +0000 Subject: dovecot-2.2: LAYOUT=index: Fixed error handling in mailbox creat... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4bcca8a822dc changeset: 19328:4bcca8a822dc user: Timo Sirainen date: Wed Oct 21 19:12:45 2015 +0300 description: LAYOUT=index: Fixed error handling in mailbox creation race condition. If two processes create the same mailbox, the other one ends up being deleted on failure. However, if the deletion itself also failed the state becomes a big ambiguous. We don't want to return MAIL_ERROR_EXISTS in that case, because the caller may try to open the mailbox with the inconsistent state and fail. So we'll instead return the original mailbox_delete() error to the caller. diffstat: src/lib-storage/list/mailbox-list-index-backend.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r a98aaaf55b13 -r 4bcca8a822dc src/lib-storage/list/mailbox-list-index-backend.c --- a/src/lib-storage/list/mailbox-list-index-backend.c Wed Oct 21 15:50:31 2015 +0300 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Wed Oct 21 19:12:45 2015 +0300 @@ -374,7 +374,8 @@ if (ret <= 0) { /* failed to add to list. rollback the backend mailbox creation */ - (void)mailbox_delete(box); + if (mailbox_delete(box) < 0) + ret = -1; } } list->create_mailbox_name = old_name; From pigeonhole at rename-it.nl Wed Oct 21 21:35:06 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 21 Oct 2015 23:35:06 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: enotify extension: mailto met... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/400be376fe02 changeset: 2121:400be376fe02 user: Stephan Bosch date: Wed Oct 21 23:31:06 2015 +0200 description: lib-sieve: enotify extension: mailto method: Implemented sieve_notify_mailto_envelope_from setting. This allows setting the MAIL FROM of the SMTP envelope for the notification e-mails. The syntax is identical to the sieve_redirect_envelope_from setting. diffstat: src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c | 100 ++++++++++++++++- tests/extensions/enotify/mailto.svtest | 118 ++++++++++++++++++++- 2 files changed, 211 insertions(+), 7 deletions(-) diffs (284 lines): diff -r 637307bdbdf2 -r 400be376fe02 src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c --- a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c Wed Oct 21 23:27:36 2015 +0200 +++ b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c Wed Oct 21 23:31:06 2015 +0200 @@ -31,6 +31,7 @@ #include "sieve-address.h" #include "sieve-message.h" #include "sieve-smtp.h" +#include "sieve-settings.h" #include "sieve-ext-enotify.h" @@ -47,9 +48,22 @@ #define NTFY_MAILTO_MAX_SUBJECT 256 /* + * Mailto notification configuration + */ + +struct ntfy_mailto_config { + struct sieve_mail_sender envelope_from; +}; + +/* * Mailto notification method */ +static bool ntfy_mailto_load + (const struct sieve_enotify_method *nmth, void **context); +static void ntfy_mailto_unload + (const struct sieve_enotify_method *nmth); + static bool ntfy_mailto_compile_check_uri (const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body); static bool ntfy_mailto_compile_check_from @@ -80,7 +94,8 @@ const struct sieve_enotify_method_def mailto_notify = { "mailto", - NULL, NULL, + ntfy_mailto_load, + ntfy_mailto_unload, ntfy_mailto_compile_check_uri, NULL, ntfy_mailto_compile_check_from, @@ -133,6 +148,45 @@ }; /* + * Method registration + */ + +static bool ntfy_mailto_load +(const struct sieve_enotify_method *nmth, void **context) +{ + struct sieve_instance *svinst = nmth->svinst; + struct ntfy_mailto_config *config; + + if ( *context != NULL ) { + ntfy_mailto_unload(nmth); + } + + config = i_new(struct ntfy_mailto_config, 1); + + if (!sieve_setting_get_mail_sender_value + (svinst, default_pool, "sieve_notify_mailto_envelope_from", + &config->envelope_from)) { + config->envelope_from.source = + SIEVE_MAIL_SENDER_SOURCE_DEFAULT; + } + + *context = (void *) config; + + return TRUE; +} + +static void ntfy_mailto_unload +(const struct sieve_enotify_method *nmth) +{ + struct ntfy_mailto_config *config = + (struct ntfy_mailto_config *) nmth->context; + char *address = (char *)config->envelope_from.address; + + i_free(address); + i_free(config); +} + +/* * Validation */ @@ -382,6 +436,10 @@ const struct sieve_script_env *senv = nenv->scriptenv; struct ntfy_mailto_context *mtctx = (struct ntfy_mailto_context *) nact->method_context; + struct ntfy_mailto_config *mth_config = + (struct ntfy_mailto_config *)nenv->method->context; + struct sieve_mail_sender *env_from = + &mth_config->envelope_from; const char *from = NULL, *from_smtp = NULL; const char *subject = mtctx->uri->subject; const char *body = mtctx->uri->body; @@ -417,12 +475,42 @@ from = nact->from; } - /* Determine SMTP from address */ - if ( sieve_message_get_sender(nenv->msgctx) != NULL ) { - if ( mtctx->from_normalized == NULL ) { + /* Determine which sender to use + + From RFC 5436, Section 2.3: + + The ":from" tag overrides the default sender of the notification + message. "Sender", here, refers to the value used in the [RFC5322] + "From" header. Implementations MAY also use this value in the + [RFC5321] "MAIL FROM" command (the "envelope sender"), or they may + prefer to establish a mailbox that receives bounces from notification + messages. + */ + from_smtp = sieve_message_get_sender(nenv->msgctx); + if ( from_smtp != NULL ) { + switch ( env_from->source ) { + case SIEVE_MAIL_SENDER_SOURCE_SENDER: + break; + case SIEVE_MAIL_SENDER_SOURCE_RECIPIENT: + from_smtp = sieve_message_get_final_recipient(nenv->msgctx); + break; + case SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT: + from_smtp = sieve_message_get_orig_recipient(nenv->msgctx); + break; + case SIEVE_MAIL_SENDER_SOURCE_EXPLICIT: + from_smtp = env_from->address; + break; + case SIEVE_MAIL_SENDER_SOURCE_DEFAULT: + if ( mtctx->from_normalized != NULL ) { + from_smtp = mtctx->from_normalized; + break; + } + /* Fall through */ + case SIEVE_MAIL_SENDER_SOURCE_POSTMASTER: from_smtp = senv->postmaster_address; - } else { - from_smtp = mtctx->from_normalized; + break; + default: + break; } } diff -r 637307bdbdf2 -r 400be376fe02 tests/extensions/enotify/mailto.svtest --- a/tests/extensions/enotify/mailto.svtest Wed Oct 21 23:27:36 2015 +0200 +++ b/tests/extensions/enotify/mailto.svtest Wed Oct 21 23:31:06 2015 +0200 @@ -294,7 +294,7 @@ } if not envelope :is "to" "stephan at example.org" { - test_fail "envelope sender set incorrectly"; + test_fail "envelope recipient set incorrectly"; } test_message :smtp 1; @@ -304,6 +304,122 @@ } if not envelope :is "to" "timo at example.com" { + test_fail "envelope recipient set incorrectly"; + } +} + +/* + * Envelope config - sender + */ + +test_set "message" text: +From: stephan at example.org +To: nico at frop.example.org +Subject: Frop! + +Klutsefluts. +. +; + +test_set "envelope.from" "sirius at example.org"; +test_set "envelope.to" "bertus at frop.example.org"; + +test_config_set "sieve_notify_mailto_envelope_from" + "sender"; +test_config_reload :extension "enotify"; +test_result_reset; + +test "Envelope config - sender" { + notify :from "nico at frop.example.org" + "mailto:stephan at example.org?cc=timo at example.com"; + + if not test_result_execute { + test_fail "failed to execute notify"; + } + + test_message :smtp 0; + + if not header :is "from" "nico at frop.example.org" { + test_fail "from set incorrectly"; + } + + if not envelope :is "from" "sirius at example.org" { test_fail "envelope sender set incorrectly"; } + + if not envelope :is "to" "stephan at example.org" { + test_fail "envelope recipient set incorrectly"; + } + + test_message :smtp 1; + + if not header :is "from" "nico at frop.example.org" { + test_fail "from set incorrectly"; + } + + if not envelope :is "from" "sirius at example.org" { + test_fail "envelope sender set incorrectly"; + } + + if not envelope :is "to" "timo at example.com" { + test_fail "envelope recipient set incorrectly"; + } } + +/* + * Envelope config - recipient + */ + +test_set "message" text: +From: stephan at example.org +To: nico at frop.example.org +Subject: Frop! + +Klutsefluts. +. +; + +test_set "envelope.from" "sirius at example.org"; +test_set "envelope.to" "bertus at frop.example.org"; + +test_config_set "sieve_notify_mailto_envelope_from" + "recipient"; +test_config_reload :extension "enotify"; +test_result_reset; + +test "Envelope config - recipient" { + notify :from "nico at frop.example.org" + "mailto:stephan at example.org?cc=timo at example.com"; + + if not test_result_execute { + test_fail "failed to execute notify"; + } + + test_message :smtp 0; + + if not header :is "from" "nico at frop.example.org" { + test_fail "from set incorrectly"; + } + + if not envelope :is "from" "bertus at frop.example.org" { + test_fail "envelope sender set incorrectly"; + } + + if not envelope :is "to" "stephan at example.org" { + test_fail "envelope recipient set incorrectly"; + } + + test_message :smtp 1; + + if not header :is "from" "nico at frop.example.org" { + test_fail "from set incorrectly"; + } + + if not envelope :is "from" "bertus at frop.example.org" { + test_fail "envelope sender set incorrectly"; + } + + if not envelope :is "to" "timo at example.com" { + test_fail "envelope recipient set incorrectly"; + } +} From pigeonhole at rename-it.nl Wed Oct 21 21:35:06 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 21 Oct 2015 23:35:06 +0200 Subject: dovecot-2.2-pigeonhole: lib-sieve: Created generic implementatio... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/637307bdbdf2 changeset: 2120:637307bdbdf2 user: Stephan Bosch date: Wed Oct 21 23:27:36 2015 +0200 description: lib-sieve: Created generic implementation for parsing an envelope_from setting, such as sieve_redirect_envelope_from. Also adds a new source for the envelope_from address called "postmaster". This means that the value is obtained from the postmaster_address LDA setting. diffstat: INSTALL | 9 ++-- src/lib-sieve/cmd-redirect.c | 22 ++++++----- src/lib-sieve/sieve-common.h | 20 +++++++--- src/lib-sieve/sieve-settings.c | 78 +++++++++++++++++++++++++---------------- src/lib-sieve/sieve-settings.h | 4 ++ 5 files changed, 81 insertions(+), 52 deletions(-) diffs (221 lines): diff -r 9ff5fac3f7a8 -r 637307bdbdf2 INSTALL --- a/INSTALL Tue Oct 20 21:54:49 2015 +0200 +++ b/INSTALL Wed Oct 21 23:27:36 2015 +0200 @@ -229,14 +229,15 @@ appears to originate from the original sender. The following values are supported for this setting: - "sender" - The sender address is used (default) - "recipient" - The final recipient address is used - "orig_recipient" - The original recipient is used + "sender" - The sender address is used (default). + "recipient" - The final recipient address is used. + "orig_recipient" - The original recipient is used. + "postmaster" - The postmaster_address configured for the LDA. "" - Redirected messages are always sent from user at domain. The angle brackets are mandatory. The null "<>" address is also supported. - When the envelope sender of the processed message is the null address "<>", + When the envelope sender of the processed message is the null address "<>", the envelope sender of the redirected message is also always "<>", irrespective of what is configured for this setting. diff -r 9ff5fac3f7a8 -r 637307bdbdf2 src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Tue Oct 20 21:54:49 2015 +0200 +++ b/src/lib-sieve/cmd-redirect.c Wed Oct 21 23:27:36 2015 +0200 @@ -317,8 +317,8 @@ const struct sieve_script_env *senv = aenv->scriptenv; const char *sender = sieve_message_get_sender(msgctx); const char *recipient = sieve_message_get_final_recipient(msgctx); - enum sieve_redirect_envelope_from env_from = - aenv->svinst->redirect_from; + struct sieve_mail_sender *env_from = + &aenv->svinst->redirect_from; struct istream *input; struct ostream *output; const char *error; @@ -350,20 +350,22 @@ when then returns a delivery status notification that also ends up being redirected to the same invalid address. */ - if ( sender != NULL && - env_from != SIEVE_REDIRECT_ENVELOPE_FROM_SENDER ) { - switch ( env_from ) { - case SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT: + if ( sender != NULL ) { + switch ( env_from->source ) { + case SIEVE_MAIL_SENDER_SOURCE_RECIPIENT: sender = sieve_message_get_final_recipient(msgctx); break; - case SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT: + case SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT: sender = sieve_message_get_orig_recipient(msgctx); break; - case SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT: - sender = aenv->svinst->redirect_from_explicit; + case SIEVE_MAIL_SENDER_SOURCE_POSTMASTER: + sender = senv->postmaster_address; + break; + case SIEVE_MAIL_SENDER_SOURCE_EXPLICIT: + sender = env_from->address; break; default: - i_unreached(); + break; } } diff -r 9ff5fac3f7a8 -r 637307bdbdf2 src/lib-sieve/sieve-common.h --- a/src/lib-sieve/sieve-common.h Tue Oct 20 21:54:49 2015 +0200 +++ b/src/lib-sieve/sieve-common.h Wed Oct 21 23:27:36 2015 +0200 @@ -21,11 +21,18 @@ #define SIEVE_MAX_NUMBER ((sieve_number_t) -1) -enum sieve_redirect_envelope_from { - SIEVE_REDIRECT_ENVELOPE_FROM_SENDER, - SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT, - SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT, - SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT +enum sieve_mail_sender_source { + SIEVE_MAIL_SENDER_SOURCE_DEFAULT = 0, + SIEVE_MAIL_SENDER_SOURCE_SENDER, + SIEVE_MAIL_SENDER_SOURCE_RECIPIENT, + SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT, + SIEVE_MAIL_SENDER_SOURCE_POSTMASTER, + SIEVE_MAIL_SENDER_SOURCE_EXPLICIT +}; + +struct sieve_mail_sender { + enum sieve_mail_sender_source source; + const char *address; }; /* @@ -206,8 +213,7 @@ size_t max_script_size; unsigned int max_actions; unsigned int max_redirects; - enum sieve_redirect_envelope_from redirect_from; - const char *redirect_from_explicit; + struct sieve_mail_sender redirect_from; }; #endif /* __SIEVE_COMMON_H */ diff -r 9ff5fac3f7a8 -r 637307bdbdf2 src/lib-sieve/sieve-settings.c --- a/src/lib-sieve/sieve-settings.c Tue Oct 20 21:54:49 2015 +0200 +++ b/src/lib-sieve/sieve-settings.c Wed Oct 21 23:27:36 2015 +0200 @@ -217,6 +217,48 @@ return TRUE; } +bool sieve_setting_get_mail_sender_value +(struct sieve_instance *svinst, pool_t pool, const char *setting, + struct sieve_mail_sender *sender) +{ + const char *str_value; + size_t set_len; + + str_value = sieve_setting_get(svinst, setting); + if ( str_value == NULL ) + return FALSE; + + str_value = t_str_trim(str_value); + str_value = t_str_lcase(str_value); + set_len = strlen(str_value); + if ( set_len > 0 ) { + if ( strcmp(str_value, "default") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_DEFAULT; + } else if ( strcmp(str_value, "sender") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_SENDER; + } else if ( strcmp(str_value, "recipient") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_RECIPIENT; + } else if ( strcmp(str_value, "orig_recipient") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT; + } else if ( strcmp(str_value, "postmaster") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_POSTMASTER; + } else if ( str_value[0] == '<' && str_value[set_len-1] == '>') { + sender->source = SIEVE_MAIL_SENDER_SOURCE_EXPLICIT; + + str_value = t_str_trim(t_strndup(str_value+1, set_len-2)); + sender->address = NULL; + if ( *str_value != '\0' ) + sender->address = p_strdup(pool, str_value); + } else { + sieve_sys_warning(svinst, + "Invalid value for setting '%s': '%s'", setting, + str_value); + return FALSE; + } + } + return TRUE; +} + /* * Main Sieve engine settings */ @@ -226,7 +268,6 @@ { unsigned long long int uint_setting; size_t size_setting; - const char *str_setting; svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE; if ( sieve_setting_get_size_value @@ -246,36 +287,11 @@ svinst->max_redirects = (unsigned int) uint_setting; } - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER; - svinst->redirect_from_explicit = NULL; - if ( (str_setting=sieve_setting_get - (svinst, "sieve_redirect_envelope_from")) != NULL ) { - size_t set_len; - - str_setting = t_str_trim(str_setting); - str_setting = t_str_lcase(str_setting); - set_len = strlen(str_setting); - if ( set_len > 0 ) { - if ( strcmp(str_setting, "sender") == 0 ) { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER; - } else if ( strcmp(str_setting, "recipient") == 0 ) { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT; - } else if ( strcmp(str_setting, "orig_recipient") == 0 ) { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT; - } else if ( str_setting[0] == '<' && str_setting[set_len-1] == '>') { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT; - - str_setting = t_str_trim(t_strndup(str_setting+1, set_len-2)); - if ( *str_setting != '\0' ) { - svinst->redirect_from_explicit = - p_strdup(svinst->pool, str_setting); - } - } else { - sieve_sys_warning(svinst, - "Invalid value `%s' for sieve_redirect_envelope_from setting", - str_setting); - } - } + if (!sieve_setting_get_mail_sender_value + (svinst, svinst->pool, "sieve_redirect_envelope_from", + &svinst->redirect_from)) { + svinst->redirect_from.source = + SIEVE_MAIL_SENDER_SOURCE_DEFAULT; } } diff -r 9ff5fac3f7a8 -r 637307bdbdf2 src/lib-sieve/sieve-settings.h --- a/src/lib-sieve/sieve-settings.h Tue Oct 20 21:54:49 2015 +0200 +++ b/src/lib-sieve/sieve-settings.h Wed Oct 21 23:27:36 2015 +0200 @@ -37,6 +37,10 @@ (struct sieve_instance *svinst, const char *setting, sieve_number_t *value_r); +bool sieve_setting_get_mail_sender_value + (struct sieve_instance *svinst, pool_t pool, const char *setting, + struct sieve_mail_sender *sender); + /* * Main Sieve engine settings */ From dovecot at dovecot.org Thu Oct 22 10:55:38 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 22 Oct 2015 10:55:38 +0000 Subject: dovecot-2.2: quota-dict: Added "no-unset" parameter. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/20b381fd95d0 changeset: 19329:20b381fd95d0 user: Timo Sirainen date: Thu Oct 22 13:55:27 2015 +0300 description: quota-dict: Added "no-unset" parameter. diffstat: src/plugins/quota/quota-dict.c | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diffs (39 lines): diff -r 4bcca8a822dc -r 20b381fd95d0 src/plugins/quota/quota-dict.c --- a/src/plugins/quota/quota-dict.c Wed Oct 21 19:12:45 2015 +0300 +++ b/src/plugins/quota/quota-dict.c Thu Oct 22 13:55:27 2015 +0300 @@ -17,6 +17,7 @@ struct quota_root root; struct dict *dict; struct timeout *to_update; + bool disable_unset; }; extern struct quota_backend quota_backend_dict; @@ -57,6 +58,9 @@ } else if (strncmp(args, "ignoreunlimited:", 16) == 0) { _root->disable_unlimited_tracking = TRUE; args += 16; + } else if (strncmp(args, "no-unset:", 9) == 0) { + root->disable_unset = TRUE; + args += 9; } else if (strncmp(args, "ns=", 3) == 0) { p = strchr(args, ':'); if (p == NULL) @@ -126,9 +130,14 @@ T_BEGIN { dt = dict_transaction_begin(root->dict); /* these unsets are mainly necessary for pgsql, because its - trigger otherwise increases quota without deleting it */ - dict_unset(dt, DICT_QUOTA_CURRENT_BYTES_PATH); - dict_unset(dt, DICT_QUOTA_CURRENT_COUNT_PATH); + trigger otherwise increases quota without deleting it. + but some people with other databases want to store the + quota usage among other data in the same row, which + shouldn't be deleted. */ + if (!root->disable_unset) { + dict_unset(dt, DICT_QUOTA_CURRENT_BYTES_PATH); + dict_unset(dt, DICT_QUOTA_CURRENT_COUNT_PATH); + } dict_set(dt, DICT_QUOTA_CURRENT_BYTES_PATH, dec2str(bytes)); dict_set(dt, DICT_QUOTA_CURRENT_COUNT_PATH, dec2str(count)); } T_END; From dovecot at dovecot.org Thu Oct 22 13:59:12 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 22 Oct 2015 13:59:12 +0000 Subject: dovecot-2.2: notify plugin: Don't access already freed memory. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3d576d682137 changeset: 19330:3d576d682137 user: Timo Sirainen date: Thu Oct 22 16:59:01 2015 +0300 description: notify plugin: Don't access already freed memory. In the same changeset I even added a comment just above that it shouldn't be accessed.. diffstat: src/plugins/notify/notify-storage.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff -r 20b381fd95d0 -r 3d576d682137 src/plugins/notify/notify-storage.c --- a/src/plugins/notify/notify-storage.c Thu Oct 22 13:55:27 2015 +0300 +++ b/src/plugins/notify/notify-storage.c Thu Oct 22 16:59:01 2015 +0300 @@ -178,6 +178,7 @@ { struct notify_transaction_context *lt = NOTIFY_CONTEXT(t); union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box); + bool no_notify = (t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) != 0; if (lt->tmp_mail != NULL) mail_free(<->tmp_mail); @@ -190,7 +191,7 @@ /* FIXME: note that t is already freed at this stage. it's not actually being dereferenced anymore though. still, a bit unsafe.. */ - if ((t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) + if (!no_notify) notify_contexts_mail_transaction_commit(t, changes_r); return 0; } From dovecot at dovecot.org Fri Oct 23 12:21:29 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 23 Oct 2015 12:21:29 +0000 Subject: dovecot-2.2: auth: Fixed userdb changing username via auth-worker Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ce132257cbb5 changeset: 19331:ce132257cbb5 user: Timo Sirainen date: Fri Oct 23 15:21:15 2015 +0300 description: auth: Fixed userdb changing username via auth-worker diffstat: src/auth/auth-worker-client.c | 2 ++ src/auth/userdb-blocking.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diffs (40 lines): diff -r 3d576d682137 -r ce132257cbb5 src/auth/auth-worker-client.c --- a/src/auth/auth-worker-client.c Thu Oct 22 16:59:01 2015 +0300 +++ b/src/auth/auth-worker-client.c Fri Oct 23 15:21:15 2015 +0300 @@ -373,6 +373,8 @@ break; case USERDB_RESULT_OK: str_append(str, "OK\t"); + str_append_tabescaped(str, auth_request->user); + str_append_c(str, '\t'); auth_fields_append(auth_request->userdb_reply, str, 0, 0); if (auth_request->userdb_lookup_tempfailed) str_append(str, "\ttempfail"); diff -r 3d576d682137 -r ce132257cbb5 src/auth/userdb-blocking.c --- a/src/auth/userdb-blocking.c Thu Oct 22 16:59:01 2015 +0300 +++ b/src/auth/userdb-blocking.c Fri Oct 23 15:21:15 2015 +0300 @@ -18,7 +18,7 @@ { struct auth_request *request = context; enum userdb_result result; - const char *args; + const char *username, *args; if (strncmp(reply, "FAIL\t", 5) == 0) { result = USERDB_RESULT_INTERNAL_FAILURE; @@ -28,7 +28,14 @@ args = reply + 9; } else if (strncmp(reply, "OK\t", 3) == 0) { result = USERDB_RESULT_OK; - args = reply + 3; + username = reply + 3; + args = strchr(username, '\t'); + if (args == NULL) + args = ""; + else + username = t_strdup_until(username, args++); + if (strcmp(request->user, username) != 0) + request->user = p_strdup(request->pool, username); } else { result = USERDB_RESULT_INTERNAL_FAILURE; i_error("BUG: auth-worker sent invalid user reply"); From dovecot at dovecot.org Mon Oct 26 14:29:06 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 26 Oct 2015 14:29:06 +0000 Subject: dovecot-2.2: acl: Fixed handling mailbox deletion when only "del... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0660772fb1dd changeset: 19332:0660772fb1dd user: Timo Sirainen date: Mon Oct 26 16:28:51 2015 +0200 description: acl: Fixed handling mailbox deletion when only "delete" right was available. So especially when there were no "lookup" or "read" rights. diffstat: src/plugins/acl/acl-attributes.c | 5 +++++ src/plugins/acl/acl-mailbox.c | 9 +++------ 2 files changed, 8 insertions(+), 6 deletions(-) diffs (41 lines): diff -r ce132257cbb5 -r 0660772fb1dd src/plugins/acl/acl-attributes.c --- a/src/plugins/acl/acl-attributes.c Fri Oct 23 15:21:15 2015 +0300 +++ b/src/plugins/acl/acl-attributes.c Mon Oct 26 16:28:51 2015 +0200 @@ -101,6 +101,11 @@ { int ret; + if (box->deleting) { + /* deleting attributes during mailbox deletion */ + return 1; + } + /* RFC 5464: When the ACL extension [RFC4314] is present, users can only set and diff -r ce132257cbb5 -r 0660772fb1dd src/plugins/acl/acl-mailbox.c --- a/src/plugins/acl/acl-mailbox.c Fri Oct 23 15:21:15 2015 +0300 +++ b/src/plugins/acl/acl-mailbox.c Mon Oct 26 16:28:51 2015 +0200 @@ -184,12 +184,7 @@ return -1; } - /* deletion might internally open the mailbox. let it succeed even if - we don't have READ permission. */ - abox->skip_acl_checks = TRUE; - ret = abox->module_ctx.super.delete_box(box); - abox->skip_acl_checks = FALSE; - return ret; + return abox->module_ctx.super.delete_box(box); } static int @@ -500,6 +495,8 @@ if ((box->flags & MAILBOX_FLAG_SAVEONLY) != 0) { open_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ? ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT; + } else if (box->deleting) { + open_right = ACL_STORAGE_RIGHT_DELETE; } else { open_right = ACL_STORAGE_RIGHT_READ; } From dovecot at dovecot.org Mon Oct 26 15:21:09 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 26 Oct 2015 15:21:09 +0000 Subject: dovecot-2.2: acl: If mailbox is autocreated, assume it already e... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c7d384bc3964 changeset: 19333:c7d384bc3964 user: Timo Sirainen date: Mon Oct 26 17:20:49 2015 +0200 description: acl: If mailbox is autocreated, assume it already exists and don't require "create" ACL diffstat: src/plugins/acl/acl-mailbox.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-) diffs (37 lines): diff -r 0660772fb1dd -r c7d384bc3964 src/plugins/acl/acl-mailbox.c --- a/src/plugins/acl/acl-mailbox.c Mon Oct 26 16:28:51 2015 +0200 +++ b/src/plugins/acl/acl-mailbox.c Mon Oct 26 17:20:49 2015 +0200 @@ -111,6 +111,14 @@ acl_object_deinit(&parent_aclobj); } +static bool mailbox_is_autocreated(struct mailbox *box) +{ + if (box->inbox_user) + return TRUE; + return box->set != NULL && + strcmp(box->set->autocreate, MAILBOX_SET_AUTO_NO) != 0; +} + static int acl_mailbox_create(struct mailbox *box, const struct mailbox_update *update, bool directory) @@ -118,9 +126,15 @@ struct acl_mailbox *abox = ACL_CONTEXT(box); int ret; - /* we're looking up CREATE permission from our parent's rights */ - ret = acl_mailbox_list_have_right(box->list, box->name, TRUE, - ACL_STORAGE_RIGHT_CREATE, NULL); + if (!mailbox_is_autocreated(box)) { + /* we're looking up CREATE permission from our parent's rights */ + ret = acl_mailbox_list_have_right(box->list, box->name, TRUE, + ACL_STORAGE_RIGHT_CREATE, NULL); + } else { + /* mailbox is autocreated, so we need to treat it as if it + already exists. ignore the "create" ACL here. */ + ret = 1; + } if (ret <= 0) { if (ret < 0) { mail_storage_set_internal_error(box->storage); From dovecot at dovecot.org Tue Oct 27 21:57:14 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 27 Oct 2015 21:57:14 +0000 Subject: dovecot-2.2: lib-mail, fts: Put application/xhtml+xml MIME parts... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c02969e65b64 changeset: 19334:c02969e65b64 user: Timo Sirainen date: Tue Oct 27 23:56:48 2015 +0200 description: lib-mail, fts: Put application/xhtml+xml MIME parts through html parser as well. diffstat: src/lib-mail/mail-html2text.h | 7 +++++++ src/lib-mail/message-snippet.c | 2 +- src/lib-mail/test-message-snippet.c | 14 ++++++++++++++ src/plugins/fts/fts-parser-html.c | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diffs (63 lines): diff -r c7d384bc3964 -r c02969e65b64 src/lib-mail/mail-html2text.h --- a/src/lib-mail/mail-html2text.h Mon Oct 26 17:20:49 2015 +0200 +++ b/src/lib-mail/mail-html2text.h Tue Oct 27 23:56:48 2015 +0200 @@ -12,4 +12,11 @@ buffer_t *output); void mail_html2text_deinit(struct mail_html2text **ht); +static inline bool +mail_html2text_content_type_match(const char *content_type) +{ + return strcasecmp(content_type, "text/html") == 0 || + strcasecmp(content_type, "application/xhtml+xml") == 0; +} + #endif diff -r c7d384bc3964 -r c02969e65b64 src/lib-mail/message-snippet.c --- a/src/lib-mail/message-snippet.c Mon Oct 26 17:20:49 2015 +0200 +++ b/src/lib-mail/message-snippet.c Tue Oct 27 23:56:48 2015 +0200 @@ -115,7 +115,7 @@ ct = message_decoder_current_content_type(decoder); if (ct == NULL) /* text/plain */ ; - else if (strcasecmp(ct, "text/html") == 0) { + else if (mail_html2text_content_type_match(ct)) { ctx.html2text = mail_html2text_init(MAIL_HTML2TEXT_FLAG_SKIP_QUOTED); ctx.plain_output = buffer_create_dynamic(pool, 1024); } else if (strncasecmp(ct, "text/", 5) != 0) diff -r c7d384bc3964 -r c02969e65b64 src/lib-mail/test-message-snippet.c --- a/src/lib-mail/test-message-snippet.c Mon Oct 26 17:20:49 2015 +0200 +++ b/src/lib-mail/test-message-snippet.c Tue Oct 27 23:56:48 2015 +0200 @@ -51,6 +51,20 @@ "
=\n", 100, "Hi, How is it going? > -foo" }, + + { "Content-Transfer-Encoding: quoted-printable\n" + "Content-Type: application/xhtml+xml;\n" + " charset=utf-8\n" + "\n" + "Hi,

How =\n" + "is it going?
quoted text is ignored
\n" + "> -foo\n" + "

=\n", + 100, + "Hi, How is it going? > -foo" }, }; static void test_message_snippet(void) diff -r c7d384bc3964 -r c02969e65b64 src/plugins/fts/fts-parser-html.c --- a/src/plugins/fts/fts-parser-html.c Mon Oct 26 17:20:49 2015 +0200 +++ b/src/plugins/fts/fts-parser-html.c Tue Oct 27 23:56:48 2015 +0200 @@ -19,7 +19,7 @@ { struct html_fts_parser *parser; - if (strcasecmp(content_type, "text/html") != 0) + if (!mail_html2text_content_type_match(content_type)) return NULL; parser = i_new(struct html_fts_parser, 1); From pigeonhole at rename-it.nl Tue Oct 27 22:43:00 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 27 Oct 2015 23:43:00 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: body extension: Properly impl... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d24a90790fc8 changeset: 2122:d24a90790fc8 user: Stephan Bosch date: Tue Oct 27 23:42:52 2015 +0100 description: lib-sieve: body extension: Properly implemented the :text body transform. It now extracts bare text from HTML/XHMTL parts. Other text/* parts are still returned as is. Any other unrecognized content types are skipped. diffstat: Makefile.am | 1 + README | 3 +- src/lib-sieve/plugins/body/ext-body-common.c | 152 ++++++++++++++-------- src/lib-sieve/plugins/body/ext-body.c | 18 +-- tests/extensions/body/text.svtest | 184 +++++++++++++++++++++++++++ 5 files changed, 284 insertions(+), 74 deletions(-) diffs (truncated from 571 to 300 lines): diff -r 400be376fe02 -r d24a90790fc8 Makefile.am --- a/Makefile.am Wed Oct 21 23:31:06 2015 +0200 +++ b/Makefile.am Tue Oct 27 23:42:52 2015 +0100 @@ -109,6 +109,7 @@ tests/extensions/body/errors.svtest \ tests/extensions/body/raw.svtest \ tests/extensions/body/content.svtest \ + tests/extensions/body/text.svtest \ tests/extensions/body/match-values.svtest \ tests/extensions/regex/basic.svtest \ tests/extensions/regex/match-values.svtest \ diff -r 400be376fe02 -r d24a90790fc8 README --- a/README Wed Oct 21 23:31:06 2015 +0200 +++ b/README Tue Oct 27 23:42:52 2015 +0100 @@ -99,8 +99,7 @@ The following Sieve language extensions are also supported: copy (RFC 3894): fully supported. - body (RFC 5173): almost fully supported, but the text body-transform - implementation is simple. + body (RFC 5173): fully supported. environment (RFC 5183): fully supported (v0.4.0+). variables (RFC 5229): fully supported. vacation (RFC 5230): fully supported. diff -r 400be376fe02 -r d24a90790fc8 src/lib-sieve/plugins/body/ext-body-common.c --- a/src/lib-sieve/plugins/body/ext-body-common.c Wed Oct 21 23:31:06 2015 +0200 +++ b/src/lib-sieve/plugins/body/ext-body-common.c Tue Oct 27 23:42:52 2015 +0100 @@ -11,6 +11,7 @@ #include "message-date.h" #include "message-parser.h" #include "message-decoder.h" +#include "mail-html2text.h" #include "mail-storage.h" #include "sieve-common.h" @@ -21,11 +22,6 @@ #include "ext-body-common.h" -/* FIXME: This implementation is largely borrowed from the original sieve-cmu.c - * of the old cmusieve plugin. This nees work to match current specification of - * the body extension. - */ - struct ext_body_part { const char *content; unsigned long size; @@ -34,10 +30,10 @@ struct ext_body_part_cached { const char *content_type; - const char *raw_body; const char *decoded_body; - size_t raw_body_size; + const char *text_body; size_t decoded_body_size; + size_t text_body_size; bool have_body; /* there's the empty end-of-headers line */ }; @@ -105,7 +101,7 @@ static bool ext_body_get_return_parts (struct ext_body_message_context *ctx, const char * const *wanted_types, - bool decode_to_plain) + bool extract_text) { const struct ext_body_part_cached *body_parts; unsigned int i, count; @@ -139,16 +135,16 @@ * cache item is read. If it is missing, this function fails and the cache * needs to be completed by ext_body_parts_add_missing(). */ - if (decode_to_plain) { + if (extract_text) { + if (body_parts[i].text_body == NULL) + return FALSE; + return_part->content = body_parts[i].text_body; + return_part->size = body_parts[i].text_body_size; + } else { if (body_parts[i].decoded_body == NULL) return FALSE; return_part->content = body_parts[i].decoded_body; - return_part->size = body_parts[i].decoded_body_size; - } else { - if (body_parts[i].raw_body == NULL) - return FALSE; - return_part->content = body_parts[i].raw_body; - return_part->size = body_parts[i].raw_body_size; + return_part->size = body_parts[i].decoded_body_size; } } @@ -157,32 +153,52 @@ static void ext_body_part_save (struct ext_body_message_context *ctx, - struct ext_body_part_cached *body_part, bool decoded) + struct ext_body_part_cached *body_part, bool extract_text) { buffer_t *buf = ctx->tmp_buffer; + buffer_t *text_buf = NULL; char *part_data; size_t part_size; /* Add terminating NUL to the body part buffer */ buffer_append_c(buf, '\0'); + if ( extract_text ) { + if ( mail_html2text_content_type_match + (body_part->content_type) ) { + struct mail_html2text *html2text; + + text_buf = buffer_create_dynamic(default_pool, 4096); + + /* Remove HTML markup */ + html2text = mail_html2text_init(0); + mail_html2text_more(html2text, buf->data, buf->used, text_buf); + mail_html2text_deinit(&html2text); + + buf = text_buf; + } + } + part_data = p_malloc(ctx->pool, buf->used); memcpy(part_data, buf->data, buf->used); part_size = buf->used - 1; - /* Depending on whether the part is decoded or not store message body in the - * appropriate cache location. + if ( text_buf != NULL) + buffer_free(&text_buf); + + /* Depending on whether the part is processed into text, store message + * body in the appropriate cache location. */ - if ( !decoded ) { - body_part->raw_body = part_data; - body_part->raw_body_size = part_size; - } else { + if ( !extract_text ) { body_part->decoded_body = part_data; body_part->decoded_body_size = part_size; + } else { + body_part->text_body = part_data; + body_part->text_body_size = part_size; } /* Clear buffer */ - buffer_set_used_size(buf, 0); + buffer_set_used_size(ctx->tmp_buffer, 0); } static const char *_parse_content_type(const struct message_header_line *hdr) @@ -214,8 +230,9 @@ static int ext_body_parts_add_missing (const struct sieve_runtime_env *renv, struct ext_body_message_context *ctx, - const char *const *content_types, bool decode_to_plain) + const char *const *content_types, bool extract_text) { + buffer_t *buf = ctx->tmp_buffer; struct mail *mail = sieve_message_get_mail(renv->msgctx); struct ext_body_part_cached *body_part = NULL, *header_part = NULL; struct message_parser_ctx *parser; @@ -229,7 +246,7 @@ int ret; /* First check whether any are missing */ - if (ext_body_get_return_parts(ctx, content_types, decode_to_plain)) { + if (ext_body_get_return_parts(ctx, content_types, extract_text)) { /* Cache hit; all are present */ return SIEVE_EXEC_OK; } @@ -248,10 +265,10 @@ t_array_init(&part_index, 8); } - buffer_set_used_size(ctx->tmp_buffer, 0); + buffer_set_used_size(buf, 0); /* Initialize body decoder */ - decoder = decode_to_plain ? message_decoder_init(NULL, 0) : NULL; + decoder = message_decoder_init(NULL, 0); //parser = message_parser_init_from_parts(parts, input, 0, //MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS); @@ -270,7 +287,7 @@ message_rfc822 = TRUE; } else { if ( save_body ) { - ext_body_part_save(ctx, body_part, decoder != NULL); + ext_body_part_save(ctx, body_part, extract_text); } } } @@ -321,14 +338,13 @@ /* Reading headers */ /* Decode block */ - if ( decoder != NULL ) - (void)message_decoder_decode_next_block(decoder, &block, &decoded); + (void)message_decoder_decode_next_block(decoder, &block, &decoded); /* Check for end of headers */ if ( block.hdr == NULL ) { /* Save headers for message/rfc822 part */ if ( header_part != NULL ) { - ext_body_part_save(ctx, header_part, decoder != NULL); + ext_body_part_save(ctx, header_part, extract_text); header_part = NULL; } @@ -348,14 +364,14 @@ } else if ( header_part != NULL ) { /* Save message/rfc822 header as part content */ if ( block.hdr->continued ) { - buffer_append(ctx->tmp_buffer, block.hdr->value, block.hdr->value_len); + buffer_append(buf, block.hdr->value, block.hdr->value_len); } else { - buffer_append(ctx->tmp_buffer, block.hdr->name, block.hdr->name_len); - buffer_append(ctx->tmp_buffer, block.hdr->middle, block.hdr->middle_len); - buffer_append(ctx->tmp_buffer, block.hdr->value, block.hdr->value_len); + buffer_append(buf, block.hdr->name, block.hdr->name_len); + buffer_append(buf, block.hdr->middle, block.hdr->middle_len); + buffer_append(buf, block.hdr->value, block.hdr->value_len); } if ( !block.hdr->no_newline ) { - buffer_append(ctx->tmp_buffer, "\r\n", 2); + buffer_append(buf, "\r\n", 2); } } @@ -384,32 +400,27 @@ /* Reading body */ if ( save_body ) { - if ( decoder != NULL ) { - (void)message_decoder_decode_next_block(decoder, &block, &decoded); - buffer_append(ctx->tmp_buffer, decoded.data, decoded.size); - } else { - buffer_append(ctx->tmp_buffer, block.data, block.size); - } + (void)message_decoder_decode_next_block(decoder, &block, &decoded); + buffer_append(buf, decoded.data, decoded.size); } } /* Save last body part if necessary */ if ( header_part != NULL ) { - ext_body_part_save(ctx, header_part, decoder != NULL); + ext_body_part_save(ctx, header_part, FALSE); } else if ( body_part != NULL && save_body ) { - ext_body_part_save(ctx, body_part, decoder != NULL); + ext_body_part_save(ctx, body_part, extract_text); } /* Try to fill the return_body_parts array once more */ - have_all = ext_body_get_return_parts(ctx, content_types, decode_to_plain); + have_all = ext_body_get_return_parts(ctx, content_types, extract_text); /* This time, failure is a bug */ i_assert(have_all); /* Cleanup */ (void)message_parser_deinit(&parser, &parts); - if (decoder != NULL) - message_decoder_deinit(&decoder); + message_decoder_deinit(&decoder); /* Return status */ if ( input->stream_errno != 0 ) { @@ -453,7 +464,7 @@ static int ext_body_get_content (const struct sieve_runtime_env *renv, const char * const *content_types, - int decode_to_plain, struct ext_body_part **parts_r) + struct ext_body_part **parts_r) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_body_message_context *ctx = @@ -463,7 +474,41 @@ T_BEGIN { /* Fill the return_body_parts array */ status = ext_body_parts_add_missing - (renv, ctx, content_types, decode_to_plain != 0); + (renv, ctx, content_types, FALSE); + } T_END; + + /* Check status */ + if ( status <= 0 ) + return status; + + /* Return the array of body items */ + (void) array_append_space(&ctx->return_body_parts); /* NULL-terminate */ + *parts_r = array_idx_modifiable(&ctx->return_body_parts, 0); + + return status; +} + From dovecot at dovecot.org Wed Oct 28 10:25:24 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 28 Oct 2015 10:25:24 +0000 Subject: dovecot-2.2: auth: nopassword field is specific to a single pass... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3a6e503c9ee6 changeset: 19335:3a6e503c9ee6 user: Timo Sirainen date: Wed Oct 28 12:25:08 2015 +0200 description: auth: nopassword field is specific to a single passdb, remove before next passdb is processed diffstat: src/auth/auth-request.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r c02969e65b64 -r 3a6e503c9ee6 src/auth/auth-request.c --- a/src/auth/auth-request.c Tue Oct 27 23:56:48 2015 +0200 +++ b/src/auth/auth-request.c Wed Oct 28 12:25:08 2015 +0200 @@ -610,6 +610,9 @@ request->passdb_success = FALSE; break; } + /* nopassword check is specific to a single passdb and shouldn't leak + to the next one. we already added it to cache. */ + auth_fields_remove(request->extra_fields, "nopassword"); if (request->requested_login_user != NULL && *result == PASSDB_RESULT_OK) { From dovecot at dovecot.org Wed Oct 28 10:28:27 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 28 Oct 2015 10:28:27 +0000 Subject: dovecot-2.2: auth: Typofix for error message. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/9654ab4c337c changeset: 19336:9654ab4c337c user: Timo Sirainen date: Wed Oct 28 12:28:12 2015 +0200 description: auth: Typofix for error message. diffstat: src/auth/auth-master-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 3a6e503c9ee6 -r 9654ab4c337c src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Wed Oct 28 12:25:08 2015 +0200 +++ b/src/auth/auth-master-connection.c Wed Oct 28 12:28:12 2015 +0200 @@ -347,7 +347,7 @@ str_printfa(str, "FAIL\t%u", auth_request->id); break; case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: - str_printfa(str, "FAIL\t%u\treason=Configured passdbs don't support crentials lookups", + str_printfa(str, "FAIL\t%u\treason=Configured passdbs don't support credentials lookups", auth_request->id); break; } From dovecot at dovecot.org Thu Oct 29 10:55:38 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Oct 2015 10:55:38 +0000 Subject: dovecot-2.2: acl: acl_object_list_*() now duplicates rights at i... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/8f198b569b01 changeset: 19337:8f198b569b01 user: Timo Sirainen date: Thu Oct 29 12:55:20 2015 +0200 description: acl: acl_object_list_*() now duplicates rights at init to avoid them changing during listing. Depending on the calling code the acl_object could have been refreshed during the listing and caused bugs/crashes. This fixes a crash at least in mailbox deletion during attribute deletion where iter->idx was higher (2) than the number of rights at the time (0). diffstat: src/plugins/acl/acl-api-private.h | 4 +++- src/plugins/acl/acl-api.c | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diffs (72 lines): diff -r 9654ab4c337c -r 8f198b569b01 src/plugins/acl/acl-api-private.h --- a/src/plugins/acl/acl-api-private.h Wed Oct 28 12:28:12 2015 +0200 +++ b/src/plugins/acl/acl-api-private.h Thu Oct 29 12:55:20 2015 +0200 @@ -75,8 +75,10 @@ struct acl_object_list_iter { struct acl_object *aclobj; + pool_t pool; - unsigned int idx; + struct acl_rights *rights; + unsigned int idx, count; unsigned int failed:1; }; diff -r 9654ab4c337c -r 8f198b569b01 src/plugins/acl/acl-api.c --- a/src/plugins/acl/acl-api.c Wed Oct 28 12:28:12 2015 +0200 +++ b/src/plugins/acl/acl-api.c Thu Oct 29 12:55:20 2015 +0200 @@ -190,8 +190,13 @@ acl_default_object_list_init(struct acl_object *aclobj) { struct acl_object_list_iter *iter; + const struct acl_rights *aclobj_rights; + unsigned int i; + pool_t pool; - iter = i_new(struct acl_object_list_iter, 1); + pool = pool_alloconly_create("acl object list", 512); + iter = p_new(pool, struct acl_object_list_iter, 1); + iter->pool = pool; iter->aclobj = aclobj; if (!array_is_created(&aclobj->rights)) { @@ -202,28 +207,31 @@ if (aclobj->backend->v.object_refresh_cache(aclobj) < 0) iter->failed = TRUE; + + aclobj_rights = array_get(&aclobj->rights, &iter->count); + if (iter->count > 0) { + iter->rights = p_new(pool, struct acl_rights, iter->count); + for (i = 0; i < iter->count; i++) + acl_rights_dup(&aclobj_rights[i], pool, &iter->rights[i]); + } return iter; } int acl_default_object_list_next(struct acl_object_list_iter *iter, struct acl_rights *rights_r) { - const struct acl_rights *rights; - if (iter->failed) return -1; - if (iter->idx == array_count(&iter->aclobj->rights)) + if (iter->idx == iter->count) return 0; - - rights = array_idx(&iter->aclobj->rights, iter->idx++); - *rights_r = *rights; + *rights_r = iter->rights[iter->idx++]; return 1; } void acl_default_object_list_deinit(struct acl_object_list_iter *iter) { - i_free(iter); + pool_unref(&iter->pool); } struct acl_mailbox_list_context * From dovecot at dovecot.org Thu Oct 29 12:10:08 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Oct 2015 12:10:08 +0000 Subject: dovecot-2.2: auth: Avoid a crash by not trying to save empty del... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/308af6582495 changeset: 19338:308af6582495 user: Timo Sirainen date: Thu Oct 29 14:09:52 2015 +0200 description: auth: Avoid a crash by not trying to save empty delayed credentials. diffstat: src/auth/auth-request.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8f198b569b01 -r 308af6582495 src/auth/auth-request.c --- a/src/auth/auth-request.c Thu Oct 29 12:55:20 2015 +0200 +++ b/src/auth/auth-request.c Thu Oct 29 14:09:52 2015 +0200 @@ -810,7 +810,7 @@ if (!auth_request_handle_passdb_callback(&result, request)) { /* try next passdb */ if (request->skip_password_check && - request->delayed_credentials == NULL) { + request->delayed_credentials == NULL && size > 0) { /* passdb continue* rule after a successful lookup. remember these credentials and use them later on. */ unsigned char *dup; From dovecot at dovecot.org Thu Oct 29 13:06:32 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Oct 2015 13:06:32 +0000 Subject: dovecot-2.2: dsync: Fixed handling of deleted directories. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/594cd05217eb changeset: 19339:594cd05217eb user: Timo Sirainen date: Thu Oct 29 15:06:16 2015 +0200 description: dsync: Fixed handling of deleted directories. We may still know about the directory node even if it doesn't exist, and we still want to delete it. diffstat: src/doveadm/dsync/dsync-mailbox-tree-fill.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 308af6582495 -r 594cd05217eb src/doveadm/dsync/dsync-mailbox-tree-fill.c --- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c Thu Oct 29 14:09:52 2015 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c Thu Oct 29 15:06:16 2015 +0200 @@ -177,7 +177,8 @@ memcpy(del->guid, rec->mailbox_guid, sizeof(del->guid)); break; case MAILBOX_LOG_RECORD_DELETE_DIR: - if (node != NULL) { + if (node != NULL && + node->existence == DSYNC_MAILBOX_NODE_EXISTS) { /* directory exists again, skip it */ break; } From dovecot at dovecot.org Thu Oct 29 13:29:43 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Oct 2015 13:29:43 +0000 Subject: dovecot-2.2: imap: Fixed crash in NOTIFY when there were watched... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/787cfed25b0f changeset: 19340:787cfed25b0f user: Timo Sirainen date: Thu Oct 29 15:29:24 2015 +0200 description: imap: Fixed crash in NOTIFY when there were watched namespaces that didn't support NOTIFY. diffstat: src/imap/imap-notify.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 594cd05217eb -r 787cfed25b0f src/imap/imap-notify.c --- a/src/imap/imap-notify.c Thu Oct 29 15:06:16 2015 +0200 +++ b/src/imap/imap-notify.c Thu Oct 29 15:29:24 2015 +0200 @@ -245,6 +245,9 @@ const struct mailbox_list_notify_rec *rec; int ret, ret2 = 1; + if (notify_ns->notify == NULL) + return 0; /* notifications not supported in this namespace */ + while ((ret = mailbox_list_notify_next(notify_ns->notify, &rec)) > 0) { if (imap_notify_match(notify_ns, rec)) T_BEGIN { ret2 = imap_notify_next(notify_ns, rec); From dovecot at dovecot.org Thu Oct 29 13:45:50 2015 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Oct 2015 13:45:50 +0000 Subject: dovecot-2.2: push-notification: Fix linking against notify plugin Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1e7fe403dd50 changeset: 19341:1e7fe403dd50 user: Michael M Slusarz date: Tue Oct 27 21:54:26 2015 -0600 description: push-notification: Fix linking against notify plugin diffstat: src/plugins/push-notification/Makefile.am | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 787cfed25b0f -r 1e7fe403dd50 src/plugins/push-notification/Makefile.am --- a/src/plugins/push-notification/Makefile.am Thu Oct 29 15:29:24 2015 +0200 +++ b/src/plugins/push-notification/Makefile.am Tue Oct 27 21:54:26 2015 -0600 @@ -12,6 +12,11 @@ module_LTLIBRARIES = lib20_push_notification_plugin.la +if DOVECOT_PLUGIN_DEPS +lib20_push_notification_plugin_la_LIBADD = \ + ../notify/lib15_notify_plugin.la +endif + lib20_push_notification_plugin_la_SOURCES = \ push-notification-driver-dlog.c \ push-notification-driver-ox.c \ From pigeonhole at rename-it.nl Thu Oct 29 21:20:53 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 29 Oct 2015 22:20:53 +0100 Subject: dovecot-2.2-pigeonhole: doveadm sieve plugin: Fixed stray debug ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/49391f7404ab changeset: 2123:49391f7404ab user: Stephan Bosch date: Thu Oct 29 22:14:24 2015 +0100 description: doveadm sieve plugin: Fixed stray debug code committed in earlier patch. diffstat: src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r d24a90790fc8 -r 49391f7404ab src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c --- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c Tue Oct 27 23:42:52 2015 +0100 +++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-get.c Thu Oct 29 22:14:24 2015 +0100 @@ -26,7 +26,6 @@ struct istream *input; enum sieve_error error; - return 0; script = sieve_storage_open_script (_ctx->storage, ctx->scriptname, &error); if ( script == NULL || sieve_script_get_stream From pigeonhole at rename-it.nl Thu Oct 29 21:20:53 2015 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 29 Oct 2015 22:20:53 +0100 Subject: dovecot-2.2-pigeonhole: lib-sieve: Added sieve_enabled setting t... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/96d06e6a9127 changeset: 2124:96d06e6a9127 user: Stephan Bosch date: Thu Oct 29 22:14:32 2015 +0100 description: lib-sieve: Added sieve_enabled setting that defaults to "yes". This allows completely disabling Sieve processing for a particular user. diffstat: src/lib-sieve/sieve-storage.c | 39 +++++++++++++++++++++++-------- src/managesieve/managesieve-client.c | 13 +++++++++- src/plugins/lda-sieve/lda-sieve-plugin.c | 12 +++++++-- 3 files changed, 49 insertions(+), 15 deletions(-) diffs (144 lines): diff -r 49391f7404ab -r 96d06e6a9127 src/lib-sieve/sieve-storage.c --- a/src/lib-sieve/sieve-storage.c Thu Oct 29 22:14:24 2015 +0100 +++ b/src/lib-sieve/sieve-storage.c Thu Oct 29 22:14:32 2015 +0100 @@ -378,7 +378,7 @@ /* disabled */ if ( debug ) { sieve_sys_debug(svinst, "storage: " - "Sieve is disabled (sieve=\"\")"); + "Personal storage is disabled (sieve=\"\")"); } *error_r = SIEVE_ERROR_NOT_FOUND; return NULL; @@ -478,7 +478,8 @@ enum sieve_storage_flags flags, enum sieve_error *error_r) { struct sieve_storage *storage; - const char *set_default, *set_default_name; + const char *set_enabled, *set_default, *set_default_name; + bool debug = svinst->debug; enum sieve_error error; if ( error_r != NULL ) @@ -486,6 +487,18 @@ else error_r = &error; + /* Check whether Sieve is disabled for this user */ + if ( (set_enabled=sieve_setting_get + (svinst, "sieve_enabled")) != NULL && + strcasecmp(set_enabled, "no") == 0) { + if ( debug ) { + sieve_sys_debug(svinst, + "Sieve is disabled for this user"); + } + *error_r = SIEVE_ERROR_NOT_POSSIBLE; + return NULL; + } + /* Determine location for default script */ set_default = sieve_setting_get(svinst, "sieve_default"); @@ -527,21 +540,27 @@ /* Failed; try using default script location (not for temporary failures, read/write access, or dsync) */ if ( set_default == NULL ) { - sieve_sys_debug(svinst, "storage: " - "No default script location configured"); + if ( debug ) { + sieve_sys_debug(svinst, "storage: " + "No default script location configured"); + } } else { - sieve_sys_debug(svinst, "storage: " - "Trying default script location `%s'", - set_default); + if ( debug ) { + sieve_sys_debug(svinst, "storage: " + "Trying default script location `%s'", + set_default); + } storage = sieve_storage_create (svinst, set_default, 0, error_r); if ( storage == NULL ) { switch ( *error_r ) { case SIEVE_ERROR_NOT_FOUND: - sieve_sys_debug(svinst, "storage: " - "Default script location `%s' not found", - set_default); + if ( debug ) { + sieve_sys_debug(svinst, "storage: " + "Default script location `%s' not found", + set_default); + } break; case SIEVE_ERROR_TEMP_FAILURE: sieve_sys_error(svinst, "storage: " diff -r 49391f7404ab -r 96d06e6a9127 src/managesieve/managesieve-client.c --- a/src/managesieve/managesieve-client.c Thu Oct 29 22:14:24 2015 +0100 +++ b/src/managesieve/managesieve-client.c Thu Oct 29 22:14:32 2015 +0100 @@ -64,14 +64,23 @@ struct sieve_storage *storage; enum sieve_error error; + /* Open personal script storage */ + storage = sieve_storage_create_main (svinst, user, SIEVE_STORAGE_FLAG_READWRITE, &error); if (storage == NULL) { switch (error) { + case SIEVE_ERROR_NOT_POSSIBLE: + printf("BYE \"Sieve processing is disabled for this user.\"\n"); + + i_fatal("Failed to open Sieve storage: " + "Sieve is disabled for this user."); + break; case SIEVE_ERROR_NOT_FOUND: - printf("BYE \"Sieve filtering is disabled for this user.\"\n"); + printf("BYE \"This user cannot manage personal Sieve scripts.\"\n"); - i_fatal("Failed to open Sieve storage: Sieve disabled for user"); + i_fatal("Failed to open Sieve storage: " + "Personal script storage disabled or not found."); break; default: { diff -r 49391f7404ab -r 96d06e6a9127 src/plugins/lda-sieve/lda-sieve-plugin.c --- a/src/plugins/lda-sieve/lda-sieve-plugin.c Thu Oct 29 22:14:24 2015 +0100 +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Thu Oct 29 22:14:32 2015 +0100 @@ -181,6 +181,7 @@ *storage_r = sieve_storage_create_main(svinst, user, 0, &error); if (*storage_r == NULL) { switch (error) { + case SIEVE_ERROR_NOT_POSSIBLE: case SIEVE_ERROR_NOT_FOUND: break; case SIEVE_ERROR_TEMP_FAILURE: @@ -640,6 +641,8 @@ ret = lda_sieve_get_personal_storage (svinst, mdctx->dest_user, &main_storage); + if ( ret == 0 && error == SIEVE_ERROR_NOT_POSSIBLE ) + return 0; if ( ret > 0 ) { srctx->main_script = sieve_storage_active_script_open(main_storage, &error); @@ -920,11 +923,14 @@ T_BEGIN { if (lda_sieve_find_scripts(&srctx) < 0) ret = -1; - else + else if ( srctx.scripts == NULL ) + ret = 0; + else { ret = lda_sieve_execute(&srctx, storage_r); - for ( i = 0; i < srctx.script_count; i++ ) - sieve_script_unref(&srctx.scripts[i]); + for ( i = 0; i < srctx.script_count; i++ ) + sieve_script_unref(&srctx.scripts[i]); + } } T_END; /* Clean up */