| 659 | */ |
| 660 | |
| 661 | AP_DECLARE(int) ap_directory_walk(request_rec *r) |
| 662 | { |
| 663 | ap_conf_vector_t *now_merged = NULL; |
| 664 | core_server_config *sconf = |
| 665 | ap_get_core_module_config(r->server->module_config); |
| 666 | ap_conf_vector_t **sec_ent = (ap_conf_vector_t **) sconf->sec_dir->elts; |
| 667 | int num_sec = sconf->sec_dir->nelts; |
| 668 | walk_cache_t *cache; |
| 669 | char *entry_dir; |
| 670 | apr_status_t rv; |
| 671 | int cached; |
| 672 | |
| 673 | /* XXX: Better (faster) tests needed!!! |
| 674 | * |
| 675 | * "OK" as a response to a real problem is not _OK_, but to allow broken |
| 676 | * modules to proceed, we will permit the not-a-path filename to pass the |
| 677 | * following two tests. This behavior may be revoked in future versions |
| 678 | * of Apache. We still must catch it later if it's heading for the core |
| 679 | * handler. Leave INFO notes here for module debugging. |
| 680 | */ |
| 681 | if (r->filename == NULL) { |
| 682 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00029) |
| 683 | "Module bug? Request filename is missing for URI %s", |
| 684 | r->uri); |
| 685 | return OK; |
| 686 | } |
| 687 | |
| 688 | /* Canonicalize the file path without resolving filename case or aliases |
| 689 | * so we can begin by checking the cache for a recent directory walk. |
| 690 | * This call will ensure we have an absolute path in the same pass. |
| 691 | */ |
| 692 | if ((rv = apr_filepath_merge(&entry_dir, NULL, r->filename, |
| 693 | APR_FILEPATH_NOTRELATIVE, r->pool)) |
| 694 | != APR_SUCCESS) { |
| 695 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00030) |
| 696 | "Module bug? Request filename path %s is invalid or " |
| 697 | "or not absolute for uri %s", |
| 698 | r->filename, r->uri); |
| 699 | return OK; |
| 700 | } |
| 701 | |
| 702 | /* XXX Notice that this forces path_info to be canonical. That might |
| 703 | * not be desired by all apps. However, some of those same apps likely |
| 704 | * have significant security holes. |
| 705 | */ |
| 706 | r->filename = entry_dir; |
| 707 | |
| 708 | cache = prep_walk_cache(AP_NOTE_DIRECTORY_WALK, r); |
| 709 | cached = (cache->cached != NULL); |
| 710 | |
| 711 | /* If this is not a dirent subrequest with a preconstructed |
| 712 | * r->finfo value, then we can simply stat the filename to |
| 713 | * save burning mega-cycles with unneeded stats - if this is |
| 714 | * an exact file match. We don't care about failure... we |
| 715 | * will stat by component failing this meager attempt. |
| 716 | * |
| 717 | * It would be nice to distinguish APR_ENOENT from other |
| 718 | * types of failure, such as APR_ENOTDIR. We can do something |
no test coverage detected