Пример #1
0
static bool paths_are_equal(struct mail_user *user1, struct mail_user *user2,
			    enum mailbox_list_path_type type)
{
	const char *path1, *path2;

	i_assert(user1->namespaces != NULL);
	i_assert(user2->namespaces != NULL);

	return mailbox_list_get_root_path(user1->namespaces->list, type, &path1) &&
		mailbox_list_get_root_path(user2->namespaces->list, type, &path2) &&
		strcmp(path1, path2) == 0;
}
Пример #2
0
static void
fts_mailbox_list_init(struct mailbox_list *list, const char *name)
{
	struct fts_backend *backend;
	const char *path, *error;

	if (!mailbox_list_get_root_path(list, MAILBOX_LIST_PATH_TYPE_INDEX, &path)) {
		if (list->mail_set->mail_debug) {
			i_debug("fts: Indexes disabled for namespace '%s'",
				list->ns->prefix);
		}
		return;
	}

	if (fts_backend_init(name, list->ns, &error, &backend) < 0) {
		i_error("fts: Failed to initialize backend '%s': %s",
			name, error);
	} else {
		struct fts_mailbox_list *flist;
		struct mailbox_list_vfuncs *v = list->vlast;

		if ((backend->flags & FTS_BACKEND_FLAG_FUZZY_SEARCH) != 0)
			list->ns->user->fuzzy_search = TRUE;

		flist = p_new(list->pool, struct fts_mailbox_list, 1);
		flist->module_ctx.super = *v;
		flist->backend = backend;
		list->vlast = &flist->module_ctx.super;
		v->deinit = fts_mailbox_list_deinit;
		MODULE_CONTEXT_SET(list, fts_mailbox_list_module, flist);
	}
}
Пример #3
0
static int
mbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
		    const char **error_r)
{
	struct mbox_storage *storage = (struct mbox_storage *)_storage;
	struct stat st;
	const char *dir;

	if (master_service_get_client_limit(master_service) > 1) {
		/* we can't handle locking related problems. */
		*error_r = "mbox requires client_limit=1 for service";
		return -1;
	}

	storage->set = mail_storage_get_driver_settings(_storage);

	if (mailbox_list_get_root_path(ns->list, MAILBOX_LIST_PATH_TYPE_INDEX, &dir)) {
		_storage->temp_path_prefix = p_strconcat(_storage->pool, dir,
			"/", mailbox_list_get_temp_prefix(ns->list), NULL);
	}
	if (stat(ns->list->set.root_dir, &st) == 0 && !S_ISDIR(st.st_mode)) {
		*error_r = t_strdup_printf(
			"mbox root directory can't be a file: %s "
			"(http://wiki2.dovecot.org/MailLocation/Mbox)",
			ns->list->set.root_dir);
		return -1;
	}
	return 0;
}
Пример #4
0
static bool acl_list_get_root_dir(struct acl_backend_vfile *backend,
				  const char **root_dir_r,
				  enum mailbox_list_path_type *type_r)
{
	struct mail_storage *storage;
	const char *rootdir, *maildir;
	enum mailbox_list_path_type type;

	storage = mailbox_list_get_namespace(backend->backend.list)->storage;
	type = (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0 ?
		MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_DIR;
	if (!mailbox_list_get_root_path(backend->backend.list, type, &rootdir))
		return FALSE;
	*type_r = type;

	if (type == MAILBOX_LIST_PATH_TYPE_DIR &&
	    mail_storage_is_mailbox_file(storage)) {
		maildir = mailbox_list_get_root_forced(backend->backend.list,
						       MAILBOX_LIST_PATH_TYPE_MAILBOX);
		if (strcmp(maildir, rootdir) == 0) {
			/* dovecot-acl-list would show up as a mailbox if we
			   created it to root dir. since we don't really have
			   any other good alternatives, place it to control
			   dir */
			rootdir = mailbox_list_get_root_forced(backend->backend.list,
					MAILBOX_LIST_PATH_TYPE_CONTROL);
			*type_r = MAILBOX_LIST_PATH_TYPE_CONTROL;
		}
	}
	*root_dir_r = rootdir;
	return TRUE;
}
static const char *
acl_backend_vfile_get_local_dir(struct acl_backend *backend,
				const char *name, const char *vname)
{
	struct mail_namespace *ns = mailbox_list_get_namespace(backend->list);
	struct mailbox_list *list = ns->list;
	struct mail_storage *storage;
	enum mailbox_list_path_type type;
	const char *dir, *inbox;

	if (*name == '\0')
		name = NULL;

	/* ACL files are very important. try to keep them among the main
	   mail files. that's not possible though with a) if the mailbox is
	   a file or b) if the mailbox path doesn't point to filesystem. */
	if (mailbox_list_get_storage(&list, vname, &storage) < 0)
		return NULL;
	i_assert(list == ns->list);

	type = mail_storage_is_mailbox_file(storage) ||
		(storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0 ?
		MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_MAILBOX;
	if (name == NULL) {
		if (!mailbox_list_get_root_path(list, type, &dir))
			return NULL;
	} else {
		if (mailbox_list_get_path(list, name, type, &dir) <= 0)
			return NULL;
	}

	/* verify that the directory isn't same as INBOX's directory.
	   this is mainly for Maildir. */
	if (name == NULL &&
	    mailbox_list_get_path(list, "INBOX",
				  MAILBOX_LIST_PATH_TYPE_MAILBOX, &inbox) > 0 &&
	    strcmp(inbox, dir) == 0) {
		/* can't have default ACLs with this setup */
		return NULL;
	}
	return dir;
}
Пример #6
0
static void fs_quota_namespace_added(struct quota *quota,
				     struct mail_namespace *ns)
{
	struct fs_quota_mountpoint *mount;
	struct fs_quota_root *root;
	const char *dir;

	if (!mailbox_list_get_root_path(ns->list, MAILBOX_LIST_PATH_TYPE_MAILBOX,
					&dir))
		mount = NULL;
	else
		mount = fs_quota_mountpoint_get(dir);
	if (mount != NULL) {
		root = fs_quota_root_find_mountpoint(quota, mount);
		if (root != NULL && root->mount == NULL)
			fs_quota_mount_init(root, mount, dir);
		else
			fs_quota_mountpoint_free(mount);
	}

	/* we would actually want to do this only once after all quota roots
	   are created, but there's no way to do this right now */
	fs_quota_add_missing_mounts(quota);
}
int mailbox_list_subscriptions_refresh(struct mailbox_list *src_list,
				       struct mailbox_list *dest_list)
{
	struct subsfile_list_context *subsfile_ctx;
	struct stat st;
	enum mailbox_list_path_type type;
	const char *path, *name;
	char sep;
	int ret;

	/* src_list is subscriptions=yes, dest_list is subscriptions=no
	   (or the same as src_list) */
	i_assert((src_list->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0);

	if (dest_list->subscriptions == NULL) {
		sep = mail_namespace_get_sep(src_list->ns);
		dest_list->subscriptions = mailbox_tree_init(sep);
	}

	type = src_list->set.control_dir != NULL ?
		MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_DIR;
	if (!mailbox_list_get_root_path(src_list, type, &path) ||
	    src_list->set.subscription_fname == NULL) {
		/* no subscriptions (e.g. pop3c) */
		return 0;
	}
	path = t_strconcat(path, "/", src_list->set.subscription_fname, NULL);
	if (stat(path, &st) < 0) {
		if (errno == ENOENT) {
			/* no subscriptions */
			mailbox_tree_clear(dest_list->subscriptions);
			dest_list->subscriptions_mtime = 0;
			return 0;
		}
		mailbox_list_set_critical(dest_list, "stat(%s) failed: %m",
					  path);
		return -1;
	}
	if (st.st_mtime == dest_list->subscriptions_mtime &&
	    st.st_mtime < dest_list->subscriptions_read_time-1) {
		/* we're up to date */
		return 0;
	}

	mailbox_tree_clear(dest_list->subscriptions);
	dest_list->subscriptions_read_time = ioloop_time;

	subsfile_ctx = subsfile_list_init(dest_list, path);
	if (subsfile_list_fstat(subsfile_ctx, &st) == 0)
		dest_list->subscriptions_mtime = st.st_mtime;
	while ((name = subsfile_list_next(subsfile_ctx)) != NULL) T_BEGIN {
		T_BEGIN {
			ret = mailbox_list_subscription_fill_one(dest_list,
								 src_list, name);
		} T_END;
		if (ret < 0) {
			i_warning("Subscriptions file %s: "
				  "Removing invalid entry: %s",
				  path, name);
			(void)subsfile_set_subscribed(src_list, path,
				mailbox_list_get_temp_prefix(src_list),
				name, FALSE);

		}
	} T_END;

	if (subsfile_list_deinit(&subsfile_ctx) < 0) {
		dest_list->subscriptions_mtime = (time_t)-1;
		return -1;
	}
	return 0;
}