diff --git a/subversion/include/svn_repos.h b/subversion/include/svn_repos.h
index 7242d29..7350b05 100644
--- a/subversion/include/svn_repos.h
+++ b/subversion/include/svn_repos.h
@@ -2246,6 +2246,7 @@ svn_repos_authz_check_access(svn_authz_t *authz, const char *repos_name,
                              const char *path, const char *user,
                              svn_repos_authz_access_t required_access,
                              svn_boolean_t *access_granted,
+			     svn_fs_root_t * repos_p,
                              apr_pool_t *pool);
 
 
diff --git a/subversion/libsvn_repos/authz.c b/subversion/libsvn_repos/authz.c
index 94cdb9e..79cad78 100644
--- a/subversion/libsvn_repos/authz.c
+++ b/subversion/libsvn_repos/authz.c
@@ -257,6 +257,9 @@ authz_parse_line(const char *name, const char *value,
 {
   struct authz_lookup_baton *b = baton;
 
+  if (*name == ' ') /* This is the line number entry, skip it. */
+    return TRUE;
+
   /* Stop if the rule doesn't apply to this user. */
   if (!authz_line_applies_to_user(name, b, pool))
     return TRUE;
@@ -320,41 +323,6 @@ authz_parse_glob_sections(const char *section_name, void *baton,
 }
 
 
-/* Callback to parse a section and update the authz_baton if the
- * section denies access to the subtree the baton describes.
- */
-static svn_boolean_t
-authz_parse_section(const char *section_name, void *baton, apr_pool_t *pool)
-{
-  struct authz_lookup_baton *b = baton;
-  svn_boolean_t conclusive;
-
-  /* Does the section apply to us? */
-  if (svn_path_is_ancestor(b->qualified_repos_path,
-                           section_name) == FALSE
-      && svn_path_is_ancestor(b->repos_path,
-                              section_name) == FALSE)
-    return TRUE;
-
-  /* Work out what this section grants. */
-  b->allow = b->deny = 0;
-  svn_config_enumerate2(b->config, section_name,
-                        authz_parse_line, b, pool);
-
-  /* Has the section explicitly determined an access? */
-  conclusive = authz_access_is_determined(b->allow, b->deny,
-                                          b->required_access);
-
-  /* Is access granted OR inconclusive? */
-  b->access = authz_access_is_granted(b->allow, b->deny,
-                                      b->required_access)
-    || !conclusive;
-
-  /* As long as access isn't conclusively denied, carry on. */
-  return b->access;
-}
-
-
 /* Validate access to the given user for the given path.  This
  * function checks rules for exactly the given path, and first tries
  * to access a section specific to the given repository before falling
@@ -401,6 +369,49 @@ authz_get_path_access(svn_config_t *cfg, const char *repos_name,
                                     required_access);
 }
 
+/* Data for a tree walk */
+struct tree_walk_baton {
+  const char * name;
+  svn_boolean_t is_dir;
+};
+
+/* Walks the repository, starting from the entries in pending_walk
+ * and returns the first child in a breadth first walk.
+ */
+static const char *
+walk_tree(svn_fs_root_t *fs_root, apr_array_header_t ** pending_walk,
+	  apr_pool_t * pool)
+{
+  struct tree_walk_baton * twb;
+  struct tree_walk_baton * tmp_baton;
+  apr_array_header_t * tmp_array;
+  apr_hash_t * tmp_hash;
+  svn_fs_dirent_t * dir_entry;
+  apr_hash_index_t * hi;
+
+  if (apr_is_empty_array(*pending_walk))
+      return NULL;
+
+  twb = apr_array_pop(*pending_walk);
+
+  if (twb->is_dir) {
+    svn_fs_dir_entries(&tmp_hash, fs_root, twb->name, pool);
+
+    tmp_array = apr_array_make(pool, apr_hash_count(tmp_hash), 
+			       sizeof(struct tree_walk_baton));
+
+    for (hi = apr_hash_first(pool, tmp_hash); hi; hi = apr_hash_next(hi)) {
+      apr_hash_this(hi, NULL, NULL, (void*) &dir_entry);
+      tmp_baton = apr_array_push(tmp_array);
+      tmp_baton->name = apr_psprintf(pool, "%s/%s", twb->name, dir_entry->name);
+      tmp_baton->is_dir = (dir_entry->kind == svn_node_dir);
+    }
+
+    *pending_walk = apr_array_append(pool, *pending_walk, tmp_array);
+  }
+
+  return twb->name;
+}
 
 /* Validate access to the given user for the subtree starting at the
  * given path.  This function walks the whole authz file in search of
@@ -414,23 +425,41 @@ static svn_boolean_t
 authz_get_tree_access(svn_config_t *cfg, const char *repos_name,
                       const char *path, const char *user,
                       svn_repos_authz_access_t required_access,
+		      svn_fs_root_t * fs_root,
                       apr_pool_t *pool)
 {
-  struct authz_lookup_baton baton = { 0 };
+  const char * child_path;
+  svn_boolean_t access_granted = TRUE;
+  svn_boolean_t path_is_dir;
+  struct tree_walk_baton * twb;
+  apr_array_header_t * pending_walk;
 
-  baton.config = cfg;
-  baton.user = user;
-  baton.required_access = required_access;
-  baton.repos_path = path;
-  baton.qualified_repos_path = apr_pstrcat(pool, repos_name,
-                                           ":", path, NULL);
-  /* Default to access granted if no rules say otherwise. */
-  baton.access = TRUE;
+  /* put children of path in pending_walk */
+  svn_fs_is_dir(&path_is_dir, fs_root, path, pool);
 
-  svn_config_enumerate_sections2(cfg, authz_parse_section,
-                                 &baton, pool);
+  if (!path_is_dir) /* Nowhere to recurse into! */
+    return TRUE;
 
-  return baton.access;
+  pending_walk = apr_array_make(pool, 1, sizeof(struct tree_walk_baton));
+  twb = apr_array_push(pending_walk);
+  twb->name = path;
+  twb->is_dir = TRUE;
+
+  /* Walk the tree once, to start the loop from the children of path */
+  walk_tree(fs_root, &pending_walk, pool);
+  
+  while ( (child_path = walk_tree(fs_root, &pending_walk, pool))
+	  != NULL ) 
+    {
+      svn_boolean_t determined = authz_get_path_access(cfg, repos_name, child_path,
+						       user, required_access,
+						       &access_granted, pool);
+      
+      if (determined && ! access_granted)
+	return FALSE;
+    }
+
+  return TRUE;
 }
 
 
@@ -805,9 +834,11 @@ svn_repos_authz_check_access(svn_authz_t *authz, const char *repos_name,
                              const char *path, const char *user,
                              svn_repos_authz_access_t required_access,
                              svn_boolean_t *access_granted,
+			     svn_fs_root_t * fs_root,
                              apr_pool_t *pool)
 {
   const char *current_path = path;
+  apr_pool_t * recurse_pool;
 
   /* If PATH is NULL, do a global access lookup. */
   if (!path)
@@ -841,9 +872,12 @@ svn_repos_authz_check_access(svn_authz_t *authz, const char *repos_name,
   /* If the caller requested recursive access, we need to walk through
      the entire authz config to see whether any child paths are denied
      to the requested user. */
+  apr_pool_create(&recurse_pool, pool);
   if (*access_granted && (required_access & svn_authz_recursive))
     *access_granted = authz_get_tree_access(authz->cfg, repos_name, path,
-                                            user, required_access, pool);
+                                            user, required_access, 
+					    fs_root, recurse_pool);
+  apr_pool_destroy(recurse_pool);
 
   return SVN_NO_ERROR;
 }
diff --git a/subversion/mod_authz_svn/mod_authz_svn.c b/subversion/mod_authz_svn/mod_authz_svn.c
index 0ab73fa..bb4d9a2 100644
--- a/subversion/mod_authz_svn/mod_authz_svn.c
+++ b/subversion/mod_authz_svn/mod_authz_svn.c
@@ -165,6 +165,11 @@ static int req_check_access(request_rec *r,
     svn_boolean_t authz_access_granted = FALSE;
     svn_authz_t *access_conf = NULL;
     svn_error_t *svn_err;
+    const char * repos_fs_path;
+    svn_repos_t *repos_p = NULL;
+    svn_fs_t * fs;
+    svn_fs_root_t *fs_root;
+    svn_revnum_t current_rev;
     char errbuf[256];
 
     switch (r->method_number) {
@@ -310,10 +315,46 @@ static int req_check_access(request_rec *r,
     if (repos_path
         || (!repos_path && (authz_svn_type & svn_authz_write)))
       {
+	if (authz_svn_type & svn_authz_recursive) 
+	  {
+	    dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_fs_path);
+	    if (dav_err) {
+	      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+			    "%s  [%d, #%d]",
+			    dav_err->desc, dav_err->status, dav_err->error_id);
+	      /* Ensure that we never allow access by dav_err->status */
+	      return (dav_err->status != OK && dav_err->status != DECLINED) ?
+		dav_err->status : HTTP_INTERNAL_SERVER_ERROR;
+	    }
+
+	    svn_err = svn_repos_open(&repos_p, repos_fs_path, r->pool);
+	    fs = svn_repos_fs(repos_p);
+	    svn_fs_youngest_rev(&current_rev, fs, r->pool);
+	    svn_fs_revision_root(&fs_root, fs, current_rev, r->pool);
+
+	    if (svn_err) {
+	      ap_log_rerror(APLOG_MARK, APLOG_ERR,
+			    /* If it is an error code that APR can make
+			       sense of, then show it, otherwise, pass
+			       zero to avoid putting "APR does not
+			       understand this error code" in the error
+			       log. */
+			    ((svn_err->apr_err >= APR_OS_START_USERERR &&
+			      svn_err->apr_err < APR_OS_START_CANONERR) ?
+			     0 : svn_err->apr_err),
+			    r, "Failed to perform access control: %s",
+			    svn_err_best_message(svn_err, errbuf, sizeof(errbuf)));
+	      svn_error_clear(svn_err);
+	      
+	      return DECLINED;
+	    }
+	  }
+
         svn_err = svn_repos_authz_check_access(access_conf, repos_name,
                                                repos_path, r->user,
                                                authz_svn_type,
                                                &authz_access_granted,
+					       fs_root,
                                                r->pool);
         if (svn_err) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR,
@@ -354,6 +395,41 @@ static int req_check_access(request_rec *r,
        repos_path == NULL (see above for explanations) */
     if (repos_path)
       {
+	if ( repos_p == NULL) 
+	  {
+	    dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_fs_path);
+	    if (dav_err) {
+	      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+			    "%s  [%d, #%d]",
+			    dav_err->desc, dav_err->status, dav_err->error_id);
+	      /* Ensure that we never allow access by dav_err->status */
+	      return (dav_err->status != OK && dav_err->status != DECLINED) ?
+		dav_err->status : HTTP_INTERNAL_SERVER_ERROR;
+	    }
+
+	    svn_err = svn_repos_open(&repos_p, repos_fs_path, r->pool);
+	    fs = svn_repos_fs(repos_p);
+	    svn_fs_youngest_rev(&current_rev, fs, r->pool);
+	    svn_fs_revision_root(&fs_root, fs, current_rev, r->pool);
+
+	    if (svn_err) {
+	      ap_log_rerror(APLOG_MARK, APLOG_ERR,
+			    /* If it is an error code that APR can make
+			       sense of, then show it, otherwise, pass
+			       zero to avoid putting "APR does not
+			       understand this error code" in the error
+			       log. */
+			    ((svn_err->apr_err >= APR_OS_START_USERERR &&
+			      svn_err->apr_err < APR_OS_START_CANONERR) ?
+			     0 : svn_err->apr_err),
+			    r, "Failed to perform access control: %s",
+			    svn_err_best_message(svn_err, errbuf, sizeof(errbuf)));
+	      svn_error_clear(svn_err);
+	      
+	      return DECLINED;
+	    }
+	  }
+
         svn_err = svn_repos_authz_check_access(access_conf,
                                                dest_repos_name,
                                                dest_repos_path,
@@ -361,6 +437,7 @@ static int req_check_access(request_rec *r,
                                                svn_authz_write
                                                |svn_authz_recursive,
                                                &authz_access_granted,
+					       fs_root,
                                                r->pool);
         if (svn_err) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR,
@@ -464,6 +541,7 @@ static int subreq_bypass(request_rec *r,
                                                repos_path, r->user,
                                                svn_authz_none|svn_authz_read,
                                                &authz_access_granted,
+					       NULL,
                                                r->pool);
         if (svn_err) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR,
diff --git a/subversion/svnserve/serve.c b/subversion/svnserve/serve.c
index ee076b3..e5ce316 100644
--- a/subversion/svnserve/serve.c
+++ b/subversion/svnserve/serve.c
@@ -158,6 +158,9 @@ static svn_error_t *authz_check_access(svn_boolean_t *allowed,
                                        server_baton_t *b,
                                        apr_pool_t *pool)
 {
+  svn_fs_root_t *fs_root;
+  svn_revnum_t current_rev;
+
   /* If authz cannot be performed, grant access.  This is NOT the same
      as the default policy when authz is performed on a path with no
      rules.  In the latter case, the default is to deny access, and is
@@ -177,9 +180,12 @@ static svn_error_t *authz_check_access(svn_boolean_t *allowed,
   if (path && *path != '/')
     path = svn_path_join("/", path, pool);
 
+  svn_fs_youngest_rev(&current_rev, b->fs, pool);
+  svn_fs_revision_root(&fs_root, b->fs, current_rev, pool);
+
   return svn_repos_authz_check_access(b->authzdb, b->authz_repos_name,
                                       path, b->user, required,
-                                      allowed, pool);
+                                      allowed, fs_root, pool);
 }
 
 /* Set *ALLOWED to TRUE if PATH is readable by the user described in
diff --git a/subversion/tests/libsvn_repos/repos-test.c b/subversion/tests/libsvn_repos/repos-test.c
index 6bbd7e3..a24364a 100644
--- a/subversion/tests/libsvn_repos/repos-test.c
+++ b/subversion/tests/libsvn_repos/repos-test.c
@@ -1168,6 +1168,11 @@ authz(const char **msg,
       apr_pool_t *pool)
 {
   const char *contents;
+  svn_repos_t *repos;
+  svn_fs_t *fs;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *txn_root, *fs_root;
+  svn_revnum_t youngest_rev;
   svn_authz_t *authz_cfg;
   svn_error_t *err;
   svn_boolean_t access_granted;
@@ -1260,6 +1265,19 @@ authz(const char **msg,
   /* Load the test authz rules. */
   SVN_ERR(authz_get_handle(&authz_cfg, contents, subpool));
 
+  /* Create a filesystem and repository. */
+  SVN_ERR(svn_test__create_repos(&repos, "test-repo-authz",
+                                 opts->fs_type, subpool));
+  fs = svn_repos_fs(repos);
+
+  /* Prepare a txn to receive the greek tree. */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
+  SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, subpool));
+
+  svn_fs_revision_root(&fs_root, fs, youngest_rev, subpool);
+
   /* Loop over the test array and test each case. */
   for (i = 0; !(test_set[i].path == NULL
                && test_set[i].required == svn_authz_none); i++)
@@ -1268,7 +1286,7 @@ authz(const char **msg,
                                            test_set[i].path,
                                            test_set[i].user,
                                            test_set[i].required,
-                                           &access_granted, subpool));
+                                           &access_granted, fs_root, subpool));
 
       if (access_granted != test_set[i].expected)
         {
@@ -1342,7 +1360,7 @@ authz(const char **msg,
                                        "/dir", NULL,
                                        (svn_authz_read
                                         | svn_authz_recursive),
-                                       &access_granted, subpool));
+                                       &access_granted, fs_root, subpool));
   if (!access_granted)
     return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
                             "Regression: incomplete ancestry test "
@@ -1368,7 +1386,7 @@ commit_authz_cb(svn_repos_authz_access_t required,
   svn_authz_t *authz_file = baton;
 
   return svn_repos_authz_check_access(authz_file, "test", path,
-                                      "plato", required, allowed,
+                                      "plato", required, allowed, root,
                                       pool);
 }
 

