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