7575#include "apr_strings.h"
7676#include "apr_portable.h"
7777#include "apr_file_io.h"
78+ #include "apr_fnmatch.h"
7879
7980#define APR_WANT_STDIO
8081#define APR_WANT_STRFUNC
@@ -1442,6 +1443,7 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
14421443 apr_finfo_t finfo ;
14431444 const char * errmsg ;
14441445 ap_configfile_t * cfp ;
1446+ int ispatt ;
14451447
14461448 /* don't require conf/httpd.conf if we have a -C or -c switch */
14471449 if ((ap_server_pre_read_config -> nelts
@@ -1451,31 +1453,52 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
14511453 return ;
14521454 }
14531455
1454- /*
1455- * here we want to check if the candidate file is really a
1456- * directory, and most definitely NOT a symlink (to prevent
1457- * horrible loops). If so, let's recurse and toss it back
1458- * into the function.
1459- */
1460- if (ap_is_rdirectory (ptemp , fname )) {
1456+ ispatt = apr_fnmatch_test (fname );
1457+ if (ispatt || ap_is_rdirectory (p , fname )) {
14611458 apr_dir_t * dirp ;
14621459 apr_finfo_t dirent ;
14631460 int current ;
14641461 apr_array_header_t * candidates = NULL ;
14651462 fnames * fnew ;
14661463 apr_status_t rv ;
1467- char errmsg [120 ];
1464+ char errmsg [120 ], * path = apr_pstrdup (p , fname ), * pattern = NULL ;
1465+
1466+ if (ispatt ) {
1467+ pattern = ap_strrchr (path , '/' );
1468+
1469+ AP_DEBUG_ASSERT (pattern != NULL ); /* path must be absolute. */
1470+
1471+ * pattern ++ = '\0' ;
1472+
1473+ if (apr_fnmatch_test (path )) {
1474+ fprintf (stderr , "%s: wildcard patterns not allowed in Include "
1475+ "%s\n" , ap_server_argv0 , fname );
1476+ exit (1 );
1477+ }
1478+
1479+ if (!ap_is_rdirectory (p , path )){
1480+ fprintf (stderr , "%s: Include directory '%s' not found" ,
1481+ ap_server_argv0 , path );
1482+ exit (1 );
1483+ }
1484+
1485+ if (!apr_fnmatch_test (pattern )) {
1486+ fprintf (stderr , "%s: must include a wildcard pattern "
1487+ "for Include %s\n" , ap_server_argv0 , fname );
1488+ exit (1 );
1489+ }
1490+
1491+ }
14681492
14691493 /*
14701494 * first course of business is to grok all the directory
14711495 * entries here and store 'em away. Recall we need full pathnames
14721496 * for this.
14731497 */
1474- fprintf (stderr , "Processing config directory: %s\n" , fname );
1475- rv = apr_dir_open (& dirp , fname , p );
1498+ rv = apr_dir_open (& dirp , path , p );
14761499 if (rv != APR_SUCCESS ) {
14771500 fprintf (stderr , "%s: could not open config directory %s: %s\n" ,
1478- ap_server_argv0 , fname ,
1501+ ap_server_argv0 , path ,
14791502 apr_strerror (rv , errmsg , sizeof errmsg ));
14801503 exit (1 );
14811504 }
@@ -1484,9 +1507,12 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
14841507 while (apr_dir_read (& dirent , APR_FINFO_DIRENT , dirp ) == APR_SUCCESS ) {
14851508 /* strip out '.' and '..' */
14861509 if (strcmp (dirent .name , "." )
1487- && strcmp (dirent .name , ".." )) {
1510+ && strcmp (dirent .name , ".." )
1511+ && (!ispatt ||
1512+ apr_fnmatch (pattern , dirent .name ,
1513+ FNM_PERIOD ) == APR_SUCCESS )) {
14881514 fnew = (fnames * ) apr_array_push (candidates );
1489- fnew -> fname = ap_make_full_path (p , fname , dirent .name );
1515+ fnew -> fname = ap_make_full_path (p , path , dirent .name );
14901516 }
14911517 }
14921518
@@ -1501,7 +1527,6 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname,
15011527 */
15021528 for (current = 0 ; current < candidates -> nelts ; ++ current ) {
15031529 fnew = & ((fnames * ) candidates -> elts )[current ];
1504- fprintf (stderr , " Processing config file: %s\n" , fnew -> fname );
15051530 ap_process_resource_config (s , fnew -> fname , conftree , p , ptemp );
15061531 }
15071532 }
0 commit comments