(This doesn't appear to have come through to the list after a day, so
I'm resending it from a different MUA.)

On 01/11/10 15:56, Philip Martin wrote:

> The name should be AuthzSVNReposRelativeAccessFile for consistency with
> SVNReposName.
> 
> It should be an error to specify both AuthzSVNAccessFile and
> AuthzSVNReposRelativeAccessFile similar to SVNPath/SVNParentPath.
> 
> Perhaps it should be a path rather than a boolean?

I've addressed all these comments, including this one to convert the
argument to be a path rather than a boolean.

New patch is:

[[[
Implement AuthzSVNReposRelativeAccessFile 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 AuthzSVNReposRelativeAccessFile is used,
  and if so, load the 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
  AuthzSVNReposRelativeAccessFile is used.
  (AuthzSVNAccessFile_cmd, AuthzSVNReposRelativeAccessFile_cmd):
  Introduce functions to ensure AuthzSVNAccessFile and
  AuthzSVNReposRelativeAccessFile are not used at the same time.
]]]

Regards,

 Nick

Index: subversion/mod_authz_svn/mod_authz_svn.c
===================================================================
--- subversion/mod_authz_svn/mod_authz_svn.c	(revision 1030029)
+++ subversion/mod_authz_svn/mod_authz_svn.c	(working copy)
@@ -52,6 +52,7 @@
   int no_auth_when_anon_ok;
   const char *base_path;
   const char *access_file;
+  const char *repo_relative_access_file;
   const char *force_username_case;
 } authz_svn_config_rec;
 
@@ -76,6 +77,33 @@
   return conf;
 }
 
+static const char *
+AuthzSVNAccessFile_cmd(cmd_parms *cmd, void *config, const char *arg1)
+{
+  authz_svn_config_rec *conf = config;
+
+  if (conf->repo_relative_access_file != NULL)
+    return "AuthzSVNAccessFile cannot be defined at same time as AuthzSVNReposRelativeAccessFile.";
+
+  conf->access_file = ap_server_root_relative(cmd->pool, arg1);
+
+  return NULL;
+}
+
+
+static const char *
+AuthzSVNReposRelativeAccessFile_cmd(cmd_parms *cmd, void *config, const char *arg1)
+{
+  authz_svn_config_rec *conf = config;
+
+  if (conf->access_file != NULL)
+    return "AuthzSVNReposRelativeAccessFile cannot be defined at same time as AuthzSVNAccessFile.";
+
+  conf->repo_relative_access_file = arg1;
+
+  return NULL;
+}
+
 /* Implements the #cmds member of Apache's #module vtable. */
 static const command_rec authz_svn_cmds[] =
 {
@@ -84,10 +112,15 @@
                OR_AUTHCFG,
                "Set to 'Off' to allow access control to be passed along to "
                "lower modules. (default is On.)"),
-  AP_INIT_TAKE1("AuthzSVNAccessFile", ap_set_file_slot,
-                (void *)APR_OFFSETOF(authz_svn_config_rec, access_file),
+  AP_INIT_TAKE1("AuthzSVNAccessFile", AuthzSVNAccessFile_cmd,
+                NULL,
                 OR_AUTHCFG,
-                "Text file containing permissions of repository paths."),
+                "Path to text file containing permissions of repository paths."),
+  AP_INIT_TAKE1("AuthzSVNReposRelativeAccessFile", AuthzSVNReposRelativeAccessFile_cmd,
+		NULL,
+		OR_AUTHCFG,
+                "Path (relative to repository 'conf' directory) to text "
+		"file containing permissions of repository paths. "),
   AP_INIT_FLAG("AuthzSVNAnonymous", ap_set_flag_slot,
                (void *)APR_OFFSETOF(authz_svn_config_rec, anonymous),
                OR_AUTHCFG,
@@ -119,18 +152,37 @@
 get_access_conf(request_rec *r, authz_svn_config_rec *conf)
 {
   const char *cache_key = NULL;
+  const char *access_file;
+  const char *repos_path;
   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 = svn_dirent_join_many(r->pool, repos_path, "conf", conf->repo_relative_access_file, 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 +568,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 +632,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 +690,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 +717,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 1030029)
+++ 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
+
+           AuthzSVNReposRelativeAccessFile authz
+
+           Require valid-user
+         </Location>
+
+         NOTE: AuthzSVNReposRelativeAccessFile filename causes the authz file
+         to be read from <repo path>/conf/<filename>
+
    2. Specifying permissions
 
       The file format of the access file looks like this:

Reply via email to