From 1b9aa8885c43fbd155ff62bc75adb7f4e3dca40f Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sat, 6 Dec 2025 10:25:01 +0200 Subject: [PATCH] acl: Remove deprecated global ACL files Use the acl { ... } settings instead. This removes acl_global_path setting. --- src/plugins/acl/Makefile.am | 2 - src/plugins/acl/acl-api-private.h | 2 - src/plugins/acl/acl-api.c | 14 -- src/plugins/acl/acl-backend-vfile.c | 80 +-------- src/plugins/acl/acl-global-file.c | 250 ---------------------------- src/plugins/acl/acl-global-file.h | 23 --- src/plugins/acl/acl-settings.c | 2 - src/plugins/acl/acl-settings.h | 1 - 8 files changed, 6 insertions(+), 368 deletions(-) delete mode 100644 src/plugins/acl/acl-global-file.c delete mode 100644 src/plugins/acl/acl-global-file.h diff --git a/src/plugins/acl/Makefile.am b/src/plugins/acl/Makefile.am index b431c3ce32..6dc19946f1 100644 --- a/src/plugins/acl/Makefile.am +++ b/src/plugins/acl/Makefile.am @@ -31,7 +31,6 @@ lib01_acl_plugin_la_SOURCES = \ acl-backend-vfile-acllist.c \ acl-backend-vfile-update.c \ acl-cache.c \ - acl-global-file.c \ acl-lookup-dict.c \ acl-mailbox.c \ acl-mailbox-list.c \ @@ -50,7 +49,6 @@ pkginc_lib_HEADERS = \ acl-api.h \ acl-api-private.h \ acl-cache.h \ - acl-global-file.h \ acl-lookup-dict.h \ acl-plugin.h \ acl-rights.h \ diff --git a/src/plugins/acl/acl-api-private.h b/src/plugins/acl/acl-api-private.h index 65073daf1d..5772a5db1f 100644 --- a/src/plugins/acl/acl-api-private.h +++ b/src/plugins/acl/acl-api-private.h @@ -44,7 +44,6 @@ struct acl_backend { struct event *event; struct mailbox_list *list; struct acl_cache *cache; - struct acl_global_file *global_file; struct acl_object *default_aclobj; struct acl_mask *default_aclmask; @@ -100,7 +99,6 @@ int acl_backend_get_default_rights(struct acl_backend *backend, void acl_rights_sort(struct acl_object *aclobj); 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); diff --git a/src/plugins/acl/acl-api.c b/src/plugins/acl/acl-api.c index b1157437c4..062704b34d 100644 --- a/src/plugins/acl/acl-api.c +++ b/src/plugins/acl/acl-api.c @@ -7,7 +7,6 @@ #include "hash.h" #include "mail-user.h" #include "mailbox-list.h" -#include "acl-global-file.h" #include "acl-cache.h" #include "acl-api-private.h" @@ -383,16 +382,3 @@ void acl_object_remove_all_access(struct acl_object *aclobj) array_push_back(&aclobj->rights, &rights); } -void acl_object_add_global_acls(struct acl_object *aclobj) -{ - struct acl_backend *backend = aclobj->backend; - const char *vname, *error; - - if (mailbox_list_is_valid_name(backend->list, aclobj->name, &error)) - vname = mailbox_list_get_vname(backend->list, aclobj->name); - else - vname = ""; - - acl_global_file_get(backend->global_file, vname, - aclobj->rights_pool, &aclobj->rights); -} diff --git a/src/plugins/acl/acl-backend-vfile.c b/src/plugins/acl/acl-backend-vfile.c index b6aafc2ba3..ba20738761 100644 --- a/src/plugins/acl/acl-backend-vfile.c +++ b/src/plugins/acl/acl-backend-vfile.c @@ -7,7 +7,6 @@ #include "nfs-workarounds.h" #include "settings.h" #include "mailbox-list-private.h" -#include "acl-global-file.h" #include "acl-cache.h" #include "acl-backend-vfile.h" @@ -30,27 +29,8 @@ static struct acl_backend *acl_backend_vfile_alloc(void) } static int -acl_backend_vfile_init(struct acl_backend *_backend, const char **error_r) +acl_backend_vfile_init(struct acl_backend *_backend, const char **error_r ATTR_UNUSED) { - 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)); @@ -66,8 +46,6 @@ static void acl_backend_vfile_deinit(struct acl_backend *_backend) array_free(&backend->acllist); pool_unref(&backend->acllist_pool); } - if (_backend->global_file != NULL) - acl_global_file_deinit(&_backend->global_file); pool_unref(&backend->backend.pool); } @@ -174,19 +152,7 @@ acl_backend_vfile_has_acl(struct acl_backend *_backend, const char *name) struct mailbox *box = mailbox_alloc(_backend->list, vname, MAILBOX_FLAG_READONLY | MAILBOX_FLAG_IGNORE_ACLS); - if (_backend->global_file != NULL) { - /* check global ACL file */ - ret = acl_global_file_refresh(_backend->global_file); - if (ret == 0 && acl_global_file_have_any(_backend->global_file, box->vname)) - ret = 1; - } else { - /* global ACLs disabled */ - ret = 0; - } - - if (ret != 0) { - /* error / global ACL found */ - } else if (mailbox_open(box) == 0) { + if (mailbox_open(box) == 0) { /* mailbox exists */ ret = 1; } else { @@ -432,30 +398,11 @@ int acl_backend_vfile_object_get_mtime(struct acl_object *aclobj, if (validity->local_validity.last_mtime != 0) *mtime_r = validity->local_validity.last_mtime; - else if (validity->global_validity.last_mtime != 0) - *mtime_r = validity->global_validity.last_mtime; else *mtime_r = 0; return 0; } -static int -acl_backend_global_file_refresh(struct acl_object *_aclobj, - struct acl_vfile_validity *validity) -{ - struct acl_backend_vfile *backend = - container_of(_aclobj->backend, struct acl_backend_vfile, backend); - struct stat st; - - if (acl_global_file_refresh(_aclobj->backend->global_file) < 0) - return -1; - - acl_global_file_last_stat(_aclobj->backend->global_file, &st); - if (validity == NULL) - return 1; - return acl_vfile_validity_has_changed(backend, validity, &st) ? 1 : 0; -} - static int acl_backend_vfile_object_refresh_cache(struct acl_object *_aclobj) { struct acl_object_vfile *aclobj = @@ -465,18 +412,13 @@ static int acl_backend_vfile_object_refresh_cache(struct acl_object *_aclobj) struct acl_backend_vfile_validity *old_validity; struct acl_backend_vfile_validity validity; time_t mtime; - int ret = 0; + int ret; old_validity = acl_cache_get_validity(_aclobj->backend->cache, _aclobj->name); - if (_aclobj->backend->global_file != NULL) - ret = acl_backend_global_file_refresh(_aclobj, old_validity == NULL ? NULL : - &old_validity->global_validity); - if (ret == 0) { - ret = acl_backend_vfile_refresh(_aclobj, aclobj->local_path, - old_validity == NULL ? NULL : - &old_validity->local_validity); - } + ret = acl_backend_vfile_refresh(_aclobj, aclobj->local_path, + old_validity == NULL ? NULL : + &old_validity->local_validity); if (ret <= 0) return ret; @@ -491,16 +433,6 @@ static int acl_backend_vfile_object_refresh_cache(struct acl_object *_aclobj) } i_zero(&validity); - if (_aclobj->backend->global_file != NULL) { - struct stat st; - - acl_object_add_global_acls(_aclobj); - acl_global_file_last_stat(_aclobj->backend->global_file, &st); - validity.global_validity.last_read_time = ioloop_time; - 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; diff --git a/src/plugins/acl/acl-global-file.c b/src/plugins/acl/acl-global-file.c deleted file mode 100644 index ba5c10ba16..0000000000 --- a/src/plugins/acl/acl-global-file.c +++ /dev/null @@ -1,250 +0,0 @@ -/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "array.h" -#include "ioloop.h" -#include "istream.h" -#include "strescape.h" -#include "wildcard-match.h" -#include "acl-api-private.h" -#include "acl-global-file.h" - -#include - -struct acl_global_rights { - const char *vpattern; - ARRAY_TYPE(acl_rights) rights; -}; - -struct acl_global_parse_rights { - const char *vpattern; - struct acl_rights rights; -}; - -struct acl_global_file { - char *path; - struct stat prev_st; - struct event *event; - time_t last_refresh_time; - - pool_t rights_pool; - ARRAY(struct acl_global_rights) rights; - - unsigned int refresh_interval_secs; -}; - -struct acl_global_file * -acl_global_file_init(const char *path, unsigned int refresh_interval_secs, - struct event *event) -{ - struct acl_global_file *file; - - file = i_new(struct acl_global_file, 1); - file->path = i_strdup(path); - file->refresh_interval_secs = refresh_interval_secs; - file->event = event_create(event); - i_array_init(&file->rights, 32); - file->rights_pool = pool_alloconly_create("acl global file rights", 1024); - return file; -} - -void acl_global_file_deinit(struct acl_global_file **_file) -{ - struct acl_global_file *file = *_file; - - if (file == NULL) - return; - *_file = NULL; - - array_free(&file->rights); - event_unref(&file->event); - pool_unref(&file->rights_pool); - i_free(file->path); - i_free(file); -} - -static int acl_global_parse_rights_cmp(const struct acl_global_parse_rights *r1, - const struct acl_global_parse_rights *r2) -{ - return strcmp(r1->vpattern, r2->vpattern); -} - -struct acl_global_file_parse_ctx { - struct acl_global_file *file; - ARRAY(struct acl_global_parse_rights) parse_rights; -}; - -static int -acl_global_file_parse_line(struct acl_global_file_parse_ctx *ctx, - const char *line, const char **error_r) -{ - struct acl_global_parse_rights *pright; - const char *p, *vpattern; - - if (*line == '"') { - line++; - if (str_unescape_next(&line, &vpattern) < 0) { - *error_r = "Missing '\"'"; - return -1; - } - if (line[0] != ' ') { - *error_r = "Expecting space after '\"'"; - return -1; - } - line++; - } else { - p = strchr(line, ' '); - if (p == NULL) { - *error_r = "Missing ACL rights"; - return -1; - } - if (p == line) { - *error_r = "Empty ACL pattern"; - return -1; - } - vpattern = t_strdup_until(line, p); - line = p + 1; - } - - pright = array_append_space(&ctx->parse_rights); - pright->vpattern = p_strdup(ctx->file->rights_pool, vpattern); - if (acl_rights_parse_line(line, ctx->file->rights_pool, - &pright->rights, error_r) < 0) - return -1; - pright->rights.global = TRUE; - return 0; -} - -static int acl_global_file_read(struct acl_global_file *file) -{ - struct acl_global_file_parse_ctx ctx; - struct acl_global_parse_rights *pright; - struct acl_global_rights *right; - struct istream *input; - const char *line, *error, *prev_vpattern; - unsigned int linenum = 0; - int ret = 0; - - array_clear(&file->rights); - p_clear(file->rights_pool); - - i_zero(&ctx); - ctx.file = file; - i_array_init(&ctx.parse_rights, 32); - - input = i_stream_create_file(file->path, SIZE_MAX); - i_stream_set_return_partial_line(input, TRUE); - while ((line = i_stream_read_next_line(input)) != NULL) { - linenum++; - if (line[0] == '\0' || line[0] == '#') - continue; - T_BEGIN { - ret = acl_global_file_parse_line(&ctx, line, &error); - if (ret < 0) { - e_error(file->event, - "Global ACL file %s line %u: %s", - file->path, linenum, error); - } - } T_END; - if (ret < 0) - break; - } - if (ret == 0 && input->stream_errno != 0) { - e_error(file->event, - "Couldn't read global ACL file %s: %s", - file->path, i_stream_get_error(input)); - ret = -1; - } - if (ret == 0) { - const struct stat *st; - - if (i_stream_stat(input, TRUE, &st) < 0) { - e_error(file->event, - "Couldn't stat global ACL file %s: %s", - file->path, i_stream_get_error(input)); - ret = -1; - } else { - file->prev_st = *st; - } - } - i_stream_destroy(&input); - - /* sort all parsed rights */ - array_sort(&ctx.parse_rights, acl_global_parse_rights_cmp); - /* combine identical patterns into same structs */ - prev_vpattern = ""; right = NULL; - array_foreach_modifiable(&ctx.parse_rights, pright) { - if (right == NULL || - strcmp(prev_vpattern, pright->vpattern) != 0) { - right = array_append_space(&file->rights); - right->vpattern = pright->vpattern; - p_array_init(&right->rights, file->rights_pool, 4); - } - array_push_back(&right->rights, &pright->rights); - } - - array_free(&ctx.parse_rights); - return ret; -} - -int acl_global_file_refresh(struct acl_global_file *file) -{ - struct stat st; - - if (file->last_refresh_time + (time_t)file->refresh_interval_secs > ioloop_time) - return 0; - if (file->last_refresh_time != 0) { - if (stat(file->path, &st) < 0) { - e_error(file->event, "stat(%s) failed: %m", file->path); - return -1; - } - if (st.st_ino == file->prev_st.st_ino && - st.st_size == file->prev_st.st_size && - CMP_ST_MTIME(&st, &file->prev_st)) { - /* no change to the file */ - file->last_refresh_time = ioloop_time; - return 0; - } - } - if (acl_global_file_read(file) < 0) - return -1; - file->last_refresh_time = ioloop_time; - return 0; -} - -void acl_global_file_last_stat(struct acl_global_file *file, struct stat *st_r) -{ - *st_r = file->prev_st; -} - -void acl_global_file_get(struct acl_global_file *file, const char *vname, - pool_t pool, ARRAY_TYPE(acl_rights) *rights_r) -{ - struct acl_global_rights *global_rights; - const struct acl_rights *rights; - struct acl_rights *new_rights; - - array_foreach_modifiable(&file->rights, global_rights) { - if (!wildcard_match(vname, global_rights->vpattern)) - continue; - e_debug(file->event, "Mailbox '%s' matches global ACL pattern '%s'", - vname, global_rights->vpattern); - array_foreach(&global_rights->rights, rights) { - new_rights = array_append_space(rights_r); - acl_rights_dup(rights, pool, new_rights); - } - } -} - -bool acl_global_file_have_any(struct acl_global_file *file, const char *vname) -{ - struct acl_global_rights *rights; - - i_assert(file->last_refresh_time != 0); - - array_foreach_modifiable(&file->rights, rights) { - if (wildcard_match(vname, rights->vpattern)) - return TRUE; - } - return FALSE; -} diff --git a/src/plugins/acl/acl-global-file.h b/src/plugins/acl/acl-global-file.h deleted file mode 100644 index d324b7cfc4..0000000000 --- a/src/plugins/acl/acl-global-file.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ACL_GLOBAL_FILE_H -#define ACL_GLOBAL_FILE_H - -#include "acl-api.h" - -struct acl_global_file * -acl_global_file_init(const char *path, unsigned int refresh_interval_secs, - struct event *event); -void acl_global_file_deinit(struct acl_global_file **file); - -/* Read the global ACLs into memory. */ -int acl_global_file_refresh(struct acl_global_file *file); -/* Return stat data for the last refresh. */ -void acl_global_file_last_stat(struct acl_global_file *file, struct stat *st_r); - -/* Return global ACL rights matching the mailbox name. The file must already - have been refreshed at least once. */ -void acl_global_file_get(struct acl_global_file *file, const char *vname, - pool_t pool, ARRAY_TYPE(acl_rights) *rights_r); -/* Returns TRUE if there are any global ACLs matching the mailbox name. */ -bool acl_global_file_have_any(struct acl_global_file *file, const char *vname); - -#endif diff --git a/src/plugins/acl/acl-settings.c b/src/plugins/acl/acl-settings.c index 37fa2ad183..d0cd947d78 100644 --- a/src/plugins/acl/acl-settings.c +++ b/src/plugins/acl/acl-settings.c @@ -48,7 +48,6 @@ static const struct setting_define acl_setting_defines[] = { DEF(STR, acl_user), DEF(BOOLLIST, acl_groups), DEF(STR, acl_driver), - DEF(STR, acl_global_path), DEF(TIME, acl_cache_ttl), DEF(BOOL, acl_globals_only), DEF(BOOL, acl_defaults_from_inbox), @@ -69,7 +68,6 @@ static const struct acl_settings acl_default_settings = { .acl_groups = ARRAY_INIT, .acl_rights = ARRAY_INIT, .acl_driver = "", - .acl_global_path = "", .acl_cache_ttl = ACL_DEFAULT_CACHE_TTL_SECS, .acl_globals_only = FALSE, .acl_defaults_from_inbox = FALSE, diff --git a/src/plugins/acl/acl-settings.h b/src/plugins/acl/acl-settings.h index 663d59dadc..f599e6fd05 100644 --- a/src/plugins/acl/acl-settings.h +++ b/src/plugins/acl/acl-settings.h @@ -19,7 +19,6 @@ struct acl_settings { ARRAY_TYPE(const_string) acl_groups; ARRAY_TYPE(const_string) acl_rights; const char *acl_driver; - const char *acl_global_path; unsigned int acl_cache_ttl; bool acl_globals_only; bool acl_defaults_from_inbox; -- 2.47.3