dovecot-1.2: Initial support for LISTing users with shared mailb...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Nov 16 19:20:33 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/dfe39e9a9e78
changeset: 8433:dfe39e9a9e78
user: Timo Sirainen <tss at iki.fi>
date: Sun Nov 16 19:20:28 2008 +0200
description:
Initial support for LISTing users with shared mailboxes.
diffstat:
15 files changed, 563 insertions(+), 44 deletions(-)
src/plugins/acl/Makefile.am | 5
src/plugins/acl/acl-api-private.h | 1
src/plugins/acl/acl-api.c | 30 ++
src/plugins/acl/acl-backend-vfile-acllist.c | 5
src/plugins/acl/acl-backend-vfile.c | 27 --
src/plugins/acl/acl-lookup-dict.c | 332 +++++++++++++++++++++++++++
src/plugins/acl/acl-lookup-dict.h | 18 +
src/plugins/acl/acl-mailbox-list.c | 27 +-
src/plugins/acl/acl-mailbox.c | 7
src/plugins/acl/acl-plugin.c | 15 -
src/plugins/acl/acl-plugin.h | 20 +
src/plugins/acl/acl-shared-storage.c | 73 +++++
src/plugins/acl/acl-shared-storage.h | 6
src/plugins/acl/acl-storage.c | 39 +++
src/plugins/acl/acl-storage.h | 2
diffs (truncated from 845 to 300 lines):
diff -r 8f083c8482e1 -r dfe39e9a9e78 src/plugins/acl/Makefile.am
--- a/src/plugins/acl/Makefile.am Sun Nov 16 19:19:26 2008 +0200
+++ b/src/plugins/acl/Makefile.am Sun Nov 16 19:20:28 2008 +0200
@@ -1,5 +1,6 @@ AM_CPPFLAGS = \
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-dict \
-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-imap \
-I$(top_srcdir)/src/lib-index \
@@ -16,9 +17,11 @@ lib01_acl_plugin_la_SOURCES = \
acl-backend-vfile.c \
acl-backend-vfile-acllist.c \
acl-cache.c \
+ acl-lookup-dict.c \
acl-mailbox.c \
acl-mailbox-list.c \
acl-plugin.c \
+ acl-shared-storage.c \
acl-storage.c
noinst_HEADERS = \
@@ -26,7 +29,9 @@ noinst_HEADERS = \
acl-api-private.h \
acl-backend-vfile.h \
acl-cache.h \
+ acl-lookup-dict.h \
acl-plugin.h \
+ acl-shared-storage.h \
acl-storage.h
install-exec-local:
diff -r 8f083c8482e1 -r dfe39e9a9e78 src/plugins/acl/acl-api-private.h
--- a/src/plugins/acl/acl-api-private.h Sun Nov 16 19:19:26 2008 +0200
+++ b/src/plugins/acl/acl-api-private.h Sun Nov 16 19:20:28 2008 +0200
@@ -82,6 +82,7 @@ acl_backend_mask_get_names(struct acl_ba
const struct acl_mask *mask, pool_t pool);
int acl_backend_get_default_rights(struct acl_backend *backend,
const struct acl_mask **mask_r);
+void acl_rights_write_id(string_t *dest, const struct acl_rights *right);
bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights);
#endif
diff -r 8f083c8482e1 -r dfe39e9a9e78 src/plugins/acl/acl-api.c
--- a/src/plugins/acl/acl-api.c Sun Nov 16 19:19:26 2008 +0200
+++ b/src/plugins/acl/acl-api.c Sun Nov 16 19:20:28 2008 +0200
@@ -1,6 +1,7 @@
/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "str.h"
#include "hash.h"
#include "acl-cache.h"
#include "acl-api-private.h"
@@ -172,6 +173,35 @@ acl_backend_nonowner_lookups_iter_deinit
ctx->backend->v.nonowner_lookups_iter_deinit(ctx);
}
+void acl_rights_write_id(string_t *dest, const struct acl_rights *right)
+{
+ switch (right->id_type) {
+ case ACL_ID_ANYONE:
+ str_append(dest, ACL_ID_NAME_ANYONE);
+ break;
+ case ACL_ID_AUTHENTICATED:
+ str_append(dest, ACL_ID_NAME_AUTHENTICATED);
+ break;
+ case ACL_ID_OWNER:
+ str_append(dest, ACL_ID_NAME_OWNER);
+ break;
+ case ACL_ID_USER:
+ str_append(dest, ACL_ID_NAME_USER_PREFIX);
+ str_append(dest, right->identifier);
+ break;
+ case ACL_ID_GROUP:
+ str_append(dest, ACL_ID_NAME_GROUP_PREFIX);
+ str_append(dest, right->identifier);
+ break;
+ case ACL_ID_GROUP_OVERRIDE:
+ str_append(dest, ACL_ID_NAME_GROUP_OVERRIDE_PREFIX);
+ str_append(dest, right->identifier);
+ break;
+ case ACL_ID_TYPE_COUNT:
+ i_unreached();
+ }
+}
+
bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights)
{
const char *const *p;
diff -r 8f083c8482e1 -r dfe39e9a9e78 src/plugins/acl/acl-backend-vfile-acllist.c
--- a/src/plugins/acl/acl-backend-vfile-acllist.c Sun Nov 16 19:19:26 2008 +0200
+++ b/src/plugins/acl/acl-backend-vfile-acllist.c Sun Nov 16 19:20:28 2008 +0200
@@ -10,6 +10,7 @@
#include "mail-storage.h"
#include "acl-plugin.h"
#include "acl-cache.h"
+#include "acl-lookup-dict.h"
#include "acl-backend-vfile.h"
#include <stdio.h>
@@ -241,8 +242,12 @@ int acl_backend_vfile_acllist_rebuild(st
}
}
if (ret == 0) {
+ struct acl_user *auser = ACL_USER_CONTEXT(ns->user);
+
backend->acllist_mtime = st.st_mtime;
backend->acllist_last_check = ioloop_time;
+ /* FIXME: dict reubild is expensive, try to avoid it */
+ (void)acl_lookup_dict_rebuild(auser->acl_lookup_dict);
} else {
acllist_clear(backend, 0);
if (unlink(str_c(path)) < 0 && errno != ENOENT)
diff -r 8f083c8482e1 -r dfe39e9a9e78 src/plugins/acl/acl-backend-vfile.c
--- a/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 19:19:26 2008 +0200
+++ b/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 19:20:28 2008 +0200
@@ -999,32 +999,7 @@ vfile_write_right(string_t *dest, const
const char *const *rights = neg ? right->neg_rights : right->rights;
if (neg) str_append_c(dest,'-');
-
- switch (right->id_type) {
- case ACL_ID_ANYONE:
- str_append(dest, ACL_ID_NAME_ANYONE);
- break;
- case ACL_ID_AUTHENTICATED:
- str_append(dest, ACL_ID_NAME_AUTHENTICATED);
- break;
- case ACL_ID_OWNER:
- str_append(dest, ACL_ID_NAME_OWNER);
- break;
- case ACL_ID_USER:
- str_append(dest, ACL_ID_NAME_USER_PREFIX);
- str_append(dest, right->identifier);
- break;
- case ACL_ID_GROUP:
- str_append(dest, ACL_ID_NAME_GROUP_PREFIX);
- str_append(dest, right->identifier);
- break;
- case ACL_ID_GROUP_OVERRIDE:
- str_append(dest, ACL_ID_NAME_GROUP_OVERRIDE_PREFIX);
- str_append(dest, right->identifier);
- break;
- case ACL_ID_TYPE_COUNT:
- i_unreached();
- }
+ acl_rights_write_id(dest, right);
str_append_c(dest, ' ');
vfile_write_rights_list(dest, rights);
str_append_c(dest, '\n');
diff -r 8f083c8482e1 -r dfe39e9a9e78 src/plugins/acl/acl-lookup-dict.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/acl/acl-lookup-dict.c Sun Nov 16 19:20:28 2008 +0200
@@ -0,0 +1,332 @@
+/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "str.h"
+#include "dict.h"
+#include "mail-user.h"
+#include "mail-namespace.h"
+#include "acl-api-private.h"
+#include "acl-storage.h"
+#include "acl-plugin.h"
+#include "acl-lookup-dict.h"
+
+#include <stdlib.h>
+
+#define DICT_SHARED_BOXES_PATH "shared-boxes/"
+
+struct acl_lookup_dict {
+ struct mail_user *user;
+};
+
+struct acl_lookup_dict_iter {
+ pool_t pool;
+ struct acl_lookup_dict *dict;
+
+ ARRAY_TYPE(const_string) iter_ids;
+ struct dict_iterate_context *dict_iter;
+ unsigned int iter_idx;
+
+ const char *prefix;
+ unsigned int prefix_len;
+
+ unsigned int failed:1;
+};
+
+static struct dict *acl_dict;
+
+void acl_lookup_dicts_init(void)
+{
+ const char *uri;
+
+ uri = getenv("ACL_SHARED_DICT");
+ if (uri == NULL) {
+ if (getenv("DEBUG") != NULL) {
+ i_info("acl: No acl_shared_dict setting - "
+ "shared mailbox listing is disabled");
+ }
+ return;
+ }
+
+ acl_dict = dict_init(uri, DICT_DATA_TYPE_STRING, "");
+ if (acl_dict == NULL)
+ i_fatal("acl: dict_init(%s) failed", uri);
+}
+
+void acl_lookup_dicts_deinit(void)
+{
+ if (acl_dict != NULL)
+ dict_deinit(&acl_dict);
+}
+
+struct acl_lookup_dict *acl_lookup_dict_init(struct mail_user *user)
+{
+ struct acl_lookup_dict *dict;
+
+ dict = i_new(struct acl_lookup_dict, 1);
+ dict->user = user;
+ return dict;
+}
+
+void acl_lookup_dict_deinit(struct acl_lookup_dict **_dict)
+{
+ struct acl_lookup_dict *dict = *_dict;
+
+ *_dict = NULL;
+ i_free(dict);
+}
+
+static void
+acl_lookup_dict_write_rights_id(string_t *dest, const struct acl_rights *right)
+{
+ switch (right->id_type) {
+ case ACL_ID_ANYONE:
+ case ACL_ID_AUTHENTICATED:
+ /* don't bother separating these */
+ str_append(dest, "anyone");
+ break;
+ case ACL_ID_USER:
+ str_append(dest, "user/");
+ str_append(dest, right->identifier);
+ break;
+ case ACL_ID_GROUP:
+ case ACL_ID_GROUP_OVERRIDE:
+ str_append(dest, "group/");
+ str_append(dest, right->identifier);
+ break;
+ case ACL_ID_OWNER:
+ case ACL_ID_TYPE_COUNT:
+ i_unreached();
+ }
+}
+
+static int acl_lookup_dict_rebuild_add_backend(struct mail_namespace *ns,
+ ARRAY_TYPE(const_string) *ids)
+{
+ struct acl_backend *backend;
+ struct acl_mailbox_list_context *ctx;
+ struct acl_object *aclobj;
+ struct acl_object_list_iter *iter;
+ struct acl_rights rights;
+ const char *name, *id_dup;
+ string_t *id;
+ int ret, ret2 = 0;
+
+ id = t_str_new(128);
+ backend = acl_storage_get_backend(ns->storage);
+ ctx = acl_backend_nonowner_lookups_iter_init(backend);
+ while ((ret = acl_backend_nonowner_lookups_iter_next(ctx, &name)) > 0) {
+ aclobj = acl_object_init_from_name(backend, ns->storage, name);
+
+ iter = acl_object_list_init(aclobj);
+ while ((ret = acl_object_list_next(iter, &rights)) > 0) {
+ if (acl_rights_has_nonowner_lookup_changes(&rights)) {
+ str_truncate(id, 0);
+ acl_lookup_dict_write_rights_id(id, &rights);
+ id_dup = t_strdup(str_c(id));
+ array_append(ids, &id_dup, 1);
+ }
+ }
+ acl_object_list_deinit(&iter);
+ if (ret < 0)
+ ret2 = -1;
+ acl_object_deinit(&aclobj);
+ }
+ acl_backend_nonowner_lookups_iter_deinit(&ctx);
+ return ret < 0 || ret2 < 0 ? -1 : 0;
+}
+
+static int
+acl_lookup_dict_rebuild_update(struct acl_lookup_dict *dict,
+ const ARRAY_TYPE(const_string) *new_ids_arr,
+ bool no_removes)
+{
+ const char *username = dict->user->username;
+ struct dict_iterate_context *iter;
More information about the dovecot-cvs
mailing list