Hi, the fixes for issue 3242 ("Subversion demands unnecessary access to parent directories of operations") currently in trunk do not address scenario gicen below.
[[[ Fix another scenario related to issue #3242: - user has no access in repo root, only in /project - someone else renames some file below /project and commits - user tries to update his working copy of /project (that still has the old name) - update deletes the old name and then fails with "access to 'http://host/repo-root' forbidden" * subversion/libsvn_client/update.c (file_fetcher): When opening an auxiliary session, don't open it at the repository root (where the user might not have read permission), but at the dirname of the file to fetch. ]]] The first attached patch amends authz_tests.py with a test for the above scenario, the second patch is the actual fix. Cheers, Roderich
Index: subversion/tests/cmdline/authz_tests.py =================================================================== --- subversion/tests/cmdline/authz_tests.py (revision 929632) +++ subversion/tests/cmdline/authz_tests.py (working copy) @@ -903,7 +903,43 @@ root_url + '/A-copy/B/E/beta', root_url + '/A-copy/C') +def authz_access_required_at_repo_root2(sbox): + "more authz issue #3242 - update to renamed file" + sbox.build(create_wc = False) + root_url = sbox.repo_url + + # Now we get all restrictive. + write_authz_file(sbox, {'/': '* =', + '/A': 'jrandom = rw'}) + write_restrictive_svnserve_conf(sbox.repo_dir) + + # Rename a file. + svntest.main.run_svn(None, 'mv', + '-m', 'rename file in readable writable space', + root_url + '/A/B/E/alpha', + root_url + '/A/B/E/alpha-renamed') + + # Check out original greek sub tree below /A/B/E + # and update it to the above rename. + wc_dir = sbox.add_wc_path('ABE') + os.mkdir(wc_dir) + svntest.main.run_svn(None, 'co', '-r', '1', root_url + '/A/B/E', wc_dir) + svntest.main.run_svn(None, 'up', wc_dir) + + # Rename a directory. + svntest.main.run_svn(None, 'mv', + '-m', 'rename diretory in readable writable space', + root_url + '/A/D/H', + root_url + '/A/D/a g e') + + # Check out original greek sub tree below /A/D + # and update it to the above rename. + wc_dir = sbox.add_wc_path('AD') + os.mkdir(wc_dir) + svntest.main.run_svn(None, 'co', '-r', '1', root_url + '/A/D', wc_dir) + svntest.main.run_svn(None, 'up', wc_dir) + def multiple_matches(sbox): "multiple lines matching a user" @@ -962,6 +998,8 @@ svntest.main.is_ra_type_file)), Skip(authz_access_required_at_repo_root, svntest.main.is_ra_type_file), + Skip(authz_access_required_at_repo_root2, + svntest.main.is_ra_type_file), Skip(multiple_matches, svntest.main.is_ra_type_file), ]
Index: subversion/libsvn_client/update.c =================================================================== --- subversion/libsvn_client/update.c (revision 929632) +++ subversion/libsvn_client/update.c (working copy) @@ -68,13 +68,22 @@ apr_pool_t *pool) { struct ff_baton *ffb = (struct ff_baton *)baton; + const char *dirpath, *base_name, *session_url, *old_session_url; - if (! ffb->session) - SVN_ERR(svn_client__open_ra_session_internal(&(ffb->session), - ffb->repos_root, - NULL, NULL, FALSE, TRUE, - ffb->ctx, ffb->pool)); - return svn_ra_get_file(ffb->session, path, revision, stream, + svn_relpath_split(path, &dirpath, &base_name, ffb->pool); + session_url = svn_path_url_add_component2(ffb->repos_root, + dirpath, ffb->pool); + + if (ffb->session) + SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ffb->session, + session_url, ffb->pool)); + else + SVN_ERR(svn_client__open_ra_session_internal(&(ffb->session), + session_url, + NULL, NULL, FALSE, TRUE, + ffb->ctx, ffb->pool)); + + return svn_ra_get_file(ffb->session, base_name, revision, stream, fetched_rev, props, pool); }