From: Aki Tuomi Date: Fri, 10 Nov 2023 11:29:09 +0000 (+0200) Subject: plugins: acl - Add acl settings X-Git-Tag: 2.4.1~1168 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1363a0036d37e58ee86542ab4710e65be862ce30;p=thirdparty%2Fdovecot%2Fcore.git plugins: acl - Add acl settings --- diff --git a/src/plugins/acl/Makefile.am b/src/plugins/acl/Makefile.am index 2f0000af9a..041d3dcbd8 100644 --- a/src/plugins/acl/Makefile.am +++ b/src/plugins/acl/Makefile.am @@ -3,6 +3,7 @@ doveadm_moduledir = $(moduledir)/doveadm AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-mail \ -I$(top_srcdir)/src/lib-imap \ @@ -32,6 +33,7 @@ lib01_acl_plugin_la_SOURCES = \ acl-mailbox.c \ acl-mailbox-list.c \ acl-plugin.c \ + acl-settings.c \ acl-shared-storage.c \ acl-storage.c @@ -47,6 +49,7 @@ pkginc_lib_HEADERS = \ acl-global-file.h \ acl-lookup-dict.h \ acl-plugin.h \ + acl-settings.h \ acl-storage.h doveadm_module_LTLIBRARIES = \ diff --git a/src/plugins/acl/acl-settings.c b/src/plugins/acl/acl-settings.c new file mode 100644 index 0000000000..eeca4cabe7 --- /dev/null +++ b/src/plugins/acl/acl-settings.c @@ -0,0 +1,142 @@ +/* Copyright (c) 2023 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "settings.h" +#include "settings-parser.h" + +#include "acl-settings.h" +#include "acl-api-private.h" + +#undef DEF +#define DEF(type, name) \ + SETTING_DEFINE_STRUCT_##type("acl_"#name, name, struct acl_rights_settings) + +static const struct setting_define acl_rights_setting_defines[] = { + DEF(STR, id), + DEF(STR, rights), + SETTING_DEFINE_LIST_END, +}; + +static const struct acl_rights_settings acl_rights_default_settings = { + .id = "", + .rights = "", +}; + +static bool acl_rights_settings_check(void *_set, pool_t ATTR_UNUSED pool, + const char **error_r); + +const struct setting_parser_info acl_rights_setting_parser_info = { + .name = "acl_rights", + + .defines = acl_rights_setting_defines, + .defaults = &acl_rights_default_settings, + + .struct_size = sizeof(struct acl_rights_settings), + + .check_func = acl_rights_settings_check, + + .pool_offset1 = 1 + offsetof(struct acl_rights_settings, pool), +}; + +#undef DEF +#define DEF(type, name) \ + SETTING_DEFINE_STRUCT_##type(#name, name, struct acl_settings) + +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), + DEF(BOOL, acl_ignore), + { .type = SET_FILTER_NAME, .key = "acl_sharing_map", + .required_setting = "dict_driver", }, + { .type = SET_FILTER_ARRAY, + .key = "acl", + .filter_array_field_name = "acl_id", + .required_setting = "acl_rights", + .offset = offsetof(struct acl_settings, acl_rights)}, + SETTING_DEFINE_LIST_END, +}; + +static const struct acl_settings acl_default_settings = { + .acl_user = "%{master_user}", + .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, + .acl_ignore = FALSE, +}; + +static bool acl_settings_check(void *_set ATTR_UNUSED, pool_t pool ATTR_UNUSED, + const char **error_r ATTR_UNUSED); + +const struct setting_parser_info acl_setting_parser_info = { + .name = "acl", + + .defines = acl_setting_defines, + .defaults = &acl_default_settings, + + .struct_size = sizeof(struct acl_settings), + + .check_func = acl_settings_check, + + .pool_offset1 = 1 + offsetof(struct acl_settings, pool), +}; + +/* */ +static bool acl_rights_settings_check(void *_set, pool_t pool, const char **error_r) +{ +#ifdef CONFIG_BINARY + /* FIXME: validate syntax */ + return TRUE; +#else + struct acl_rights_settings *set = _set; + const char *const *right_names; + const char *id_str = set->id; + const char *rights_str = set->rights; + + /* Empty id */ + if (*id_str == '\0') + return TRUE; + + bool neg = *rights_str == '-'; + if (neg) + rights_str++; + + set->parsed = p_new(pool, struct acl_rights, 1); + + if (acl_identifier_parse(set->id, set->parsed) < 0) { + *error_r = t_strdup_printf("Invalid identifier '%s'", set->id); + return FALSE; + } + + right_names = acl_right_names_parse(pool, rights_str, error_r); + if (right_names == NULL) + return FALSE; + + if (neg) { + set->parsed->neg_rights = right_names; + } else { + set->parsed->rights = right_names; + } + return TRUE; +#endif +} + +static bool acl_settings_check(void *_set ATTR_UNUSED, pool_t pool ATTR_UNUSED, + const char **error_r ATTR_UNUSED) +{ + struct acl_settings *set = _set; + if (array_is_created(&set->acl_groups)) + array_sort(&set->acl_groups, i_strcmp_p); + return TRUE; +} + +/* */ diff --git a/src/plugins/acl/acl-settings.h b/src/plugins/acl/acl-settings.h new file mode 100644 index 0000000000..eca4564f2d --- /dev/null +++ b/src/plugins/acl/acl-settings.h @@ -0,0 +1,32 @@ +#ifndef ACL_SETTINGS_H +#define ACL_SETTINGS_H + +#define ACL_DEFAULT_CACHE_TTL_SECS 30 + +struct acl_rights_settings { + pool_t pool; + const char *id; + const char *rights; + + struct acl_rights *parsed; +}; + +ARRAY_DEFINE_TYPE(acl_rights_setting, struct acl_rights_settings); + +struct acl_settings { + pool_t pool; + const char *acl_user; + 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; + bool acl_ignore; +}; + +extern const struct setting_parser_info acl_rights_setting_parser_info; +extern const struct setting_parser_info acl_setting_parser_info; + +#endif