You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Joe Orton <jo...@orton.demon.co.uk> on 2000/07/24 03:19:44 UTC
[PATCH] mod_dav: authorization checking for Depth > 1
This adds full authorization checking for Depth > 1 requests as per the
mod_dav 1.1 tree.
joe
Index: fs/repos.c
===================================================================
RCS file: /home/joe/lib/cvsroot/apache2/src/modules/dav/fs/repos.c,v
retrieving revision 1.15
diff -u -p -r1.15 repos.c
--- repos.c 2000/07/15 02:07:21 1.15
+++ repos.c 2000/07/24 01:13:28
@@ -1316,10 +1316,9 @@ static dav_error * dav_fs_walker(dav_fs_
}
if (wctx->walk_type & DAV_WALKTYPE_AUTH) {
- /* ### need to authorize each file */
- /* ### example: .htaccess is normally configured to fail auth */
-
- /* stuff in the state directory is never authorized! */
+ /* authorize properly after we have worked out the URI for
+ * this resource: stuff in the state directory is never
+ * authorized! */
if (!strcmp(name, DAV_FS_STATE_DIR)) {
continue;
}
@@ -1355,6 +1354,25 @@ static dav_error * dav_fs_walker(dav_fs_
/* set up the URI for the current resource */
fsctx->res1.uri = wctx->uri.buf;
+
+ if (wctx->walk_type & DAV_WALKTYPE_AUTH) {
+ request_rec *subr;
+
+ /* check authorization for new resource, using apropriate method */
+ subr = ap_sub_req_method_uri(wctx->r->method, wctx->uri.buf, wctx->r);
+ /* we're only interested in the status */
+ wctx->status = subr->status;
+ ap_destroy_sub_req(subr);
+
+ if (wctx->status != HTTP_OK) {
+ /* signal the error */
+ if ((err = (*wctx->func)(wctx, DAV_CALLTYPE_ERROR)) != NULL)
+ return err;
+
+ /* otherwise, skip to the next member resource */
+ continue;
+ }
+ }
/* ### for now, only process regular files (e.g. skip symlinks) */
if (fsctx->info1.finfo.filetype == APR_REG) {
Index: main/mod_dav.c
===================================================================
RCS file: /home/joe/lib/cvsroot/apache2/src/modules/dav/main/mod_dav.c,v
retrieving revision 1.14
diff -u -p -r1.14 mod_dav.c
--- mod_dav.c 2000/07/17 05:17:02 1.14
+++ mod_dav.c 2000/07/24 01:13:50
@@ -1418,6 +1418,11 @@ static dav_error * dav_propfind_walker(d
dav_propdb *propdb;
dav_get_props_result propstats = { 0 };
+ if (calltype == DAV_CALLTYPE_ERROR) {
+ dav_add_response(ctx, ctx->uri.buf, ctx->status, NULL);
+ return NULL;
+ }
+
/*
** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since
** dav_get_allprops() does not need to do namespace translation,
@@ -2176,29 +2181,29 @@ static int dav_method_copymove(request_r
}
/*
- ** Check If-Headers and existing locks for each resource in the source
- ** if we are performing a MOVE. We will return a 424 response with a
- ** DAV:multistatus body. The multistatus responses will contain the
- ** information about any resource that fails the validation.
+ ** Check If-Headers and existing locks for each resource in the source.
+ ** We will return a 424 response with a DAV:multistatus body. The
+ ** multistatus responses will contain the information about any
+ ** resource that fails the validation.
**
- ** We check the parent resource, too, since this is a MOVE. Moving the
+ ** We check the parent resource, too, if this is a MOVE. Moving the
** resource effectively removes it from the parent collection, so we
** must ensure that we have met the appropriate conditions.
**
** If a problem occurs with the Request-URI itself, then a plain error
** (rather than a multistatus) will be returned.
*/
- if (is_move
- && (err = dav_validate_request(r, resource, depth, NULL,
- &multi_response,
- DAV_VALIDATE_PARENT
- | DAV_VALIDATE_USE_424,
- NULL)) != NULL) {
+ if ((err = dav_validate_request(r, resource, depth, NULL,
+ &multi_response,
+ (is_move?DAV_VALIDATE_PARENT:
+ DAV_VALIDATE_READONLY)
+ | DAV_VALIDATE_USE_424,
+ NULL)) != NULL) {
err = dav_push_error(r->pool, err->status, 0,
ap_psprintf(r->pool,
- "Could not MOVE %s due to a failed "
+ "Could not %s %s due to a failed "
"precondition on the source "
- "(e.g. locks).",
+ "(e.g. locks).", r->method,
ap_escape_html(r->pool, r->uri)),
err);
return dav_handle_err(r, err, multi_response);
Index: main/mod_dav.h
===================================================================
RCS file: /home/joe/lib/cvsroot/apache2/src/modules/dav/main/mod_dav.h,v
retrieving revision 1.13
diff -u -p -r1.13 mod_dav.h
--- mod_dav.h 2000/07/10 07:49:48 1.13
+++ mod_dav.h 2000/07/24 01:13:54
@@ -843,6 +843,8 @@ dav_error * dav_validate_request(request
the 424 DAV:response */
#define DAV_VALIDATE_USE_424 0x0080 /* return 424 status, not 207 */
#define DAV_VALIDATE_IS_PARENT 0x0100 /* for internal use */
+#define DAV_VALIDATE_READONLY 0x0200 /* validate for read access only
+ (e.g. source of COPY) */
/* Lock-null related public lock functions */
int dav_get_resource_state(request_rec *r, const dav_resource *resource);
@@ -1168,6 +1170,8 @@ typedef struct dav_walker_ctx
#define DAV_CALLTYPE_COLLECTION 2 /* called for a collection */
#define DAV_CALLTYPE_LOCKNULL 3 /* called for a locknull resource */
#define DAV_CALLTYPE_POSTFIX 4 /* postfix call for a collection */
+#define DAV_CALLTYPE_ERROR 5 /* called for an error
+ (e.g. unauthorized) */
ap_pool_t *pool;
@@ -1201,6 +1205,9 @@ typedef struct dav_walker_ctx
int skip_root; /* for dav_inherit_locks() */
int flags;
+
+ /* the status-code for error calltype */
+ int status;
dav_walker_private *info; /* for use by repository manager */
Index: main/util.c
===================================================================
RCS file: /home/joe/lib/cvsroot/apache2/src/modules/dav/main/util.c,v
retrieving revision 1.5
diff -u -p -r1.5 util.c
--- util.c 2000/07/03 22:51:01 1.5
+++ util.c 2000/07/24 01:13:57
@@ -759,9 +759,12 @@ static dav_error * dav_validate_resource
** pretending that we've already met the requirement of seeing one
** of the resource's locks in the If: header.
**
+ ** Ditto if we have only need read access to the resource.
+ **
** Otherwise, it must be cleared and we'll look for one.
*/
- seen_locktoken = (lock_list == NULL);
+ seen_locktoken = (lock_list == NULL) ||
+ ((flags & DAV_VALIDATE_READONLY) == DAV_VALIDATE_READONLY);
}
/*
@@ -1179,6 +1182,11 @@ static dav_error * dav_validate_walker(d
{
dav_error *err;
+ if (calltype == DAV_CALLTYPE_ERROR) {
+ dav_add_response(ctx, ctx->uri.buf, ctx->status, NULL);
+ return NULL;
+ }
+
if ((err = dav_validate_resource_state(ctx->pool, ctx->resource,
ctx->lockdb,
ctx->if_header, ctx->flags,
@@ -1305,7 +1313,7 @@ dav_error * dav_validate_request(request
if (resource->exists && depth > 0) {
dav_walker_ctx ctx = { 0 };
- ctx.walk_type = DAV_WALKTYPE_ALL;
+ ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_AUTH;
ctx.postfix = 0;
ctx.func = dav_validate_walker;
ctx.pool = r->pool;
Index: main/util_lock.c
===================================================================
RCS file: /home/joe/lib/cvsroot/apache2/src/modules/dav/main/util_lock.c,v
retrieving revision 1.5
diff -u -p -r1.5 util_lock.c
--- util_lock.c 2000/07/07 10:38:23 1.5
+++ util_lock.c 2000/07/24 01:14:02
@@ -354,7 +354,7 @@ dav_error * dav_add_lock(request_rec *r,
/* Walk existing collection and set indirect locks */
dav_walker_ctx ctx = { 0 };
- ctx.walk_type = DAV_WALKTYPE_ALL | DAV_WALKTYPE_AUTH;
+ ctx.walk_type = DAV_WALKTYPE_ALL;
ctx.postfix = 0;
ctx.func = dav_lock_walker;
ctx.pool = r->pool;