View | Details | Raw Unified | Return to bug 48130
Collapse All | Expand All

(-)httpd-2.2.21.orig/modules/dav/fs/repos.c (-24 / +37 lines)
Lines 81-86 typedef struct { Link Here
81
    const dav_resource *root;
81
    const dav_resource *root;
82
    apr_pool_t *pool;
82
    apr_pool_t *pool;
83
83
84
    /* scratch pool, cleared for each element in the walk */
85
    apr_pool_t *scratchpool;
86
84
} dav_fs_copymove_walk_ctx;
87
} dav_fs_copymove_walk_ctx;
85
88
86
/* an internal WALKTYPE to walk hidden files (the .DAV directory) */
89
/* an internal WALKTYPE to walk hidden files (the .DAV directory) */
Lines 309-318 static void dav_format_time(int style, a Link Here
309
312
310
/* Copy or move src to dst; src_finfo is used to propagate permissions
313
/* Copy or move src to dst; src_finfo is used to propagate permissions
311
 * bits across if non-NULL; dst_finfo must be non-NULL iff dst already
314
 * bits across if non-NULL; dst_finfo must be non-NULL iff dst already
312
 * exists. */
315
 * exists. The pool *sp is a scratch pool cleaned after each call to this
316
 * function while *rp is a pool that lives as much as the request. */
313
static dav_error * dav_fs_copymove_file(
317
static dav_error * dav_fs_copymove_file(
314
    int is_move,
318
    int is_move,
315
    apr_pool_t * p,
319
    apr_pool_t * sp,
320
    apr_pool_t * rp,
316
    const char *src,
321
    const char *src,
317
    const char *dst,
322
    const char *dst,
318
    const apr_finfo_t *src_finfo,
323
    const apr_finfo_t *src_finfo,
Lines 320-332 static dav_error * dav_fs_copymove_file( Link Here
320
    dav_buffer *pbuf)
325
    dav_buffer *pbuf)
321
{
326
{
322
    dav_buffer work_buf = { 0 };
327
    dav_buffer work_buf = { 0 };
328
    apr_pool_t *bp;
323
    apr_file_t *inf = NULL;
329
    apr_file_t *inf = NULL;
324
    apr_file_t *outf = NULL;
330
    apr_file_t *outf = NULL;
325
    apr_status_t status;
331
    apr_status_t status;
326
    apr_fileperms_t perms;
332
    apr_fileperms_t perms;
327
333
328
    if (pbuf == NULL)
334
    if (pbuf == NULL) {
329
        pbuf = &work_buf;
335
        pbuf = &work_buf;
336
        bp = sp;
337
    } else {
338
        bp = rp;
339
    }
330
340
331
    /* Determine permissions to use for destination */
341
    /* Determine permissions to use for destination */
332
    if (src_finfo && src_finfo->valid & APR_FINFO_PROT
342
    if (src_finfo && src_finfo->valid & APR_FINFO_PROT
Lines 336-342 static dav_error * dav_fs_copymove_file( Link Here
336
        if (dst_finfo != NULL) {
346
        if (dst_finfo != NULL) {
337
            /* chmod it if it already exist */
347
            /* chmod it if it already exist */
338
            if (apr_file_perms_set(dst, perms)) {
348
            if (apr_file_perms_set(dst, perms)) {
339
                return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
349
                return dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
340
                                     "Could not set permissions on destination");
350
                                     "Could not set permissions on destination");
341
            }
351
            }
342
        }
352
        }
Lines 345-366 static dav_error * dav_fs_copymove_file( Link Here
345
        perms = APR_OS_DEFAULT;
355
        perms = APR_OS_DEFAULT;
346
    }
356
    }
347
357
348
    dav_set_bufsize(p, pbuf, DAV_FS_COPY_BLOCKSIZE);
358
    dav_set_bufsize(bp, pbuf, DAV_FS_COPY_BLOCKSIZE);
349
359
350
    if ((apr_file_open(&inf, src, APR_READ | APR_BINARY, APR_OS_DEFAULT, p))
360
    if ((apr_file_open(&inf, src, APR_READ | APR_BINARY, APR_OS_DEFAULT, sp))
351
            != APR_SUCCESS) {
361
            != APR_SUCCESS) {
352
        /* ### use something besides 500? */
362
        /* ### use something besides 500? */
353
        return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
363
        return dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
354
                             "Could not open file for reading");
364
                             "Could not open file for reading");
355
    }
365
    }
356
366
357
    /* ### do we need to deal with the umask? */
367
    /* ### do we need to deal with the umask? */
358
    status = apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE
368
    status = apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE
359
                           | APR_BINARY, perms, p);
369
                           | APR_BINARY, perms, sp);
360
    if (status != APR_SUCCESS) {
370
    if (status != APR_SUCCESS) {
361
        apr_file_close(inf);
371
        apr_file_close(inf);
362
372
363
        return dav_new_error(p, MAP_IO2HTTP(status), 0,
373
        return dav_new_error(rp, MAP_IO2HTTP(status), 0,
364
                             "Could not open file for writing");
374
                             "Could not open file for writing");
365
    }
375
    }
366
376
Lines 372-389 static dav_error * dav_fs_copymove_file( Link Here
372
            apr_file_close(inf);
382
            apr_file_close(inf);
373
            apr_file_close(outf);
383
            apr_file_close(outf);
374
384
375
            if (apr_file_remove(dst, p) != APR_SUCCESS) {
385
            if (apr_file_remove(dst, sp) != APR_SUCCESS) {
376
                /* ### ACK! Inconsistent state... */
386
                /* ### ACK! Inconsistent state... */
377
387
378
                /* ### use something besides 500? */
388
                /* ### use something besides 500? */
379
                return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
389
                return dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
380
                                     "Could not delete output after read "
390
                                     "Could not delete output after read "
381
                                     "failure. Server is now in an "
391
                                     "failure. Server is now in an "
382
                                     "inconsistent state.");
392
                                     "inconsistent state.");
383
            }
393
            }
384
394
385
            /* ### use something besides 500? */
395
            /* ### use something besides 500? */
386
            return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
396
            return dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
387
                                 "Could not read input file");
397
                                 "Could not read input file");
388
        }
398
        }
389
399
Lines 396-412 static dav_error * dav_fs_copymove_file( Link Here
396
            apr_file_close(inf);
406
            apr_file_close(inf);
397
            apr_file_close(outf);
407
            apr_file_close(outf);
398
408
399
            if (apr_file_remove(dst, p) != APR_SUCCESS) {
409
            if (apr_file_remove(dst, sp) != APR_SUCCESS) {
400
                /* ### ACK! Inconsistent state... */
410
                /* ### ACK! Inconsistent state... */
401
411
402
                /* ### use something besides 500? */
412
                /* ### use something besides 500? */
403
                return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
413
                return dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
404
                                     "Could not delete output after write "
414
                                     "Could not delete output after write "
405
                                     "failure. Server is now in an "
415
                                     "failure. Server is now in an "
406
                                     "inconsistent state.");
416
                                     "inconsistent state.");
407
            }
417
            }
408
418
409
            return dav_new_error(p, MAP_IO2HTTP(status), 0,
419
            return dav_new_error(rp, MAP_IO2HTTP(status), 0,
410
                                 "Could not write output file");
420
                                 "Could not write output file");
411
        }
421
        }
412
    }
422
    }
Lines 414-436 static dav_error * dav_fs_copymove_file( Link Here
414
    apr_file_close(inf);
424
    apr_file_close(inf);
415
    apr_file_close(outf);
425
    apr_file_close(outf);
416
426
417
    if (is_move && apr_file_remove(src, p) != APR_SUCCESS) {
427
    if (is_move && apr_file_remove(src, sp) != APR_SUCCESS) {
418
        dav_error *err;
428
        dav_error *err;
419
        int save_errno = errno;   /* save the errno that got us here */
429
        int save_errno = errno;   /* save the errno that got us here */
420
430
421
        if (apr_file_remove(dst, p) != APR_SUCCESS) {
431
        if (apr_file_remove(dst, sp) != APR_SUCCESS) {
422
            /* ### ACK. this creates an inconsistency. do more!? */
432
            /* ### ACK. this creates an inconsistency. do more!? */
423
433
424
            /* ### use something besides 500? */
434
            /* ### use something besides 500? */
425
            /* Note that we use the latest errno */
435
            /* Note that we use the latest errno */
426
            return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
436
            return dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
427
                                 "Could not remove source or destination "
437
                                 "Could not remove source or destination "
428
                                 "file. Server is now in an inconsistent "
438
                                 "file. Server is now in an inconsistent "
429
                                 "state.");
439
                                 "state.");
430
        }
440
        }
431
441
432
        /* ### use something besides 500? */
442
        /* ### use something besides 500? */
433
        err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
443
        err = dav_new_error(rp, HTTP_INTERNAL_SERVER_ERROR, 0,
434
                            "Could not remove source file after move. "
444
                            "Could not remove source file after move. "
435
                            "Destination was removed to ensure consistency.");
445
                            "Destination was removed to ensure consistency.");
436
        err->save_errno = save_errno;
446
        err->save_errno = save_errno;
Lines 511-517 static dav_error * dav_fs_copymove_state Link Here
511
    else
521
    else
512
    {
522
    {
513
        /* gotta copy (and delete) */
523
        /* gotta copy (and delete) */
514
        return dav_fs_copymove_file(is_move, p, src, dst, NULL, NULL, pbuf);
524
        return dav_fs_copymove_file(is_move, p, p, src, dst, NULL, NULL, pbuf);
515
    }
525
    }
516
526
517
    return NULL;
527
    return NULL;
Lines 1047-1064 static dav_error * dav_fs_copymove_walke Link Here
1047
    dav_resource_private *dstinfo = ctx->res_dst->info;
1057
    dav_resource_private *dstinfo = ctx->res_dst->info;
1048
    dav_error *err = NULL;
1058
    dav_error *err = NULL;
1049
1059
1060
    apr_pool_clear(ctx->scratchpool);
1061
1050
    if (wres->resource->collection) {
1062
    if (wres->resource->collection) {
1051
        if (calltype == DAV_CALLTYPE_POSTFIX) {
1063
        if (calltype == DAV_CALLTYPE_POSTFIX) {
1052
            /* Postfix call for MOVE. delete the source dir.
1064
            /* Postfix call for MOVE. delete the source dir.
1053
             * Note: when copying, we do not enable the postfix-traversal.
1065
             * Note: when copying, we do not enable the postfix-traversal.
1054
             */
1066
             */
1055
            /* ### we are ignoring any error here; what should we do? */
1067
            /* ### we are ignoring any error here; what should we do? */
1056
            (void) apr_dir_remove(srcinfo->pathname, ctx->pool);
1068
            (void) apr_dir_remove(srcinfo->pathname, ctx->scratchpool);
1057
        }
1069
        }
1058
        else {
1070
        else {
1059
            /* copy/move of a collection. Create the new, target collection */
1071
            /* copy/move of a collection. Create the new, target collection */
1060
            if (apr_dir_make(dstinfo->pathname, APR_OS_DEFAULT,
1072
            if (apr_dir_make(dstinfo->pathname, APR_OS_DEFAULT,
1061
                             ctx->pool) != APR_SUCCESS) {
1073
                             ctx->scratchpool) != APR_SUCCESS) {
1062
                /* ### assume it was a permissions problem */
1074
                /* ### assume it was a permissions problem */
1063
                /* ### need a description here */
1075
                /* ### need a description here */
1064
                err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL);
1076
                err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL);
Lines 1066-1072 static dav_error * dav_fs_copymove_walke Link Here
1066
        }
1078
        }
1067
    }
1079
    }
1068
    else {
1080
    else {
1069
        err = dav_fs_copymove_file(ctx->is_move, ctx->pool,
1081
        err = dav_fs_copymove_file(ctx->is_move, ctx->scratchpool, ctx->pool,
1070
                                   srcinfo->pathname, dstinfo->pathname,
1082
                                   srcinfo->pathname, dstinfo->pathname,
1071
                                   &srcinfo->finfo,
1083
                                   &srcinfo->finfo,
1072
                                   ctx->res_dst->exists ? &dstinfo->finfo : NULL,
1084
                                   ctx->res_dst->exists ? &dstinfo->finfo : NULL,
Lines 1149-1155 static dav_error *dav_fs_copymove_resour Link Here
1149
    }
1161
    }
1150
1162
1151
    /* not a collection */
1163
    /* not a collection */
1152
    if ((err = dav_fs_copymove_file(is_move, src->info->pool,
1164
    if ((err = dav_fs_copymove_file(is_move, src->info->pool, src->info->pool,
1153
                                    src->info->pathname, dst->info->pathname,
1165
                                    src->info->pathname, dst->info->pathname,
1154
                                    &src->info->finfo,
1166
                                    &src->info->finfo,
1155
                                    dst->exists ? &dst->info->finfo : NULL,
1167
                                    dst->exists ? &dst->info->finfo : NULL,
Lines 1730-1735 static dav_error * dav_fs_internal_walk( Link Here
1730
        cm_ctx.res_dst = &fsctx.res2;
1742
        cm_ctx.res_dst = &fsctx.res2;
1731
        cm_ctx.root = params->root;
1743
        cm_ctx.root = params->root;
1732
        cm_ctx.pool = params->pool;
1744
        cm_ctx.pool = params->pool;
1745
        apr_pool_create(&cm_ctx.scratchpool, cm_ctx.pool);
1733
1746
1734
        fsctx.res2 = *root_dst;
1747
        fsctx.res2 = *root_dst;
1735
        fsctx.res2.exists = 0;
1748
        fsctx.res2.exists = 0;

Return to bug 48130