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