From: Timo Sirainen Date: Mon, 15 Feb 2010 00:08:02 +0000 (+0200) Subject: Fixed creating mailboxes over \noselect mailboxes. X-Git-Tag: 2.0.beta3~82 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c1a6ff4972754448985f179358f236e9032ac8da;p=thirdparty%2Fdovecot%2Fcore.git Fixed creating mailboxes over \noselect mailboxes. --HG-- branch : HEAD --- diff --git a/src/imap/cmd-rename.c b/src/imap/cmd-rename.c index 567e3df055..fddbf62dc2 100644 --- a/src/imap/cmd-rename.c +++ b/src/imap/cmd-rename.c @@ -21,7 +21,7 @@ bool cmd_rename(struct client_command_context *cmd) return TRUE; new_ns = client_find_namespace(cmd, &newname, - CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST); + CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST); if (new_ns == NULL) return TRUE; diff --git a/src/imap/imap-commands-util.c b/src/imap/imap-commands-util.c index a7a5940109..7bdc63c2a1 100644 --- a/src/imap/imap-commands-util.c +++ b/src/imap/imap-commands-util.c @@ -91,14 +91,22 @@ client_find_namespace(struct client_command_context *cmd, const char **mailboxp, switch (mailbox_status) { case MAILBOX_NAME_EXISTS_MAILBOX: + case MAILBOX_NAME_EXISTS_DIR: switch (mode) { + case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST: + case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE: + if (mailbox_status == MAILBOX_NAME_EXISTS_DIR) + break; + return ns; case CLIENT_VERIFY_MAILBOX_NONE: case CLIENT_VERIFY_MAILBOX_NAME: - case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST: case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST: - case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE: return ns; case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST: + if (mailbox_status == MAILBOX_NAME_EXISTS_DIR) + return ns; + break; + case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST: break; } @@ -108,11 +116,11 @@ client_find_namespace(struct client_command_context *cmd, const char **mailboxp, break; case MAILBOX_NAME_VALID: - case MAILBOX_NAME_EXISTS_DIR: resp_code = ""; switch (mode) { case CLIENT_VERIFY_MAILBOX_NAME: case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST: + case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST: case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST: return ns; case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST: diff --git a/src/imap/imap-commands-util.h b/src/imap/imap-commands-util.h index 8c4abab953..078bea5d7c 100644 --- a/src/imap/imap-commands-util.h +++ b/src/imap/imap-commands-util.h @@ -13,7 +13,9 @@ enum client_verify_mailbox_mode { /* If mailbox doesn't exist, fail with [TRYCREATE] resp code */ CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE, /* If mailbox exists, fail with [ALREADYEXISTS] resp code */ - CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST + CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST, + /* If dir/mailbox exists, fail with [ALREADYEXISTS] resp code */ + CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST }; struct msgset_generator_context { diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index 5c328577ef..33763b8092 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -317,6 +317,16 @@ static int fs_list_set_subscribed(struct mailbox_list *_list, name, set); } +static int mailbox_is_selectable(struct mailbox_list *list, const char *name) +{ + enum mailbox_info_flags flags; + + if (mailbox_list_mailbox(list, name, &flags) < 0) + return -1; + + return (flags & (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) == 0 ? 1 : 0; +} + static int fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name, bool directory) @@ -326,6 +336,7 @@ fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name, mode_t mode; gid_t gid; bool create_parent_dir; + int ret; /* make sure the alt path doesn't exist yet. it shouldn't (except with race conditions with RENAME/DELETE), but if something crashed and @@ -361,6 +372,10 @@ fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name, else if (errno == EEXIST) { if (create_parent_dir) return 0; + if (!directory && *list->set.mailbox_dir_name == '\0') { + if ((ret = mailbox_is_selectable(list, name)) <= 0) + return ret; + } mailbox_list_set_error(list, MAIL_ERROR_EXISTS, "Mailbox already exists"); } else if (errno == ENOTDIR) {