]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
plugins: acl - Add acl_backend_init_auto()
authorAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 10 Nov 2023 13:19:58 +0000 (15:19 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:11 +0000 (12:34 +0200)
src/plugins/acl/acl-api-private.h
src/plugins/acl/acl-api.h
src/plugins/acl/acl-backend-vfile.c
src/plugins/acl/acl-backend-vfile.h
src/plugins/acl/acl-backend.c

index 79ed24159578d40242c1a21fe31747d0e2f6e68b..5166500634a7b7a92a7094451a17ba47d0988f37 100644 (file)
@@ -7,6 +7,7 @@
 struct acl_backend_vfuncs {
        const char *name;
        struct acl_backend *(*alloc)(void);
+       int (*init)(struct acl_backend *backend, const char **error_r);
        int (*init_legacy)(struct acl_backend *backend, const char *data);
        void (*deinit)(struct acl_backend *backend);
 
index 6e35330ce680372c42d132947e5fbdcea93db51d..ae13e6baa0e1bd5ae85243f7b8a2cfe100b7d5d0 100644 (file)
@@ -21,6 +21,8 @@ struct acl_backend *
 acl_backend_init(const char *data, struct mailbox_list *list,
                 const char *acl_username, const struct acl_settings *set,
                 bool owner);
+int acl_backend_init_auto(struct mailbox_list *list, struct acl_backend **backend_r,
+                         const char **error_r);
 void acl_backend_deinit(struct acl_backend **backend);
 
 /* Returns the acl_username passed to acl_backend_init(). Note that with
index 34727ea3eb19873cd71644791eed4d3addaf40ba..2524bc8461fa8a4d10dcf55cef6ccd2b4b0c586c 100644 (file)
@@ -5,6 +5,7 @@
 #include "array.h"
 #include "istream.h"
 #include "nfs-workarounds.h"
+#include "settings.h"
 #include "mailbox-list-private.h"
 #include "acl-global-file.h"
 #include "acl-cache.h"
@@ -28,6 +29,34 @@ static struct acl_backend *acl_backend_vfile_alloc(void)
        return &backend->backend;
 }
 
+static int
+acl_backend_vfile_init(struct acl_backend *_backend, const char **error_r)
+{
+       struct event *event = _backend->event;
+       struct stat st;
+
+       const char *global_path = _backend->set->acl_global_path;
+
+       if (*global_path != '\0') {
+               if (stat(global_path, &st) < 0) {
+                       *error_r = t_strdup_printf("stat(%s) failed: %m", global_path);
+                       return -1;
+               } else if (S_ISDIR(st.st_mode)) {
+                       *error_r = t_strdup_printf("Global ACL directories are no longer supported");
+                       return -1;
+               } else {
+                       _backend->global_file = acl_global_file_init(
+                               global_path, _backend->set->acl_cache_ttl / 1000, event);
+                       e_debug(event, "vfile: Deprecated Global ACL file: %s", global_path);
+               }
+       }
+
+       _backend->cache =
+               acl_cache_init(_backend,
+                              sizeof(struct acl_backend_vfile_validity));
+       return 0;
+}
+
 static int
 acl_backend_vfile_init_legacy(struct acl_backend *_backend, const char *data)
 {
@@ -564,6 +593,7 @@ static int acl_backend_vfile_object_last_changed(struct acl_object *_aclobj,
 const struct acl_backend_vfuncs acl_backend_vfile = {
        .name = "vfile",
        .alloc = acl_backend_vfile_alloc,
+       .init = acl_backend_vfile_init,
        .init_legacy = acl_backend_vfile_init_legacy,
        .deinit = acl_backend_vfile_deinit,
        .nonowner_lookups_iter_init = acl_backend_vfile_nonowner_iter_init,
index 0550771c4723ac1ee16c2b75526d39b54a1a6713..0c8eb75672037a81b614ee831eee3cd23b13965b 100644 (file)
@@ -35,6 +35,7 @@ struct acl_backend_vfile_acllist {
 
 struct acl_backend_vfile {
        struct acl_backend backend;
+       const struct acl_vfile_settings *set;
 
        pool_t acllist_pool;
        ARRAY(struct acl_backend_vfile_acllist) acllist;
index e3c9970705efa878c3e112e3ef9bafa391023d9e..eff5628e75f014301b384a7acfe928b85d7711b8 100644 (file)
@@ -5,8 +5,9 @@
 #include "array.h"
 #include "hash.h"
 #include "sort.h"
+#include "settings.h"
 #include "mail-storage-settings.h"
-#include "mailbox-list.h"
+#include "mailbox-list-private.h"
 #include "mail-namespace.h"
 #include "mail-user.h"
 #include "acl-cache.h"
@@ -42,6 +43,73 @@ static struct acl_backend_entry *acl_backend_find(const char *name)
        return be;
 }
 
+
+int acl_backend_init_auto(struct mailbox_list *list, struct acl_backend **backend_r,
+                         const char **error_r)
+{
+       const struct acl_settings *set;
+       struct event *event = event_create(list->event);
+       event_add_category(event, &event_category_acl);
+       event_set_append_log_prefix(event, "acl: ");
+
+       /* try to get settings again */
+       if (settings_get(event, &acl_setting_parser_info, 0, &set, error_r) < 0) {
+               event_unref(&event);
+               return -1;
+       }
+
+       if (*set->acl_driver == '\0') {
+               e_debug(event, "No acl_driver setting - ACLs are disabled");
+               settings_free(set);
+               event_unref(&event);
+               return 0;
+       }
+
+       struct acl_backend_entry *be = acl_backend_find(set->acl_driver);
+       struct acl_backend *backend = be->v->alloc();
+
+       const char *owner_username = list->ns->user->username;
+       backend->username = set->acl_user;
+       if (*backend->username == '\0') {
+               backend->username = owner_username;
+               backend->owner = TRUE;
+       } else
+               backend->owner = strcmp(backend->username, owner_username) == 0;
+       if (list->ns->type != MAIL_NAMESPACE_TYPE_PRIVATE)
+               backend->owner = FALSE;
+
+       backend->v = be->v;
+       backend->list = list;
+       backend->set = set;
+       backend->event = event;
+
+       e_debug(backend->event, "initializing backend %s", backend->v->name);
+       e_debug(backend->event, "acl username = %s", backend->username);
+       e_debug(backend->event, "owner = %s", backend->owner ? "yes" : "no");
+       e_debug(backend->event, "ignore = %s", set->acl_ignore ? "yes" : "no");
+       if (event_want_debug(backend->event) && array_is_created(&set->acl_groups)) {
+               const char *group;
+               array_foreach_elem(&set->acl_groups, group)
+                       e_debug(backend->event, "group added: %s", group);
+       }
+
+       if (backend->v->init(backend, error_r) < 0) {
+               *error_r = t_strdup_printf("acl %s: %s", backend->v->name, *error_r);
+               acl_backend_deinit(&backend);
+               return -1;
+       }
+
+       backend->default_rights = backend->owner ? owner_mailbox_rights :
+               non_owner_mailbox_rights;
+       backend->default_aclmask =
+               acl_cache_mask_init(backend->cache, backend->pool,
+                                   backend->default_rights);
+
+       *backend_r = backend;
+
+       return 1;
+}
+
 struct acl_backend *
 acl_backend_init(const char *data, struct mailbox_list *list,
                 const char *acl_username, const struct acl_settings *set,
@@ -109,6 +177,7 @@ void acl_backend_deinit(struct acl_backend **_backend)
        acl_object_deinit(&backend->default_aclobj);
        acl_cache_deinit(&backend->cache);
        event_unref(&backend->event);
+       settings_free(backend->set);
        backend->v->deinit(backend);
 }