Dear Subversion maintainers,

We would like to avoid having to mention each of our subversion
repositories inside an Apache configuration, so we use SVNParentPath.

However, this currently means we can only use a single authz
configuration file. We'd like to be able to have a different file for
each repository, to increase isolation.

We've implemented a patch that allows this, by introducing a new
Apache configuration directive:

      D. Example 4: Per-repository access file

         This configuration allows to use SVNParentPath but have
         different authz files per repository.

         <Location /svn>
           DAV svn
           SVNParentPath /path/to/reposparent

           AuthType Basic
           AuthName "Subversion repository"
           AuthUserFile /path/to/htpasswd/file

           AuthzSVNRepoRelativeAccessFile on

           Require valid-user
         </Location>

         NOTE: AuthzSVNRepoRelativeAccessFile on causes the authz file
         to be read from /path/to/reposparent/<repo>/conf/authz

Is this something that might be included in subversion?

[[[
Implement AuthzSVNRepoRelativeAccessFile to allow SVNParentPath to use
a different authz configuration file for each repository.

* subversion/mod_authz_svn/mod_authz_svn.c
  (get_access_conf) Check if AuthzSVNRepoRelativeAccessFile is on, and
  if so, load the conf/authz file from inside the repository being
  accessed rather than one which is statically configured in the
  Apache configuration.
  (subreq_bypass, access_checker, check_user_id, auth_checker)
  Recognise that it's valid not to have a AuthzSVNAccessFile if
  AuthzSVNRepoRelativeAccessFile is used.
]]]

-- 
Nick Piper MEng MIET RHCE| #define Joint Lead Architect
250 Brook Drive, Green Park, Reading RG2 6UA | United Kingdom
nick.pi...@logica.com | www.logica.com 
Logica UK Limited, registered in England & Wales (registered number 947968)
Registered Office: 250 Brook Drive, Green Park, Reading RG2 6UA, United Kingdom 

Index: subversion/mod_authz_svn/mod_authz_svn.c
===================================================================
--- subversion/mod_authz_svn/mod_authz_svn.c	(revision 1028364)
+++ subversion/mod_authz_svn/mod_authz_svn.c	(working copy)
@@ -50,6 +50,7 @@
   int authoritative;
   int anonymous;
   int no_auth_when_anon_ok;
+  int repo_relative_access_file;
   const char *base_path;
   const char *access_file;
   const char *force_username_case;
@@ -103,6 +104,13 @@
                "Set to 'On' to suppress authentication and authorization "
                "for requests which anonymous users are allowed to perform. "
                "(default is Off.)"),
+  AP_INIT_FLAG("AuthzSVNRepoRelativeAccessFile", ap_set_flag_slot,
+	       (void *)APR_OFFSETOF(authz_svn_config_rec,
+				    repo_relative_access_file),
+	       OR_AUTHCFG,
+	       "Set to 'On' to allow the AuthzSVNAccessFile to be relative "
+	       "to the repository disk path. "
+	       "(default is Off.)"),
   AP_INIT_TAKE1("AuthzForceUsernameCase", ap_set_string_slot,
                 (void *)APR_OFFSETOF(authz_svn_config_rec,
                                      force_username_case),
@@ -119,18 +127,34 @@
 get_access_conf(request_rec *r, authz_svn_config_rec *conf)
 {
   const char *cache_key = NULL;
+  const char *access_file = NULL;
+  const char *repos_path = NULL;
   void *user_data = NULL;
   svn_authz_t *access_conf = NULL;
   svn_error_t *svn_err;
+  dav_error *dav_err;
   char errbuf[256];
 
+  if (conf->repo_relative_access_file) {
+    dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_path);
+    if (dav_err) {
+      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, dav_err->desc);
+      return NULL;
+    }
+    access_file = apr_pstrcat(r->pool, repos_path, "/conf/authz", NULL);
+  } else {
+    access_file = conf->access_file;
+  }
+
+  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Path to authz file is %s", access_file);
+
   cache_key = apr_pstrcat(r->pool, "mod_authz_svn:",
-                          conf->access_file, (char *)NULL);
+                          access_file, (char *)NULL);
   apr_pool_userdata_get(&user_data, cache_key, r->connection->pool);
   access_conf = user_data;
   if (access_conf == NULL)
     {
-      svn_err = svn_repos_authz_read(&access_conf, conf->access_file,
+      svn_err = svn_repos_authz_read(&access_conf, access_file,
                                      TRUE, r->connection->pool);
       if (svn_err)
         {
@@ -516,7 +540,7 @@
   username_to_authorize = get_username_to_authorize(r, conf);
 
   /* If configured properly, this should never be true, but just in case. */
-  if (!conf->anonymous || !conf->access_file)
+  if (!conf->anonymous || !conf->access_file || !conf->repo_relative_access_file)
     {
       log_access_verdict(APLOG_MARK, r, 0, repos_path, NULL);
       return HTTP_FORBIDDEN;
@@ -580,7 +604,7 @@
   int status;
 
   /* We are not configured to run */
-  if (!conf->anonymous || !conf->access_file)
+  if (!conf->anonymous || ( !conf->access_file && !conf->repo_relative_access_file))
     return DECLINED;
 
   if (ap_some_auth_required(r))
@@ -638,7 +662,7 @@
 
   /* We are not configured to run, or, an earlier module has already
    * authenticated this request. */
-  if (!conf->access_file || !conf->no_auth_when_anon_ok || r->user)
+  if ((!conf->access_file && !conf->repo_relative_access_file) || !conf->no_auth_when_anon_ok || r->user)
     return DECLINED;
 
   /* If anon access is allowed, return OK, preventing later modules
@@ -665,7 +689,7 @@
   int status;
 
   /* We are not configured to run */
-  if (!conf->access_file)
+  if (!conf->access_file && !conf->repo_relative_access_file)
     return DECLINED;
 
   /* Previous hook (check_user_id) already did all the work,
Index: subversion/mod_authz_svn/INSTALL
===================================================================
--- subversion/mod_authz_svn/INSTALL	(revision 1028364)
+++ subversion/mod_authz_svn/INSTALL	(working copy)
@@ -79,7 +79,27 @@
          though AuthzSVNAnonymous was set to 'No'.  The AuthzSVNAnonymous
          directive prevents the anonymous access check from being run.
 
+      D. Example 4: Per-repository access file
 
+         This configuration allows to use SVNParentPath but have
+         different authz files per repository.
+
+         <Location /svn>
+           DAV svn
+           SVNParentPath /path/to/reposparent
+
+           AuthType Basic
+           AuthName "Subversion repository"
+           AuthUserFile /path/to/htpasswd/file
+
+           AuthzSVNRepoRelativeAccessFile on
+
+           Require valid-user
+         </Location>
+
+         NOTE: AuthzSVNRepoRelativeAccessFile on causes the authz file
+         to be read from /path/to/reposparent/<repo>/conf/authz
+
    2. Specifying permissions
 
       The file format of the access file looks like this:

Reply via email to