# HG changeset patch # User Timo Sirainen # Date 1247020075 14400 # Node ID 4c81754521739b61354bdf69a996242cfb88bc13 # Parent f3c6cabae3af6c5df011e5792247e90556bdd35f acl+mbox: Create dovecot-acl-list to control dir. diff -r f3c6cabae3af -r 4c8175452173 src/plugins/acl/acl-backend-vfile-acllist.c --- a/src/plugins/acl/acl-backend-vfile-acllist.c Tue Jul 07 22:26:24 2009 -0400 +++ b/src/plugins/acl/acl-backend-vfile-acllist.c Tue Jul 07 22:27:55 2009 -0400 @@ -38,24 +38,48 @@ } } +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 */ @@ -165,13 +189,34 @@ } 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 mailbox_list *list = backend->backend.list; 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; @@ -244,14 +289,8 @@ 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); @@ -270,15 +309,13 @@ 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;