Use the repository name in mod_authz_svn if configured with SVNParentPath,
so that we can control access to repositories, which seems more useful
to me.  Normally nothing changes for those who use SNVPath.
* subversion/mod_dav_svn/repos.c, subversion/include/mod_dav_svn.h,
    (dav_svn_split_uri): extra output parameter authz_path
* subversion/mod_authz_svn/mod_authz_svn.c
    (check_access): renamed "repos_path" param to "authz_path"
    (auth_checker): use authz_path instead of repos_path
I tested the change with release 0.27.0.  It applies also to rev 6772.
This diff is against rev 6772.
Didn't I break anything?
JH
(Replies from non-spammers are welcome at jhatala at wanadoo dot fr.)
Index: subversion/mod_authz_svn/mod_authz_svn.c
===================================================================
--- subversion/mod_authz_svn/mod_authz_svn.c	(revision 6772)
+++ subversion/mod_authz_svn/mod_authz_svn.c	(working copy)
@@ -146,13 +146,13 @@
 }
 
 static int check_access(svn_config_t *cfg,
-                        const char *repos_path, const char *user,
+                        const char *authz_path, const char *user,
                         int required_access, apr_pool_t *pool)
 {
     const char *base_name;
     struct parse_authz_line_baton baton = { 0 };
 
-    if (!repos_path) {
+    if (!authz_path) {
         /* XXX: Check if the user has 'required_access' _anywhere_ in the
          * XXX: repository.  For now, make this always succeed, until
          * XXX: we come up with a good way of figuring this out.
@@ -164,10 +164,10 @@
     baton.config = cfg;
     baton.user = user;
 
-    svn_config_enumerate(cfg, repos_path,
+    svn_config_enumerate(cfg, authz_path,
                          parse_authz_line, &baton);
 
-    base_name = repos_path;
+    base_name = authz_path;
     while (!(baton.deny & required_access)
            && !(baton.allow & required_access)) {
         if (base_name[0] == '/' && base_name[1] == '\0') {
@@ -175,8 +175,8 @@
             return 0;
         }
 
-        svn_path_split(repos_path, &repos_path, &base_name, pool);
-        svn_config_enumerate(cfg, repos_path,
+        svn_path_split(authz_path, &authz_path, &base_name, pool);
+        svn_config_enumerate(cfg, authz_path,
                              parse_authz_line, &baton);
     }
 
@@ -202,8 +202,10 @@
     int trailing_slash;
     const char *repos_name;
     const char *relative_path;
-    const char *repos_path;
+    const char *repos_path = NULL;
+    const char *authz_path = NULL;
     const char *dest_repos_path = NULL;
+    const char *dest_authz_path = NULL;
     dav_error *dav_err;
     int authz_svn_type;
     svn_config_t *access_conf = NULL;
@@ -248,7 +250,8 @@
                                 &trailing_slash,
                                 &repos_name,
                                 &relative_path,
-                                &repos_path);
+                                &repos_path,
+                                &authz_path);
     if (dav_err) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                       "%s  [%d, #%d]",
@@ -256,9 +259,6 @@
         return HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    if (repos_path)
-        repos_path = svn_path_join("/", repos_path, r->pool);
-
     svn_err = svn_config_read(&access_conf, conf->access_file, FALSE, r->pool);
     if (svn_err) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, svn_err->apr_err, r,
@@ -268,12 +268,12 @@
     }
 
     if (!check_access(access_conf,
-                      repos_path, r->user, authz_svn_type,
+                      authz_path, r->user, authz_svn_type,
                       r->pool)) {
         if (conf->authoritative) {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                 "Access denied: '%s' %s %s",
-                r->user, r->method, repos_path);
+                r->user, r->method, authz_path);
             ap_note_auth_failure(r);
             return HTTP_UNAUTHORIZED;
         }
@@ -282,7 +282,7 @@
     }
     
     /* XXX: DELETE, MOVE, MKCOL and PUT, if the path doesn't exist yet, also
-     * XXX: require write access to the parent dir of repos_path.
+     * XXX: require write access to the parent dir of authz_path.
      */
 
     /* Only MOVE and COPY have a second uri we have to check access to. */
@@ -292,7 +292,7 @@
             return DECLINED;
 
         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
-            "Access granted: '%s' %s %s", r->user, r->method, repos_path);
+            "Access granted: '%s' %s %s", r->user, r->method, authz_path);
         return OK;
     }
 
@@ -323,7 +323,8 @@
                                 &trailing_slash,
                                 &repos_name,
                                 &relative_path,
-                                &dest_repos_path);
+                                &dest_repos_path,
+                                &dest_authz_path);
 
     if (dav_err) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
@@ -332,25 +333,22 @@
         return HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    if (dest_repos_path)
-        dest_repos_path = svn_path_join("/", dest_repos_path, r->pool);
-
-    /* Check access on the first repos_path */
+    /* Check access on the first authz_path */
     if (!check_access(access_conf,
-                      dest_repos_path, r->user, AUTHZ_SVN_WRITE,
+                      dest_authz_path, r->user, AUTHZ_SVN_WRITE,
                       r->pool)) {
         if (!conf->authoritative)
             return DECLINED;
 
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
             "Access denied: '%s' %s %s %s",
-            r->user, r->method, repos_path, dest_repos_path);
+            r->user, r->method, authz_path, dest_authz_path);
         ap_note_auth_failure(r);
         return HTTP_UNAUTHORIZED;
     }
 
     /* XXX: MOVE and COPY, if the path doesn't exist yet, also
-     * XXX: require write access to the parent dir of dest_repos_path.
+     * XXX: require write access to the parent dir of dest_authz_path.
      */
 
     if (status == DECLINED)
@@ -358,7 +356,7 @@
 
     ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
         "Access granted: '%s' %s %s %s",
-        r->user, r->method, repos_path, dest_repos_path);
+        r->user, r->method, authz_path, dest_authz_path);
     return OK;
 }
 
Index: subversion/include/mod_dav_svn.h
===================================================================
--- subversion/include/mod_dav_svn.h	(revision 6772)
+++ subversion/include/mod_dav_svn.h	(working copy)
@@ -450,6 +450,10 @@
                       the repository.  (e.g. "!svn/vcc/default" or
                       "!svn/bln/25")
 
+   * AUTHZ_PATH:      The path in the repository filesystem, but "relative"
+                      to SVNPath or SVNParentPath (whichever was used),
+                      so that mod_authz_svn is useful in both cases.
+                      Starts with a slash!
 
    So for example, consider the uri
 
@@ -464,6 +468,15 @@
      * RELATIVE_PATH:  /!svn/blah/13/A/B/alpha
      * REPOS_PATH:     A/B/alpha
      * TRAILING_SLASH: FALSE
+
+   In the SVNPath case we'll have:
+
+     * AUTHZ_PATH:     /A/B/alpha
+
+   In the SVNParentPath case we'll have:
+
+     * AUTHZ_PATH:     /proj1/A/B/alpha
+
 */
 AP_MODULE_DECLARE(dav_error *)
        dav_svn_split_uri (request_rec *r,
@@ -473,7 +486,8 @@
                           int *trailing_slash,
                           const char **repos_name,
                           const char **relative_path,
-                          const char **repos_path);
+                          const char **repos_path,
+                          const char **authz_path);
 
 
 
Index: subversion/mod_dav_svn/repos.c
===================================================================
--- subversion/mod_dav_svn/repos.c	(revision 6772)
+++ subversion/mod_dav_svn/repos.c	(working copy)
@@ -806,6 +806,11 @@
 }
 
 
+/* JH: authz_path is the path relative SVNRoot or SVNParentRoot:
+   = /repos_path if SVNRoot is used, or
+   = /repos_name/repos_path if SVNParentRoot is used
+   it can be NULL if one of the ingredients is NULL
+*/
 AP_MODULE_DECLARE(dav_error *)
 dav_svn_split_uri (request_rec *r,
                    const char *uri_to_split,
@@ -814,7 +819,8 @@
                    int *trailing_slash,
                    const char **repos_name,
                    const char **relative_path,
-                   const char **repos_path)
+                   const char **repos_path,
+                   const char **authz_path)
 {
   apr_size_t len1;
   int had_slash;
@@ -1056,6 +1062,38 @@
       }    
   }
 
+  {
+    char *apath = NULL;
+    int len;
+
+    if (fs_parent_path == NULL)
+      {
+        if (*repos_path != NULL)
+          apath = apr_pstrcat(r->pool, "/", *repos_path, NULL);
+      }
+    else
+      {
+        if (*repos_name != NULL || *repos_path != NULL)
+          apath = apr_pstrcat(r->pool, "/", *repos_name, "/", *repos_path, NULL);
+      }
+
+    if (apath != NULL)
+      {
+        int len = strlen(apath);
+
+        // the path is supposed to be cannonical
+        while(len > 1 && apath[len-1] == '/')
+          {
+            --len;
+            apath[len] = 0;
+          }
+        if (len == 0)
+            apath = "/";
+      }
+
+    *authz_path = apath;
+  }
+  
   return NULL;
 }
 
@@ -1076,6 +1114,7 @@
   const char *repos_name;
   const char *relative;
   const char *repos_path;
+  const char *authz_path;
   const char *repos_key;
   const char *version_name;
   svn_error_t *serr;
@@ -1088,7 +1127,7 @@
   /* This does all the work of interpreting/splitting the request uri. */
   err = dav_svn_split_uri (r, r->uri, root_path,
                            &cleaned_uri, &had_slash, 
-                           &repos_name, &relative, &repos_path);
+                           &repos_name, &relative, &repos_path, &authz_path);
   if (err)
     return err;
 
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Aug 18 07:02:10 2003