]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Silently show an empty storage if namespace is unusable
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 22 Dec 2023 20:17:45 +0000 (15:17 -0500)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:11 +0000 (12:34 +0200)
When imapc is used as a shared namespace storage, users can try to
access nonexistent users. These will end up having a namespace with
NAMESPACE_FLAG_UNUSABLE set. Accessing such unusable namespace should
show it as empty, but there shouldn't be any errors logged.

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

index 1ce83f8e5e3a49ccec6a5c987bb3a94907e8c19c..4bc576ef60b7104a49ca11bcfc6efcf63acfa951 100644 (file)
@@ -1922,6 +1922,10 @@ void imapc_connection_connect(struct imapc_connection *conn)
        imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_CONNECTING);
        if (conn->ips_count > 0) {
                /* do nothing */
+       } else if (conn->client->set.host[0] == '\0') {
+               e_error(conn->event, "imapc host is empty");
+               imapc_connection_set_disconnected(conn);
+               return;
        } else if (net_addr2ip(conn->client->set.host, &ip) == 0) {
                conn->ips_count = 1;
                conn->ips = i_new(struct ip_addr, conn->ips_count);
index 3a863092247b9138e87ebd6edd2641540b92a3fe..474a32fd0b4e66caab22d7374e41982af1136f18 100644 (file)
@@ -103,6 +103,12 @@ static int imapc_list_init(struct mailbox_list *_list, const char **error_r)
        list->client->_list = list;
        list->set = list->client->set;
 
+       if ((_list->ns->flags & NAMESPACE_FLAG_UNUSABLE) != 0) {
+               /* Avoid connecting to imapc just to access mailbox names.
+                  There are no mailboxes, so the separator doesn't matter. */
+               list->root_sep = '/';
+       }
+
        imapc_storage_client_register_untagged(list->client, "LIST",
                                               imapc_untagged_list);
        imapc_storage_client_register_untagged(list->client, "LSUB",
@@ -599,6 +605,11 @@ static int imapc_list_refresh(struct imapc_mailbox_list *list)
                return -1;
        if (list->refreshed_mailboxes)
                return 0;
+       if ((list->list.ns->flags & NAMESPACE_FLAG_UNUSABLE) != 0) {
+               list->refreshed_mailboxes = TRUE;
+               list->refreshed_mailboxes_recently = TRUE;
+               return 0;
+       }
 
        if (*list->set->imapc_list_prefix == '\0')
                pattern = "*";
@@ -850,7 +861,8 @@ imapc_list_subscriptions_refresh(struct mailbox_list *_src_list,
        if (imapc_list_try_get_root_sep(src_list, &list_sep) < 0)
                return -1;
 
-       if (src_list->refreshed_subscriptions) {
+       if (src_list->refreshed_subscriptions ||
+           (src_list->list.ns->flags & NAMESPACE_FLAG_UNUSABLE) != 0) {
                if (dest_list->subscriptions == NULL)
                        dest_list->subscriptions = mailbox_tree_init(dest_sep);
                return 0;
index 4bb1d521ce97f08e500ec9a64761a79a7cd79ec3..3373d3fe3db693f51ce95b6fa66306049de6922f 100644 (file)
@@ -321,11 +321,19 @@ int imapc_storage_client_create(struct mail_namespace *ns,
                return -1;
 
        i_zero(&set);
-       set.host = imapc_set->imapc_host;
-       if (*set.host == '\0') {
-               *error_r = "missing imapc_host";
-               settings_free(imapc_set);
-               return -1;
+       if ((ns->flags & NAMESPACE_FLAG_UNUSABLE) != 0) {
+               /* Shared namespace user doesn't actually exist. Don't try to
+                  access the user via imapc, but also don't make this a
+                  visible error. If any code path tries to connect to imapc,
+                  it's a bug. Use an empty host to enforce this. */
+               set.host = "";
+       } else {
+               set.host = imapc_set->imapc_host;
+               if (*set.host == '\0') {
+                       *error_r = "missing imapc_host";
+                       settings_free(imapc_set);
+                       return -1;
+               }
        }
        set.port = imapc_set->imapc_port;
        if (imapc_set->imapc_user[0] != '\0')