]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Allow feature callbacks to not enable the feature
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 10 Feb 2025 07:48:39 +0000 (09:48 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:39 +0000 (12:34 +0200)
src/imap/cmd-select.c
src/imap/cmd-store.c
src/imap/imap-client.c
src/imap/imap-feature.h
src/imap/imap-fetch.c
src/imap/imap-search.c
src/imap/imap-state.c
src/imap/imap-status.c

index 73d8d1d1627bc316626c7026ad1f4082e2e72e4a..f11449ce2858de2ed5432af229d96a02e04743b0 100644 (file)
@@ -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);
index 796226155217e3b69e78d0e975147acd392fb7b1..a817f36679336c71a97aab34d97ebed476d697f9 100644 (file)
@@ -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");
index b94624dd444b1c5c4ed0124034a49d9ff553cc24..628e22f6e1bafff85923a685bc416fdbe8f89b94 100644 (file)
@@ -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
 
index a96aa6e4c5765b41c8c487005aabf7669af300d4..2c2dcb3ee251665a31f305279995b85692753d94 100644 (file)
@@ -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;
index db811f774379b531bae2db610cad65f2b0ed5612..ca4b3216cef8aedf798a1a032b4538bfe88900b1 100644 (file)
@@ -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;
index 941b74751c817cacd411feea318b082bf804f416..e62ddd9ce9f310b35d6a764e2437003c9e966484 100644 (file)
@@ -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;
index fa795b1b758a4da12a9921b5443735412de5f34e..3736296bea05466ac38bb5b24a927c5b3a66f2ee 100644 (file)
@@ -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;
 }
 
index e8d5520d2cb35bfef68857561f9c2da386a8aa2b..bf0ca57f636ef1f51c8207223a3afee88de7a8f6 100644 (file)
@@ -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 |