Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conversations issues #5181

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion imap/conversations.c
Original file line number Diff line number Diff line change
Expand Up @@ -2280,7 +2280,7 @@ static int conversations_guid_setitem(struct conversations_state *state,
buf_appendbit32(&val, system_flags);
buf_appendbit32(&val, internal_flags);
buf_appendbit64(&val, (bit64)internaldate);
buf_appendbit64(&val, basecid);
buf_appendbit64(&val, basecid == cid ? 0 : basecid);
}

r = cyrusdb_store(state->db, buf_base(&key), buf_len(&key),
Expand Down
48 changes: 45 additions & 3 deletions imap/imapd.c
Original file line number Diff line number Diff line change
Expand Up @@ -7605,6 +7605,8 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,
int rename_user = 0;
int mbtype = 0;
mbentry_t *mbentry = NULL;
mbentry_t *olddestmbentry = NULL;
mbentry_t *newdestmbentry = NULL;
struct renrock rock = {0};
const char *orig_oldname = oldname;
const char *orig_newname = newname;
Expand Down Expand Up @@ -7875,6 +7877,32 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,
imapd_userisadmin) {

rename_user = 1;

// we can't rename users if the new inbox already exists!
r = mboxlist_lookup_allow_all(newmailboxname, &olddestmbentry, NULL);
if (r == IMAP_MAILBOX_NONEXISTENT) {
// all good, there's nothing here
} else if (r) {
// any other error, abort - something bad with mailboxesdb
goto respond;
} else if (olddestmbentry->mbtype & MBTYPE_DELETED) {
// this is OK, we're replacing a tombstone - hold on to the old entry in case we need to recreate it
}
else {
// can't rename over an existing mailbox - abort
mboxlist_entry_free(&olddestmbentry);
r = IMAP_MAILBOX_EXISTS;
brong marked this conversation as resolved.
Show resolved Hide resolved
goto respond;
}

/* we need to create a reference for the uniqueid so we find the right
* conversations DB */
newdestmbentry = mboxlist_entry_copy(mbentry);
free(newdestmbentry->name);
newdestmbentry->name = xstrdup(newmailboxname);
newdestmbentry->mbtype |= MBTYPE_DELETED;
r = mboxlist_update_full(newdestmbentry, /*localonly*/1, /*silent*/1);
if (r) goto respond;
}

/* if we're renaming something inside of something else,
Expand Down Expand Up @@ -7919,7 +7947,7 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,
rock.newuser = newuser;
rock.partition = location;
rock.rename_user = rename_user;
rock.noisy = noisy;
rock.noisy = noisy;

/* Check mboxnames to ensure we can write them all BEFORE we start */
r = mboxlist_allmbox(ombn, checkmboxname, &rock, 0);
Expand Down Expand Up @@ -7993,12 +8021,12 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,

/* rename all mailboxes matching this */
if (!r && recursive_rename) {
if (noisy) {
if (noisy) {
prot_printf(imapd_out,
"* OK [INPROGRESS (\"%s\" NIL NIL)] rename %s %s\r\n",
tag, oldextname, newextname);
prot_flush(imapd_out);
}
}

submboxes:
strcat(oldmailboxname, ".");
Expand Down Expand Up @@ -8037,6 +8065,18 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,

if (r) {
prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r));
// ensure the mboxlist entry gets fixed up or removed
if (olddestmbentry) {
int r2 = mboxlist_update_full(olddestmbentry, /*localonly*/1, /*silent*/1);
if (r2)
xsyslog(LOG_ERR, "IOERROR: replacing old destination tombstone after rename error",
"mboxname=<%s>, error=<%s>", olddestmbentry->name, error_message(r));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all four cases here should we also be logging error_message(r2) so we know why the cleanup failed?

"mboxname=<%s>, error=<%s>, cleanuperror=<%s>", oldestmbentry->name, error_message(r), error_message(r2));

} else if (newdestmbentry) {
int r2 = mboxlist_delete(newdestmbentry);
if (r2)
xsyslog(LOG_ERR, "IOERROR: removing temporary uniqueid tombstone after rename error",
"mboxname=<%s>, error=<%s>", newdestmbentry->name, error_message(r));
}
} else {
if (config_mupdate_server)
kick_mupdate();
Expand Down Expand Up @@ -8071,6 +8111,8 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,
if (!r && rename_user)
user_sharee_renameacls(&imapd_namespace, olduser, newuser);
mboxlist_entry_free(&mbentry);
mboxlist_entry_free(&olddestmbentry);
mboxlist_entry_free(&newdestmbentry);
if (oldname != orig_oldname) free(oldname);
if (newname != orig_newname) free(newname);
strarray_fini(&listargs.pat);
Expand Down
68 changes: 59 additions & 9 deletions imap/sync_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -3853,6 +3853,8 @@ int sync_apply_rename(struct dlist *kin, struct sync_state *sstate)

struct mboxlock *oldlock = NULL;
struct mboxlock *newlock = NULL;
mbentry_t *olddestmbentry = NULL;
mbentry_t *newdestmbentry = NULL;

/* make sure we grab these locks in a stable order! */
if (strcmpsafe(oldmboxname, newmboxname) < 0) {
Expand All @@ -3866,18 +3868,66 @@ int sync_apply_rename(struct dlist *kin, struct sync_state *sstate)
}

r = mboxlist_lookup_allow_all(oldmboxname, &mbentry, 0);
if (r) goto done;

if (mboxname_isusermailbox(oldmboxname, 1) &&
mboxname_isusermailbox(newmboxname, 1)) {
// we can't rename users if the new inbox already exists!
r = mboxlist_lookup_allow_all(newmboxname, &olddestmbentry, NULL);
if (r == IMAP_MAILBOX_NONEXISTENT) {
// all good, there's nothing here
} else if (r) {
// any other error, abort - something bad with mailboxesdb
goto done;
} else if (olddestmbentry->mbtype & MBTYPE_DELETED) {
// this is OK, we're replacing a tombstone - hold on to the old entry in case we need to recreate it
}
else {
// can't rename over an existing mailbox - abort
mboxlist_entry_free(&olddestmbentry);
r = IMAP_MAILBOX_EXISTS;
brong marked this conversation as resolved.
Show resolved Hide resolved
goto done;
}

/* we need to create a reference for the uniqueid so we find the right
* conversations DB */
newdestmbentry = mboxlist_entry_copy(mbentry);
free(newdestmbentry->name);
newdestmbentry->name = xstrdup(newmboxname);
newdestmbentry->mbtype |= MBTYPE_DELETED;
r = mboxlist_update_full(newdestmbentry, /*localonly*/1, /*silent*/1);
if (r) goto done;
}

r = mboxlist_renamemailbox(mbentry, newmboxname, partition,
uidvalidity, 1, sstate->userid,
sstate->authstate, NULL,
(sstate->flags & SYNC_FLAG_LOCALONLY),
1/*forceuser*/,
1/*ignorequota*/,
1/*keep_intermediaries*/,
0/*move_subscription*/,
1/*silent*/);

if (!r) r = mboxlist_renamemailbox(mbentry, newmboxname, partition,
uidvalidity, 1, sstate->userid,
sstate->authstate, NULL,
(sstate->flags & SYNC_FLAG_LOCALONLY),
1/*forceuser*/,
1/*ignorequota*/,
1/*keep_intermediaries*/,
0/*move_subscription*/,
1/*silent*/);

done:
if (r) {
// ensure the mboxlist entry gets fixed up or removed
if (olddestmbentry) {
int r2 = mboxlist_update_full(olddestmbentry, /*localonly*/1, /*silent*/1);
if (r2)
xsyslog(LOG_ERR, "IOERROR: replacing old destination tombstone after rename error",
"mboxname=<%s>, error=<%s>", olddestmbentry->name, error_message(r));
} else if (newdestmbentry) {
int r2 = mboxlist_delete(newdestmbentry);
if (r2)
xsyslog(LOG_ERR, "IOERROR: removing temporary uniqueid tombstone after rename error",
"mboxname=<%s>, error=<%s>", newdestmbentry->name, error_message(r));
}
}
mboxlist_entry_free(&mbentry);
mboxlist_entry_free(&olddestmbentry);
mboxlist_entry_free(&newdestmbentry);
mboxname_release(&oldlock);
mboxname_release(&newlock);

Expand Down
4 changes: 2 additions & 2 deletions imap/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ EXPORTED const char *user_sieve_path(const char *inuser)
char *inboxname = mboxname_user_mbox(user, NULL);
mbentry_t *mbentry = NULL;

int r = mboxlist_lookup(inboxname, &mbentry, NULL);
int r = mboxlist_lookup_allow_all(inboxname, &mbentry, NULL);
free(inboxname);

if (r || (mbentry->mbtype & MBTYPE_LEGACY_DIRS)) {
Expand Down Expand Up @@ -633,7 +633,7 @@ EXPORTED char *user_hash_xapian(const char *userid, const char *root)
char *basedir = NULL;
int r;

r = mboxlist_lookup(inboxname, &mbentry, NULL);
r = mboxlist_lookup_allow_all(inboxname, &mbentry, NULL);
if (r) goto out;

mbname = mbname_from_intname(mbentry->name);
Expand Down
Loading