mailbox-list-fs.c revision a574952c01611899b8ecf81434dbbb3345f27518
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2006-2010 Dovecot authors, see the included COPYING file */
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainenstatic struct mailbox_list *fs_list_alloc(void)
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen pool = pool_alloconly_create("fs list", 1024);
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen list = p_new(pool, struct fs_mailbox_list, 1);
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen list->temp_prefix = p_strconcat(pool, GLOBAL_TEMP_PREFIX,
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainenstatic void fs_list_deinit(struct mailbox_list *_list)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainenstatic bool fs_list_is_valid_common(const char *name, size_t *len_r)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainenfs_list_is_valid_common_nonfs(struct mailbox_list *list, const char *name)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen const char *p;
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen /* make sure it's not absolute path */
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen /* make sure the mailbox name doesn't contain any foolishness:
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen "../" could give access outside the mailbox directory.
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen "./" and "//" could fool ACL checks. */
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen if (p[0] == '/')
74ec4fe074dfc487e9a5b98ff237391c082eceb1Timo Sirainen if (p[0] == '.') {
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen /* don't allow maildir_name to be used as part
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen of the mailbox name */
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen /* "." and ".." aren't allowed. */
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainenfs_is_valid_pattern(struct mailbox_list *list, const char *pattern)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen if (list->mail_set->mail_full_filesystem_access)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen return fs_list_is_valid_common_nonfs(list, pattern);
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainenfs_is_valid_existing_name(struct mailbox_list *list, const char *name)
4dfaf598d6f2539caaab7ff0dd51d24a20928db8Timo Sirainen if (list->mail_set->mail_full_filesystem_access)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen return fs_list_is_valid_common_nonfs(list, name);
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainenfs_is_valid_create_name(struct mailbox_list *list, const char *name)
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen if (list->mail_set->mail_full_filesystem_access)
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen if (mailbox_list_name_is_too_large(name, '/'))
93e742e81653922361ce61f38319bd53e9bcad91Timo Sirainen return fs_list_is_valid_common_nonfs(list, name);
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainenstatic const char *
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainenfs_list_get_path(struct mailbox_list *_list, const char *name,
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen const struct mailbox_list_settings *set = &_list->set;
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen /* return root directories */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen i_assert(mailbox_list_is_valid_pattern(_list, name));
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (mailbox_list_try_get_absolute_path(_list, &name))
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return t_strdup_printf("%s/%s%s", set->root_dir,
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen return t_strdup_printf("%s/%s%s", set->alt_dir,
7ca397e910d2b267bcfaecbcdf9b23523c639776Timo Sirainen return t_strdup_printf("%s/%s%s", set->control_dir,
37c4359391810bc5bab0d2c72d7d25d8335b2858Timo Sirainen return t_strdup_printf("%s/%s%s", set->index_dir,
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen /* don't use inbox_path */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen } else if (strcmp(name, "INBOX") == 0 && set->inbox_path != NULL) {
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen /* If INBOX is a file, index and control directories are
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen located in root directory. */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen if ((_list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) == 0 ||
a497e8b94b55e035a1ebd28cf1368a8869ddaa62Timo Sirainen return t_strdup_printf("%s/%s%s/%s", root_dir,
826d9b7a1dec011e4777b334af5f4dc4feebb64bTimo Sirainenfs_list_get_mailbox_name_status(struct mailbox_list *_list, const char *name,
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen if (strcmp(name, "INBOX") == 0 || stat(path, &st) == 0) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen /* see if the directory exists */
49dc101839b5f37a1a3c000421796f162e0017d9Timo Sirainen if (strcmp(path, dir_path) != 0 && stat(dir_path, &st) == 0) {
a497e8b94b55e035a1ebd28cf1368a8869ddaa62Timo Sirainen if (!mailbox_list_is_valid_create_name(_list, name)) {
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen mailbox_list_set_critical(_list, "stat(%s) failed: %m", path);
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainenstatic const char *
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainenfs_list_get_temp_prefix(struct mailbox_list *_list, bool global)
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen return global ? GLOBAL_TEMP_PREFIX : list->temp_prefix;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenstatic const char *
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenfs_list_join_refpattern(struct mailbox_list *_list ATTR_UNUSED,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen /* pattern overrides reference */
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen /* merge reference and pattern */
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenstatic int fs_list_set_subscribed(struct mailbox_list *_list,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen path = t_strconcat(_list->set.control_dir != NULL ?
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen return subsfile_set_subscribed(_list, path, list->temp_prefix,
bool directory)
bool create_parent_dir;
if (!directory) {
if (create_parent_dir) {
if (p == NULL)
if (create_parent_dir)
const char *path;
const char *oldname,
if (rename_children)
if (p != NULL) {
newpath);
if (!rename_children) {
.props = 0,
NULL,
NULL,