}
}
+static const char *acl_list_get_path(struct acl_backend_vfile *backend)
+{
+ struct mail_storage *storage;
+ const char *rootdir, *maildir;
+ bool is_file;
+
+ rootdir = mailbox_list_get_path(backend->backend.list, NULL,
+ MAILBOX_LIST_PATH_TYPE_DIR);
+
+ storage = mailbox_list_get_namespace(backend->backend.list)->storage;
+ (void)mail_storage_get_mailbox_path(storage, "", &is_file);
+ if (is_file) {
+ maildir = mailbox_list_get_path(backend->backend.list, NULL,
+ 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_path(backend->backend.list,
+ NULL, MAILBOX_LIST_PATH_TYPE_CONTROL);
+ }
+ }
+ return t_strconcat(rootdir, "/"ACLLIST_FILENAME, NULL);
+}
+
static int acl_backend_vfile_acllist_read(struct acl_backend_vfile *backend)
{
struct acl_backend_vfile_acllist acllist;
struct istream *input;
struct stat st;
- const char *rootdir, *path, *line, *p;
+ const char *path, *line, *p;
int fd, ret = 0;
backend->acllist_last_check = ioloop_time;
- rootdir = mailbox_list_get_path(backend->backend.list, NULL,
- MAILBOX_LIST_PATH_TYPE_DIR);
- if (rootdir == NULL) {
+ path = acl_list_get_path(backend);
+ if (path == NULL) {
/* we're never going to build acllist for this namespace. */
i_array_init(&backend->acllist, 1);
return 0;
}
- path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir);
if (backend->acllist_mtime != 0) {
/* see if the file's mtime has changed */
return ret < 0 ? -1 : 0;
}
+static int
+acllist_rename(struct acl_backend_vfile *backend, const char *temp_path)
+{
+ const char *acllist_path;
+
+ acllist_path = acl_list_get_path(backend);
+ if (rename(temp_path, acllist_path) == 0)
+ return 0;
+
+ if (errno == ENOENT) {
+ if (mailbox_list_create_parent_dir(backend->backend.list, NULL,
+ acllist_path) < 0)
+ return -1;
+ if (rename(temp_path, acllist_path) == 0)
+ return 0;
+ }
+
+ i_error("rename(%s, %s) failed: %m", temp_path, acllist_path);
+ return -1;
+}
+
static int
acl_backend_vfile_acllist_try_rebuild(struct acl_backend_vfile *backend)
{
struct mail_namespace *ns;
struct mailbox_list_iterate_context *iter;
const struct mailbox_info *info;
- const char *rootdir, *acllist_path, *origin;
+ const char *rootdir, *origin;
struct ostream *output;
struct stat st;
string_t *path;
ret = -1;
}
- if (ret == 0) {
- acllist_path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir);
- if (rename(str_c(path), acllist_path) < 0) {
- i_error("rename(%s, %s) failed: %m",
- str_c(path), acllist_path);
- ret = -1;
- }
- }
+ if (ret == 0)
+ ret = acllist_rename(backend, str_c(path));
if (ret == 0) {
struct acl_user *auser = ACL_USER_CONTEXT(ns->user);
int acl_backend_vfile_acllist_rebuild(struct acl_backend_vfile *backend)
{
- const char *rootdir, *acllist_path;
+ const char *acllist_path;
if (acl_backend_vfile_acllist_try_rebuild(backend) == 0)
return 0;
else {
/* delete it to make sure it gets rebuilt later */
- rootdir = mailbox_list_get_path(backend->backend.list, NULL,
- MAILBOX_LIST_PATH_TYPE_DIR);
- acllist_path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir);
+ acllist_path = acl_list_get_path(backend);
if (unlink(acllist_path) < 0 && errno != ENOENT)
i_error("unlink(%s) failed: %m", acllist_path);
return -1;