aboutsummaryrefslogtreecommitdiff
path: root/subversion/libsvn_repos/authz.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_repos/authz.c')
-rw-r--r--subversion/libsvn_repos/authz.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/subversion/libsvn_repos/authz.c b/subversion/libsvn_repos/authz.c
index 9f8dbc5a08f7..0a47a0928638 100644
--- a/subversion/libsvn_repos/authz.c
+++ b/subversion/libsvn_repos/authz.c
@@ -889,9 +889,7 @@ create_user_authz(authz_full_t *authz,
/* Use a separate sub-pool to keep memory usage tight. */
apr_pool_t *subpool = svn_pool_create(scratch_pool);
- /* Find all ACLs for REPOSITORY.
- * Note that repo-specific rules replace global rules,
- * even if they don't apply to the current user. */
+ /* Find all ACLs for REPOSITORY. */
apr_array_header_t *acls = apr_array_make(subpool, authz->acls->nelts,
sizeof(authz_acl_t *));
for (i = 0; i < authz->acls->nelts; ++i)
@@ -908,15 +906,36 @@ create_user_authz(authz_full_t *authz,
= APR_ARRAY_IDX(acls, acls->nelts - 1, const authz_acl_t *);
if (svn_authz__compare_paths(&prev_acl->rule, &acl->rule) == 0)
{
+ svn_boolean_t global_acl_applies;
+ svn_boolean_t repos_acl_applies;
+
+ /* Previous ACL is a global rule. */
SVN_ERR_ASSERT_NO_RETURN(!strcmp(prev_acl->rule.repos,
AUTHZ_ANY_REPOSITORY));
+ /* Current ACL is a per-repository rule. */
SVN_ERR_ASSERT_NO_RETURN(strcmp(acl->rule.repos,
AUTHZ_ANY_REPOSITORY));
- apr_array_pop(acls);
+
+ global_acl_applies =
+ svn_authz__get_acl_access(NULL, prev_acl, user, repository);
+ repos_acl_applies =
+ svn_authz__get_acl_access(NULL, acl, user, repository);
+
+ /* Prefer rules which apply to both this user and this path
+ * over rules which apply only to the path. In cases where
+ * both rules apply to user and path, always prefer the
+ * repository-specific rule. */
+ if (!global_acl_applies || repos_acl_applies)
+ {
+ apr_array_pop(acls);
+ APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
+ }
}
+ else
+ APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
}
-
- APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
+ else
+ APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
}
}