You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2020/10/08 16:42:43 UTC

svn commit: r1882326 - in /subversion/trunk/subversion: libsvn_repos/authz.c tests/libsvn_repos/authz-test.c

Author: stsp
Date: Thu Oct  8 16:42:43 2020
New Revision: 1882326

URL: http://svn.apache.org/viewvc?rev=1882326&view=rev
Log:
Fix issue #4762 "authz doesn't combine global and repository rules"

The new authz implementation of SVN 1.10 introduced an incompatible
change in the interpretation of authz rules:

Global access rules can be configured for a particular user and a specific
path. Such global rules were ignored if a repository-specific rule is also
present for the same path, even if this repository-specific rule does not
apply to the user in question.

This change seems unnecessary because it broke backwards compatibility with
existing authz files, from SVN 1.9 and older, for no discernible benefit.
The change was probably not intentional as this situation was not covered
by the test suite before a test case was added in r1835049.

Restore the behaviour of SVN 1.9: It is now again possible to override
per-path access rules for specific users (and groups) at the global level.
Such global rules are overridden by repository-specific rules only if
both the user and the path match the repository-specific rule.

* subversion/libsvn_repos/authz.c
  (create_user_authz): Prefer rules which apply to both the user and
    the path over rules which apply only to the path. If both a global
    and a repository-specific rule apply to user and path then prefer
    the repository-specific one.

* subversion/tests/libsvn_repos/authz-test.c
  (reposful_reposless_stanzas_inherit): Remove XFAIL marker.

Modified:
    subversion/trunk/subversion/libsvn_repos/authz.c
    subversion/trunk/subversion/tests/libsvn_repos/authz-test.c

Modified: subversion/trunk/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/authz.c?rev=1882326&r1=1882325&r2=1882326&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/authz.c (original)
+++ subversion/trunk/subversion/libsvn_repos/authz.c Thu Oct  8 16:42:43 2020
@@ -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;
         }
     }
 

Modified: subversion/trunk/subversion/tests/libsvn_repos/authz-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_repos/authz-test.c?rev=1882326&r1=1882325&r2=1882326&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_repos/authz-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_repos/authz-test.c Thu Oct  8 16:42:43 2020
@@ -522,7 +522,7 @@ static struct svn_test_descriptor_t test
                    "test svn_authz__get_global_rights"),
     SVN_TEST_PASS2(issue_4741_groups,
                    "issue 4741 groups"),
-    SVN_TEST_XFAIL2(reposful_reposless_stanzas_inherit,
+    SVN_TEST_PASS2(reposful_reposless_stanzas_inherit,
                     "[foo:/] inherits [/]"),
     SVN_TEST_NULL
   };