From c1f8e1429afc26168f9cfd3c7a92f67ba553522f Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Fri, 10 Nov 2023 15:19:58 +0200 Subject: [PATCH] plugins: acl - Add acl_backend_init_auto() --- src/plugins/acl/acl-api-private.h | 1 + src/plugins/acl/acl-api.h | 2 + src/plugins/acl/acl-backend-vfile.c | 30 ++++++++++++ src/plugins/acl/acl-backend-vfile.h | 1 + src/plugins/acl/acl-backend.c | 71 ++++++++++++++++++++++++++++- 5 files changed, 104 insertions(+), 1 deletion(-) diff --git a/src/plugins/acl/acl-api-private.h b/src/plugins/acl/acl-api-private.h index 79ed241595..5166500634 100644 --- a/src/plugins/acl/acl-api-private.h +++ b/src/plugins/acl/acl-api-private.h @@ -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); diff --git a/src/plugins/acl/acl-api.h b/src/plugins/acl/acl-api.h index 6e35330ce6..ae13e6baa0 100644 --- a/src/plugins/acl/acl-api.h +++ b/src/plugins/acl/acl-api.h @@ -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 diff --git a/src/plugins/acl/acl-backend-vfile.c b/src/plugins/acl/acl-backend-vfile.c index 34727ea3eb..2524bc8461 100644 --- a/src/plugins/acl/acl-backend-vfile.c +++ b/src/plugins/acl/acl-backend-vfile.c @@ -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, diff --git a/src/plugins/acl/acl-backend-vfile.h b/src/plugins/acl/acl-backend-vfile.h index 0550771c47..0c8eb75672 100644 --- a/src/plugins/acl/acl-backend-vfile.h +++ b/src/plugins/acl/acl-backend-vfile.h @@ -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; diff --git a/src/plugins/acl/acl-backend.c b/src/plugins/acl/acl-backend.c index e3c9970705..eff5628e75 100644 --- a/src/plugins/acl/acl-backend.c +++ b/src/plugins/acl/acl-backend.c @@ -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); } -- 2.47.3