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