1 /* http_dav.h -- Routines for dealing with DAV properties in httpd 2 * 3 * Copyright (c) 1994-2011 Carnegie Mellon University. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. The name "Carnegie Mellon University" must not be used to 18 * endorse or promote products derived from this software without 19 * prior written permission. For permission or any legal 20 * details, please contact 21 * Carnegie Mellon University 22 * Center for Technology Transfer and Enterprise Creation 23 * 4615 Forbes Avenue 24 * Suite 302 25 * Pittsburgh, PA 15213 26 * (412) 268-7393, fax: (412) 268-7395 27 * innovation@andrew.cmu.edu 28 * 29 * 4. Redistributions of any form whatsoever must retain the following 30 * acknowledgment: 31 * "This product includes software developed by Computing Services 32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 33 * 34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 41 * 42 */ 43 44 #ifndef HTTP_DAV_H 45 #define HTTP_DAV_H 46 47 #include <stdint.h> 48 #include <libical/ical.h> 49 #include <libxml/tree.h> 50 51 #include "acl.h" 52 #include "annotate.h" 53 #include "caldav_db.h" 54 #include "httpd.h" 55 #include "spool.h" 56 #include "quota.h" 57 #include "strarray.h" 58 59 #define NULL_ETAG "da39a3ee5e6b4b0d3255bfef95601890afd80709" 60 /* SHA1("") */ 61 62 #define SERVER_INFO ".server-info" 63 #define SCHED_INBOX "Inbox/" 64 #define SCHED_OUTBOX "Outbox/" 65 #define SCHED_DEFAULT "Default/" 66 #define MANAGED_ATTACH "Attachments/" 67 68 /* XML namespace URIs */ 69 #define XML_NS_DAV "DAV:" 70 #define XML_NS_CALDAV "urn:ietf:params:xml:ns:caldav" 71 #define XML_NS_CARDDAV "urn:ietf:params:xml:ns:carddav" 72 #define XML_NS_ISCHED "urn:ietf:params:xml:ns:ischedule" 73 #define XML_NS_CS "http://calendarserver.org/ns/" 74 #define XML_NS_MECOM "http://me.com/_namespace/" 75 #define XML_NS_MOBME "urn:mobileme:davservices" 76 #define XML_NS_APPLE "http://apple.com/ns/ical/" 77 #define XML_NS_USERFLAG "http://cyrusimap.org/ns/userflag/" 78 #define XML_NS_SYSFLAG "http://cyrusimap.org/ns/sysflag/" 79 #define XML_NS_DAVMOUNT "http://purl.org/NET/webdav/mount/" 80 81 #define USER_COLLECTION_PREFIX "user" 82 #define GROUP_COLLECTION_PREFIX "group" 83 84 #define LOCK_TOKEN_URL_SCHEME "urn:uuid:" 85 #define SYNC_TOKEN_URL_SCHEME "data:," 86 87 #define SHARED_COLLECTION_DELIM '.' 88 89 /* Index into known namespace array */ 90 enum { 91 NS_REQ_ROOT = -1, /* special case: ns of request root (not an index) */ 92 NS_DAV, 93 NS_CALDAV, 94 NS_CARDDAV, 95 NS_ISCHED, 96 NS_CS, 97 NS_MECOM, 98 NS_MOBME, 99 NS_CYRUS, 100 }; 101 #define NUM_NAMESPACE 8 102 103 /* Cyrus-specific privileges */ 104 #define DACL_PROPCOL ACL_WRITE /* CY:write-properties-collection */ 105 #define DACL_PROPRSRC ACL_ANNOTATEMSG /* CY:write-properties-resource */ 106 #define DACL_MKCOL ACL_CREATE /* CY:make-collection */ 107 #define DACL_ADDRSRC ACL_POST /* CY:add-resource */ 108 #define DACL_RMCOL ACL_DELETEMBOX /* CY:remove-collection */ 109 #define DACL_RMRSRC (ACL_DELETEMSG\ 110 |ACL_EXPUNGE) /* CY:remove-resource */ 111 #define DACL_ADMIN ACL_ADMIN /* CY:admin (aggregates 112 DAV:read-acl, DAV:write-acl, 113 DAV:unlock and DAV:share) */ 114 115 /* WebDAV (RFC 3744) privileges */ 116 #define DACL_READ (ACL_READ\ 117 |ACL_LOOKUP) /* DAV:read (aggregates 118 DAV:read-current-user-privilege-set 119 and CALDAV:read-free-busy) */ 120 #define DACL_WRITECONT ACL_INSERT /* DAV:write-content */ 121 #define DACL_WRITEPROPS (DACL_PROPCOL\ 122 |DACL_PROPRSRC)/* DAV:write-properties */ 123 #define DACL_BIND (DACL_MKCOL\ 124 |DACL_ADDRSRC) /* DAV:bind */ 125 #define DACL_UNBIND (DACL_RMCOL\ 126 |DACL_RMRSRC) /* DAV:unbind */ 127 #define DACL_WRITE (DACL_WRITECONT\ 128 |DACL_WRITEPROPS\ 129 |DACL_BIND\ 130 |DACL_UNBIND) /* DAV:write */ 131 #define DACL_ALL (DACL_READ\ 132 |DACL_WRITE\ 133 |DACL_ADMIN) /* DAV:all */ 134 135 /* CalDAV (RFC 4791) privileges */ 136 #define DACL_READFB ACL_USER9 /* CALDAV:read-free-busy 137 (implicit if user has DAV:read) */ 138 139 /* CalDAV Scheduling (RFC 6638) privileges 140 141 We use the same ACLs for both schedule-deliver* and schedule-send* because 142 functionality of Scheduling Inbox and Outbox are mutually exclusive. 143 We use ACL_USER9 for both read-free-busy and schedule-*-freebusy because 144 Scheduling Inbox and Outbox don't contribute to free-busy. 145 */ 146 #define DACL_SCHEDFB ACL_USER9 /* For Scheduling Inbox: 147 CALDAV:schedule-query-freebusy 148 149 For Scheduling Outbox: 150 CALDAV:schedule-send-freebusy */ 151 #define DACL_INVITE ACL_USER8 /* For Scheduling Inbox: 152 CALDAV:schedule-deliver-invite 153 154 For Scheduling Outbox: 155 CALDAV:schedule-send-invite */ 156 #define DACL_REPLY ACL_USER7 /* For Scheduling Inbox: 157 CALDAV:schedule-deliver-reply 158 159 For Scheduling Outbox: 160 CALDAV:schedule-send-reply */ 161 #define DACL_SCHED (DACL_SCHEDFB\ 162 |DACL_INVITE\ 163 |DACL_REPLY) /* For Scheduling Inbox: 164 CALDAV:schedule-deliver (aggregates 165 CALDAV:schedule-deliver-invite, 166 schedule-deliver-reply, 167 schedule-query-freebusy); 168 169 For Scheduling Outbox: 170 CALDAV:schedule-send (aggregates 171 CALDAV:schedule-send-invite, 172 schedule-send-reply, 173 schedule-send-freebusy) */ 174 175 /* Index into preconditions array */ 176 enum { 177 /* WebDAV (RFC 4918) preconditions */ 178 DAV_PROT_PROP = 1, 179 DAV_BAD_LOCK_TOKEN, 180 DAV_NEED_LOCK_TOKEN, 181 DAV_LOCKED, 182 DAV_FINITE_DEPTH, 183 184 /* WebDAV Versioning (RFC 3253) preconditions */ 185 DAV_SUPP_REPORT, 186 DAV_RES_EXISTS, 187 188 /* WebDAV ACL (RFC 3744) preconditions */ 189 DAV_NEED_PRIVS, 190 DAV_NO_INVERT, 191 DAV_NO_ABSTRACT, 192 DAV_SUPP_PRIV, 193 DAV_RECOG_PRINC, 194 DAV_ALLOW_PRINC, 195 DAV_GRANT_ONLY, 196 197 /* WebDAV Quota (RFC 4331) preconditions */ 198 DAV_OVER_QUOTA, 199 DAV_NO_DISK_SPACE, 200 201 /* WebDAV Extended MKCOL (RFC 5689) preconditions */ 202 DAV_VALID_RESTYPE, 203 204 /* WebDAV Sync (RFC 6578) preconditions */ 205 DAV_SYNC_TOKEN, 206 DAV_OVER_LIMIT, 207 208 /* CalDAV (RFC 4791) preconditions */ 209 CALDAV_SUPP_DATA, 210 CALDAV_VALID_DATA, 211 CALDAV_VALID_OBJECT, 212 CALDAV_SUPP_COMP, 213 CALDAV_LOCATION_OK, 214 CALDAV_UID_CONFLICT, 215 CALDAV_SUPP_FILTER, 216 CALDAV_VALID_FILTER, 217 CALDAV_SUPP_COLLATION, 218 219 /* RSCALE (RFC 7529) preconditions */ 220 CALDAV_SUPP_RSCALE, 221 222 /* Time Zones by Reference (RFC 7809) preconditions */ 223 CALDAV_VALID_TIMEZONE, 224 225 /* Managed Attachments (draft-ietf-calext-caldav-attachments) preconditions */ 226 CALDAV_VALID_MANAGEDID, 227 228 /* Bulk Change (draft-daboo-calendarserver-bulk-change) preconditions */ 229 CALDAV_CTAG_OK, 230 231 /* CalDAV Scheduling (RFC 6638) preconditions */ 232 CALDAV_VALID_SCHED, 233 CALDAV_VALID_ORGANIZER, 234 CALDAV_UNIQUE_OBJECT, 235 CALDAV_SAME_ORGANIZER, 236 CALDAV_ALLOWED_ORG_CHANGE, 237 CALDAV_ALLOWED_ATT_CHANGE, 238 CALDAV_DEFAULT_NEEDED, 239 CALDAV_VALID_DEFAULT, 240 241 /* iSchedule (draft-desruisseaux-ischedule) preconditions */ 242 ISCHED_UNSUPP_VERSION, 243 ISCHED_UNSUPP_DATA, 244 ISCHED_INVALID_DATA, 245 ISCHED_INVALID_SCHED, 246 ISCHED_ORIG_MISSING, 247 ISCHED_MULTIPLE_ORIG, 248 ISCHED_ORIG_INVALID, 249 ISCHED_ORIG_DENIED, 250 ISCHED_RECIP_MISSING, 251 ISCHED_RECIP_MISMATCH, 252 ISCHED_VERIFICATION_FAILED, 253 254 /* CardDAV (RFC 6352) preconditions */ 255 CARDDAV_SUPP_DATA, 256 CARDDAV_VALID_DATA, 257 CARDDAV_UID_CONFLICT, 258 CARDDAV_LOCATION_OK, 259 CARDDAV_SUPP_FILTER, 260 CARDDAV_SUPP_COLLATION 261 }; 262 263 /* Preference bits */ 264 enum { 265 PREFER_MIN = (1<<0), 266 PREFER_REP = (1<<1), 267 PREFER_NOROOT = (1<<2) 268 }; 269 270 #define NO_DUP_CHECK (1<<7) 271 272 /* PROPFIND modes */ 273 enum { 274 PROPFIND_NONE = 0, /* only used with REPORT */ 275 PROPFIND_ALL, 276 PROPFIND_NAME, 277 PROPFIND_PROP, 278 PROPFIND_EXPAND /* only used with expand-prop REPORT */ 279 }; 280 281 282 extern struct meth_params princ_params; 283 284 /* Function to fetch resource validators */ 285 typedef int (*get_validators_t)(struct mailbox *mailbox, void *data, 286 const char *userid, struct index_record *record, 287 const char **etag, time_t *lastmod); 288 289 /* Function to fetch resource modseq */ 290 typedef modseq_t (*get_modseq_t)(struct mailbox *mailbox, 291 void *data, const char *userid); 292 293 typedef void *(*db_open_proc_t)(struct mailbox *mailbox); 294 typedef int (*db_close_proc_t)(void *davdb); 295 296 /* Function to lookup DAV 'resource' in 'mailbox', 297 * placing the record in 'data' 298 */ 299 typedef int (*db_lookup_proc_t)(void *davdb, const char *mailbox, 300 const char *resource, void **data, 301 int tombstones); 302 303 /* Function to lookup DAV 'imapuid' in 'mailbox', 304 * placing the record in 'data' 305 */ 306 typedef int (*db_imapuid_proc_t)(void *davdb, const char *mailbox, 307 int uid, void **data, int tombstones); 308 309 /* Function to process each DAV resource in 'mailbox' with 'cb' */ 310 typedef int (*db_foreach_proc_t)(void *davdb, const char *mailbox, 311 int (*cb)(void *rock, void *data), void *rock); 312 313 /* Function to process 'limit' DAV resources 314 updated since 'oldmodseq' in 'mailbox' with 'cb' */ 315 typedef int (*db_updates_proc_t)(void *davdb, modseq_t oldmodseq, 316 const char *mailbox, int kind, int limit, 317 int (*cb)(void *rock, void *data), void *rock); 318 319 /* Context for fetching properties */ 320 struct propfind_entry_list; 321 struct prop_entry; 322 struct error_t; 323 324 /* Propfind return flags */ 325 struct fctx_flags_t { 326 unsigned long fetcheddata : 1; /* Did we fetch iCalendar/vCard data? */ 327 unsigned long cs_sharing : 1; /* Is client using CS sharing? */ 328 }; 329 330 struct propfind_ctx { 331 struct transaction_t *txn; /* request transaction */ 332 struct request_target_t *req_tgt; /* parsed target URL */ 333 unsigned mode; /* none, allprop, propname, prop */ 334 unsigned depth; /* 0 = root, 1 = calendar, 2 = resrc */ 335 unsigned prefer; /* bitmask of client preferences */ 336 const char *userid; /* userid client has logged in as */ 337 int userisadmin; /* is userid an admin */ 338 struct auth_state *authstate; /* authorization state for userid */ 339 void *davdb; /* DAV DB corresponding to collection */ 340 const mbentry_t *mbentry; /* mbentry corresponding to collection */ 341 struct mailbox *mailbox; /* mailbox corresponding to collection */ 342 struct quota quota; /* quota info for collection */ 343 struct index_record *record; /* cyrus.index record for resource */ 344 void *data; /* DAV record for resource */ 345 get_validators_t get_validators; /* fetch resource validators */ 346 struct buf msg_buf; /* mmap()'d resource file */ 347 void *obj; /* parsed resource */ 348 void (*free_obj)(void *); /* free parsed object */ 349 unsigned long reqd_privs; /* privileges req'd on collections */ 350 int (*filter)(struct propfind_ctx *, 351 void *data); /* callback to filter resources */ 352 void *filter_crit; /* criteria to filter resources */ 353 db_open_proc_t open_db; /* open DAV DB for a given mailbox */ 354 db_close_proc_t close_db; /* close DAV DB for a given mailbox */ 355 db_lookup_proc_t lookup_resource; /* lookup a specific resource */ 356 db_foreach_proc_t foreach_resource; /* process all resources in a mailbox */ 357 int (*proc_by_resource)(void *rock, /* Callback to process a resource */ 358 void *data); 359 struct propfind_entry_list *elist; /* List of props to fetch w/callbacks */ 360 const struct prop_entry *lprops; /* Array of known "live" properties */ 361 xmlNodePtr root; /* root node to add to XML tree */ 362 xmlNsPtr *ns; /* Array of our known namespaces */ 363 struct hash_table *ns_table; /* Table of all ns attached to resp */ 364 unsigned prefix_count; /* Count of new ns added to resp */ 365 int *ret; /* Return code to pass up to caller */ 366 struct fctx_flags_t flags; /* Return flags for this propfind */ 367 struct buf buf; /* Working buffer */ 368 xmlBufferPtr xmlbuf; /* Buffer for dumping XML nodes */ 369 }; 370 371 372 /* Context for patching (writing) properties */ 373 struct proppatch_ctx { 374 struct transaction_t *txn; /* request transaction */ 375 struct mailbox *mailbox; /* mailbox related to the collection */ 376 struct index_record *record; /* record of the specific resource */ 377 const struct prop_entry *lprops; /* Array of known "live" properties */ 378 xmlNodePtr root; /* root node to add to XML tree */ 379 xmlNsPtr *ns; /* Array of our supported namespaces */ 380 struct txn *tid; /* Transaction ID for annot writes */ 381 int *ret; /* Return code to pass up to caller */ 382 struct buf buf; /* Working buffer */ 383 }; 384 385 386 /* Structure for property status */ 387 struct propstat { 388 xmlNodePtr root; 389 long status; 390 unsigned precond; 391 }; 392 393 /* Index into propstat array */ 394 enum { 395 PROPSTAT_OK = 0, 396 PROPSTAT_UNAUTH, 397 PROPSTAT_FORBID, 398 PROPSTAT_NOTFOUND, 399 PROPSTAT_CONFLICT, 400 PROPSTAT_FAILEDDEP, 401 PROPSTAT_ERROR, 402 PROPSTAT_OVERQUOTA 403 }; 404 #define NUM_PROPSTAT 8 405 406 407 /* Context for "live" properties */ 408 struct prop_entry { 409 const char *name; /* Property name */ 410 unsigned ns; /* Property namespace */ 411 unsigned char flags; /* Flags for how/where props apply */ 412 int (*get)(const xmlChar *name, /* Callback to fetch property */ 413 xmlNsPtr ns, struct propfind_ctx *fctx, xmlNodePtr prop, 414 xmlNodePtr resp, struct propstat *propstat, void *rock); 415 int (*put)(xmlNodePtr prop, /* Callback to write property */ 416 unsigned set, struct proppatch_ctx *pctx, 417 struct propstat *propstat, void *rock); 418 void *rock; /* Add'l data to pass to callback */ 419 }; 420 421 /* Bitmask of property flags */ 422 enum { 423 PROP_ALLPROP = (1<<0), /* Returned in <allprop> request */ 424 PROP_COLLECTION = (1<<1), /* Returned for collection */ 425 PROP_RESOURCE = (1<<2), /* Returned for resource */ 426 PROP_PERUSER = (1<<3), /* Per-user property */ 427 PROP_PRESCREEN = (1<<4), /* Prescreen property using callback */ 428 PROP_CLEANUP = (1<<5) /* Cleanup property using callback */ 429 }; 430 431 432 /* Function to check headers for preconditions */ 433 struct meth_params; 434 typedef int (*check_precond_t)(struct transaction_t *txn, 435 struct meth_params *params, 436 struct mailbox *mailbox, const void *data, 437 const char *etag, time_t lastmod); 438 439 /* Function to insert/update DAV resource in 'data' */ 440 typedef int (*db_write_proc_t)(void *davdb, void *data); 441 442 /* Function to delete resource in 'rowid' */ 443 typedef int (*db_delete_proc_t)(void *davdb, unsigned rowid); 444 445 typedef int (*db_proc_t)(void *davdb); 446 447 struct davdb_params { 448 db_open_proc_t open_db; /* open DAV DB for a given mailbox */ 449 db_close_proc_t close_db; /* close DAV DB for a given mailbox */ 450 db_proc_t begin_transaction; 451 db_proc_t commit_transaction; 452 db_proc_t abort_transaction; 453 db_lookup_proc_t lookup_resource; /* lookup a specific resource */ 454 db_imapuid_proc_t lookup_imapuid; /* lookup a specific resource */ 455 db_foreach_proc_t foreach_resource; /* process all resources in a mailbox */ 456 db_updates_proc_t foreach_update; /* process updated resources in a mbox */ 457 /* XXX - convert these to lock management only. For everything else, 458 * we need to go via mailbox.c for replication support */ 459 db_write_proc_t write_resourceLOCKONLY; /* write a specific resource */ 460 db_delete_proc_t delete_resourceLOCKONLY; /* delete a specific resource */ 461 }; 462 463 /* 464 * Process 'priv', augmenting 'rights' as necessary. 465 * Returns 1 if processing is complete. 466 * Returns 0 if processing should continue in meth_acl() 467 */ 468 typedef int (*acl_proc_t)(struct transaction_t *txn, xmlNodePtr priv, 469 int *rights); 470 471 /* Function to do special processing for DELETE method (optional) */ 472 typedef int (*delete_proc_t)(struct transaction_t *txn, struct mailbox *mailbox, 473 struct index_record *record, void *data); 474 475 /* Function to do special processing for GET method (optional) */ 476 typedef int (*get_proc_t)(struct transaction_t *txn, struct mailbox *mailbox, 477 struct index_record *record, void *data, void **obj); 478 479 /* Function to convert to/from MIME type */ 480 struct mime_type_t { 481 const char *content_type; 482 const char *version; 483 const char *file_ext; 484 struct buf* (*from_object)(void *); 485 void* (*to_object)(const struct buf *); 486 void (*free)(void *); 487 const char* (*begin_stream)(struct buf *, struct mailbox *mailbox, 488 const char *prodid, const char *name, 489 const char *desc, const char *color); 490 void (*end_stream)(struct buf *); 491 }; 492 493 /* meth_mkcol() parameters */ 494 typedef int (*mkcol_proc_t)(struct mailbox *mailbox); 495 496 struct mkcol_params { 497 unsigned location_precond; /* precond code for bad location */ 498 uint32_t mbtype; /* mailbox type collection */ 499 mkcol_proc_t proc; /* func to do post-create processing */ 500 }; 501 502 /* 503 * Function to do special processing for POST method (optional). 504 * Returns HTTP_CONTINUE if processing should continue in meth_post(), 505 * otherwise processing is complete. 506 */ 507 typedef int (*post_proc_t)(struct transaction_t *txn); 508 509 typedef int (*import_proc_t)(struct transaction_t *txn, void *obj, 510 struct mailbox *mailbox, void *davdb, 511 xmlNodePtr root, xmlNsPtr *ns, unsigned flags); 512 513 /* POST "mode" bits */ 514 enum { 515 POST_ADDMEMBER = (1<<0), 516 POST_SHARE = (1<<1) 517 }; 518 519 /* meth_put() parameters */ 520 typedef int (*put_proc_t)(struct transaction_t *txn, void *obj, 521 struct mailbox *mailbox, const char *resource, 522 void *davdb, unsigned flags); 523 524 struct copy_params { 525 unsigned uid_conf_precond; /* precond code for UID conflict */ 526 put_proc_t proc; /* function to process & COPY a rsrc */ 527 }; 528 529 struct post_params { 530 unsigned allowed; /* allowed generic POST "modes" */ 531 post_proc_t proc; /* special POST handling (optional) */ 532 struct { 533 unsigned data_ns; /* namespace of "data" property */ 534 const char *data_prop; /* name of "data" prop for CRUD (opt) */ 535 import_proc_t import; /* func to import multiple rsrcs (opt) */ 536 } bulk; 537 }; 538 539 struct put_params { 540 unsigned supp_data_precond; /* precond code for unsupported data */ 541 put_proc_t proc; /* function to process & PUT a rsrc */ 542 }; 543 544 struct propfind_params { 545 unsigned finite_depth_precond; /* precond code for finite depth */ 546 const struct prop_entry *lprops; /* array of "live" properties */ 547 }; 548 549 /* meth_report() parameters */ 550 typedef int (*report_proc_t)(struct transaction_t *txn, 551 struct meth_params *rparams, 552 xmlNodePtr inroot, struct propfind_ctx *fctx); 553 554 struct report_type_t { 555 const char *name; /* report name */ 556 unsigned ns; /* report namespace */ 557 const char *resp_root; /* name of XML root element in resp */ 558 report_proc_t proc; /* function to generate the report */ 559 unsigned long reqd_privs; /* privileges required to run report */ 560 unsigned flags; /* report-specific flags */ 561 }; 562 563 /* Report flags */ 564 enum { 565 REPORT_NEED_MBOX = (1<<0), 566 REPORT_NEED_PROPS = (1<<1), 567 REPORT_ALLOW_PROPS = (1<<2), 568 REPORT_DEPTH_ZERO = (1<<3) 569 }; 570 571 /* Overwrite flags */ 572 enum { 573 OVERWRITE_NO = 0, 574 OVERWRITE_YES 575 }; 576 577 struct meth_params { 578 struct mime_type_t *mime_types; /* array of MIME types and conv funcs */ 579 parse_path_t parse_path; /* parse URI path & generate mboxname */ 580 get_validators_t get_validators; /* fetch resource validators */ 581 get_modseq_t get_modseq; /* fetch resource modseq */ 582 check_precond_t check_precond; /* check headers for preconditions */ 583 struct davdb_params davdb; /* DAV DB access functions */ 584 acl_proc_t acl_ext; /* special ACL handling (extensions) */ 585 struct copy_params copy; /* params for copying a resource */ 586 delete_proc_t delete; /* special DELETE handling (optional) */ 587 get_proc_t get; /* special GET handling (optional) */ 588 struct mkcol_params mkcol; /* params for creating new collection */ 589 struct patch_doc_t *patch_docs; /* array of patch docs & funcs (opt) */ 590 struct post_params post; /* params for POST handling */ 591 struct put_params put; /* params for putting a resource */ 592 struct propfind_params propfind; /* params for finding properties */ 593 const struct report_type_t *reports;/* array of reports & proc functions */ 594 }; 595 596 extern struct meth_params webdav_params; 597 598 enum { 599 MATCH_TYPE_CONTAINS = 0, 600 MATCH_TYPE_EQUALS, 601 MATCH_TYPE_PREFIX, 602 MATCH_TYPE_SUFFIX 603 }; 604 605 struct match_type_t { 606 const char *name; 607 unsigned value; 608 }; 609 610 extern const struct match_type_t dav_match_types[]; 611 612 enum { 613 COLLATION_UNICODE = 0, 614 COLLATION_ASCII, 615 COLLATION_OCTET 616 }; 617 618 struct collation_t { 619 const char *name; 620 unsigned value; 621 }; 622 623 extern const struct collation_t dav_collations[]; 624 625 struct text_match_t { 626 xmlChar *text; 627 unsigned negate : 1; 628 unsigned type : 3; 629 unsigned collation : 3; 630 struct text_match_t *next; 631 }; 632 633 struct param_filter { 634 xmlChar *name; 635 unsigned kind; 636 unsigned not_defined : 1; 637 struct text_match_t *match; 638 struct param_filter *next; 639 }; 640 641 struct prop_filter { 642 xmlChar *name; 643 unsigned kind; 644 unsigned allof : 1; 645 unsigned not_defined : 1; 646 void *other; /* some other filter defined by caller */ 647 struct text_match_t *match; 648 struct param_filter *param; 649 struct prop_filter *next; 650 }; 651 652 struct filter_profile_t { 653 unsigned allof : 1; 654 unsigned collation : 3; 655 unsigned filter_precond; 656 unsigned collation_precond; 657 unsigned (*prop_string_to_kind)(const char *); 658 unsigned no_prop_value; 659 unsigned (*param_string_to_kind)(const char *); 660 unsigned no_param_value; 661 void (*parse_propfilter)(xmlNodePtr, struct prop_filter *, 662 struct error_t *); 663 }; 664 665 #define DAV_FILTER_ISNOTDEF_ERR \ 666 "is-not-defined can NOT be combined with other elements" 667 668 void dav_get_synctoken(struct mailbox *mailbox, 669 struct buf *buf, const char *prefix); 670 671 void dav_parse_propfilter(xmlNodePtr root, struct prop_filter **prop, 672 struct filter_profile_t *profile, 673 struct error_t *error); 674 void dav_free_propfilter(struct prop_filter *prop); 675 int dav_apply_textmatch(xmlChar *text, struct text_match_t *match); 676 677 int report_expand_prop(struct transaction_t *txn, struct meth_params *rparams, 678 xmlNodePtr inroot, struct propfind_ctx *fctx); 679 int report_acl_prin_prop(struct transaction_t *txn, struct meth_params *rparams, 680 xmlNodePtr inroot, struct propfind_ctx *fctx); 681 int report_multiget(struct transaction_t *txn, struct meth_params *rparams, 682 xmlNodePtr inroot, struct propfind_ctx *fctx); 683 int report_sync_col(struct transaction_t *txn, struct meth_params *rparams, 684 xmlNodePtr inroot, struct propfind_ctx *fctx); 685 686 687 unsigned long calcarddav_allow_cb(struct request_target_t *tgt); 688 int dav_parse_req_target(struct transaction_t *txn, 689 struct meth_params *params); 690 int calcarddav_parse_path(const char *path, struct request_target_t *tgt, 691 const char *mboxprefix, const char **resultstr); 692 int dav_get_validators(struct mailbox *mailbox, void *data, 693 const char *userid, struct index_record *record, 694 const char **etag, time_t *lastmod); 695 modseq_t dav_get_modseq(struct mailbox *mailbox, 696 void *data, const char *userid); 697 int dav_check_precond(struct transaction_t *txn, struct meth_params *params, 698 struct mailbox *mailbox, const void *data, 699 const char *etag, time_t lastmod); 700 int dav_store_resource(struct transaction_t *txn, 701 const char *data, size_t datalen, 702 struct mailbox *mailbox, struct index_record *oldrecord, 703 modseq_t createdmodseq, strarray_t *imapflags); 704 int dav_premethod(struct transaction_t *txn); 705 unsigned get_preferences(struct transaction_t *txn); 706 struct mime_type_t *get_accept_type(const char **hdr, struct mime_type_t *types); 707 708 int parse_xml_body(struct transaction_t *txn, xmlNodePtr *root, 709 const char *mimetype); 710 711 size_t make_collection_url(struct buf *buf, const char *urlprefix, int haszzzz, 712 const mbname_t *mbname, const char *userid); 713 714 /* Initialize an XML tree */ 715 xmlNodePtr init_xml_response(const char *resp, int ns, 716 xmlNodePtr req, xmlNsPtr *respNs); 717 718 xmlNodePtr xml_add_href(xmlNodePtr parent, xmlNsPtr ns, const char *href); 719 xmlNodePtr xml_add_error(xmlNodePtr root, struct error_t *err, 720 xmlNsPtr *avail_ns); 721 xmlNodePtr xml_add_prop(long status, xmlNsPtr davns, 722 struct propstat *propstat, 723 const xmlChar *name, xmlNsPtr ns, 724 xmlChar *content, unsigned precond); 725 void xml_add_lockdisc(xmlNodePtr node, const char *path, struct dav_data *data); 726 int ensure_ns(xmlNsPtr *respNs, int ns, xmlNodePtr node, 727 const char *url, const char *prefix); 728 729 int xml_add_response(struct propfind_ctx *fctx, long code, unsigned precond, 730 const char *desc, const char *location); 731 int propfind_by_resource(void *rock, void *data); 732 int propfind_by_collection(const mbentry_t *mbentry, void *rock); 733 int expand_property(xmlNodePtr inroot, struct propfind_ctx *fctx, 734 struct namespace_t *namespace, const char *href, 735 parse_path_t parse_path, const struct prop_entry *lprops, 736 xmlNodePtr root, int depth); 737 738 int preload_proplist(xmlNodePtr proplist, struct propfind_ctx *fctx); 739 void free_entry_list(struct propfind_entry_list *elist); 740 741 /* DAV method processing functions */ 742 int meth_acl(struct transaction_t *txn, void *params); 743 int meth_copy_move(struct transaction_t *txn, void *params); 744 int meth_delete(struct transaction_t *txn, void *params); 745 int meth_get_head(struct transaction_t *txn, void *params); 746 int meth_lock(struct transaction_t *txn, void *params); 747 int meth_mkcol(struct transaction_t *txn, void *params); 748 int meth_propfind(struct transaction_t *txn, void *params); 749 int meth_proppatch(struct transaction_t *txn, void *params); 750 int meth_patch(struct transaction_t *txn, void *params); 751 int meth_post(struct transaction_t *txn, void *params); 752 int meth_put(struct transaction_t *txn, void *params); 753 int meth_report(struct transaction_t *txn, void *params); 754 int meth_unlock(struct transaction_t *txn, void *params); 755 756 757 /* PROPFIND callbacks */ 758 759 int propfind_getdata(const xmlChar *name, xmlNsPtr ns, 760 struct propfind_ctx *fctx, 761 xmlNodePtr prop, struct propstat propstat[], 762 struct mime_type_t *mime_types, 763 struct mime_type_t **out_type, 764 const char *data, unsigned long datalen); 765 int propfind_fromdb(const xmlChar *name, xmlNsPtr ns, 766 struct propfind_ctx *fctx, 767 xmlNodePtr prop, xmlNodePtr resp, 768 struct propstat propstat[], void *rock); 769 int propfind_fromhdr(const xmlChar *name, xmlNsPtr ns, 770 struct propfind_ctx *fctx, 771 xmlNodePtr prop, xmlNodePtr resp, 772 struct propstat propstat[], void *rock); 773 int propfind_creationdate(const xmlChar *name, xmlNsPtr ns, 774 struct propfind_ctx *fctx, 775 xmlNodePtr prop, xmlNodePtr resp, 776 struct propstat propstat[], void *rock); 777 int propfind_collectionname(const xmlChar *name, xmlNsPtr ns, 778 struct propfind_ctx *fctx, 779 xmlNodePtr prop, xmlNodePtr resp, 780 struct propstat propstat[], void *rock); 781 int propfind_getlength(const xmlChar *name, xmlNsPtr ns, 782 struct propfind_ctx *fctx, 783 xmlNodePtr prop, xmlNodePtr resp, 784 struct propstat propstat[], void *rock); 785 int propfind_getetag(const xmlChar *name, xmlNsPtr ns, 786 struct propfind_ctx *fctx, 787 xmlNodePtr prop, xmlNodePtr resp, 788 struct propstat propstat[], void *rock); 789 int propfind_getlastmod(const xmlChar *name, xmlNsPtr ns, 790 struct propfind_ctx *fctx, 791 xmlNodePtr prop, xmlNodePtr resp, 792 struct propstat propstat[], void *rock); 793 int propfind_lockdisc(const xmlChar *name, xmlNsPtr ns, 794 struct propfind_ctx *fctx, 795 xmlNodePtr prop, xmlNodePtr resp, 796 struct propstat propstat[], void *rock); 797 int propfind_suplock(const xmlChar *name, xmlNsPtr ns, 798 struct propfind_ctx *fctx, 799 xmlNodePtr prop, xmlNodePtr resp, 800 struct propstat propstat[], void *rock); 801 802 int propfind_reportset(const xmlChar *name, xmlNsPtr ns, 803 struct propfind_ctx *fctx, 804 xmlNodePtr prop, xmlNodePtr resp, 805 struct propstat propstat[], void *rock); 806 807 int propfind_methodset(const xmlChar *name, xmlNsPtr ns, 808 struct propfind_ctx *fctx, 809 xmlNodePtr prop, xmlNodePtr, 810 struct propstat propstat[], void *rock); 811 812 int propfind_collationset(const xmlChar *name, xmlNsPtr ns, 813 struct propfind_ctx *fctx, 814 xmlNodePtr prop, xmlNodePtr resp, 815 struct propstat propstat[], void *rock); 816 817 int propfind_principalurl(const xmlChar *name, xmlNsPtr ns, 818 struct propfind_ctx *fctx, 819 xmlNodePtr prop, xmlNodePtr resp, 820 struct propstat propstat[], void *rock); 821 int propfind_owner(const xmlChar *name, xmlNsPtr ns, 822 struct propfind_ctx *fctx, 823 xmlNodePtr prop, xmlNodePtr resp, 824 struct propstat propstat[], void *rock); 825 int propfind_supprivset(const xmlChar *name, xmlNsPtr ns, 826 struct propfind_ctx *fctx, 827 xmlNodePtr prop, xmlNodePtr resp, 828 struct propstat propstat[], void *rock); 829 int propfind_curprivset(const xmlChar *name, xmlNsPtr ns, 830 struct propfind_ctx *fctx, 831 xmlNodePtr prop, xmlNodePtr resp, 832 struct propstat propstat[], void *rock); 833 int propfind_acl(const xmlChar *name, xmlNsPtr ns, 834 struct propfind_ctx *fctx, 835 xmlNodePtr prop, xmlNodePtr resp, 836 struct propstat propstat[], void *rock); 837 int propfind_aclrestrict(const xmlChar *name, xmlNsPtr ns, 838 struct propfind_ctx *fctx, 839 xmlNodePtr prop, xmlNodePtr resp, 840 struct propstat propstat[], void *rock); 841 int propfind_princolset(const xmlChar *name, xmlNsPtr ns, 842 struct propfind_ctx *fctx, 843 xmlNodePtr prop, xmlNodePtr resp, 844 struct propstat propstat[], void *rock); 845 846 int propfind_quota(const xmlChar *name, xmlNsPtr ns, 847 struct propfind_ctx *fctx, 848 xmlNodePtr prop, xmlNodePtr resp, 849 struct propstat propstat[], void *rock); 850 851 int propfind_curprin(const xmlChar *name, xmlNsPtr ns, 852 struct propfind_ctx *fctx, 853 xmlNodePtr prop, xmlNodePtr resp, 854 struct propstat propstat[], void *rock); 855 856 int propfind_serverinfo(const xmlChar *name, xmlNsPtr ns, 857 struct propfind_ctx *fctx, 858 xmlNodePtr prop, xmlNodePtr resp, 859 struct propstat propstat[], void *rock); 860 861 int propfind_addmember(const xmlChar *name, xmlNsPtr ns, 862 struct propfind_ctx *fctx, 863 xmlNodePtr prop, xmlNodePtr resp, 864 struct propstat propstat[], void *rock); 865 866 int propfind_sync_token(const xmlChar *name, xmlNsPtr ns, 867 struct propfind_ctx *fctx, 868 xmlNodePtr prop, xmlNodePtr resp, 869 struct propstat propstat[], void *rock); 870 871 int propfind_bulkrequests(const xmlChar *name, xmlNsPtr ns, 872 struct propfind_ctx *fctx, 873 xmlNodePtr prop, xmlNodePtr resp, 874 struct propstat propstat[], void *rock); 875 876 int propfind_calurl(const xmlChar *name, xmlNsPtr ns, 877 struct propfind_ctx *fctx, 878 xmlNodePtr prop, xmlNodePtr resp, 879 struct propstat propstat[], void *rock); 880 int propfind_caluseraddr(const xmlChar *name, xmlNsPtr ns, 881 struct propfind_ctx *fctx, 882 xmlNodePtr prop, xmlNodePtr resp, 883 struct propstat propstat[], void *rock); 884 int propfind_caluseremail(const xmlChar *name, xmlNsPtr ns, 885 struct propfind_ctx *fctx, 886 xmlNodePtr prop, xmlNodePtr resp, 887 struct propstat propstat[], void *rock); 888 int proppatch_caluseraddr(xmlNodePtr prop, unsigned set, 889 struct proppatch_ctx *pctx, 890 struct propstat propstat[], void *rock); 891 int propfind_calusertype(const xmlChar *name, xmlNsPtr ns, 892 struct propfind_ctx *fctx, 893 xmlNodePtr prop, xmlNodePtr resp, 894 struct propstat propstat[], void *rock); 895 int propfind_abookhome(const xmlChar *name, xmlNsPtr ns, 896 struct propfind_ctx *fctx, 897 xmlNodePtr prop, xmlNodePtr resp, 898 struct propstat propstat[], void *rock); 899 900 int propfind_push_transports(const xmlChar *name, xmlNsPtr ns, 901 struct propfind_ctx *fctx, 902 xmlNodePtr prop, xmlNodePtr resp, 903 struct propstat propstat[], void *rock); 904 int propfind_pushkey(const xmlChar *name, xmlNsPtr ns, 905 struct propfind_ctx *fctx, 906 xmlNodePtr prop, xmlNodePtr resp, 907 struct propstat propstat[], void *rock); 908 909 /* PROPPATCH callbacks */ 910 int proppatch_todb(xmlNodePtr prop, unsigned set, struct proppatch_ctx *pctx, 911 struct propstat propstat[], void *rock); 912 int proppatch_restype(xmlNodePtr prop, unsigned set, struct proppatch_ctx *pctx, 913 struct propstat propstat[], void *rock); 914 915 #endif /* HTTP_DAV_H */ 916