Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 390443
Collapse All | Expand All

(-)httpd-2.2.8/modules/dav/fs/repos.c (-10 / +16 lines)
Lines 46-51 Link Here
46
    apr_pool_t *pool;        /* memory storage pool associated with request */
46
    apr_pool_t *pool;        /* memory storage pool associated with request */
47
    const char *pathname;   /* full pathname to resource */
47
    const char *pathname;   /* full pathname to resource */
48
    apr_finfo_t finfo;       /* filesystem info */
48
    apr_finfo_t finfo;       /* filesystem info */
49
    request_rec *r;
49
};
50
};
50
51
51
/* private context for doing a filesystem walk */
52
/* private context for doing a filesystem walk */
Lines 200-205 Link Here
200
**
201
**
201
** PRIVATE REPOSITORY FUNCTIONS
202
** PRIVATE REPOSITORY FUNCTIONS
202
*/
203
*/
204
request_rec *dav_fs_get_request_rec(const dav_resource *resource)
205
{
206
    return resource->info->r;
207
}
208
203
apr_pool_t *dav_fs_pool(const dav_resource *resource)
209
apr_pool_t *dav_fs_pool(const dav_resource *resource)
204
{
210
{
205
    return resource->info->pool;
211
    return resource->info->pool;
Lines 638-643 Link Here
638
    /* Create private resource context descriptor */
644
    /* Create private resource context descriptor */
639
    ctx = apr_pcalloc(r->pool, sizeof(*ctx));
645
    ctx = apr_pcalloc(r->pool, sizeof(*ctx));
640
    ctx->finfo = r->finfo;
646
    ctx->finfo = r->finfo;
647
    ctx->r = r;
641
648
642
    /* ### this should go away */
649
    /* ### this should go away */
643
    ctx->pool = r->pool;
650
    ctx->pool = r->pool;
Lines 1775-1791 Link Here
1775
1782
1776
    if (!resource->exists)
1783
    if (!resource->exists)
1777
        return apr_pstrdup(ctx->pool, "");
1784
        return apr_pstrdup(ctx->pool, "");
1785
    {
1786
      	request_rec *r = ctx->r;
1778
1787
1779
    if (ctx->finfo.filetype != 0) {
1788
	r->mtime = ctx->finfo.mtime;
1780
        return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "-%"
1789
        r->finfo = ctx->finfo;
1781
                            APR_UINT64_T_HEX_FMT "-%" APR_UINT64_T_HEX_FMT "\"",
1790
      	return ap_make_etag(r, 0);
1782
                            (apr_uint64_t) ctx->finfo.inode,
1791
    } 	
1783
                            (apr_uint64_t) ctx->finfo.size,
1784
                            (apr_uint64_t) ctx->finfo.mtime);
1785
    }
1786
1787
    return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "\"",
1788
                       (apr_uint64_t) ctx->finfo.mtime);
1789
}
1792
}
1790
1793
1791
static const dav_hooks_repository dav_hooks_repository_fs =
1794
static const dav_hooks_repository dav_hooks_repository_fs =
Lines 1812-1817 Link Here
1812
    dav_fs_remove_resource,
1815
    dav_fs_remove_resource,
1813
    dav_fs_walk,
1816
    dav_fs_walk,
1814
    dav_fs_getetag,
1817
    dav_fs_getetag,
1818
    dav_fs_get_request_rec,
1819
    dav_fs_pathname,
1820
    NULL
1815
};
1821
};
1816
1822
1817
static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource,
1823
static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource,
(-)httpd-2.2.8/modules/dav/main/mod_dav.c (-35 / +188 lines)
Lines 57-62 Link Here
57
#include "http_request.h"
57
#include "http_request.h"
58
#include "util_script.h"
58
#include "util_script.h"
59
59
60
#include "ap_provider.h"
61
60
#include "mod_dav.h"
62
#include "mod_dav.h"
61
63
62
64
Lines 79-84 Link Here
79
    const char *dir;
81
    const char *dir;
80
    int locktimeout;
82
    int locktimeout;
81
    int allow_depthinfinity;
83
    int allow_depthinfinity;
84
    int acl_checking;
85
    int etag_response;  
82
86
83
} dav_dir_conf;
87
} dav_dir_conf;
84
88
Lines 195-204 Link Here
195
    newconf->dir = DAV_INHERIT_VALUE(parent, child, dir);
199
    newconf->dir = DAV_INHERIT_VALUE(parent, child, dir);
196
    newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child,
200
    newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child,
197
                                                     allow_depthinfinity);
201
                                                     allow_depthinfinity);
202
    newconf->acl_checking = DAV_INHERIT_VALUE(parent, child, acl_checking);
203
    newconf->etag_response = DAV_INHERIT_VALUE(parent, child, etag_response);
198
204
199
    return newconf;
205
    return newconf;
200
}
206
}
201
207
208
DAV_DECLARE(const char *) dav_get_provider_name(request_rec *r)
209
{
210
    dav_dir_conf *conf = ap_get_module_config(r->per_dir_config, &dav_module);
211
    return conf ? conf->provider_name : NULL;
212
}
213
202
static const dav_provider *dav_get_provider(request_rec *r)
214
static const dav_provider *dav_get_provider(request_rec *r)
203
{
215
{
204
    dav_dir_conf *conf;
216
    dav_dir_conf *conf;
Lines 287-292 Link Here
287
}
299
}
288
300
289
/*
301
/*
302
 * Command handler for the DAVACL directive, which is FLAG.
303
 */
304
static const char *dav_cmd_acl_checking(cmd_parms *cmd, void *config,
305
                                         int arg)
306
{
307
    dav_dir_conf *conf = (dav_dir_conf *)config;
308
309
    conf->acl_checking = arg;
310
    return NULL;
311
}
312
313
/*
314
 * Command handler for the DAVETagResponse directive, which is FLAG.
315
 */
316
static const char *dav_cmd_etag_response(cmd_parms *cmd, void *config,
317
                                         int arg)
318
{
319
    dav_dir_conf *conf = (dav_dir_conf *)config;
320
321
    conf->etag_response = arg;
322
    return NULL;
323
}
324
325
/*
290
 * Command handler for DAVMinTimeout directive, which is TAKE1
326
 * Command handler for DAVMinTimeout directive, which is TAKE1
291
 */
327
 */
292
static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config,
328
static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config,
Lines 361-378 Link Here
361
        ap_rputs(" xmlns:m=\"http://apache.org/dav/xmlns\"", r);
397
        ap_rputs(" xmlns:m=\"http://apache.org/dav/xmlns\"", r);
362
    }
398
    }
363
399
364
    if (err->namespace != NULL) {
400
    if (err->childtags) {
365
        ap_rprintf(r,
401
        if (err->namespace != NULL) {
366
                   " xmlns:C=\"%s\">" DEBUG_CR
402
            ap_rprintf(r,
367
                   "<C:%s/>" DEBUG_CR,
403
                       " xmlns:C=\"%s\">" DEBUG_CR
368
                   err->namespace, err->tagname);
404
                       "<C:%s>%s</C:%s>" DEBUG_CR,
369
    }
405
                        err->namespace, 
406
                        err->tagname, err->childtags, err->tagname);
407
        }
408
        else {
409
            ap_rprintf(r,
410
                       ">" DEBUG_CR
411
                       "<D:%s>%s<D:%s>" DEBUG_CR, 
412
                       err->tagname, err->childtags, err->tagname);
413
                        
414
        }
415
    } 
370
    else {
416
    else {
371
        ap_rprintf(r,
417
        if (err->namespace != NULL) {
372
                   ">" DEBUG_CR
418
            ap_rprintf(r,
373
                   "<D:%s/>" DEBUG_CR, err->tagname);
419
                       " xmlns:C=\"%s\">" DEBUG_CR
420
                       "<C:%s/>" DEBUG_CR,
421
                       err->namespace, err->tagname);
422
        }
423
        else {
424
            ap_rprintf(r,
425
                       ">" DEBUG_CR
426
                       "<D:%s/>" DEBUG_CR, err->tagname);
427
        }
374
    }
428
    }
375
376
    /* here's our mod_dav specific tag: */
429
    /* here's our mod_dav specific tag: */
377
    if (err->desc != NULL) {
430
    if (err->desc != NULL) {
378
        ap_rprintf(r,
431
        ap_rprintf(r,
Lines 423-429 Link Here
423
   [Presumably the <multistatus> tag has already been written;  this
476
   [Presumably the <multistatus> tag has already been written;  this
424
   routine is shared by dav_send_multistatus and dav_stream_response.]
477
   routine is shared by dav_send_multistatus and dav_stream_response.]
425
*/
478
*/
426
static void dav_send_one_response(dav_response *response,
479
void dav_send_one_response(dav_response *response,
427
                                  apr_bucket_brigade *bb,
480
                                  apr_bucket_brigade *bb,
428
                                  ap_filter_t *output,
481
                                  ap_filter_t *output,
429
                                  apr_pool_t *pool)
482
                                  apr_pool_t *pool)
Lines 485-493 Link Here
485
   response and write <multistatus> tag into BB, destined for
538
   response and write <multistatus> tag into BB, destined for
486
   R->output_filters.  Use xml NAMESPACES in initial tag, if
539
   R->output_filters.  Use xml NAMESPACES in initial tag, if
487
   non-NULL. */
540
   non-NULL. */
488
static void dav_begin_multistatus(apr_bucket_brigade *bb,
541
void dav_begin_multistatus(apr_bucket_brigade *bb,
489
                                  request_rec *r, int status,
542
                           request_rec *r, int status,
490
                                  apr_array_header_t *namespaces)
543
                           apr_array_header_t *namespaces)
491
{
544
{
492
    /* Set the correct status and Content-Type */
545
    /* Set the correct status and Content-Type */
493
    r->status = status;
546
    r->status = status;
Lines 510-517 Link Here
510
}
563
}
511
564
512
/* Finish a multistatus response started by dav_begin_multistatus: */
565
/* Finish a multistatus response started by dav_begin_multistatus: */
513
static apr_status_t dav_finish_multistatus(request_rec *r,
566
apr_status_t dav_finish_multistatus(request_rec *r,
514
                                           apr_bucket_brigade *bb)
567
                                    apr_bucket_brigade *bb)
515
{
568
{
516
    apr_bucket *b;
569
    apr_bucket *b;
517
570
Lines 525-533 Link Here
525
    return ap_pass_brigade(r->output_filters, bb);
578
    return ap_pass_brigade(r->output_filters, bb);
526
}
579
}
527
580
528
static void dav_send_multistatus(request_rec *r, int status,
581
void dav_send_multistatus(request_rec *r, int status,
529
                                 dav_response *first,
582
                          dav_response *first,
530
                                 apr_array_header_t *namespaces)
583
                          apr_array_header_t *namespaces)
531
{
584
{
532
    apr_pool_t *subpool;
585
    apr_pool_t *subpool;
533
    apr_bucket_brigade *bb = apr_brigade_create(r->pool,
586
    apr_bucket_brigade *bb = apr_brigade_create(r->pool,
Lines 587-594 Link Here
587
 *   - repos_hooks->copy_resource
640
 *   - repos_hooks->copy_resource
588
 *   - vsn_hooks->update
641
 *   - vsn_hooks->update
589
 */
642
 */
590
static int dav_handle_err(request_rec *r, dav_error *err,
643
int dav_handle_err(request_rec *r, dav_error *err,
591
                          dav_response *response)
644
                   dav_response *response)
592
{
645
{
593
    /* log the errors */
646
    /* log the errors */
594
    dav_log_err(r, err, APLOG_ERR);
647
    dav_log_err(r, err, APLOG_ERR);
Lines 621-631 Link Here
621
                       int replaced)
674
                       int replaced)
622
{
675
{
623
    const char *body;
676
    const char *body;
677
    dav_dir_conf *conf;
624
678
625
    if (locn == NULL) {
679
    if (locn == NULL) {
626
        locn = r->uri;
680
        locn = r->uri;
627
    }
681
    }
628
682
683
    /* ### insert an ETag header? see HTTP/1.1 S10.2.2 */
684
    conf = ap_get_module_config(r->per_dir_config, &dav_module);
685
686
    /* added ETag response ... vlv disabled as well ! */
687
    if (conf->etag_response) {
688
        char *vlv = r->vlist_validator;
689
	r->vlist_validator = NULL;
690
        apr_stat(&r->finfo, r->filename, APR_FINFO_MIN, r->pool);
691
	r->mtime = r->finfo.mtime;
692
   	ap_set_etag(r);
693
	r->vlist_validator = vlv;
694
    }   
695
629
    /* did the target resource already exist? */
696
    /* did the target resource already exist? */
630
    if (replaced) {
697
    if (replaced) {
631
        /* Apache will supply a default message */
698
        /* Apache will supply a default message */
Lines 634-645 Link Here
634
701
635
    /* Per HTTP/1.1, S10.2.2: add a Location header to contain the
702
    /* Per HTTP/1.1, S10.2.2: add a Location header to contain the
636
     * URI that was created. */
703
     * URI that was created. */
637
704
    
638
    /* Convert locn to an absolute URI, and return in Location header */
705
    /* Convert locn to an absolute URI, and return in Location header */
639
    apr_table_setn(r->headers_out, "Location", ap_construct_url(r->pool, locn, r));
706
    apr_table_setn(r->headers_out, "Location", ap_construct_url(r->pool, locn, r));
640
707
641
    /* ### insert an ETag header? see HTTP/1.1 S10.2.2 */
642
643
    /* Apache doesn't allow us to set a variable body for HTTP_CREATED, so
708
    /* Apache doesn't allow us to set a variable body for HTTP_CREATED, so
644
     * we must manufacture the entire response. */
709
     * we must manufacture the entire response. */
645
    body = apr_psprintf(r->pool, "%s %s has been created.",
710
    body = apr_psprintf(r->pool, "%s %s has been created.",
Lines 647-652 Link Here
647
    return dav_error_response(r, HTTP_CREATED, body);
712
    return dav_error_response(r, HTTP_CREATED, body);
648
}
713
}
649
714
715
650
/* ### move to dav_util? */
716
/* ### move to dav_util? */
651
DAV_DECLARE(int) dav_get_depth(request_rec *r, int def_depth)
717
DAV_DECLARE(int) dav_get_depth(request_rec *r, int def_depth)
652
{
718
{
Lines 711-717 Link Here
711
    dav_dir_conf *conf;
777
    dav_dir_conf *conf;
712
    const char *label = NULL;
778
    const char *label = NULL;
713
    dav_error *err;
779
    dav_error *err;
714
780
  
715
    /* if the request target can be overridden, get any target selector */
781
    /* if the request target can be overridden, get any target selector */
716
    if (label_allowed) {
782
    if (label_allowed) {
717
        label = apr_table_get(r->headers_in, "label");
783
        label = apr_table_get(r->headers_in, "label");
Lines 745-750 Link Here
745
     * add it now */
811
     * add it now */
746
    dav_add_vary_header(r, r, *res_p);
812
    dav_add_vary_header(r, r, *res_p);
747
813
814
    /* if acls checking -> check if allowed method excluding propfind */
815
    if (conf->acl_checking &&
816
        ((*res_p)->acl_hooks = dav_get_acl_hooks()) && 
817
        (err = (*res_p)->acl_hooks->acl_check_method(r, *res_p)))
818
      return err;  
819
748
    return NULL;
820
    return NULL;
749
}
821
}
750
822
Lines 1092-1102 Link Here
1092
            return dav_handle_err(r, err, NULL);
1164
            return dav_handle_err(r, err, NULL);
1093
        }
1165
        }
1094
    }
1166
    }
1095
1167
 
1096
    /* NOTE: WebDAV spec, S8.7.1 states properties should be unaffected */
1168
    /* NOTE: WebDAV spec, S8.7.1 states properties should be unaffected */
1097
1169
1098
    /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */
1170
    /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */
1099
    return dav_created(r, NULL, "Resource", resource_state == DAV_RESOURCE_EXISTS);
1171
    int rc = dav_created(r, NULL, "Resource", resource_state == DAV_RESOURCE_EXISTS);
1172
1173
    if (resource->acl_hooks)
1174
        resource->acl_hooks->acl_post_processing(r, resource, r->status == HTTP_CREATED);
1175
        
1176
    return rc;    
1100
}
1177
}
1101
1178
1102
1179
Lines 1245-1250 Link Here
1245
        dav_log_err(r, err, APLOG_WARNING);
1322
        dav_log_err(r, err, APLOG_WARNING);
1246
    }
1323
    }
1247
1324
1325
    if (resource->acl_hooks)
1326
        resource->acl_hooks->acl_post_processing(r, resource, 0);
1327
1248
    /* ### HTTP_NO_CONTENT if no body, HTTP_OK if there is a body (some day) */
1328
    /* ### HTTP_NO_CONTENT if no body, HTTP_OK if there is a body (some day) */
1249
1329
1250
    /* Apache will supply a default error for this. */
1330
    /* Apache will supply a default error for this. */
Lines 1609-1614 Link Here
1609
    if (binding_hooks != NULL)
1689
    if (binding_hooks != NULL)
1610
        dav_level = apr_pstrcat(r->pool, dav_level, ",bindings", NULL);
1690
        dav_level = apr_pstrcat(r->pool, dav_level, ",bindings", NULL);
1611
1691
1692
    { /* DAV header additions registered by external modules */
1693
        int i;
1694
        apr_array_header_t *extensions = 
1695
            ap_list_provider_names(r->pool, DAV_OPTIONS_EXTENSION_GROUP, "0");
1696
        ap_list_provider_names_t *entry = 
1697
            (ap_list_provider_names_t *)extensions->elts;
1698
1699
        for (i = 0; i < extensions->nelts; i++, entry++) {
1700
            const dav_hooks_options *options = 
1701
                dav_get_options_hooks(entry->provider_name);
1702
1703
            if (options && options->dav_header) {
1704
                apr_text_header hoptions = { 0 };
1705
              
1706
                options->dav_header(r, resource, &hoptions);
1707
                for (t = hoptions.first; t && t->text; t = t->next)
1708
                    dav_level = apr_pstrcat(r->pool, dav_level, ",", t->text, NULL);
1709
            }   
1710
        }
1711
    }
1712
1612
    /* ###
1713
    /* ###
1613
     * MSFT Web Folders chokes if length of DAV header value > 63 characters!
1714
     * MSFT Web Folders chokes if length of DAV header value > 63 characters!
1614
     * To workaround that, we use separate DAV headers for versioning and
1715
     * To workaround that, we use separate DAV headers for versioning and
Lines 1670-1676 Link Here
1670
        apr_table_addn(methods, "COPY", "");
1771
        apr_table_addn(methods, "COPY", "");
1671
        apr_table_addn(methods, "MOVE", "");
1772
        apr_table_addn(methods, "MOVE", "");
1672
1773
1673
        if (!resource->collection)
1774
    /*    if (!resource->collection)  */
1674
            apr_table_addn(methods, "PUT", "");
1775
            apr_table_addn(methods, "PUT", "");
1675
1776
1676
        if (locks_hooks != NULL) {
1777
        if (locks_hooks != NULL) {
Lines 1752-1757 Link Here
1752
        apr_table_addn(methods, "SEARCH", "");
1853
        apr_table_addn(methods, "SEARCH", "");
1753
    }
1854
    }
1754
1855
1856
    { /* additional methods registered by external modules */
1857
        int i;
1858
        apr_array_header_t *extensions = 
1859
            ap_list_provider_names(r->pool, DAV_OPTIONS_EXTENSION_GROUP, "0");
1860
        ap_list_provider_names_t *entry = 
1861
            (ap_list_provider_names_t *)extensions->elts;
1862
1863
        for (i = 0; i < extensions->nelts; i++, entry++) {
1864
            const dav_hooks_options *options = 
1865
                dav_get_options_hooks(entry->provider_name);
1866
1867
            if (options && options->dav_method) {
1868
                apr_text_header hoptions = { 0 };
1869
              
1870
                options->dav_method(r, resource, &hoptions);
1871
                for (t = hoptions.first; t && t->text; t = t->next)
1872
                    apr_table_addn(methods, t->text, "");
1873
            }    
1874
        }
1875
    }
1876
1755
    /* Generate the Allow header */
1877
    /* Generate the Allow header */
1756
    arr = apr_table_elts(methods);
1878
    arr = apr_table_elts(methods);
1757
    elts = (const apr_table_entry_t *)arr->elts;
1879
    elts = (const apr_table_entry_t *)arr->elts;
Lines 2023-2029 Link Here
2023
                      "the required child elements (the specific command).");
2145
                      "the required child elements (the specific command).");
2024
        return HTTP_BAD_REQUEST;
2146
        return HTTP_BAD_REQUEST;
2025
    }
2147
    }
2026
2148
    if (resource->acl_hooks &&
2149
        (ctx.propfind_type == DAV_PROPFIND_IS_PROPNAME || 
2150
         ctx.propfind_type == DAV_PROPFIND_IS_ALLPROP) &&
2151
         (err = resource->acl_hooks->acl_check_read(r, resource)))
2152
        return dav_handle_err(r, err, NULL);
2153
   
2027
    ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
2154
    ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
2028
    ctx.w.func = dav_propfind_walker;
2155
    ctx.w.func = dav_propfind_walker;
2029
    ctx.w.walk_ctx = &ctx;
2156
    ctx.w.walk_ctx = &ctx;
Lines 2088-2095 Link Here
2088
    return DONE;
2215
    return DONE;
2089
}
2216
}
2090
2217
2091
static apr_text * dav_failed_proppatch(apr_pool_t *p,
2218
apr_text * dav_failed_proppatch(apr_pool_t *p,
2092
                                      apr_array_header_t *prop_ctx)
2219
                                apr_array_header_t *prop_ctx)
2093
{
2220
{
2094
    apr_text_header hdr = { 0 };
2221
    apr_text_header hdr = { 0 };
2095
    int i = prop_ctx->nelts;
2222
    int i = prop_ctx->nelts;
Lines 2149-2155 Link Here
2149
    return hdr.first;
2276
    return hdr.first;
2150
}
2277
}
2151
2278
2152
static apr_text * dav_success_proppatch(apr_pool_t *p, apr_array_header_t *prop_ctx)
2279
apr_text * dav_success_proppatch(apr_pool_t *p, apr_array_header_t *prop_ctx)
2153
{
2280
{
2154
    apr_text_header hdr = { 0 };
2281
    apr_text_header hdr = { 0 };
2155
    int i = prop_ctx->nelts;
2282
    int i = prop_ctx->nelts;
Lines 2370-2375 Link Here
2370
2497
2371
    dav_send_multistatus(r, HTTP_MULTI_STATUS, &resp, doc->namespaces);
2498
    dav_send_multistatus(r, HTTP_MULTI_STATUS, &resp, doc->namespaces);
2372
2499
2500
    if (resource->acl_hooks)
2501
        resource->acl_hooks->acl_post_processing(r, resource, 0);
2502
2373
    /* the response has been sent. */
2503
    /* the response has been sent. */
2374
    return DONE;
2504
    return DONE;
2375
}
2505
}
Lines 2546-2553 Link Here
2546
        }
2676
        }
2547
    }
2677
    }
2548
2678
2679
2549
    /* return an appropriate response (HTTP_CREATED) */
2680
    /* return an appropriate response (HTTP_CREATED) */
2550
    return dav_created(r, NULL, "Collection", 0);
2681
    int rc = dav_created(r, NULL, "Collection", 0);
2682
2683
    if (resource->acl_hooks)
2684
        resource->acl_hooks->acl_post_processing(r, resource, r->status == 201);
2685
2686
    return rc; 
2551
}
2687
}
2552
2688
2553
/* handle the COPY and MOVE methods */
2689
/* handle the COPY and MOVE methods */
Lines 2949-2957 Link Here
2949
        }
3085
        }
2950
    }
3086
    }
2951
3087
3088
2952
    /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */
3089
    /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */
2953
    return dav_created(r, lookup.rnew->uri, "Destination",
3090
    int rc = dav_created(r, lookup.rnew->uri, "Destination",
2954
                       resnew_state == DAV_RESOURCE_EXISTS);
3091
                         resnew_state == DAV_RESOURCE_EXISTS);
3092
3093
    if (resource->acl_hooks)
3094
        resource->acl_hooks->acl_post_processing(r, is_move ? resource : resnew, 
3095
                                                 r->status == 201);
3096
        
3097
    return rc;
2955
}
3098
}
2956
3099
2957
/* dav_method_lock:  Handler to implement the DAV LOCK method
3100
/* dav_method_lock:  Handler to implement the DAV LOCK method
Lines 4816-4821 Link Here
4816
                 ACCESS_CONF|RSRC_CONF,
4959
                 ACCESS_CONF|RSRC_CONF,
4817
                 "allow Depth infinity PROPFIND requests"),
4960
                 "allow Depth infinity PROPFIND requests"),
4818
4961
4962
    /* per directory/location, or per server */
4963
    AP_INIT_FLAG("DAVETagResponse", dav_cmd_etag_response, NULL,
4964
                 ACCESS_CONF|RSRC_CONF,
4965
                 "response with ETag for dav_created"),
4966
4967
    /* per directory/location, or per server */
4968
    AP_INIT_FLAG("DAVACL", dav_cmd_acl_checking, NULL,
4969
                 ACCESS_CONF|RSRC_CONF,
4970
                 "Access Control List as per rfc3744"),
4971
4819
    { NULL }
4972
    { NULL }
4820
};
4973
};
4821
4974
(-)httpd-2.2.8/modules/dav/main/mod_dav.h (-1 / +121 lines)
Lines 46-52 Link Here
46
#define DAV_VERSION             AP_SERVER_BASEREVISION
46
#define DAV_VERSION             AP_SERVER_BASEREVISION
47
47
48
#define DAV_XML_HEADER          "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
48
#define DAV_XML_HEADER          "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
49
#define DAV_XML_CONTENT_TYPE    "text/xml; charset=\"utf-8\""
49
#define DAV_XML_CONTENT_TYPE     "application/xml; charset=\"utf-8\""
50
50
51
#define DAV_READ_BLOCKSIZE      2048    /* used for reading input blocks */
51
#define DAV_READ_BLOCKSIZE      2048    /* used for reading input blocks */
52
52
Lines 128-137 Link Here
128
    const char *namespace;      /* [optional] namespace of error */
128
    const char *namespace;      /* [optional] namespace of error */
129
    const char *tagname;        /* name of error-tag */
129
    const char *tagname;        /* name of error-tag */
130
130
131
    const char *childtags;      /* error-tag may have children */
132
131
    struct dav_error *prev;     /* previous error (in stack) */
133
    struct dav_error *prev;     /* previous error (in stack) */
132
134
133
} dav_error;
135
} dav_error;
134
136
137
135
/*
138
/*
136
** Create a new error structure. save_errno will be filled with the current
139
** Create a new error structure. save_errno will be filled with the current
137
** errno value.
140
** errno value.
Lines 349-354 Link Here
349
**     baselined  = 0
352
**     baselined  = 0
350
**     working    = 0
353
**     working    = 0
351
*/
354
*/
355
356
typedef struct dav_hooks_acl dav_hooks_acl;
357
358
352
typedef struct dav_resource {
359
typedef struct dav_resource {
353
    dav_resource_type type;
360
    dav_resource_type type;
354
361
Lines 381-386 Link Here
381
       long as the dav_resource structure. */
388
       long as the dav_resource structure. */
382
    apr_pool_t *pool;
389
    apr_pool_t *pool;
383
390
391
                         /* acl hooks */
392
    const dav_hooks_acl *acl_hooks;
393
394
    void *ctx;  /* additional parameter */  
395
    
384
} dav_resource;
396
} dav_resource;
385
397
386
/*
398
/*
Lines 648-653 Link Here
648
                                        const dav_provider *hooks);
660
                                        const dav_provider *hooks);
649
DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name);
661
DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name);
650
662
663
DAV_DECLARE(const char *) dav_get_provider_name(request_rec *r);
664
651
665
652
/* ### deprecated */
666
/* ### deprecated */
653
#define DAV_GET_HOOKS_PROPDB(r)         dav_get_propdb_hooks(r)
667
#define DAV_GET_HOOKS_PROPDB(r)         dav_get_propdb_hooks(r)
Lines 1935-1940 Link Here
1935
    /* Get the entity tag for a resource */
1949
    /* Get the entity tag for a resource */
1936
    const char * (*getetag)(const dav_resource *resource);
1950
    const char * (*getetag)(const dav_resource *resource);
1937
1951
1952
    /* return request record */
1953
    request_rec * (*get_request_rec)(const dav_resource *resource);
1954
1955
    /* return path */
1956
    const char * (*get_pathname)(const dav_resource *resource);
1957
1938
    /*
1958
    /*
1939
    ** If a provider needs a context to associate with this hooks structure,
1959
    ** If a provider needs a context to associate with this hooks structure,
1940
    ** then this field may be used. In most cases, it will just be NULL.
1960
    ** then this field may be used. In most cases, it will just be NULL.
Lines 2419-2424 Link Here
2419
    const dav_hooks_liveprop *provider;  /* the provider defining this prop */
2439
    const dav_hooks_liveprop *provider;  /* the provider defining this prop */
2420
} dav_elem_private;    
2440
} dav_elem_private;    
2421
2441
2442
2443
/* --------------------------------------------------------------------
2444
**
2445
** DAV ACL HOOKS
2446
*/
2447
2448
struct dav_hooks_acl
2449
{
2450
    dav_error * (*acl_check_method)(request_rec *r,
2451
                                    const dav_resource *resource);
2452
2453
    dav_error * (*acl_check_read)(request_rec *r,
2454
                                  const dav_resource *resource);
2455
                                    
2456
    dav_error * (*acl_check_prop)(request_rec *r,
2457
                                  const dav_resource *resource,
2458
                                  const dav_prop_name *name,
2459
                                  dav_prop_insert what);
2460
2461
    void (*acl_post_processing)(request_rec *r,
2462
                                const dav_resource *resource, 
2463
                                int fStoreOwner);
2464
    void *ctx;                              
2465
};
2466
2467
2468
DAV_DECLARE(void) dav_acl_register_hooks(apr_pool_t *p, 
2469
                                         const dav_hooks_acl *acl);
2470
2471
DAV_DECLARE(const dav_hooks_acl *) dav_get_acl_hooks();
2472
                                           
2473
/* moved some nice functions to public */
2474
extern void dav_begin_multistatus(apr_bucket_brigade *bb,
2475
                                  request_rec *r, int status,
2476
                                  apr_array_header_t *namespaces);
2477
extern void dav_send_one_response(dav_response *response,
2478
                                  apr_bucket_brigade *bb,
2479
                                  ap_filter_t *output,
2480
                                  apr_pool_t *pool);
2481
extern apr_status_t dav_finish_multistatus(request_rec *r,
2482
                                           apr_bucket_brigade *bb);
2483
extern void dav_send_multistatus(request_rec *r, int status,
2484
                                 dav_response *first,
2485
                                 apr_array_header_t *namespaces);
2486
extern int dav_handle_err(request_rec *r, dav_error *err,
2487
                          dav_response *response);
2488
extern apr_text * dav_failed_proppatch(apr_pool_t *p,
2489
                                       apr_array_header_t *prop_ctx);
2490
extern apr_text * dav_success_proppatch(apr_pool_t *p, apr_array_header_t *prop_ctx);
2491
2492
2493
/* --------------------------------------------------------------------
2494
**
2495
** DAV RESOURCE TYPE HOOKS
2496
*/
2497
2498
typedef struct dav_hooks_resource
2499
{
2500
    int (*get_resource_type)(const dav_resource *resource, 
2501
                             const char **name, 
2502
                             const char **uri);
2503
                                  
2504
    void *ctx;                              
2505
} dav_hooks_resource;
2506
2507
#define DAV_RESOURCE_GROUP "dav_resource"
2508
2509
DAV_DECLARE(void) dav_resource_register_hooks(apr_pool_t *p, 
2510
                                              const char *name, 
2511
                                              const dav_hooks_resource *provider);
2512
2513
DAV_DECLARE(const dav_hooks_resource *) dav_get_resource_hooks(const char *name);
2514
2515
2516
/* --------------------------------------------------------------------
2517
**
2518
** DAV OPTIONS HOOKS
2519
*/
2520
#define DAV_OPTIONS_EXTENSION_GROUP "dav_options"
2521
2522
typedef struct dav_hooks_options
2523
{
2524
    dav_error* (*dav_header)(request_rec *r,
2525
                             const dav_resource *resource,
2526
                             apr_text_header *phdr);
2527
2528
    dav_error* (*dav_method)(request_rec *r,
2529
                             const dav_resource *resource,
2530
                             apr_text_header *phdr);
2531
2532
    void *ctx;                              
2533
} dav_hooks_options;
2534
2535
extern DAV_DECLARE(const dav_hooks_options *) dav_get_options_hooks(const char *name);
2536
2537
extern DAV_DECLARE(void) dav_options_register_hooks(apr_pool_t *p, 
2538
                                                    const char *name,
2539
                                                    const dav_hooks_options *provider);
2540
2541
2422
#ifdef __cplusplus
2542
#ifdef __cplusplus
2423
}
2543
}
2424
#endif
2544
#endif
(-)httpd-2.2.8/modules/dav/main/props.c (-4 / +71 lines)
Lines 538-544 Link Here
538
    propdb->ns_xlate = ns_xlate;
538
    propdb->ns_xlate = ns_xlate;
539
539
540
    propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r);
540
    propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r);
541
541
 
542
    propdb->lockdb = lockdb;
542
    propdb->lockdb = lockdb;
543
543
544
    /* always defer actual open, to avoid expense of accessing db
544
    /* always defer actual open, to avoid expense of accessing db
Lines 617-623 Link Here
617
                        found_contentlang = 1;
617
                        found_contentlang = 1;
618
                    }
618
                    }
619
                }
619
                }
620
620
                /* check for possible acl restrictions */    
621
                if (propdb->resource->acl_hooks && 
622
                    propdb->resource->acl_hooks->acl_check_prop(propdb->r, 
623
                                                  propdb->resource, 
624
                                                  &name, 
625
                                                  what)) {
626
                    goto next_key;
627
                }  
621
                if (what == DAV_PROP_INSERT_VALUE) {
628
                if (what == DAV_PROP_INSERT_VALUE) {
622
                    dav_error *err;
629
                    dav_error *err;
623
                    int found;
630
                    int found;
Lines 700-705 Link Here
700
    apr_xml_elem *elem = dav_find_child(doc->root, "prop");
707
    apr_xml_elem *elem = dav_find_child(doc->root, "prop");
701
    apr_text_header hdr_good = { 0 };
708
    apr_text_header hdr_good = { 0 };
702
    apr_text_header hdr_bad = { 0 };
709
    apr_text_header hdr_bad = { 0 };
710
    apr_text_header hdr_not_auth = { 0 };
703
    apr_text_header hdr_ns = { 0 };
711
    apr_text_header hdr_ns = { 0 };
704
    int have_good = 0;
712
    int have_good = 0;
705
    dav_get_props_result result = { 0 };
713
    dav_get_props_result result = { 0 };
Lines 707-712 Link Here
707
    dav_xmlns_info *xi;
715
    dav_xmlns_info *xi;
708
    int xi_filled = 0;
716
    int xi_filled = 0;
709
717
718
    /* check for possible acl restrictions */    
719
    dav_error *err_read = propdb->resource->acl_hooks ?
720
        propdb->resource->acl_hooks->acl_check_read(propdb->r, 
721
                                                    propdb->resource) : NULL; 
722
    
710
    /* ### NOTE: we should pass in TWO buffers -- one for keys, one for
723
    /* ### NOTE: we should pass in TWO buffers -- one for keys, one for
711
       the marks */
724
       the marks */
712
725
Lines 729-735 Link Here
729
        dav_error *err;
742
        dav_error *err;
730
        dav_prop_insert inserted;
743
        dav_prop_insert inserted;
731
        dav_prop_name name;
744
        dav_prop_name name;
732
745
        
733
        /*
746
        /*
734
        ** First try live property providers; if they don't handle
747
        ** First try live property providers; if they don't handle
735
        ** the property, then try looking it up in the propdb.
748
        ** the property, then try looking it up in the propdb.
Lines 746-751 Link Here
746
759
747
        if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {
760
        if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {
748
761
762
            /* check for possible acl restrictions
763
             * ask for each live prop separately (e.g. read-acl privilege) */    
764
            if (propdb->resource->acl_hooks) {
765
                if (elem->ns == APR_XML_NS_NONE)
766
            	    name.ns = "";
767
        	else
768
            	    name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns);
769
   		name.name = elem->name;
770
771
                if (propdb->resource->acl_hooks->
772
                    acl_check_prop(propdb->r, propdb->resource, 
773
                                              &name, 
774
                                              DAV_PROP_INSERT_VALUE)) {
775
                                                  
776
                    if (hdr_not_auth.first == NULL) {
777
                        apr_text_append(propdb->p, &hdr_not_auth,
778
                                        "<D:propstat>" DEBUG_CR
779
                                        "<D:prop>" DEBUG_CR);
780
                    }
781
                    if (!name.ns)
782
                      name.ns = "";
783
                    dav_output_prop_name(propdb->p, &name, xi, &hdr_not_auth);
784
                    continue;
785
                }
786
            }
787
749
            /* insert the property. returns 1 if an insertion was done. */
788
            /* insert the property. returns 1 if an insertion was done. */
750
            if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE,
789
            if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE,
751
                                           &hdr_good, &inserted)) != NULL) {
790
                                           &hdr_good, &inserted)) != NULL) {
Lines 783-789 Link Here
783
            else if (inserted == DAV_PROP_INSERT_NOTDEF) {
822
            else if (inserted == DAV_PROP_INSERT_NOTDEF) {
784
                /* nothing to do. fall thru to allow property to be handled
823
                /* nothing to do. fall thru to allow property to be handled
785
                   as a dead property */
824
                   as a dead property */
786
            }
825
            } 
787
#if DAV_DEBUG
826
#if DAV_DEBUG
788
            else {
827
            else {
789
#if 0
828
#if 0
Lines 811-816 Link Here
811
            name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns);
850
            name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns);
812
        name.name = elem->name;
851
        name.name = elem->name;
813
852
853
        /* check for possible acl restrictions */    
854
        if (err_read) {
855
            if (hdr_not_auth.first == NULL) {
856
                apr_text_append(propdb->p, &hdr_not_auth,
857
                                "<D:propstat>" DEBUG_CR
858
                                "<D:prop>" DEBUG_CR);
859
            }
860
            if (!name.ns)
861
              name.ns = "";
862
            dav_output_prop_name(propdb->p, &name, xi, &hdr_not_auth);
863
            continue;
864
        }   
865
814
        /* only bother to look if a database exists */
866
        /* only bother to look if a database exists */
815
        if (propdb->db != NULL) {
867
        if (propdb->db != NULL) {
816
            int found;
868
            int found;
Lines 874-879 Link Here
874
        }
926
        }
875
    }
927
    }
876
928
929
    if (hdr_not_auth.first != NULL) {
930
        apr_text_append(propdb->p, &hdr_not_auth,
931
                        "</D:prop>" DEBUG_CR
932
                        "<D:status>HTTP/1.1 403 Forbidden</D:status>" DEBUG_CR
933
                        "</D:propstat>" DEBUG_CR);
934
935
        if (!have_good && !hdr_bad.first)
936
            result.propstats = hdr_not_auth.first;
937
        else if (hdr_bad.first != NULL)
938
            hdr_bad.last->next = hdr_not_auth.first;
939
        else     
940
            hdr_good.last->next = hdr_not_auth.first;
941
            
942
    }
943
877
    /* add in all the various namespaces, and return them */
944
    /* add in all the various namespaces, and return them */
878
    dav_xmlns_generate(xi, &hdr_ns);
945
    dav_xmlns_generate(xi, &hdr_ns);
879
    result.xmlns = hdr_ns.first;
946
    result.xmlns = hdr_ns.first;
(-)httpd-2.2.8/modules/dav/main/providers.c (+38 lines)
Lines 31-33 Link Here
31
{
31
{
32
    return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0");
32
    return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0");
33
}
33
}
34
35
DAV_DECLARE(void) dav_acl_register_hooks(apr_pool_t *p, 
36
                                         const dav_hooks_acl *provider)
37
{
38
    ap_register_provider(p, DAV_PROVIDER_GROUP, "acl", "0", provider);
39
}
40
41
DAV_DECLARE(const dav_hooks_acl *) dav_get_acl_hooks()
42
{
43
    return ap_lookup_provider(DAV_PROVIDER_GROUP, "acl", "0");
44
}
45
46
DAV_DECLARE(void) dav_options_register_hooks(apr_pool_t *p, 
47
                                             const char *name,
48
                                             const dav_hooks_options *provider)
49
{
50
    ap_register_provider(p, DAV_OPTIONS_EXTENSION_GROUP, name, "0", provider);
51
}
52
53
DAV_DECLARE(const dav_hooks_options *) dav_get_options_hooks(const char *name)
54
{
55
    return ap_lookup_provider(DAV_OPTIONS_EXTENSION_GROUP, name, "0");
56
}
57
58
DAV_DECLARE(void) dav_resource_register_hooks(apr_pool_t *p, 
59
                                              const char *name, 
60
                                              const dav_hooks_resource *provider)
61
{
62
    ap_register_provider(p, DAV_RESOURCE_GROUP, name, "0", provider);
63
}
64
65
DAV_DECLARE(const dav_hooks_resource *) dav_get_resource_hooks(const char *name)
66
{
67
    return ap_lookup_provider(DAV_RESOURCE_GROUP, name, "0");
68
}
69
70
71
(-)httpd-2.2.8/modules/dav/main/std_liveprop.c (-8 / +40 lines)
Lines 17-22 Link Here
17
#include "httpd.h"
17
#include "httpd.h"
18
#include "util_xml.h"
18
#include "util_xml.h"
19
#include "apr_strings.h"
19
#include "apr_strings.h"
20
#include "ap_provider.h"
20
21
21
#include "mod_dav.h"
22
#include "mod_dav.h"
22
23
Lines 59-65 Link Here
59
                                            int propid, dav_prop_insert what,
60
                                            int propid, dav_prop_insert what,
60
                                            apr_text_header *phdr)
61
                                            apr_text_header *phdr)
61
{
62
{
62
    const char *value;
63
    const char *value = NULL;
63
    const char *s;
64
    const char *s;
64
    apr_pool_t *p = resource->pool;
65
    apr_pool_t *p = resource->pool;
65
    const dav_liveprop_spec *info;
66
    const dav_liveprop_spec *info;
Lines 68-99 Link Here
68
    switch (propid)
69
    switch (propid)
69
    {
70
    {
70
    case DAV_PROPID_resourcetype:
71
    case DAV_PROPID_resourcetype:
72
73
        { /* additional type info provided by external modules ? */
74
            int i;
75
76
            apr_array_header_t *extensions = 
77
                ap_list_provider_names(p, DAV_RESOURCE_GROUP, "0");
78
            ap_list_provider_names_t *entry = 
79
                (ap_list_provider_names_t *)extensions->elts;
80
81
            for (i = 0; i < extensions->nelts; i++, entry++) {
82
                const dav_hooks_resource *res_hooks = 
83
                    dav_get_resource_hooks(entry->provider_name);
84
                const char *name = NULL, *uri = NULL;        
85
          
86
                if (!res_hooks || !res_hooks->get_resource_type)
87
                    continue; 
88
                   
89
                if (!res_hooks->get_resource_type(resource, &name, &uri) &&
90
  	            name) {
91
92
                    if (!uri || !strcasecmp(uri, "DAV:"))
93
                        value = apr_pstrcat(p, value ? value : "", 
94
                                               "<D:", name, "/>", NULL);
95
                    else
96
                        value = apr_pstrcat(p, value ? value : "", 
97
                                               "<x:", name, 
98
                                               " xmlns:x=\"", uri, 
99
                                               "\"/>", NULL);
100
                }
101
            }
102
        }
71
        switch (resource->type) {
103
        switch (resource->type) {
72
        case DAV_RESOURCE_TYPE_VERSION:
104
        case DAV_RESOURCE_TYPE_VERSION:
73
            if (resource->baselined) {
105
            if (resource->baselined) {
74
                value = "<D:baseline/>";
106
                value = apr_pstrcat(p, value ? value : "", "<D:baseline/>", NULL);
75
                break;
107
                break;
76
            }
108
            }
77
            /* fall through */
109
            /* fall through */
78
        case DAV_RESOURCE_TYPE_REGULAR:
110
        case DAV_RESOURCE_TYPE_REGULAR:
79
        case DAV_RESOURCE_TYPE_WORKING:
111
        case DAV_RESOURCE_TYPE_WORKING:
80
            if (resource->collection) {
112
            if (resource->collection) {
81
                value = "<D:collection/>";
113
                value = apr_pstrcat(p, value ? value : "", "<D:collection/>", NULL);
82
            }
114
            }
83
            else {
115
            else {
84
                /* ### should we denote lock-null resources? */
116
                /* ### should we denote lock-null resources? */
85
117
                if (value == NULL) 
86
                value = "";        /* becomes: <D:resourcetype/> */
118
                    value = "";        /* becomes: <D:resourcetype/> */
87
            }
119
            }
88
            break;
120
            break;
89
        case DAV_RESOURCE_TYPE_HISTORY:
121
        case DAV_RESOURCE_TYPE_HISTORY:
90
            value = "<D:version-history/>";
122
            value = apr_pstrcat(p, value ? value : "", "<D:version-history/>", NULL);
91
            break;
123
            break;
92
        case DAV_RESOURCE_TYPE_WORKSPACE:
124
        case DAV_RESOURCE_TYPE_WORKSPACE:
93
            value = "<D:collection/>";
125
            value = apr_pstrcat(p, value ? value : "", "<D:collection/>", NULL);
94
            break;
126
            break;
95
        case DAV_RESOURCE_TYPE_ACTIVITY:
127
        case DAV_RESOURCE_TYPE_ACTIVITY:
96
            value = "<D:activity/>";
128
            value = apr_pstrcat(p, value ? value : "", "<D:activity/>", NULL);
97
            break;
129
            break;
98
130
99
        default:
131
        default:
(-)httpd-2.2.8/modules/http/http_etag.c (-1 / +6 lines)
Lines 100-106 Link Here
100
     * be modified again later in the second, and the validation
100
     * be modified again later in the second, and the validation
101
     * would be incorrect.
101
     * would be incorrect.
102
     */
102
     */
103
    if ((r->request_time - r->mtime > (1 * APR_USEC_PER_SEC)) &&
103
    if (
104
#if 0
105
    imo weak etags are bogus 
106
        (r->request_time - r->mtime > (1 * APR_USEC_PER_SEC)) &&
107
#endif
108
104
        !force_weak) {
109
        !force_weak) {
105
        weak = NULL;
110
        weak = NULL;
106
        weak_len = 0;
111
        weak_len = 0;

Return to bug 390443