From: Timo Sirainen Date: Wed, 8 Jul 2009 02:27:55 +0000 (-0400) Subject: acl+mbox: Create dovecot-acl-list to control dir. X-Git-Tag: 2.0.alpha1~470 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d6407ae9e545d41fe6152bba47602f3299c26236;p=thirdparty%2Fdovecot%2Fcore.git acl+mbox: Create dovecot-acl-list to control dir. --HG-- branch : HEAD --- diff --git a/src/plugins/acl/acl-backend-vfile-acllist.c b/src/plugins/acl/acl-backend-vfile-acllist.c index a7fa254f53..c723d3ad88 100644 --- a/src/plugins/acl/acl-backend-vfile-acllist.c +++ b/src/plugins/acl/acl-backend-vfile-acllist.c @@ -38,24 +38,48 @@ acllist_clear(struct acl_backend_vfile *backend, uoff_t file_size) } } +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 */ @@ -164,6 +188,27 @@ acllist_append(struct acl_backend_vfile *backend, struct ostream *output, 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) { @@ -171,7 +216,7 @@ 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; @@ -243,14 +288,8 @@ acl_backend_vfile_acllist_try_rebuild(struct acl_backend_vfile *backend) 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); @@ -269,15 +308,13 @@ acl_backend_vfile_acllist_try_rebuild(struct acl_backend_vfile *backend) 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;