
Changes to mod_dav to use the privilege separated file io functions

Index: modules/dav/fs/repos.c
===================================================================
--- modules/dav/fs/repos.c	(revision 602639)
+++ modules/dav/fs/repos.c	(working copy)
@@ -46,6 +46,7 @@
     apr_pool_t *pool;        /* memory storage pool associated with request */
     const char *pathname;   /* full pathname to resource */
     apr_finfo_t finfo;       /* filesystem info */
+    request_rec *r;
 };
 
 /* private context for doing a filesystem walk */
@@ -181,6 +182,7 @@
     apr_pool_t *p;
     apr_file_t *f;
     const char *pathname;       /* we may need to remove it at close time */
+    request_rec *r;
 };
 
 /* returns an appropriate HTTP status code given an APR status code for a
@@ -307,7 +309,8 @@
     const char *dst,
     const apr_finfo_t *src_finfo,
     const apr_finfo_t *dst_finfo,
-    dav_buffer *pbuf)
+    dav_buffer *pbuf,
+    request_rec *r)
 {
     dav_buffer work_buf = { 0 };
     apr_file_t *inf = NULL;
@@ -325,7 +328,7 @@
 
         if (dst_finfo != NULL) {
             /* chmod it if it already exist */
-            if (apr_file_perms_set(dst, perms)) {
+            if (ap_privsep_file_perms_set(ap_privsep_token(r), dst, perms)) {
                 return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                      "Could not set permissions on destination");
             }
@@ -337,7 +340,8 @@
 
     dav_set_bufsize(p, pbuf, DAV_FS_COPY_BLOCKSIZE);
 
-    if ((apr_file_open(&inf, src, APR_READ | APR_BINARY, APR_OS_DEFAULT, p))
+    if ((ap_privsep_file_open(ap_privsep_token(r), &inf, src,
+			      APR_READ | APR_BINARY, APR_OS_DEFAULT, p))
             != APR_SUCCESS) {
         /* ### use something besides 500? */
         return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
@@ -345,7 +349,7 @@
     }
 
     /* ### do we need to deal with the umask? */
-    status = apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE
+    status = ap_privsep_file_open(ap_privsep_token(r), &outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE
                            | APR_BINARY, perms, p);
     if (status != APR_SUCCESS) {
         apr_file_close(inf);
@@ -362,7 +366,7 @@
             apr_file_close(inf);
             apr_file_close(outf);
 
-            if (apr_file_remove(dst, p) != APR_SUCCESS) {
+            if (ap_privsep_file_remove(ap_privsep_token(r), dst, p) != APR_SUCCESS) {
                 /* ### ACK! Inconsistent state... */
 
                 /* ### use something besides 500? */
@@ -386,7 +390,7 @@
             apr_file_close(inf);
             apr_file_close(outf);
 
-            if (apr_file_remove(dst, p) != APR_SUCCESS) {
+            if (ap_privsep_file_remove(ap_privsep_token(r), dst, p) != APR_SUCCESS) {
                 /* ### ACK! Inconsistent state... */
 
                 /* ### use something besides 500? */
@@ -404,11 +408,11 @@
     apr_file_close(inf);
     apr_file_close(outf);
 
-    if (is_move && apr_file_remove(src, p) != APR_SUCCESS) {
+    if (is_move && ap_privsep_file_remove(ap_privsep_token(r), src, p) != APR_SUCCESS) {
         dav_error *err;
         int save_errno = errno;   /* save the errno that got us here */
 
-        if (apr_file_remove(dst, p) != APR_SUCCESS) {
+        if (ap_privsep_file_remove(ap_privsep_token(r), dst, p) != APR_SUCCESS) {
             /* ### ACK. this creates an inconsistency. do more!? */
 
             /* ### use something besides 500? */
@@ -437,7 +441,8 @@
     apr_pool_t * p,
     const char *src_dir, const char *src_file,
     const char *dst_dir, const char *dst_file,
-    dav_buffer *pbuf)
+    dav_buffer *pbuf,
+    request_rec *r)
 {
     apr_finfo_t src_finfo;        /* finfo for source file */
     apr_finfo_t dst_state_finfo;        /* finfo for STATE directory */
@@ -449,7 +454,7 @@
     src = apr_pstrcat(p, src_dir, "/" DAV_FS_STATE_DIR "/", src_file, NULL);
 
     /* the source file doesn't exist */
-    rv = apr_stat(&src_finfo, src, APR_FINFO_NORM, p);
+    rv = ap_privsep_stat(ap_privsep_token(r), &src_finfo, src, APR_FINFO_NORM, p);
     if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
         return NULL;
     }
@@ -460,7 +465,7 @@
     /* ### do we need to deal with the umask? */
 
     /* ensure that it exists */
-    rv = apr_dir_make(dst, APR_OS_DEFAULT, p);
+    rv = ap_privsep_dir_make(ap_privsep_token(r), dst, APR_OS_DEFAULT, p);
     if (rv != APR_SUCCESS) {
         if (!APR_STATUS_IS_EEXIST(rv)) {
             /* ### use something besides 500? */
@@ -470,7 +475,7 @@
     }
 
     /* get info about the state directory */
-    rv = apr_stat(&dst_state_finfo, dst, APR_FINFO_NORM, p);
+    rv = ap_privsep_stat(ap_privsep_token(r), &dst_state_finfo, dst, APR_FINFO_NORM, p);
     if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
         /* Ack! Where'd it go? */
         /* ### use something besides 500? */
@@ -492,7 +497,7 @@
     /* copy/move the file now */
     if (is_move && src_finfo.device == dst_state_finfo.device) {
         /* simple rename is possible since it is on the same device */
-        if (apr_file_rename(src, dst, p) != APR_SUCCESS) {
+        if (ap_privsep_file_rename(ap_privsep_token(r), src, dst, p) != APR_SUCCESS) {
             /* ### use something besides 500? */
             return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                  "Could not move state file.");
@@ -501,7 +506,7 @@
     else
     {
         /* gotta copy (and delete) */
-        return dav_fs_copymove_file(is_move, p, src, dst, NULL, NULL, pbuf);
+        return dav_fs_copymove_file(is_move, p, src, dst, NULL, NULL, pbuf, r);
     }
 
     return NULL;
@@ -542,13 +547,13 @@
     err = dav_fs_copymove_state(is_move, p,
                                 src_dir, src_state1,
                                 dst_dir, dst_state1,
-                                pbuf);
+                                pbuf, src->info->r);
 
     if (err == NULL && src_state2 != NULL) {
         err = dav_fs_copymove_state(is_move, p,
                                     src_dir, src_state2,
                                     dst_dir, dst_state2,
-                                    pbuf);
+                                    pbuf, src->info->r);
 
         if (err != NULL) {
             /* ### CRAP. inconsistency. */
@@ -588,7 +593,7 @@
                           NULL);
 
     /* note: we may get ENOENT if the state dir is not present */
-    if ((status = apr_file_remove(pathname, p)) != APR_SUCCESS
+    if ((status = ap_privsep_file_remove(ap_privsep_token(resource->info->r), pathname, p)) != APR_SUCCESS
         && !APR_STATUS_IS_ENOENT(status)) {
         return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
                              "Could not remove properties.");
@@ -602,7 +607,7 @@
                               state2,
                               NULL);
 
-        if ((status = apr_file_remove(pathname, p)) != APR_SUCCESS
+        if ((status = ap_privsep_file_remove(ap_privsep_token(resource->info->r), pathname, p)) != APR_SUCCESS
             && !APR_STATUS_IS_ENOENT(status)) {
             /* ### CRAP. only removed half. */
             return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
@@ -638,6 +643,7 @@
     /* Create private resource context descriptor */
     ctx = apr_pcalloc(r->pool, sizeof(*ctx));
     ctx->finfo = r->finfo;
+    ctx->r = r;
 
     /* ### this should go away */
     ctx->pool = r->pool;
@@ -760,6 +766,7 @@
 
     /* Create private resource context descriptor */
     parent_ctx = apr_pcalloc(ctx->pool, sizeof(*parent_ctx));
+    parent_ctx->r = ctx->r;
 
     /* ### this should go away */
     parent_ctx->pool = ctx->pool;
@@ -782,8 +789,9 @@
         parent_resource->uri = uri;
     }
 
-    rv = apr_stat(&parent_ctx->finfo, parent_ctx->pathname,
-                  APR_FINFO_NORM, ctx->pool);
+    rv = ap_privsep_stat(ap_privsep_token(ctx->r),
+			 &parent_ctx->finfo, parent_ctx->pathname,
+			 APR_FINFO_NORM, ctx->pool);
     if (rv == APR_SUCCESS || rv == APR_INCOMPLETE) {
         parent_resource->exists = 1;
     }
@@ -837,6 +845,7 @@
 {
     apr_pool_t *p = resource->info->pool;
     dav_stream *ds = apr_pcalloc(p, sizeof(*ds));
+    ds->r = resource->info->r;
     apr_int32_t flags;
     apr_status_t rv;
 
@@ -855,7 +864,9 @@
 
     ds->p = p;
     ds->pathname = resource->info->pathname;
-    rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
+    rv = ap_privsep_file_open(ap_privsep_token(resource->info->r),
+			      &ds->f, ds->pathname, flags,
+			      APR_OS_DEFAULT, ds->p);
     if (rv != APR_SUCCESS) {
         return dav_new_error(p, MAP_IO2HTTP(rv), 0,
                              "An error occurred while opening a resource.");
@@ -872,7 +883,8 @@
     apr_file_close(stream->f);
 
     if (!commit) {
-        if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
+	if (ap_privsep_file_remove(ap_privsep_token(stream->r),
+				   stream->pathname, stream->p) != APR_SUCCESS) {
             /* ### use a better description? */
             return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                  "There was a problem removing (rolling "
@@ -971,9 +983,10 @@
                              "collection.");
     }
 
-    if ((status = apr_file_open(&fd, resource->info->pathname,
-                                APR_READ | APR_BINARY, 0,
-                                pool)) != APR_SUCCESS) {
+    if ((status = ap_privsep_file_open(ap_privsep_token(r),
+				       &fd, resource->info->pathname,
+				       APR_READ | APR_BINARY, 0,
+				       pool)) != APR_SUCCESS) {
         return dav_new_error(pool, HTTP_FORBIDDEN, 0,
                              "File permissions deny server access.");
     }
@@ -1001,7 +1014,8 @@
     dav_resource_private *ctx = resource->info;
     apr_status_t status;
 
-    status = apr_dir_make(ctx->pathname, APR_OS_DEFAULT, ctx->pool);
+    status = ap_privsep_dir_make(ap_privsep_token(resource->info->r),
+				 ctx->pathname, APR_OS_DEFAULT, ctx->pool);
     if (APR_STATUS_IS_ENOSPC(status)) {
         return dav_new_error(ctx->pool, HTTP_INSUFFICIENT_STORAGE, 0,
                              "There is not enough storage to create "
@@ -1039,12 +1053,14 @@
              * Note: when copying, we do not enable the postfix-traversal.
              */
             /* ### we are ignoring any error here; what should we do? */
-            (void) apr_dir_remove(srcinfo->pathname, ctx->pool);
+            (void) ap_privsep_dir_remove(ap_privsep_token(srcinfo->r),
+					 srcinfo->pathname, ctx->pool);
         }
         else {
             /* copy/move of a collection. Create the new, target collection */
-            if (apr_dir_make(dstinfo->pathname, APR_OS_DEFAULT,
-                             ctx->pool) != APR_SUCCESS) {
+            if (ap_privsep_dir_make(ap_privsep_token(srcinfo->r),
+				    dstinfo->pathname, APR_OS_DEFAULT,
+				    ctx->pool) != APR_SUCCESS) {
                 /* ### assume it was a permissions problem */
                 /* ### need a description here */
                 err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL);
@@ -1056,7 +1072,7 @@
                                    srcinfo->pathname, dstinfo->pathname,
                                    &srcinfo->finfo,
                                    ctx->res_dst->exists ? &dstinfo->finfo : NULL,
-                                   &ctx->work_buf);
+                                   &ctx->work_buf, srcinfo->r);
         /* ### push a higher-level description? */
     }
 
@@ -1139,7 +1155,7 @@
                                     src->info->pathname, dst->info->pathname,
                                     &src->info->finfo,
                                     dst->exists ? &dst->info->finfo : NULL,
-                                    &work_buf)) != NULL) {
+                                    &work_buf, src->info->r)) != NULL) {
         /* ### push a higher-level description? */
         return err;
     }
@@ -1224,7 +1240,8 @@
          * Really need a try and failover for those platforms.
          *
          */
-        rv = apr_stat(&finfo, dirpath, APR_FINFO_DEV, dstinfo->pool);
+        rv = ap_privsep_stat(ap_privsep_token(src->info->r),
+			     &finfo, dirpath, APR_FINFO_DEV, dstinfo->pool);
         if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE)
             && (finfo.valid & srcinfo->finfo.valid & APR_FINFO_DEV)
             && (finfo.device == srcinfo->finfo.device)) {
@@ -1252,8 +1269,9 @@
     *response = NULL;
 
     /* ### APR has no rename? */
-    if (apr_file_rename(srcinfo->pathname, dstinfo->pathname,
-                       srcinfo->pool) != APR_SUCCESS) {
+    if (ap_privsep_file_rename(ap_privsep_token(srcinfo->r),
+			       srcinfo->pathname, dstinfo->pathname,
+			       srcinfo->pool) != APR_SUCCESS) {
         /* ### should have a better error than this. */
         return dav_new_error(srcinfo->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                              "Could not rename resource.");
@@ -1272,8 +1290,9 @@
     }
 
     /* error occurred during properties move; try to put resource back */
-    if (apr_file_rename(dstinfo->pathname, srcinfo->pathname,
-                       srcinfo->pool) != APR_SUCCESS) {
+    if (ap_privsep_file_rename(ap_privsep_token(dstinfo->r),
+			       dstinfo->pathname, srcinfo->pathname,
+			       srcinfo->pool) != APR_SUCCESS) {
         /* couldn't put it back! */
         return dav_push_error(srcinfo->pool,
                               HTTP_INTERNAL_SERVER_ERROR, 0,
@@ -1316,8 +1335,10 @@
         apr_status_t result;
 
         result = wres->resource->collection
-            ? apr_dir_remove(info->pathname, wres->pool)
-            : apr_file_remove(info->pathname, wres->pool);
+            ? ap_privsep_dir_remove(ap_privsep_token(info->r),
+				    info->pathname, wres->pool)
+	    : ap_privsep_file_remove(ap_privsep_token(info->r),
+				     info->pathname, wres->pool);
 
         /*
         ** If an error occurred, then add it to multistatus response.
@@ -1380,7 +1401,8 @@
     }
 
     /* not a collection; remove the file and its properties */
-    if (apr_file_remove(info->pathname, info->pool) != APR_SUCCESS) {
+    if (ap_privsep_file_remove(ap_privsep_token(info->r),
+			       info->pathname, info->pool) != APR_SUCCESS) {
         /* ### put a description in here */
         return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL);
     }
@@ -1441,11 +1463,13 @@
     fsctx->res2.collection = 0;
 
     /* open and scan the directory */
-    if ((apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
+    if ((ap_privsep_dir_open(ap_privsep_token(fsctx->info1.r),
+			     &dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
         /* ### need a better error */
         return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
     }
-    while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
+    while ((ap_privsep_dir_read(ap_privsep_token(fsctx->info1.r),
+				&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
         apr_size_t len;
         apr_status_t status;
 
@@ -1477,8 +1501,9 @@
 
 
         /* ### Optimize me, dirent can give us what we need! */
-        status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,
-                          APR_FINFO_NORM | APR_FINFO_LINK, pool);
+        status = ap_privsep_stat(ap_privsep_token(fsctx->info1.r),
+				 &fsctx->info1.finfo, fsctx->path1.buf,
+				 APR_FINFO_NORM | APR_FINFO_LINK, pool);
         if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
             /* woah! where'd it go? */
             /* ### should have a better error here */
@@ -2017,7 +2042,8 @@
     if (value)
         perms |= APR_UEXECUTE;
 
-    if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) {
+    if (ap_privsep_file_perms_set(ap_privsep_token(resource->info->r),
+				  resource->info->pathname, perms) != APR_SUCCESS) {
         return dav_new_error(resource->info->pool,
                              HTTP_INTERNAL_SERVER_ERROR, 0,
                              "Could not set the executable flag of the "
@@ -2053,7 +2079,8 @@
     if (value)
         perms |= APR_UEXECUTE;
 
-    if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) {
+    if (ap_privsep_file_perms_set(ap_privsep_token(resource->info->r),
+				  resource->info->pathname, perms) != APR_SUCCESS) {
         return dav_new_error(resource->info->pool,
                              HTTP_INTERNAL_SERVER_ERROR, 0,
                              "After a failure occurred, the resource's "

