dovecot-2.0: acl: Added doveadm plugin supporting acl get/set/ri...

dovecot at dovecot.org dovecot at dovecot.org
Fri Mar 4 03:23:20 EET 2011


details:   http://hg.dovecot.org/dovecot-2.0/rev/a2120ee55303
changeset: 12635:a2120ee55303
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Mar 04 03:22:45 2011 +0200
description:
acl: Added doveadm plugin supporting acl get/set/rights/debug commands.

diffstat:

 src/plugins/acl/Makefile.am         |   12 +-
 src/plugins/acl/acl-api-private.h   |    4 +
 src/plugins/acl/acl-api.c           |   27 ++
 src/plugins/acl/acl-backend-vfile.c |   50 +---
 src/plugins/acl/acl-backend.c       |    3 +-
 src/plugins/acl/acl-lookup-dict.c   |    5 +
 src/plugins/acl/acl-lookup-dict.h   |    2 +
 src/plugins/acl/doveadm-acl.c       |  421 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 481 insertions(+), 43 deletions(-)

diffs (truncated from 625 to 300 lines):

diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/Makefile.am
--- a/src/plugins/acl/Makefile.am	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/Makefile.am	Fri Mar 04 03:22:45 2011 +0200
@@ -1,11 +1,15 @@
+doveadm_moduledir = $(moduledir)/doveadm
+
 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 \
-	-I$(top_srcdir)/src/lib-storage
+	-I$(top_srcdir)/src/lib-storage \
+	-I$(top_srcdir)/src/doveadm
 
+lib10_doveadm_acl_plugin_la_LDFLAGS = -module -avoid-version
 lib01_acl_plugin_la_LDFLAGS = -module -avoid-version
 
 module_LTLIBRARIES = \
@@ -33,3 +37,9 @@
 	acl-plugin.h \
 	acl-shared-storage.h \
 	acl-storage.h
+
+doveadm_module_LTLIBRARIES = \
+	lib10_doveadm_acl_plugin.la
+
+lib10_doveadm_acl_plugin_la_SOURCES = \
+	doveadm-acl.c
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/acl-api-private.h
--- a/src/plugins/acl/acl-api-private.h	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/acl-api-private.h	Fri Mar 04 03:22:45 2011 +0200
@@ -74,6 +74,8 @@
 	unsigned int failed:1;
 };
 
+extern const char *const all_mailbox_rights[];
+
 const char *const *
 acl_backend_mask_get_names(struct acl_backend *backend,
 			   const struct acl_mask *mask, pool_t pool);
@@ -82,4 +84,6 @@
 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);
 
+int acl_identifier_parse(const char *line, struct acl_rights *rights);
+
 #endif
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/acl-api.c
--- a/src/plugins/acl/acl-api.c	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/acl-api.c	Fri Mar 04 03:22:45 2011 +0200
@@ -210,3 +210,30 @@
 	}
 	return FALSE;
 }
+
+int acl_identifier_parse(const char *line, struct acl_rights *rights)
+{
+	if (strncmp(line, ACL_ID_NAME_USER_PREFIX,
+		    strlen(ACL_ID_NAME_USER_PREFIX)) == 0) {
+		rights->id_type = ACL_ID_USER;
+		rights->identifier = line + 5;
+	} else if (strcmp(line, ACL_ID_NAME_OWNER) == 0) {
+		rights->id_type = ACL_ID_OWNER;
+	} else if (strncmp(line, ACL_ID_NAME_GROUP_PREFIX,
+			   strlen(ACL_ID_NAME_GROUP_PREFIX)) == 0) {
+		rights->id_type = ACL_ID_GROUP;
+		rights->identifier = line + 6;
+	} else if (strncmp(line, ACL_ID_NAME_GROUP_OVERRIDE_PREFIX,
+			   strlen(ACL_ID_NAME_GROUP_OVERRIDE_PREFIX)) == 0) {
+		rights->id_type = ACL_ID_GROUP_OVERRIDE;
+		rights->identifier = line + 15;
+	} else if (strcmp(line, ACL_ID_NAME_AUTHENTICATED) == 0) {
+		rights->id_type = ACL_ID_AUTHENTICATED;
+	} else if (strcmp(line, ACL_ID_NAME_ANYONE) == 0 ||
+		   strcmp(line, "anonymous") == 0) {
+		rights->id_type = ACL_ID_ANYONE;
+	} else {
+		return -1;
+	}
+	return 0;
+}
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/acl-backend-vfile.c
--- a/src/plugins/acl/acl-backend-vfile.c	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/acl-backend-vfile.c	Fri Mar 04 03:22:45 2011 +0200
@@ -419,44 +419,8 @@
 		rights.neg_rights = right_names;
 	}
 
-	switch (*line) {
-	case 'u':
-		if (strncmp(line, ACL_ID_NAME_USER_PREFIX,
-			    strlen(ACL_ID_NAME_USER_PREFIX)) == 0) {
-			rights.id_type = ACL_ID_USER;
-			rights.identifier = line + 5;
-			break;
-		}
-	case 'o':
-		if (strcmp(line, ACL_ID_NAME_OWNER) == 0) {
-			rights.id_type = ACL_ID_OWNER;
-			break;
-		}
-	case 'g':
-		if (strncmp(line, ACL_ID_NAME_GROUP_PREFIX,
-			    strlen(ACL_ID_NAME_GROUP_PREFIX)) == 0) {
-			rights.id_type = ACL_ID_GROUP;
-			rights.identifier = line + 6;
-			break;
-		} else if (strncmp(line, ACL_ID_NAME_GROUP_OVERRIDE_PREFIX,
-				   strlen(ACL_ID_NAME_GROUP_OVERRIDE_PREFIX)) == 0) {
-			rights.id_type = ACL_ID_GROUP_OVERRIDE;
-			rights.identifier = line + 15;
-			break;
-		}
-	case 'a':
-		if (strcmp(line, ACL_ID_NAME_AUTHENTICATED) == 0) {
-			rights.id_type = ACL_ID_AUTHENTICATED;
-			break;
-		} else if (strcmp(line, ACL_ID_NAME_ANYONE) == 0 ||
-			   strcmp(line, "anonymous") == 0) {
-			rights.id_type = ACL_ID_ANYONE;
-			break;
-		}
-	default:
+	if (acl_identifier_parse(line, &rights) < 0)
 		error = t_strdup_printf("Unknown ID '%s'", line);
-		break;
-	}
 
 	if (error != NULL) {
 		i_error("ACL file %s line %u: %s", path, linenum, error);
@@ -1110,12 +1074,16 @@
 	   first global */
 	rights = array_get(&aclobj->rights, &count);
 	for (i = 0; i < count && !rights[i].global; i++) {
-		if (rights[i].rights != NULL)
+		if (rights[i].rights != NULL) {
 			vfile_write_right(str, &rights[i], FALSE);
-		if (rights[i].neg_rights != NULL)
+			o_stream_send(output, str_data(str), str_len(str));
+			str_truncate(str, 0);
+		}
+		if (rights[i].neg_rights != NULL) {
 			vfile_write_right(str, &rights[i], TRUE);
-		o_stream_send(output, str_data(str), str_len(str));
-		str_truncate(str, 0);
+			o_stream_send(output, str_data(str), str_len(str));
+			str_truncate(str, 0);
+		}
 	}
 	str_free(&str);
 	if (o_stream_flush(output) < 0) {
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/acl-backend.c
--- a/src/plugins/acl/acl-backend.c	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/acl-backend.c	Fri Mar 04 03:22:45 2011 +0200
@@ -12,7 +12,7 @@
 
 extern struct acl_backend_vfuncs acl_backend_vfile;
 
-static const char *const owner_mailbox_rights[] = {
+const char *const all_mailbox_rights[] = {
 	MAIL_ACL_LOOKUP,
 	MAIL_ACL_READ,
 	MAIL_ACL_WRITE,
@@ -27,6 +27,7 @@
 	NULL
 };
 
+static const char *const *owner_mailbox_rights = all_mailbox_rights;
 static const char *const non_owner_mailbox_rights[] = { NULL };
 
 struct acl_backend *
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/acl-lookup-dict.c
--- a/src/plugins/acl/acl-lookup-dict.c	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/acl-lookup-dict.c	Fri Mar 04 03:22:45 2011 +0200
@@ -63,6 +63,11 @@
 	i_free(dict);
 }
 
+bool acl_lookup_dict_is_enabled(struct acl_lookup_dict *dict)
+{
+	return dict->dict != NULL;
+}
+
 static void
 acl_lookup_dict_write_rights_id(string_t *dest, const struct acl_rights *right)
 {
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/acl-lookup-dict.h
--- a/src/plugins/acl/acl-lookup-dict.h	Fri Mar 04 03:16:25 2011 +0200
+++ b/src/plugins/acl/acl-lookup-dict.h	Fri Mar 04 03:22:45 2011 +0200
@@ -4,6 +4,8 @@
 struct acl_lookup_dict *acl_lookup_dict_init(struct mail_user *user);
 void acl_lookup_dict_deinit(struct acl_lookup_dict **dict);
 
+bool acl_lookup_dict_is_enabled(struct acl_lookup_dict *dict);
+
 int acl_lookup_dict_rebuild(struct acl_lookup_dict *dict);
 
 struct acl_lookup_dict_iter *
diff -r 35577e832d5a -r a2120ee55303 src/plugins/acl/doveadm-acl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/acl/doveadm-acl.c	Fri Mar 04 03:22:45 2011 +0200
@@ -0,0 +1,421 @@
+/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "module-dir.h"
+#include "acl-plugin.h"
+#include "acl-api-private.h"
+#include "acl-lookup-dict.h"
+#include "doveadm-print.h"
+#include "doveadm-mail.h"
+
+struct doveadm_acl_cmd_context {
+	struct doveadm_mail_cmd_context ctx;
+	bool get_match_me;
+};
+
+const char *doveadm_acl_plugin_version = DOVECOT_VERSION;
+
+void doveadm_acl_plugin_init(struct module *module);
+void doveadm_acl_plugin_deinit(void);
+
+static int
+cmd_acl_mailbox_open(struct mail_user *user, const char *mailbox,
+		     struct mailbox **box_r)
+{
+	struct acl_user *auser = ACL_USER_CONTEXT(user);
+	struct mail_namespace *ns;
+	struct mailbox *box;
+	const char *storage_name;
+
+	if (auser == NULL) {
+		i_error("ACL not enabled for %s", user->username);
+		return -1;
+	}
+
+	storage_name = mailbox;
+	ns = mail_namespace_find(user->namespaces, &storage_name);
+	if (ns == NULL) {
+		i_error("No namespace found for mailbox %s", mailbox);
+		return -1;
+	}
+	box = mailbox_alloc(ns->list, storage_name,
+			    MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT |
+			    MAILBOX_FLAG_IGNORE_ACLS);
+	if (mailbox_open(box) < 0) {
+		i_error("Can't open mailbox %s: %s", mailbox,
+			mail_storage_get_last_error(box->storage, NULL));
+		mailbox_free(&box);
+		return -1;
+	}
+	*box_r = box;
+	return 0;
+}
+
+static void cmd_acl_get_right(const struct acl_rights *rights)
+{
+	const char *id = "";
+	string_t *str;
+
+	switch (rights->id_type) {
+	case ACL_ID_ANYONE:
+		id = ACL_ID_NAME_ANYONE;
+		break;
+	case ACL_ID_AUTHENTICATED:
+		id = ACL_ID_NAME_AUTHENTICATED;
+		break;
+	case ACL_ID_OWNER:
+		id = ACL_ID_NAME_OWNER;
+		break;
+	case ACL_ID_USER:
+		id = t_strconcat(ACL_ID_NAME_USER_PREFIX,
+				 rights->identifier, NULL);
+		break;
+	case ACL_ID_GROUP:
+		id = t_strconcat(ACL_ID_NAME_GROUP_PREFIX,
+				 rights->identifier, NULL);
+		break;
+	case ACL_ID_GROUP_OVERRIDE:
+		id = t_strconcat(ACL_ID_NAME_GROUP_OVERRIDE_PREFIX,
+				 rights->identifier, NULL);
+		break;
+	case ACL_ID_TYPE_COUNT:
+		i_unreached();
+	}
+	doveadm_print(id);
+
+	if (rights->global)
+		doveadm_print("global");
+	else
+		doveadm_print("");
+
+	str = t_str_new(256);
+	if (rights->rights != NULL)
+		str_append(str, t_strarray_join(rights->rights, " "));
+	if (rights->neg_rights != NULL) {
+		if (str_len(str) > 0)


More information about the dovecot-cvs mailing list