From: William A. Rowe Jr Date: Sat, 27 Jan 2001 21:28:28 +0000 (+0000) Subject: Use the appropriate APR_FINFO_flags for the apr_stat/lstat/getfileinfo X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e458a4684910619cc0b8598e7fd89863a63a49f;p=apache Use the appropriate APR_FINFO_flags for the apr_stat/lstat/getfileinfo calls to avoid ownership and permissions on Win32 when they are not required, and until they are implemented. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@87873 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index d0399d0760..40912ce2ae 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,11 @@ Changes with Apache 2.0b1 + *) Modify the apr_stat/lstat/getfileinfo calls within apache to use + the most optimal APR_FINFO_wanted bits. This spares Win32 from + performing very expensive owner, group and permission lookups + and allows the server to function until these apr_finfo_t fields + are implemented under Win32. [William Rowe] + *) Support for typedsafe optional functions - that is functions exported by optional modules, which, therefore, may or may not be present, depending on configuration. See the experimental modules mod_optional_fn_{ex,im}port diff --git a/modules/arch/win32/mod_isapi.c b/modules/arch/win32/mod_isapi.c index b2a551b33a..803b9da139 100644 --- a/modules/arch/win32/mod_isapi.c +++ b/modules/arch/win32/mod_isapi.c @@ -1239,7 +1239,7 @@ static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy, fspec = ap_os_case_canonical_filename(cmd->pool, filename); if (apr_stat(&tmp, fspec, - APR_FINFO_NORM, cmd->temp_pool) != APR_SUCCESS) { + APR_FINFO_TYPE, cmd->temp_pool) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server, "ISAPI: unable to stat(%s), skipping", filename); return NULL; diff --git a/modules/cache/mod_file_cache.c b/modules/cache/mod_file_cache.c index cb815d82a2..cf2d8cc70f 100644 --- a/modules/cache/mod_file_cache.c +++ b/modules/cache/mod_file_cache.c @@ -200,7 +200,7 @@ static const char *cachefile(cmd_parms *cmd, void *dummy, const char *filename) /* canonicalize the file name? */ /* os_canonical... */ /* XXX: uh... yea, or expect them to be -very- accurate typists */ - if ((rc = apr_stat(&tmp.finfo, filename, APR_FINFO_NORM, + if ((rc = apr_stat(&tmp.finfo, filename, APR_FINFO_MIN, cmd->temp_pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, "mod_file_cache: unable to stat(%s), skipping", filename); @@ -250,7 +250,7 @@ static const char *mmapfile(cmd_parms *cmd, void *dummy, const char *filename) const char *fspec; fspec = ap_os_case_canonical_filename(cmd->pool, filename); - if ((rc = apr_stat(&tmp.finfo, fspec, APR_FINFO_NORM, + if ((rc = apr_stat(&tmp.finfo, fspec, APR_FINFO_MIN, cmd->temp_pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, "mod_file_cache: unable to stat(%s), skipping", filename); diff --git a/modules/http/http_request.c b/modules/http/http_request.c index af289b71f7..f9032da229 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -180,7 +180,7 @@ static int check_symlinks(char *d, int opts, apr_pool_t *p) else lastp = NULL; - res = apr_lstat(&lfi, d, APR_FINFO_NORM, p); + res = apr_lstat(&lfi, d, APR_FINFO_TYPE | APR_FINFO_OWNER, p); if (lastp) *lastp = '/'; @@ -190,7 +190,8 @@ static int check_symlinks(char *d, int opts, apr_pool_t *p) * the like may cons up a way to run the transaction anyway)... */ - if ((res != APR_SUCCESS) || lfi.filetype != APR_LNK) + if ((res != APR_SUCCESS && res != APR_INCOMPLETE) + || (lfi.filetype != APR_LNK)) return OK; /* OK, it's a symlink. May still be OK with OPT_SYM_OWNER */ @@ -198,11 +199,16 @@ static int check_symlinks(char *d, int opts, apr_pool_t *p) if (!(opts & OPT_SYM_OWNER)) return HTTP_FORBIDDEN; - if (apr_stat(&fi, d, APR_FINFO_NORM, p) != APR_SUCCESS) + /* OPT_SYM_OWNER only works if we can get the owner from the file */ + + if (res != APR_SUCCESS) + return HTTP_FORBIDDEN; + + if (apr_stat(&fi, d, APR_FINFO_OWNER, p) != APR_SUCCESS) return HTTP_FORBIDDEN; - return ((fi.valid & lfi.valid & APR_FINFO_OWNER) - && (fi.user == lfi.user)) ? OK : HTTP_FORBIDDEN; + /* TODO: replace with an apr_compare_users() fn */ + return (fi.user == lfi.user) ? OK : HTTP_FORBIDDEN; #endif } @@ -281,7 +287,7 @@ static int get_path_info(request_rec *r) if (cp != end) *cp = '/'; - if (rv == APR_SUCCESS) { + if (rv == APR_SUCCESS || rv == APR_INCOMPLETE) { /* * Aha! Found something. If it was a directory, we will search * contents of that directory for a multi_match, so the PATH_INFO @@ -297,8 +303,7 @@ static int get_path_info(request_rec *r) *cp = '\0'; return OK; } - - if (APR_STATUS_IS_ENOENT(rv) || APR_STATUS_IS_ENOTDIR(rv)) { + else if (APR_STATUS_IS_ENOENT(rv) || APR_STATUS_IS_ENOTDIR(rv)) { last_cp = cp; while (--cp > path && *cp != '/') @@ -967,13 +972,15 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, if (ap_strchr_c(new_file, '/') == NULL) { char *udir = ap_make_dirstr_parent(rnew->pool, r->uri); + apr_status_t rv; rnew->uri = ap_make_full_path(rnew->pool, udir, new_file); rnew->filename = ap_make_full_path(rnew->pool, fdir, new_file); ap_parse_uri(rnew, rnew->uri); /* fill in parsed_uri values */ - if (apr_stat(&rnew->finfo, rnew->filename, - APR_FINFO_NORM, rnew->pool) != APR_SUCCESS) { + if (((rv = apr_stat(&rnew->finfo, rnew->filename, + APR_FINFO_NORM, rnew->pool)) != APR_SUCCESS) + && (rv != APR_INCOMPLETE)) { rnew->finfo.protection = 0; } diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index 2a38a72b8d..b86e65674e 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -1468,7 +1468,7 @@ static float find_content_length(negotiation_state *neg, var_rec *variant) variant->file_name); if (apr_stat(&statb, fullname, - APR_FINFO_NORM, neg->pool) == APR_SUCCESS) { + APR_FINFO_SIZE, neg->pool) == APR_SUCCESS) { /* Note, precision may be lost */ variant->bytes = (float) statb.size; } diff --git a/os/win32/mod_isapi.c b/os/win32/mod_isapi.c index b2a551b33a..803b9da139 100644 --- a/os/win32/mod_isapi.c +++ b/os/win32/mod_isapi.c @@ -1239,7 +1239,7 @@ static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy, fspec = ap_os_case_canonical_filename(cmd->pool, filename); if (apr_stat(&tmp, fspec, - APR_FINFO_NORM, cmd->temp_pool) != APR_SUCCESS) { + APR_FINFO_TYPE, cmd->temp_pool) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server, "ISAPI: unable to stat(%s), skipping", filename); return NULL; diff --git a/server/config.c b/server/config.c index 8bf52b350b..956add016b 100644 --- a/server/config.c +++ b/server/config.c @@ -1271,17 +1271,17 @@ void ap_process_resource_config(server_rec *s, const char *fname, if ((ap_server_pre_read_config->nelts || ap_server_post_read_config->nelts) && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) { - if (apr_stat(&finfo, fname, APR_FINFO_NORM, p) != APR_SUCCESS) + if (apr_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS) return; } /* * here we want to check if the candidate file is really a * directory, and most definitely NOT a symlink (to prevent - * horrible loops). If so, let's recurse and toss it back into - * the function. + * horrible loops). So we do so above using apr_lstat. + * If so, let's recurse and toss it back into the function. */ - if (ap_is_rdirectory(ptemp, fname)) { + if (finfo.filetype == APR_DIR) { apr_dir_t *dirp; apr_finfo_t dirent; int current; diff --git a/server/log.c b/server/log.c index 24751d570c..c83ce5481d 100644 --- a/server/log.c +++ b/server/log.c @@ -521,7 +521,7 @@ void ap_log_pid(apr_pool_t *p, const char *fname) fname = ap_server_root_relative(p, fname); mypid = getpid(); if (mypid != saved_pid - && apr_stat(&finfo, fname, APR_FINFO_NORM, p) == APR_SUCCESS) { + && apr_stat(&finfo, fname, APR_FINFO_MTIME, p) == APR_SUCCESS) { /* WINCH and HUP call this on each restart. * Only warn on first time through for this pid. * diff --git a/server/mpm/beos/beos.c b/server/mpm/beos/beos.c index efd1f735d3..ba6e9e1d0d 100644 --- a/server/mpm/beos/beos.c +++ b/server/mpm/beos/beos.c @@ -1003,7 +1003,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/mpm/dexter/dexter.c b/server/mpm/dexter/dexter.c index be77322504..9b13a85e2f 100644 --- a/server/mpm/dexter/dexter.c +++ b/server/mpm/dexter/dexter.c @@ -1347,7 +1347,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/mpm/mpmt_beos/mpmt_beos.c b/server/mpm/mpmt_beos/mpmt_beos.c index 618ec8a990..9d41c2ac8e 100644 --- a/server/mpm/mpmt_beos/mpmt_beos.c +++ b/server/mpm/mpmt_beos/mpmt_beos.c @@ -1015,7 +1015,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg) } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/mpm/mpmt_pthread/mpmt_pthread.c b/server/mpm/mpmt_pthread/mpmt_pthread.c index 19a234eb97..be95ecac72 100644 --- a/server/mpm/mpmt_pthread/mpmt_pthread.c +++ b/server/mpm/mpmt_pthread/mpmt_pthread.c @@ -1364,7 +1364,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index eb1968482b..e914f9347a 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -1715,7 +1715,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/mpm/spmt_os2/spmt_os2.c b/server/mpm/spmt_os2/spmt_os2.c index 1c5cfaf32d..d22f02a735 100644 --- a/server/mpm/spmt_os2/spmt_os2.c +++ b/server/mpm/spmt_os2/spmt_os2.c @@ -1496,7 +1496,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg) } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index cd31219080..3da8215eab 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -2299,7 +2299,7 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg) } fname = ap_server_root_relative(cmd->pool, arg); - if ((apr_stat(&finfo, fname, APR_FINFO_NORM, cmd->pool) != APR_SUCCESS) + if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS) || (finfo.filetype != APR_DIR)) { return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, " does not exist or is not a directory", NULL); diff --git a/server/util.c b/server/util.c index 62bd5eeade..3e9d7a1d3c 100644 --- a/server/util.c +++ b/server/util.c @@ -895,7 +895,7 @@ AP_DECLARE(apr_status_t) ap_pcfg_openfile(configfile_t **ret_cfg, apr_pool_t *p, if (status != APR_SUCCESS) return status; - status = apr_getfileinfo(&finfo, APR_FINFO_NORM, file); + status = apr_getfileinfo(&finfo, APR_FINFO_TYPE, file); if (status != APR_SUCCESS) return status; @@ -1679,7 +1679,7 @@ AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path) { apr_finfo_t finfo; - if (apr_stat(&finfo, path, APR_FINFO_NORM, p) != APR_SUCCESS) + if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) return 0; /* in error condition, just return no */ return (finfo.filetype == APR_DIR); @@ -1689,7 +1689,7 @@ AP_DECLARE(int) ap_is_rdirectory(apr_pool_t *p, const char *path) { apr_finfo_t finfo; - if (apr_lstat(&finfo, path, APR_FINFO_NORM, p) != APR_SUCCESS) + if (apr_lstat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) return 0; /* in error condition, just return no */ return (finfo.filetype == APR_DIR);