dovecot-1.2: Added IMAP ACL commands with ability to modify ACLs.
dovecot at dovecot.org
dovecot at dovecot.org
Sun Nov 16 04:46:19 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/29b1ec15880a
changeset: 8418:29b1ec15880a
user: Timo Sirainen <tss at iki.fi>
date: Sun Nov 16 04:46:14 2008 +0200
description:
Added IMAP ACL commands with ability to modify ACLs.
Based on patch by Bernhard Herzog and Sascha Wilde.
diffstat:
14 files changed, 951 insertions(+), 92 deletions(-)
configure.in | 1
src/plugins/Makefile.am | 1
src/plugins/acl/Makefile.am | 3
src/plugins/acl/acl-api-private.h | 13
src/plugins/acl/acl-api.c | 54 ++-
src/plugins/acl/acl-api.h | 13
src/plugins/acl/acl-backend-vfile.c | 384 ++++++++++++++++++++++++---
src/plugins/acl/acl-cache.c | 2
src/plugins/acl/acl-mailbox.c | 46 ++-
src/plugins/acl/acl-plugin.h | 16 -
src/plugins/acl/acl-storage.h | 28 +
src/plugins/imap-acl/Makefile.am | 20 +
src/plugins/imap-acl/imap-acl-plugin.c | 455 ++++++++++++++++++++++++++++++++
src/plugins/imap-acl/imap-acl-plugin.h | 7
diffs (truncated from 1400 to 300 lines):
diff -r 106ad33091ca -r 29b1ec15880a configure.in
--- a/configure.in Sun Nov 16 04:45:06 2008 +0200
+++ b/configure.in Sun Nov 16 04:46:14 2008 +0200
@@ -2453,6 +2453,7 @@ src/util/Makefile
src/util/Makefile
src/plugins/Makefile
src/plugins/acl/Makefile
+src/plugins/imap-acl/Makefile
src/plugins/autocreate/Makefile
src/plugins/convert/Makefile
src/plugins/expire/Makefile
diff -r 106ad33091ca -r 29b1ec15880a src/plugins/Makefile.am
--- a/src/plugins/Makefile.am Sun Nov 16 04:45:06 2008 +0200
+++ b/src/plugins/Makefile.am Sun Nov 16 04:46:14 2008 +0200
@@ -12,6 +12,7 @@ endif
SUBDIRS = \
acl \
+ imap-acl \
autocreate \
convert \
expire \
diff -r 106ad33091ca -r 29b1ec15880a src/plugins/acl/Makefile.am
--- a/src/plugins/acl/Makefile.am Sun Nov 16 04:45:06 2008 +0200
+++ b/src/plugins/acl/Makefile.am Sun Nov 16 04:46:14 2008 +0200
@@ -26,7 +26,8 @@ noinst_HEADERS = \
acl-api-private.h \
acl-backend-vfile.h \
acl-cache.h \
- acl-plugin.h
+ acl-plugin.h \
+ acl-storage.h
install-exec-local:
for d in imap lda; do \
diff -r 106ad33091ca -r 29b1ec15880a src/plugins/acl/acl-api-private.h
--- a/src/plugins/acl/acl-api-private.h Sun Nov 16 04:45:06 2008 +0200
+++ b/src/plugins/acl/acl-api-private.h Sun Nov 16 04:46:14 2008 +0200
@@ -2,6 +2,13 @@
#define ACL_API_PRIVATE_H
#include "acl-api.h"
+
+#define ACL_ID_NAME_ANYONE "anyone"
+#define ACL_ID_NAME_AUTHENTICATED "authenticated"
+#define ACL_ID_NAME_OWNER "owner"
+#define ACL_ID_NAME_USER_PREFIX "user="
+#define ACL_ID_NAME_GROUP_PREFIX "group="
+#define ACL_ID_NAME_GROUP_OVERRIDE_PREFIX "group-override="
struct acl_backend_vfuncs {
struct acl_backend *(*alloc)(void);
@@ -25,7 +32,7 @@ struct acl_backend_vfuncs {
int (*object_refresh_cache)(struct acl_object *aclobj);
int (*object_update)(struct acl_object *aclobj,
- const struct acl_rights_update *rights);
+ const struct acl_rights_update *update);
struct acl_object_list_iter *
(*object_list_init)(struct acl_object *aclobj);
@@ -65,9 +72,13 @@ struct acl_object_list_iter {
struct acl_object *aclobj;
unsigned int idx;
+ unsigned int returned_owner:1;
unsigned int failed:1;
};
+const char *const *
+acl_backend_mask_get_names(struct acl_backend *backend,
+ const struct acl_mask *mask, pool_t pool);
int acl_backend_get_default_rights(struct acl_backend *backend,
const struct acl_mask **mask_r);
diff -r 106ad33091ca -r 29b1ec15880a src/plugins/acl/acl-api.c
--- a/src/plugins/acl/acl-api.c Sun Nov 16 04:45:06 2008 +0200
+++ b/src/plugins/acl/acl-api.c Sun Nov 16 04:46:14 2008 +0200
@@ -52,30 +52,13 @@ int acl_object_have_right(struct acl_obj
return acl_cache_mask_isset(have_mask, right_idx);
}
-static int acl_object_get_my_rights_real(struct acl_object *aclobj, pool_t pool,
- const char *const **rights_r)
+const char *const *
+acl_backend_mask_get_names(struct acl_backend *backend,
+ const struct acl_mask *mask, pool_t pool)
{
- struct acl_backend *backend = aclobj->backend;
- const struct acl_mask *mask;
const char *const *names;
const char **buf, **rights;
unsigned int names_count, count, i, j, name_idx;
-
- if (*aclobj->name == '\0') {
- /* we want to look up default rights */
- if (acl_backend_get_default_rights(backend, &mask) < 0)
- return -1;
- } else {
- if (backend->v.object_refresh_cache(aclobj) < 0)
- return -1;
-
- mask = acl_cache_get_my_rights(backend->cache,
- aclobj->name);
- if (mask == NULL) {
- if (acl_backend_get_default_rights(backend, &mask) < 0)
- return -1;
- }
- }
names = acl_cache_get_names(backend->cache, &names_count);
buf = t_new(const char *, (mask->size * CHAR_BIT) + 1);
@@ -98,7 +81,32 @@ static int acl_object_get_my_rights_real
/* @UNSAFE */
rights = p_new(pool, const char *, count + 1);
memcpy(rights, buf, count * sizeof(const char *));
- *rights_r = rights;
+ return rights;
+}
+
+static int acl_object_get_my_rights_real(struct acl_object *aclobj, pool_t pool,
+ const char *const **rights_r)
+{
+ struct acl_backend *backend = aclobj->backend;
+ const struct acl_mask *mask;
+
+ if (*aclobj->name == '\0') {
+ /* we want to look up default rights */
+ if (acl_backend_get_default_rights(backend, &mask) < 0)
+ return -1;
+ } else {
+ if (backend->v.object_refresh_cache(aclobj) < 0)
+ return -1;
+
+ mask = acl_cache_get_my_rights(backend->cache,
+ aclobj->name);
+ if (mask == NULL) {
+ if (acl_backend_get_default_rights(backend, &mask) < 0)
+ return -1;
+ }
+ }
+
+ *rights_r = acl_backend_mask_get_names(backend, mask, pool);
return 0;
}
@@ -116,9 +124,9 @@ int acl_object_get_my_rights(struct acl_
}
int acl_object_update(struct acl_object *aclobj,
- const struct acl_rights_update *rights)
+ const struct acl_rights_update *update)
{
- return aclobj->backend->v.object_update(aclobj, rights);
+ return aclobj->backend->v.object_update(aclobj, update);
}
struct acl_object_list_iter *acl_object_list_init(struct acl_object *aclobj)
diff -r 106ad33091ca -r 29b1ec15880a src/plugins/acl/acl-api.h
--- a/src/plugins/acl/acl-api.h Sun Nov 16 04:45:06 2008 +0200
+++ b/src/plugins/acl/acl-api.h Sun Nov 16 04:46:14 2008 +0200
@@ -3,6 +3,7 @@
struct mailbox_list;
struct mail_storage;
+struct mailbox;
struct acl_object;
/* Show mailbox in mailbox list. Allow subscribing to it. */
@@ -48,12 +49,14 @@ enum acl_id_type {
};
enum acl_modify_mode {
+ /* Remove rights from existing ACL */
+ ACL_MODIFY_MODE_REMOVE = 0,
/* Add rights to existing ACL (or create a new one) */
- ACL_MODIFY_MODE_ADD = 0,
- /* Remove rights from existing ACL */
- ACL_MODIFY_MODE_REMOVE,
+ ACL_MODIFY_MODE_ADD,
/* Replace existing ACL with given rights */
- ACL_MODIFY_MODE_REPLACE
+ ACL_MODIFY_MODE_REPLACE,
+ /* Clear all the rights from an existing ACL */
+ ACL_MODIFY_MODE_CLEAR
};
struct acl_rights {
@@ -126,7 +129,7 @@ int acl_object_get_my_rights(struct acl_
/* Update ACL of given object. */
int acl_object_update(struct acl_object *aclobj,
- const struct acl_rights_update *rights);
+ const struct acl_rights_update *update);
/* List all identifiers. */
struct acl_object_list_iter *acl_object_list_init(struct acl_object *aclobj);
diff -r 106ad33091ca -r 29b1ec15880a src/plugins/acl/acl-backend-vfile.c
--- a/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 04:45:06 2008 +0200
+++ b/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 04:46:14 2008 +0200
@@ -3,9 +3,14 @@
#include "lib.h"
#include "ioloop.h"
#include "array.h"
+#include "bsearch-insert-pos.h"
+#include "str.h"
#include "istream.h"
+#include "ostream.h"
+#include "file-dotlock.h"
#include "nfs-workarounds.h"
#include "mail-storage-private.h"
+#include "mail-namespace.h"
#include "acl-cache.h"
#include "acl-backend-vfile.h"
@@ -52,6 +57,14 @@ static const struct acl_letter_map acl_l
{ '\0', NULL }
};
+static struct dotlock_settings dotlock_set = {
+ MEMBER(temp_prefix) NULL,
+ MEMBER(lock_suffix) NULL,
+
+ MEMBER(timeout) 30,
+ MEMBER(stale_timeout) 120
+};
+
static struct acl_backend *acl_backend_vfile_alloc(void)
{
struct acl_backend_vfile *backend;
@@ -266,7 +279,8 @@ static void acl_backend_vfile_object_dei
}
static const char *const *
-acl_rights_alloc(pool_t pool, ARRAY_TYPE(const_string) *rights_arr)
+acl_rights_alloc(pool_t pool, ARRAY_TYPE(const_string) *rights_arr,
+ bool dup_strings)
{
const char **ret, **rights;
unsigned int i, dest, count;
@@ -283,6 +297,11 @@ acl_rights_alloc(pool_t pool, ARRAY_TYPE
if (strcmp(rights[i-1], rights[i]) != 0)
ret[dest++] = rights[i];
}
+ ret[dest] = NULL;
+ if (dup_strings) {
+ for (i = 0; i < dest; i++)
+ ret[i] = p_strdup(pool, ret[i]);
+ }
}
return ret;
}
@@ -326,7 +345,7 @@ acl_parse_rights(pool_t pool, const char
}
}
- return acl_rights_alloc(pool, &rights);
+ return acl_rights_alloc(pool, &rights, FALSE);
}
static int
@@ -362,31 +381,34 @@ acl_object_vfile_parse_line(struct acl_o
switch (*line) {
case 'u':
- if (strncmp(line, "user=", 5) == 0) {
+ 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, "owner") == 0) {
+ if (strcmp(line, ACL_ID_NAME_OWNER) == 0) {
rights.id_type = ACL_ID_OWNER;
break;
}
case 'g':
- if (strncmp(line, "group=", 6) == 0) {
+ 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, "group-override=", 15) == 0) {
+ } 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, "authenticated") == 0) {
+ if (strcmp(line, ACL_ID_NAME_AUTHENTICATED) == 0) {
rights.id_type = ACL_ID_AUTHENTICATED;
break;
- } else if (strcmp(line, "anyone") == 0 ||
+ } else if (strcmp(line, ACL_ID_NAME_ANYONE) == 0 ||
strcmp(line, "anonymous") == 0) {
More information about the dovecot-cvs
mailing list