From bce13c496f02d0f4e49eacdf9997ae19cff94996 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Fri, 17 Nov 2023 13:55:07 +0200 Subject: [PATCH] plugins: acl - Support loading ACLs directly from config Allows setting global, per-namespace and per-mailbox ACLs. --- src/plugins/acl/acl-api-private.h | 3 ++ src/plugins/acl/acl-backend-vfile.c | 4 +++ src/plugins/acl/acl-backend.c | 43 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/plugins/acl/acl-api-private.h b/src/plugins/acl/acl-api-private.h index 1a6fb27d3d..65073daf1d 100644 --- a/src/plugins/acl/acl-api-private.h +++ b/src/plugins/acl/acl-api-private.h @@ -102,6 +102,9 @@ void acl_object_rebuild_cache(struct acl_object *aclobj); void acl_object_remove_all_access(struct acl_object *aclobj); void acl_object_add_global_acls(struct acl_object *aclobj); +int acl_backend_get_mailbox_acl(struct acl_backend *backend, + struct acl_object *aclobj); + void acl_backend_register(const struct acl_backend_vfuncs *v); void acl_backend_unregister(const char *name); diff --git a/src/plugins/acl/acl-backend-vfile.c b/src/plugins/acl/acl-backend-vfile.c index 193928230f..b6aafc2ba3 100644 --- a/src/plugins/acl/acl-backend-vfile.c +++ b/src/plugins/acl/acl-backend-vfile.c @@ -500,6 +500,10 @@ static int acl_backend_vfile_object_refresh_cache(struct acl_object *_aclobj) validity.global_validity.last_mtime = st.st_mtime; validity.global_validity.last_size = st.st_size; } + + if (acl_backend_get_mailbox_acl(_aclobj->backend, _aclobj) < 0) + return -1; + if (acl_backend_vfile_read_with_retry(_aclobj, aclobj->local_path, &validity.local_validity) < 0) return -1; diff --git a/src/plugins/acl/acl-backend.c b/src/plugins/acl/acl-backend.c index 1ab639e83c..0aff001951 100644 --- a/src/plugins/acl/acl-backend.c +++ b/src/plugins/acl/acl-backend.c @@ -8,6 +8,7 @@ #include "settings.h" #include "mail-storage-settings.h" #include "mailbox-list-private.h" +#include "mail-storage-private.h" #include "mail-namespace.h" #include "mail-user.h" #include "acl-cache.h" @@ -219,6 +220,48 @@ int acl_backend_get_default_rights(struct acl_backend *backend, return 0; } +int acl_backend_get_mailbox_acl(struct acl_backend *backend, struct acl_object *aclobj) +{ + const char *error; + if (!mailbox_list_is_valid_name(backend->list, aclobj->name, &error)) { + e_debug(backend->event, "'%s' is not a valid mailbox name: %s", + aclobj->name, error); + return 0; + } + + const char *vname = mailbox_list_get_vname(backend->list, aclobj->name); + struct event *event = + mail_storage_mailbox_create_event(backend->event, backend->list, + vname); + struct acl_settings *aset; + const char *aname; + int ret; + + if ((ret = settings_get(event, &acl_setting_parser_info, 0, + &aset, &error)) < 0) { + e_error(event, "%s", error); + } else if (array_is_created(&aset->acl_rights)) { + array_foreach_elem(&aset->acl_rights, aname) { + struct acl_rights_settings *rset; + if ((ret = settings_get_filter(event, "acl", aname, + &acl_rights_setting_parser_info, + 0, &rset, &error)) < 0) { + e_error(event, "%s", error); + break; + } + + struct acl_rights *right = array_append_space(&aclobj->rights); + e_debug(event, "Using configured acl '%s'", rset->id); + acl_rights_dup(rset->parsed, aclobj->rights_pool, right); + settings_free(rset); + } + } + + settings_free(aset); + event_unref(&event); + return ret < 0 ? -1 : 0; +} + void acl_backend_register(const struct acl_backend_vfuncs *v) { struct acl_backend_entry *be = i_new(struct acl_backend_entry, 1); -- 2.47.3