]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
plugins: acl - Add ability to register acl backends
authorAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 10 Nov 2023 12:13:49 +0000 (14:13 +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-backend-vfile.c
src/plugins/acl/acl-backend.c
src/plugins/acl/acl-plugin.c

index 3087ea2ae4cb5de1b980446a9980cbe53a136753..bc47473eddd14067019f11800fdc192492ecee4a 100644 (file)
@@ -11,6 +11,7 @@
 #define ACL_ID_NAME_GROUP_OVERRIDE_PREFIX "group-override="
 
 struct acl_backend_vfuncs {
+       const char *name;
        struct acl_backend *(*alloc)(void);
        int (*init)(struct acl_backend *backend, const char *data);
        void (*deinit)(struct acl_backend *backend);
@@ -132,4 +133,7 @@ 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);
 
+void acl_backend_register(const struct acl_backend_vfuncs *v);
+void acl_backend_unregister(const char *name);
+
 #endif
index 1d7af57b63eaf655a9d51e4d9346daeb020c93a7..a0265cfc38bf9bffe55f7192a9ba92ae3b17ea9c 100644 (file)
@@ -562,6 +562,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,
        .deinit = acl_backend_vfile_deinit,
index c507b2d4740bb318e6af0c829a15a54a2ad1a0ec..f5eaa24f7ec76b337d4d769e883d797b89efccb8 100644 (file)
@@ -1,6 +1,7 @@
 /* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "llist.h"
 #include "hash.h"
 #include "sort.h"
 #include "mail-storage-settings.h"
 
 
 extern const struct acl_backend_vfuncs acl_backend_vfile;
+static struct acl_backend_entry {
+       struct acl_backend_entry *prev, *next;
+       const struct acl_backend_vfuncs *v;
+} *acl_backend_list_head = NULL;
 
 struct event_category event_category_acl = {
        .name = "acl",
@@ -35,13 +40,30 @@ const char *const all_mailbox_rights[] = {
 static const char *const *owner_mailbox_rights = all_mailbox_rights;
 static const char *const non_owner_mailbox_rights[] = { NULL };
 
+static struct acl_backend_entry *acl_backend_find(const char *name)
+{
+       struct acl_backend_entry *be = acl_backend_list_head;
+
+       while (be != NULL) {
+               if (strcmp(be->v->name, name) == 0)
+                       break;
+               be = be->next;
+       }
+
+       if (be == NULL)
+                i_fatal("Unknown ACL backend: %s", name);
+       return be;
+}
+
 struct acl_backend *
 acl_backend_init(const char *data, struct mailbox_list *list,
                 const char *acl_username, const char *const *groups,
                 bool owner)
 {
        struct mail_user *user = mailbox_list_get_user(list);
+       struct acl_backend_entry *be;
        struct acl_backend *backend;
+       const char *be_name;
        unsigned int i, group_count;
 
        e_debug(user->event, "acl: initializing backend with data: %s", data);
@@ -50,18 +72,21 @@ acl_backend_init(const char *data, struct mailbox_list *list,
 
        group_count = str_array_length(groups);
 
-       if (str_begins(data, "vfile:", &data))
-               ;
-       else if (strcmp(data, "vfile") == 0)
-               data = "";
-       else
-               i_fatal("Unknown ACL backend: %s", t_strcut(data, ':'));
+       be_name = strchr(data, ':');
+       if (be_name == NULL)
+               be_name = data;
+       else {
+               be_name = t_strdup_until(data, be_name);
+               data = be_name++;
+       }
+
+       be = acl_backend_find(be_name);
 
-       backend = acl_backend_vfile.alloc();
+       backend = be->v->alloc();
        backend->event = event_create(user->event);
        event_add_category(backend->event, &event_category_acl);
 
-       backend->v = &acl_backend_vfile;
+       backend->v = be->v;
        backend->list = list;
        backend->username = p_strdup(backend->pool, acl_username);
        backend->owner = owner;
@@ -82,8 +107,8 @@ acl_backend_init(const char *data, struct mailbox_list *list,
 
        T_BEGIN {
                if (backend->v->init(backend, data) < 0)
-                       i_fatal("acl: backend vfile init failed with data: %s",
-                               data);
+                       i_fatal("acl: backend %s init failed with data: %s",
+                               backend->v->name, data);
        } T_END;
 
        backend->default_rights = owner ? owner_mailbox_rights :
@@ -200,3 +225,18 @@ int acl_backend_get_default_rights(struct acl_backend *backend,
                *mask_r = backend->default_aclmask;
        return 0;
 }
+
+void acl_backend_register(const struct acl_backend_vfuncs *v)
+{
+       struct acl_backend_entry *be = i_new(struct acl_backend_entry, 1);
+       be->v = v;
+       DLLIST_PREPEND(&acl_backend_list_head, be);
+}
+
+void acl_backend_unregister(const char *name)
+{
+       struct acl_backend_entry *be = acl_backend_find(name);
+       i_assert(be != NULL);
+       DLLIST_REMOVE(&acl_backend_list_head, be);
+       i_free(be);
+}
index b446dcd42996cb1d0b0f291cd23a8e289c1ce9bd..8091af390373702d97de12645f7873ec0449cac0 100644 (file)
@@ -2,9 +2,10 @@
 
 #include "lib.h"
 #include "mailbox-list-private.h"
-#include "acl-api.h"
+#include "acl-api-private.h"
 #include "acl-plugin.h"
 
+extern const struct acl_backend_vfuncs acl_backend_vfile;
 
 const char *acl_plugin_version = DOVECOT_ABI_VERSION;
 
@@ -18,10 +19,12 @@ static struct mail_storage_hooks acl_mail_storage_hooks = {
 
 void acl_plugin_init(struct module *module)
 {
+       acl_backend_register(&acl_backend_vfile);
        mail_storage_hooks_add(module, &acl_mail_storage_hooks);
 }
 
 void acl_plugin_deinit(void)
 {
        mail_storage_hooks_remove(&acl_mail_storage_hooks);
+       acl_backend_unregister(acl_backend_vfile.name);
 }