dovecot-1.2: ACL: Crashfix to previous change. Also fixes "-id" ...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Nov 16 01:34:34 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/d00c446a95df
changeset: 8415:d00c446a95df
user: Timo Sirainen <tss at iki.fi>
date: Sun Nov 16 01:34:16 2008 +0200
description:
ACL: Crashfix to previous change. Also fixes "-id" to work correctly with missing "id".
diffstat:
4 files changed, 68 insertions(+), 32 deletions(-)
src/plugins/acl/acl-api.h | 3 +
src/plugins/acl/acl-backend-vfile.c | 28 +++++++++++---
src/plugins/acl/acl-cache.c | 67 ++++++++++++++++++++++-------------
src/plugins/acl/acl-cache.h | 2 -
diffs (197 lines):
diff -r d486dfe02c1e -r d00c446a95df src/plugins/acl/acl-api.h
--- a/src/plugins/acl/acl-api.h Sun Nov 16 00:15:15 2008 +0200
+++ b/src/plugins/acl/acl-api.h Sun Nov 16 01:34:16 2008 +0200
@@ -62,7 +62,8 @@ struct acl_rights {
/* Identifier, eg. username / group name */
const char *identifier;
- /* Rights assigned */
+ /* Rights assigned. NULL entry can be ignored, but { NULL } means user
+ has no rights. */
const char *const *rights;
/* Negative rights assigned */
const char *const *neg_rights;
diff -r d486dfe02c1e -r d00c446a95df src/plugins/acl/acl-backend-vfile.c
--- a/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 00:15:15 2008 +0200
+++ b/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 01:34:16 2008 +0200
@@ -632,10 +632,14 @@ acl_rights_merge(pool_t pool, const char
unsigned int i;
t_array_init(&rights, 64);
- for (i = 0; dest[i] != NULL; i++)
- array_append(&rights, &dest[i], 1);
- for (i = 0; src[i] != NULL; i++)
- array_append(&rights, &src[i], 1);
+ if (dest != NULL) {
+ for (i = 0; dest[i] != NULL; i++)
+ array_append(&rights, &dest[i], 1);
+ }
+ if (src != NULL) {
+ for (i = 0; src[i] != NULL; i++)
+ array_append(&rights, &src[i], 1);
+ }
*destp = acl_rights_alloc(pool, &rights);
}
@@ -679,6 +683,7 @@ static void acl_backend_vfile_cache_rebu
struct acl_rights_update ru;
const struct acl_rights *rights;
unsigned int i, count;
+ bool first_global = TRUE;
acl_cache_flush(_aclobj->backend->cache, _aclobj->name);
@@ -688,9 +693,20 @@ static void acl_backend_vfile_cache_rebu
memset(&ru, 0, sizeof(ru));
rights = array_get(&aclobj->rights, &count);
for (i = 0; i < count; i++) {
- ru.modify_mode = ACL_MODIFY_MODE_REPLACE;
- ru.neg_modify_mode = ACL_MODIFY_MODE_REPLACE;
+ /* If [neg_]rights is NULL it needs to be ignored.
+ The easiest way to do that is to just mark it with
+ REMOVE mode */
+ ru.modify_mode = rights[i].rights == NULL ?
+ ACL_MODIFY_MODE_REMOVE : ACL_MODIFY_MODE_REPLACE;
+ ru.neg_modify_mode = rights[i].neg_rights == NULL ?
+ ACL_MODIFY_MODE_REMOVE : ACL_MODIFY_MODE_REPLACE;
ru.rights = rights[i];
+ if (rights[i].global && first_global) {
+ /* first global: reset negative ACLs so local ACLs
+ can't mess things up via them */
+ first_global = FALSE;
+ ru.neg_modify_mode = ACL_MODIFY_MODE_REPLACE;
+ }
acl_cache_update(_aclobj->backend->cache, _aclobj->name, &ru);
}
}
diff -r d486dfe02c1e -r d00c446a95df src/plugins/acl/acl-cache.c
--- a/src/plugins/acl/acl-cache.c Sun Nov 16 00:15:15 2008 +0200
+++ b/src/plugins/acl/acl-cache.c Sun Nov 16 01:34:16 2008 +0200
@@ -4,7 +4,7 @@
#include "array.h"
#include "hash.h"
#include "acl-cache.h"
-#include "acl-api.h"
+#include "acl-api-private.h"
/* Give more than enough so that the arrays should never have to be grown.
IMAP ACLs define only 10 standard rights and 10 user-defined rights. */
@@ -116,6 +116,18 @@ struct acl_mask *acl_cache_mask_init(str
return mask;
}
+static struct acl_mask *
+acl_cache_mask_dup(pool_t pool, const struct acl_mask *src)
+{
+ struct acl_mask *mask;
+
+ mask = p_malloc(pool, SIZEOF_ACL_MASK(src->size));
+ memcpy(mask->mask, src->mask, src->size);
+ mask->pool = pool;
+ mask->size = src->size;
+ return mask;
+}
+
void acl_cache_mask_deinit(struct acl_mask **_mask)
{
struct acl_mask *mask = *_mask;
@@ -251,19 +263,6 @@ acl_cache_update_rights_mask(struct acl_
}
}
-static void
-acl_cache_update_rights(struct acl_cache *cache,
- struct acl_object_cache *obj_cache,
- const struct acl_rights_update *rights)
-{
- acl_cache_update_rights_mask(cache, obj_cache, rights->modify_mode,
- rights->rights.rights,
- &obj_cache->my_rights);
- acl_cache_update_rights_mask(cache, obj_cache, rights->neg_modify_mode,
- rights->rights.neg_rights,
- &obj_cache->my_neg_rights);
-}
-
static struct acl_object_cache *
acl_cache_object_get(struct acl_cache *cache, const char *objname,
bool *created_r)
@@ -283,8 +282,9 @@ acl_cache_object_get(struct acl_cache *c
return obj_cache;
}
-void acl_cache_update(struct acl_cache *cache, const char *objname,
- const struct acl_rights_update *rights)
+static void
+acl_cache_update_rights(struct acl_cache *cache, const char *objname,
+ const struct acl_rights_update *update)
{
struct acl_object_cache *obj_cache;
bool created;
@@ -292,28 +292,47 @@ void acl_cache_update(struct acl_cache *
obj_cache = acl_cache_object_get(cache, objname, &created);
i_assert(obj_cache->my_current_rights != &negative_cache_entry);
- switch (rights->rights.id_type) {
+ if (created && update->modify_mode != ACL_MODIFY_MODE_REPLACE) {
+ /* since the rights aren't being replaced, start with our
+ default rights */
+ obj_cache->my_rights =
+ acl_cache_mask_dup(default_pool,
+ cache->backend->default_aclmask);
+ }
+
+ acl_cache_update_rights_mask(cache, obj_cache, update->modify_mode,
+ update->rights.rights,
+ &obj_cache->my_rights);
+ acl_cache_update_rights_mask(cache, obj_cache, update->neg_modify_mode,
+ update->rights.neg_rights,
+ &obj_cache->my_neg_rights);
+}
+
+void acl_cache_update(struct acl_cache *cache, const char *objname,
+ const struct acl_rights_update *update)
+{
+ switch (update->rights.id_type) {
case ACL_ID_ANYONE:
- acl_cache_update_rights(cache, obj_cache, rights);
+ acl_cache_update_rights(cache, objname, update);
break;
case ACL_ID_AUTHENTICATED:
if (acl_backend_user_is_authenticated(cache->backend))
- acl_cache_update_rights(cache, obj_cache, rights);
+ acl_cache_update_rights(cache, objname, update);
break;
case ACL_ID_GROUP:
case ACL_ID_GROUP_OVERRIDE:
if (acl_backend_user_is_in_group(cache->backend,
- rights->rights.identifier))
- acl_cache_update_rights(cache, obj_cache, rights);
+ update->rights.identifier))
+ acl_cache_update_rights(cache, objname, update);
break;
case ACL_ID_USER:
if (acl_backend_user_name_equals(cache->backend,
- rights->rights.identifier))
- acl_cache_update_rights(cache, obj_cache, rights);
+ update->rights.identifier))
+ acl_cache_update_rights(cache, objname, update);
break;
case ACL_ID_OWNER:
if (acl_backend_user_is_owner(cache->backend))
- acl_cache_update_rights(cache, obj_cache, rights);
+ acl_cache_update_rights(cache, objname, update);
break;
case ACL_ID_TYPE_COUNT:
i_unreached();
diff -r d486dfe02c1e -r d00c446a95df src/plugins/acl/acl-cache.h
--- a/src/plugins/acl/acl-cache.h Sun Nov 16 00:15:15 2008 +0200
+++ b/src/plugins/acl/acl-cache.h Sun Nov 16 01:34:16 2008 +0200
@@ -34,7 +34,7 @@ void acl_cache_flush_all(struct acl_cach
/* Update object ACLs. The new rights are always applied on top of the
existing rights. The ordering by acl_id_type must be done by the caller. */
void acl_cache_update(struct acl_cache *cache, const char *objname,
- const struct acl_rights_update *rights);
+ const struct acl_rights_update *update);
/* Return ACL object validity, or NULL if object doesn't exit. */
void *acl_cache_get_validity(struct acl_cache *cache, const char *objname);
/* Update ACL object validity, creating the object if needed. */
More information about the dovecot-cvs
mailing list