From: Timo Sirainen Date: Sun, 16 Nov 2008 12:06:15 +0000 (+0200) Subject: acl: Default owner rights override anyone/authenticated/group rights. X-Git-Tag: 1.2.alpha4~68 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7705148680904051b573a9125ecee765032a5809;p=thirdparty%2Fdovecot%2Fcore.git acl: Default owner rights override anyone/authenticated/group rights. --HG-- branch : HEAD --- diff --git a/src/plugins/acl/acl-api-private.h b/src/plugins/acl/acl-api-private.h index 54d24ba196..ae5d691c99 100644 --- a/src/plugins/acl/acl-api-private.h +++ b/src/plugins/acl/acl-api-private.h @@ -52,6 +52,7 @@ struct acl_backend { struct acl_object *default_aclobj; struct acl_mask *default_aclmask; + const char *const *default_rights; struct acl_backend_vfuncs v; diff --git a/src/plugins/acl/acl-backend-vfile.c b/src/plugins/acl/acl-backend-vfile.c index b379a7af91..333be1bdb8 100644 --- a/src/plugins/acl/acl-backend-vfile.c +++ b/src/plugins/acl/acl-backend-vfile.c @@ -702,6 +702,20 @@ static void acl_backend_vfile_rights_sort(struct acl_object_vfile *aclobj) array_delete(&aclobj->rights, dest, count - dest); } +static void apply_owner_rights(struct acl_object *_aclobj) +{ + struct acl_rights_update ru; + const char *null = NULL; + + memset(&ru, 0, sizeof(ru)); + ru.modify_mode = ACL_MODIFY_MODE_REPLACE; + ru.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; + ru.rights.id_type = ACL_ID_OWNER; + ru.rights.rights = _aclobj->backend->default_rights; + ru.rights.neg_rights = &null; + acl_cache_update(_aclobj->backend->cache, _aclobj->name, &ru); +} + static void acl_backend_vfile_cache_rebuild(struct acl_object_vfile *aclobj) { static const char *const admin_rights[] = { MAIL_ACL_ADMIN, NULL }; @@ -710,7 +724,7 @@ static void acl_backend_vfile_cache_rebuild(struct acl_object_vfile *aclobj) struct acl_rights_update ru, ru2; const struct acl_rights *rights; unsigned int i, count; - bool first_global = TRUE; + bool owner_applied, first_global = TRUE; acl_cache_flush(_aclobj->backend->cache, _aclobj->name); @@ -723,9 +737,20 @@ static void acl_backend_vfile_cache_rebuild(struct acl_object_vfile *aclobj) ru2.rights.id_type = ACL_ID_OWNER; ru2.rights.rights = admin_rights; + owner_applied = ns->type != NAMESPACE_PRIVATE; + memset(&ru, 0, sizeof(ru)); rights = array_get(&aclobj->rights, &count); for (i = 0; i < count; i++) { + if (!owner_applied && + (rights[i].id_type >= ACL_ID_OWNER || rights[i].global)) { + owner_applied = TRUE; + if (rights[i].id_type != ACL_ID_OWNER) { + /* owner rights weren't explicitly specified. + replace all the current rights */ + apply_owner_rights(_aclobj); + } + } /* If [neg_]rights is NULL it needs to be ignored. The easiest way to do that is to just mark it with REMOVE mode */ @@ -749,7 +774,9 @@ static void acl_backend_vfile_cache_rebuild(struct acl_object_vfile *aclobj) } acl_cache_update(_aclobj->backend->cache, _aclobj->name, &ru); } - if (first_global && ns->type == NAMESPACE_PRIVATE) + if (!owner_applied && count > 0) + apply_owner_rights(_aclobj); + else if (first_global && ns->type == NAMESPACE_PRIVATE) acl_cache_update(_aclobj->backend->cache, _aclobj->name, &ru2); } diff --git a/src/plugins/acl/acl-backend.c b/src/plugins/acl/acl-backend.c index 8f5744547d..62cefe17b9 100644 --- a/src/plugins/acl/acl-backend.c +++ b/src/plugins/acl/acl-backend.c @@ -73,10 +73,11 @@ acl_backend_init(const char *data, struct mailbox_list *list, data); } T_END; + backend->default_rights = owner ? owner_mailbox_rights : + non_owner_mailbox_rights; backend->default_aclmask = acl_cache_mask_init(backend->cache, backend->pool, - owner ? owner_mailbox_rights : - non_owner_mailbox_rights); + backend->default_rights); backend->default_aclobj = acl_object_init_from_name(backend, NULL, ""); return backend;