mailbox-list.c revision c040ee67d0ac0fb7375bb543965bf67dcae6affa
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen then start renaming them to larger names from end to beginning, which
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen eventually would start causing the failures when trying to use too
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen long mailbox names. */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen/* Message to show to users when critical error occurs */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen "Internal error occurred. Refer to server log for more information."
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstruct mailbox_list_module_register mailbox_list_module_register = { 0 };
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen unsigned int i, count;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen for (i = 0; i < count; i++) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen unsigned int idx;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen array_append(&mailbox_list_drivers, &list, 1);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenvoid mailbox_list_unregister(const struct mailbox_list *list)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen unsigned int idx;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (!mailbox_list_driver_find(list->name, &idx)) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("mailbox_list_unregister(%s): unknown driver",
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenint mailbox_list_alloc(const char *driver, struct mailbox_list **list_r,
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen const char **error_r)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen unsigned int idx;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen *error_r = t_strdup_printf("Unknown mailbox list driver: %s",
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainenint mailbox_list_settings_parse(const char *data,
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen const char **error_r)
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen /* <root dir> */
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen else if (strcmp(key, "ALT") == 0 && alt_dir_r != NULL)
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen *error_r = t_strdup_printf("Unknown setting: %s", key);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen if (set->index_dir != NULL && strcmp(set->index_dir, "MEMORY") == 0)
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainenvoid mailbox_list_init(struct mailbox_list *list, struct mail_namespace *ns,
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen i_assert(set->root_dir == NULL || *set->root_dir != '\0');
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen /* copy settings */
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen list->set.index_dir = set->index_dir == NULL ||
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen list->set.control_dir = set->control_dir == NULL ||
77a41c18e6c37ea9d88a300173672746e29fe61bTimo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
77a41c18e6c37ea9d88a300173672746e29fe61bTimo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen p_strdup(list->pool, set->subscription_fname);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen list->set.maildir_name = p_strdup(list->pool, set->maildir_name);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen list->set.mail_storage_flags = set->mail_storage_flags;
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenvoid mailbox_list_deinit(struct mailbox_list *list)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenconst char *mailbox_list_get_driver_name(struct mailbox_list *list)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenchar mailbox_list_get_hierarchy_sep(struct mailbox_list *list)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenenum mailbox_list_flags mailbox_list_get_flags(struct mailbox_list *list)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenstruct mail_namespace *mailbox_list_get_namespace(struct mailbox_list *list)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenvoid mailbox_list_get_permissions(struct mailbox_list *list,
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi const char *path;
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi path = mailbox_list_get_path(list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi mailbox_list_set_critical(list, "stat(%s) failed: %m",
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen /* return safe defaults */
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen /* directory's GID is used automatically for new files */
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen /* group doesn't have any permissions, so don't bother
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen changing it */
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen /* using our own gid, no need to change it */
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenbool mailbox_list_is_valid_pattern(struct mailbox_list *list,
const char *pattern)
const char *name)
const char *name)
return pattern;
const char *name,
struct mailbox_list_iterate_context *
struct mailbox_list_iterate_context *
const char *const *patterns,
const struct mailbox_info *
const char *name)
if (created) {
if (create_flags != 0)
if (!match_parents)
if (p == NULL)
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;