(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: