]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: mailbox-list - Detect duplicate GUIDs
authorAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 9 Aug 2021 08:56:17 +0000 (11:56 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 7 Sep 2021 08:38:03 +0000 (08:38 +0000)
This is only done for LAYOUT=INDEX.

src/lib-storage/list/mailbox-list-index.c

index 58bd2fc959a8a9097f82150190ffcf246af15099..de55aef6c4bcbd52b495c1577147e1a22a1ae439 100644 (file)
@@ -305,6 +305,7 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
        const void *data;
        bool expunged;
        uint32_t seq, uid, count;
+       HASH_TABLE(uint8_t *, struct mailbox_list_index_node *) duplicate_guid;
 
        *error_r = NULL;
 
@@ -314,6 +315,10 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
                          mailbox_list_index_node_hash,
                          mailbox_list_index_node_cmp);
        count = mail_index_view_get_messages_count(view);
+       if (!ilist->has_backing_store)
+               hash_table_create(&duplicate_guid, dup_pool, 0, guid_128_hash,
+                                 guid_128_cmp);
+
        for (seq = 1; seq <= count; seq++) {
                node = p_new(ilist->mailbox_pool,
                             struct mailbox_list_index_node, 1);
@@ -370,6 +375,24 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
                        node->corrupted_flags = TRUE;
                }
 
+               if (!ilist->has_backing_store && !guid_128_is_empty(irec->guid)) {
+                       struct mailbox_list_index_node *dup_node;
+                       uint8_t *guid_p = p_memdup(dup_pool, irec->guid,
+                                                  sizeof(guid_128_t));
+                       if ((dup_node = hash_table_lookup(duplicate_guid, guid_p)) != NULL) {
+                               *error_r = t_strdup_printf(
+                                               "duplicate GUID %s for mailbox '%s' and '%s'",
+                                               guid_128_to_string(guid_p),
+                                               node->raw_name,
+                                               dup_node->raw_name);
+                               node->corrupted_ext = TRUE;
+                               ilist->corrupted_names_or_parents = TRUE;
+                               ilist->call_corruption_callback = TRUE;
+                       } else {
+                               hash_table_insert(duplicate_guid, guid_p, node);
+                       }
+               }
+
                hash_table_insert(ilist->mailbox_hash,
                                  POINTER_CAST(node->uid), node);
        }
@@ -444,6 +467,8 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
                }
        }
        hash_table_destroy(&duplicate_hash);
+       if (!ilist->has_backing_store)
+               hash_table_destroy(&duplicate_guid);
        pool_unref(&dup_pool);
        return *error_r == NULL ? 0 : -1;
 }