]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Make sure client is logged in when checking capabilities
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sun, 23 Apr 2017 16:14:54 +0000 (19:14 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 24 Apr 2017 08:48:47 +0000 (11:48 +0300)
Especially with imapc_features=delay-login the capability could have been
looked at before the client was even connected.

src/lib-imap-client/imapc-client.c
src/lib-imap-client/imapc-client.h
src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-storage.c

index a7a58cc2ac31128452725a86e939aabf2e68972d..5755e4b96392c7566e9d2955af16489d2ecece06 100644 (file)
@@ -506,22 +506,38 @@ bool imapc_client_mailbox_is_opened(struct imapc_client_mailbox *box)
        return TRUE;
 }
 
-enum imapc_capability
-imapc_client_get_capabilities(struct imapc_client *client)
+static bool
+imapc_client_get_any_capabilities(struct imapc_client *client,
+                                 enum imapc_capability *capabilities_r)
 {
        struct imapc_client_connection *const *connp;
        struct imapc_connection *conn = NULL;
 
-       /* try to find a connection that is already logged in */
        array_foreach(&client->conns, connp) {
                conn = (*connp)->conn;
-               if (imapc_connection_get_state(conn) == IMAPC_CONNECTION_STATE_DONE)
-                       return imapc_connection_get_capabilities(conn);
+               if (imapc_connection_get_state(conn) == IMAPC_CONNECTION_STATE_DONE) {
+                       *capabilities_r = imapc_connection_get_capabilities(conn);
+                       return TRUE;
+               }
        }
+       return FALSE;
+}
+
+int imapc_client_get_capabilities(struct imapc_client *client,
+                                 enum imapc_capability *capabilities_r)
+{
+       /* try to find a connection that is already logged in */
+       if (imapc_client_get_any_capabilities(client, capabilities_r))
+               return 0;
+
+       /* wait for any of the connections to login (there always exists one) */
+       i_assert(array_count(&client->conns) > 0);
+       imapc_client_run(client);
+       if (imapc_client_get_any_capabilities(client, capabilities_r))
+               return 0;
 
-       /* fallback to whatever exists (there always exists one) */
-       i_assert(conn != NULL);
-       return imapc_connection_get_capabilities(conn);
+       /* failed */
+       return -1;
 }
 
 int imapc_client_create_temp_fd(struct imapc_client *client,
index 8687a994f0e4d7c641465137387cd86319dce053..2000af3a55094e88540395ffdec7ce5b7e026072 100644 (file)
@@ -228,8 +228,8 @@ imapc_client_mailbox_get_msgmap(struct imapc_client_mailbox *box);
 void imapc_client_mailbox_idle(struct imapc_client_mailbox *box);
 bool imapc_client_mailbox_is_opened(struct imapc_client_mailbox *box);
 
-enum imapc_capability
-imapc_client_get_capabilities(struct imapc_client *client);
+int imapc_client_get_capabilities(struct imapc_client *client,
+                                 enum imapc_capability *capabilities_r);
 
 int imapc_client_create_temp_fd(struct imapc_client *client,
                                const char **path_r);
index a746e2effc2bc59198eb5648ccacda8026074125..8f83a702da5d190c219ddce3517db7f6c1ed923d 100644 (file)
@@ -854,7 +854,8 @@ imapc_list_delete_mailbox(struct mailbox_list *_list, const char *name)
        struct imapc_command *cmd;
        struct imapc_simple_context ctx;
 
-       capa = imapc_client_get_capabilities(list->client->client);
+       if (imapc_client_get_capabilities(list->client->client, &capa) < 0)
+               return -1;
 
        cmd = imapc_list_simple_context_init(&ctx, list);
        imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
index aa3f61fed157c6fb7e6fdc81dd8e6f52095fd9e1..33de439e010e3e77cad4c1e4f0bf38800b8aa952 100644 (file)
@@ -603,9 +603,11 @@ imapc_mailbox_open_callback(const struct imapc_command_reply *reply,
        imapc_client_stop(ctx->mbox->storage->client->client);
 }
 
-static void imapc_mailbox_get_capabilities(struct imapc_mailbox *mbox)
+static int imapc_mailbox_get_capabilities(struct imapc_mailbox *mbox)
 {
-       mbox->capabilities = imapc_client_get_capabilities(mbox->storage->client->client);
+       return imapc_client_get_capabilities(mbox->storage->client->client,
+                                            &mbox->capabilities);
+
 }
 
 static void imapc_mailbox_get_extensions(struct imapc_mailbox *mbox)
@@ -630,7 +632,8 @@ int imapc_mailbox_select(struct imapc_mailbox *mbox)
        if (mbox->storage->client->auth_failed) {
                return -1;
        }
-       imapc_mailbox_get_capabilities(mbox);
+       if (imapc_mailbox_get_capabilities(mbox) < 0)
+               return -1;
 
        if (imapc_mailbox_has_modseqs(mbox)) {
                if (!array_is_created(&mbox->rseq_modseqs))
@@ -898,7 +901,8 @@ static int imapc_mailbox_run_status(struct mailbox *box,
        struct imapc_simple_context sctx;
        string_t *str;
 
-       imapc_mailbox_get_capabilities(mbox);
+       if (imapc_mailbox_get_capabilities(mbox) < 0)
+               return -1;
 
        str = t_str_new(256);
        if ((items & STATUS_MESSAGES) != 0)
@@ -979,7 +983,8 @@ static int imapc_mailbox_get_namespaces(struct imapc_mailbox *mbox)
        if (storage->namespaces_requested)
                return 0;
 
-       imapc_mailbox_get_capabilities(mbox);
+       if (imapc_mailbox_get_capabilities(mbox) < 0)
+               return -1;
        if ((mbox->capabilities & IMAPC_CAPABILITY_NAMESPACE) == 0) {
                /* NAMESPACE capability not supported */
                return 0;