From: Timo Sirainen Date: Mon, 10 Feb 2025 07:48:39 +0000 (+0200) Subject: imap: Allow feature callbacks to not enable the feature X-Git-Tag: 2.4.1~229 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78c513b6fbf2fa44652ce551d7fbc1b4bc3199e9;p=thirdparty%2Fdovecot%2Fcore.git imap: Allow feature callbacks to not enable the feature --- diff --git a/src/imap/cmd-select.c b/src/imap/cmd-select.c index 73d8d1d162..f11449ce28 100644 --- a/src/imap/cmd-select.c +++ b/src/imap/cmd-select.c @@ -410,7 +410,7 @@ bool cmd_select_full(struct client_command_context *cmd, bool readonly) if (ctx->condstore) { /* Enable while no mailbox is opened to avoid sending HIGHESTMODSEQ for previously opened mailbox */ - client_enable(client, imap_feature_condstore); + (void)client_enable(client, imap_feature_condstore); } ret = select_open(ctx, mailbox, readonly); diff --git a/src/imap/cmd-store.c b/src/imap/cmd-store.c index 7962261552..a817f36679 100644 --- a/src/imap/cmd-store.c +++ b/src/imap/cmd-store.c @@ -66,7 +66,7 @@ store_parse_modifiers(struct imap_store_context *ctx, "Invalid modseq"); return FALSE; } - client_enable(ctx->cmd->client, imap_feature_condstore); + (void)client_enable(ctx->cmd->client, imap_feature_condstore); } else { client_send_command_error(ctx->cmd, "Unknown STORE modifier"); diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index b94624dd44..628e22f6e1 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -1582,7 +1582,9 @@ bool client_enable(struct client *client, unsigned int feature_idx) return FALSE; } - feat->callback(client); + if (!feat->callback(client)) + return FALSE; + /* set after the callback, so the callback can see what features were previously set */ bool value = TRUE; @@ -1599,16 +1601,16 @@ bool client_has_enabled(struct client *client, unsigned int feature_idx) return *featurep; } -static void imap_client_enable_condstore(struct client *client) +static bool imap_client_enable_condstore(struct client *client) { struct mailbox_status status; int ret; if (client->mailbox == NULL) - return; + return TRUE; if ((client_enabled_mailbox_features(client) & MAILBOX_FEATURE_CONDSTORE) != 0) - return; + return TRUE; ret = mailbox_enable(client->mailbox, MAILBOX_FEATURE_CONDSTORE); if (ret == 0) { @@ -1626,19 +1628,21 @@ static void imap_client_enable_condstore(struct client *client) client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); } + return TRUE; } -static void imap_client_enable_qresync(struct client *client) +static bool imap_client_enable_qresync(struct client *client) { /* enable also CONDSTORE */ - client_enable(client, imap_feature_condstore); + return client_enable(client, imap_feature_condstore); } #ifdef EXPERIMENTAL_MAIL_UTF8 -static void imap_client_enable_utf8accept(struct client *client) +static bool imap_client_enable_utf8accept(struct client *client) { if (client->mailbox != NULL) mailbox_enable(client->mailbox, MAILBOX_FEATURE_UTF8ACCEPT); + return TRUE; } #endif diff --git a/src/imap/imap-feature.h b/src/imap/imap-feature.h index a96aa6e4c5..2c2dcb3ee2 100644 --- a/src/imap/imap-feature.h +++ b/src/imap/imap-feature.h @@ -1,7 +1,8 @@ #ifndef IMAP_FEATURE_H #define IMAP_FEATURE_H -typedef void imap_client_enable_callback_t(struct client *); +/* Returns TRUE if the ENABLE was accepted. */ +typedef bool imap_client_enable_callback_t(struct client *); struct imap_feature { const char *feature; diff --git a/src/imap/imap-fetch.c b/src/imap/imap-fetch.c index db811f7743..ca4b3216ce 100644 --- a/src/imap/imap-fetch.c +++ b/src/imap/imap-fetch.c @@ -869,7 +869,7 @@ bool imap_fetch_modseq_init(struct imap_fetch_init_context *ctx) ctx->error = "FETCH MODSEQ can't be used with non-permanent modseqs"; return FALSE; } - client_enable(ctx->fetch_ctx->client, imap_feature_condstore); + (void)client_enable(ctx->fetch_ctx->client, imap_feature_condstore); imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_BUFFERED, NULL, fetch_modseq, NULL); return TRUE; diff --git a/src/imap/imap-search.c b/src/imap/imap-search.c index 941b74751c..e62ddd9ce9 100644 --- a/src/imap/imap-search.c +++ b/src/imap/imap-search.c @@ -526,7 +526,7 @@ bool imap_search_start(struct imap_search_context *ctx, if (ctx->have_modseqs) { ctx->return_options |= SEARCH_RETURN_MODSEQ; - client_enable(cmd->client, imap_feature_condstore); + (void)client_enable(cmd->client, imap_feature_condstore); } ctx->box = cmd->client->mailbox; diff --git a/src/imap/imap-state.c b/src/imap/imap-state.c index fa795b1b75..3736296bea 100644 --- a/src/imap/imap-state.c +++ b/src/imap/imap-state.c @@ -742,7 +742,11 @@ import_state_enabled_feature(struct client *client, const unsigned char *data, *error_r = t_strdup_printf("Unknown feature '%s'", name); return 0; } - client_enable(client, feature_idx); + if (!client_enable(client, feature_idx)) { + *error_r = t_strdup_printf("Feature '%s' couldn't be enabled", + name); + return 0; + } return p - data; } diff --git a/src/imap/imap-status.c b/src/imap/imap-status.c index e8d5520d2c..bf0ca57f63 100644 --- a/src/imap/imap-status.c +++ b/src/imap/imap-status.c @@ -76,7 +76,7 @@ int imap_status_get_result(struct client *client, struct mailbox *box, if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UNSEEN)) status |= STATUS_UNSEEN; if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_HIGHESTMODSEQ)) { - client_enable(client, imap_feature_condstore); + (void)client_enable(client, imap_feature_condstore); status |= STATUS_HIGHESTMODSEQ; } if (HAS_ANY_BITS(items->flags, IMAP_STATUS_ITEM_SIZE |