You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by nd...@apache.org on 2003/08/07 18:38:19 UTC

cvs commit: httpd-2.0/server config.c

nd          2003/08/07 09:38:19

  Modified:    .        CHANGES
               server   config.c
  Log:
  split ap_process_resource_config into two functions (since we don't wanna
  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
  
  Revision  Changes    Path
  1.1248    +4 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.1247
  retrieving revision 1.1248
  diff -u -r1.1247 -r1.1248
  --- CHANGES	6 Aug 2003 14:46:48 -0000	1.1247
  +++ CHANGES	7 Aug 2003 16:38:18 -0000	1.1248
  @@ -2,6 +2,10 @@
   
     [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 <ti...@robbins.dropbear.id.au>, Andr� Malo]
  
  
  
  1.165     +111 -54   httpd-2.0/server/config.c
  
  Index: config.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/config.c,v
  retrieving revision 1.164
  retrieving revision 1.165
  diff -u -r1.164 -r1.165
  --- config.c	17 Feb 2003 07:04:50 -0000	1.164
  +++ config.c	7 Aug 2003 16:38:19 -0000	1.165
  @@ -1442,64 +1442,23 @@
       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 @@
           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 @@
                */
               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 @@
       }
   
       /* GCC's initialization extensions are soooo nice here... */
  -
       parms = default_parms;
       parms.pool = p;
       parms.temp_pool = ptemp;
  @@ -1575,6 +1531,107 @@
       }
   
       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,