]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
acl+mbox: Create dovecot-acl-list to control dir.
authorTimo Sirainen <tss@iki.fi>
Wed, 8 Jul 2009 02:27:55 +0000 (22:27 -0400)
committerTimo Sirainen <tss@iki.fi>
Wed, 8 Jul 2009 02:27:55 +0000 (22:27 -0400)
--HG--
branch : HEAD

src/plugins/acl/acl-backend-vfile-acllist.c

index a7fa254f5349a76167ee1cb91f31524f83394f1f..c723d3ad88fa9cc25263fe6d2430ec2ddf36086b 100644 (file)
@@ -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;