]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
acl: Default owner rights override anyone/authenticated/group rights.
authorTimo Sirainen <tss@iki.fi>
Sun, 16 Nov 2008 12:06:15 +0000 (14:06 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 16 Nov 2008 12:06:15 +0000 (14:06 +0200)
--HG--
branch : HEAD

src/plugins/acl/acl-api-private.h
src/plugins/acl/acl-backend-vfile.c
src/plugins/acl/acl-backend.c

index 54d24ba19639b4f97f311010f4ecef22ab2b315a..ae5d691c990e06a4c6502f79abd0e3b1b3e682f6 100644 (file)
@@ -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;
 
index b379a7af914722ea97bb21019cd322a705d58c2b..333be1bdb84de6ee90595be3c0c61124664101f4 100644 (file)
@@ -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);
 }
 
index 8f5744547d0e17b0975a7bec8505d9b858d81822..62cefe17b977f99c9223cc8cf92ca182fbef76f2 100644 (file)
@@ -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;