]> granicus.if.org Git - apache/commitdiff
split ap_process_resource_config into two functions (since we don't wanna
authorAndré Malo <nd@apache.org>
Thu, 7 Aug 2003 16:38:19 +0000 (16:38 +0000)
committerAndré Malo <nd@apache.org>
Thu, 7 Aug 2003 16:38:19 +0000 (16:38 +0000)
change the api). Only the first one (the ap_ entry point) now checks
for fnmatch and the second one will be called for every file/directory
included.
This, however, avoids infinite recursions, if a filename contains
wildcard characters.

PR: 22194

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@100931 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/config.c

diff --git a/CHANGES b/CHANGES
index bf1985e16f688b1de3c925b6bf621e557682ea48..d23ffce1c3bfd6b9fe90eb059c79dfc047467809 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@ Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) Avoid an infinite recursion, which occured if the name of an included
+     config file or directory contained a wildcard character. PR 22194.
+     [André Malo]
+
   *) mod_dav: Use bucket brigades when reading PUT data. This avoids
      problems if the data stream is modified by an input filter. PR 22104.
      [Tim Robbins <tim@robbins.dropbear.id.au>, André Malo]
index 3be4368841f1f7ba717a0183d518d8779bfb173c..86daeeb66698133919a17f00e24c7129ecdec5b5 100644 (file)
@@ -1442,64 +1442,23 @@ static int fname_alphasort(const void *fn1, const void *fn2)
     return strcmp(f1->fname,f2->fname);
 }
 
-AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
-                                            ap_directive_t **conftree,
-                                            apr_pool_t *p,
-                                            apr_pool_t *ptemp)
+static void process_resource_config_nofnmatch(server_rec *s, const char *fname,
+                                              ap_directive_t **conftree,
+                                              apr_pool_t *p,
+                                              apr_pool_t *ptemp)
 {
     cmd_parms parms;
-    apr_finfo_t finfo;
-    const char *errmsg;
     ap_configfile_t *cfp;
-    int ispatt;
-
-    /* XXX: lstat() won't work on the wildcard pattern...
-     */
-
-    /* don't require conf/httpd.conf if we have a -C or -c switch */
-    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_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS)
-            return;
-    }
+    const char *errmsg;
 
-    ispatt = apr_fnmatch_test(fname);
-    if (ispatt || ap_is_rdirectory(p, fname)) {
+    if (ap_is_rdirectory(p, fname)) {
         apr_dir_t *dirp;
         apr_finfo_t dirent;
         int current;
         apr_array_header_t *candidates = NULL;
         fnames *fnew;
         apr_status_t rv;
-        char errmsg[120], *path = apr_pstrdup(p, fname), *pattern = NULL;
-
-        if (ispatt) {
-            pattern = ap_strrchr(path, '/');
-        
-            AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */
-        
-            *pattern++ = '\0';
-            
-            if (apr_fnmatch_test(path)) {
-                fprintf(stderr, "%s: wildcard patterns not allowed in Include "
-                        "%s\n", ap_server_argv0, fname);
-                exit(1);
-            }
-
-            if (!ap_is_rdirectory(p, path)){ 
-                fprintf(stderr, "%s: Include directory '%s' not found",
-                        ap_server_argv0, path);
-                exit(1);
-            }
-            
-            if (!apr_fnmatch_test(pattern)) {
-                fprintf(stderr, "%s: must include a wildcard pattern "
-                        "for Include %s\n", ap_server_argv0, fname);
-                exit(1);
-            }
-
-        }
+        char errmsg[120], *path = apr_pstrdup(p, fname);
 
         /*
          * first course of business is to grok all the directory
@@ -1518,10 +1477,7 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
             /* strip out '.' and '..' */
             if (strcmp(dirent.name, ".")
-                && strcmp(dirent.name, "..")
-                && (!ispatt ||
-                    apr_fnmatch(pattern, dirent.name, 
-                                FNM_PERIOD) == APR_SUCCESS)) {
+                && strcmp(dirent.name, "..")) {
                 fnew = (fnames *) apr_array_push(candidates);
                 fnew->fname = ap_make_full_path(p, path, dirent.name);
             }
@@ -1538,7 +1494,8 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
              */
             for (current = 0; current < candidates->nelts; ++current) {
                 fnew = &((fnames *) candidates->elts)[current];
-                ap_process_resource_config(s, fnew->fname, conftree, p, ptemp);
+                process_resource_config_nofnmatch(s, fnew->fname, conftree, p,
+                                                  ptemp);
             }
         }
 
@@ -1546,7 +1503,6 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
     }
 
     /* GCC's initialization extensions are soooo nice here... */
-
     parms = default_parms;
     parms.pool = p;
     parms.temp_pool = ptemp;
@@ -1575,6 +1531,107 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
     }
 
     ap_cfg_closefile(cfp);
+
+    return;
+}
+
+AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
+                                            ap_directive_t **conftree,
+                                            apr_pool_t *p,
+                                            apr_pool_t *ptemp)
+{
+    /* XXX: lstat() won't work on the wildcard pattern...
+     */
+
+    /* don't require conf/httpd.conf if we have a -C or -c switch */
+    if ((ap_server_pre_read_config->nelts
+        || ap_server_post_read_config->nelts)
+        && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) {
+        apr_finfo_t finfo;
+
+        if (apr_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS)
+            return;
+    }
+
+    if (!apr_fnmatch_test(fname)) {
+        process_resource_config_nofnmatch(s, fname, conftree, p, ptemp);
+    }
+    else {
+        apr_dir_t *dirp;
+        apr_finfo_t dirent;
+        int current;
+        apr_array_header_t *candidates = NULL;
+        fnames *fnew;
+        apr_status_t rv;
+        char errmsg[120], *path = apr_pstrdup(p, fname), *pattern = NULL;
+
+        pattern = ap_strrchr(path, '/');
+
+        AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */
+
+        *pattern++ = '\0';
+
+        if (apr_fnmatch_test(path)) {
+            fprintf(stderr, "%s: wildcard patterns not allowed in Include "
+                    "%s\n", ap_server_argv0, fname);
+            exit(1);
+        }
+
+        if (!ap_is_rdirectory(p, path)){ 
+            fprintf(stderr, "%s: Include directory '%s' not found",
+                    ap_server_argv0, path);
+            exit(1);
+        }
+
+        if (!apr_fnmatch_test(pattern)) {
+            fprintf(stderr, "%s: must include a wildcard pattern "
+                    "for Include %s\n", ap_server_argv0, fname);
+            exit(1);
+        }
+
+        /*
+         * first course of business is to grok all the directory
+         * entries here and store 'em away. Recall we need full pathnames
+         * for this.
+         */
+        rv = apr_dir_open(&dirp, path, p);
+        if (rv != APR_SUCCESS) {
+            fprintf(stderr, "%s: could not open config directory %s: %s\n",
+                    ap_server_argv0, path,
+                    apr_strerror(rv, errmsg, sizeof errmsg));
+            exit(1);
+        }
+
+        candidates = apr_array_make(p, 1, sizeof(fnames));
+        while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
+            /* strip out '.' and '..' */
+            if (strcmp(dirent.name, ".")
+                && strcmp(dirent.name, "..")
+                && (apr_fnmatch(pattern, dirent.name,
+                                FNM_PERIOD) == APR_SUCCESS)) {
+                fnew = (fnames *) apr_array_push(candidates);
+                fnew->fname = ap_make_full_path(p, path, dirent.name);
+            }
+        }
+
+        apr_dir_close(dirp);
+        if (candidates->nelts != 0) {
+            qsort((void *) candidates->elts, candidates->nelts,
+                  sizeof(fnames), fname_alphasort);
+
+            /*
+             * Now recurse these... we handle errors and subdirectories
+             * via the recursion, which is nice
+             */
+            for (current = 0; current < candidates->nelts; ++current) {
+                fnew = &((fnames *) candidates->elts)[current];
+                process_resource_config_nofnmatch(s, fnew->fname, conftree, p,
+                                                  ptemp);
+            }
+        }
+    }
+
+    return;
 }
 
 AP_DECLARE(int) ap_process_config_tree(server_rec *s,