bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainensync_create_box(struct dsync_brain *brain, struct mailbox *box,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen const guid_128_t mailbox_guid, uint32_t uid_validity,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen memcpy(update.mailbox_guid, mailbox_guid, sizeof(update.mailbox_guid));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_create(box, &update, FALSE) < 0) {
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi errstr = mailbox_get_last_internal_error(box, &error);
329c2181e609b39294cc9cc76921a96a15e8f8a2Timo Sirainen /* trust that create worked, we can't actually open it
329c2181e609b39294cc9cc76921a96a15e8f8a2Timo Sirainen and verify. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* sync the mailbox so we can look up its latest status */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, error_r));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* verify that the GUID is what we wanted. if it's not, it probably
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen means that the mailbox had already been created. then we'll use the
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen GUID that is higher.
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mismatching UIDVALIDITY is handled later, because we choose it by
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen checking which mailbox has more messages */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, error_r));
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainen ret = memcmp(mailbox_guid, metadata.guid, sizeof(metadata.guid));
b78c41586816833aee1de8de732e542aac7b940dAki Tuomi /* if THEIR guid is bigger than OUR guid, and we are not doing
b78c41586816833aee1de8de732e542aac7b940dAki Tuomi backup in either direction, OR GUID did not match and we are
b78c41586816833aee1de8de732e542aac7b940dAki Tuomi receiving backup, try change the mailbox GUID.
b78c41586816833aee1de8de732e542aac7b940dAki Tuomi !brain->backup_send) || (ret != 0 && brain->backup_recv)) {
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainen i_debug("brain %c: Changing mailbox %s GUID %s -> %s",
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, error_r));
9d8f243a8765cb8dc0b513df7add7475affed0bbTimo Sirainen /* verify that the update worked */
9d8f243a8765cb8dc0b513df7add7475affed0bbTimo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID,
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, error_r));
9d8f243a8765cb8dc0b513df7add7475affed0bbTimo Sirainen i_error("Backend didn't update mailbox %s GUID",
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainen } else if (ret < 0) {
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainen i_debug("brain %c: Other brain should change mailbox "
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainen "%s GUID %s -> %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint dsync_brain_mailbox_tree_sync_change(struct dsync_brain *brain,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen const struct dsync_mailbox_tree_sync_change *change,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *errstr, *func_name = NULL, *storage_name;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* make sure we're deleting the correct mailbox */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ret = dsync_brain_mailbox_alloc(brain, change->mailbox_guid,
cabf98de0145c8e233e41073fe3f8c1cc85ed1ebTimo Sirainen i_error("Mailbox sync: Couldn't allocate mailbox %s GUID %s: %s",
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen guid_128_to_string(change->mailbox_guid), errstr);
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_brain_set_changes_during_sync(brain, t_strdup_printf(
b1533bd0dd0787b9c0d879c2d7398b1ff7964570Timo Sirainen "Mailbox %s GUID %s deletion conflict: %s",
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen guid_128_to_string(change->mailbox_guid), errstr));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen storage_name = mailbox_list_get_storage_name(change->ns->list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_delete_dir(change->ns->list, storage_name) == 0)
d4847b921058734e0668bc7690465c91523d9ec0Martti Rannanjärvi errstr = mailbox_list_get_last_internal_error(change->ns->list, &error);
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_brain_set_changes_during_sync(brain, t_strdup_printf(
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen "Mailbox %s mailbox_list_delete_dir conflict: %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Mailbox sync: mailbox_list_delete_dir failed: %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen box = mailbox_alloc(change->ns->list, change->full_name, 0);
19e161dd9e2c3a2ffc96ee8852bec0720cb30d1cTimo Sirainen mailbox_skip_create_name_restrictions(box, TRUE);
d24f5d5563b9d444920e57d0c5cfc5797fcf687dTimo Sirainen ret = sync_create_box(brain, box, change->mailbox_guid,
66f7fc500f134274c67c836a1de1128221b5bcaeTimo Sirainen mailbox_get_last_mail_error(box) == MAIL_ERROR_EXISTS) {
66f7fc500f134274c67c836a1de1128221b5bcaeTimo Sirainen /* it doesn't matter if somebody else created this
66f7fc500f134274c67c836a1de1128221b5bcaeTimo Sirainen directory or we automatically did while creating its
66f7fc500f134274c67c836a1de1128221b5bcaeTimo Sirainen child mailbox. it's there now anyway and we don't
66f7fc500f134274c67c836a1de1128221b5bcaeTimo Sirainen gain anything by treating this failure any
66f7fc500f134274c67c836a1de1128221b5bcaeTimo Sirainen differently from success. */
19e161dd9e2c3a2ffc96ee8852bec0720cb30d1cTimo Sirainen mailbox_skip_create_name_restrictions(destbox, TRUE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen case DSYNC_MAILBOX_TREE_SYNC_TYPE_UNSUBSCRIBE:
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi errstr = mailbox_get_last_internal_error(box, &error);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* mailbox was already created or was already deleted.
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen let the next sync figure out what to do */
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_brain_set_changes_during_sync(brain, t_strdup_printf(
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen "Mailbox %s %s conflict: %s",