mailbox-list.c revision adb6413686e52e00dded4932babcc08ff041876b
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen then start renaming them to larger names from end to beginning, which
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen eventually would start causing the failures when trying to use too
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen long mailbox names. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen/* Message to show to users when critical error occurs */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "Internal error occurred. Refer to server log for more information."
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct mailbox_list_module_register mailbox_list_module_register = { 0 };
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
a21f618de284dc22a480af1371d5f5cea50a39dfTimo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i, count;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (i = 0; i < count; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int idx;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen array_append(&mailbox_list_drivers, &list, 1);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid mailbox_list_unregister(const struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int idx;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (!mailbox_list_driver_find(list->name, &idx)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_fatal("mailbox_list_unregister(%s): unknown driver",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenint mailbox_list_alloc(const char *driver, struct mailbox_list **list_r,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char **error_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int idx;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *error_r = t_strdup_printf("Unknown mailbox list driver: %s",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenint mailbox_list_settings_parse(const char *data,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* <root dir> */
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen *error_r = t_strdup_printf("Unknown setting: %s", key);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (set->index_dir != NULL && strcmp(set->index_dir, "MEMORY") == 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid mailbox_list_init(struct mailbox_list *list, struct mail_namespace *ns,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_assert(set->root_dir == NULL || *set->root_dir != '\0');
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* copy settings */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.index_dir = set->index_dir == NULL ||
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.control_dir = set->control_dir == NULL ||
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (mkdir_parents(list->set.index_dir, 0700) < 0 &&
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("mkdir(%s) failed: %m", list->set.index_dir);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (mkdir_parents(list->set.control_dir, 0700) < 0 &&
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("mkdir(%s) failed: %m", list->set.control_dir);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen p_strdup(list->pool, set->subscription_fname);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.maildir_name = p_strdup(list->pool, set->maildir_name);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.mail_storage_flags = set->mail_storage_flags;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid mailbox_list_deinit(struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst char *mailbox_list_get_driver_name(struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenchar mailbox_list_get_hierarchy_sep(struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenenum mailbox_list_flags mailbox_list_get_flags(struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct mail_namespace *mailbox_list_get_namespace(struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenbool mailbox_list_is_valid_pattern(struct mailbox_list *list,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return list->v.is_valid_pattern(list, pattern);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenbool mailbox_list_is_valid_existing_name(struct mailbox_list *list,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return list->v.is_valid_existing_name(list, name);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenbool mailbox_list_is_valid_create_name(struct mailbox_list *list,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return list->v.is_valid_create_name(list, name);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst char *mailbox_list_get_path(struct mailbox_list *list, const char *name,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenint mailbox_list_get_permissions(struct mailbox_list *list, const char *name,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *uid_r = list->cached_uid == st.st_uid ? (uid_t)-1 : st.st_uid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* directory's GID is used automatically for new files */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *gid_r = list->cached_gid == st.st_gid ? (gid_t)-1 : st.st_gid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst char *mailbox_list_get_temp_prefix(struct mailbox_list *list)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst char *mailbox_list_join_refpattern(struct mailbox_list *list,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return list->v.join_refpattern(list, ref, pattern);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* the default implementation: */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* merge reference and pattern */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenint mailbox_list_get_mailbox_name_status(struct mailbox_list *list,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (!mailbox_list_is_valid_existing_name(list, name)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return list->v.get_mailbox_name_status(list, name, status);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenmailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return mailbox_list_iter_init_multiple(list, patterns, flags);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenmailbox_list_iter_init_multiple(struct mailbox_list *list,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *const *patterns,
const struct mailbox_info *
const char *name)
return TRUE;
levels++;
level_len = 0;
level_len++;
return TRUE;
return TRUE;
return FALSE;
#ifdef HAVE_DIRENT_D_TYPE
switch (d->d_type) {
case DT_UNKNOWN:
case DT_REG:
case DT_DIR:
case DT_LNK:
return type;
const char *error_string;
return FALSE;
return TRUE;