diff -u -r freeradius-server-2.2.0.orig/src/include/libradius.h freeradius-server-2.2.0.configfile/src/include/libradius.h --- freeradius-server-2.2.0.orig/src/include/libradius.h 2012-09-10 07:51:34.000000000 -0400 +++ freeradius-server-2.2.0.configfile/src/include/libradius.h 2012-10-03 15:45:13.002106110 -0400 @@ -416,6 +416,17 @@ int fr_sockaddr2ipaddr(const struct sockaddr_storage *sa, socklen_t salen, fr_ipaddr_t *ipaddr, int * port); +int +str_starts_with(const char *subject, const char *pattern); +int +strn_starts_with(const char *subject, const char *pattern, size_t sbj_len, size_t pat_len); +int +str_ends_with(const char *subject, const char *pattern); +int +strn_ends_with(const char *subject, const char *pattern, size_t sbj_len, size_t pat_len); +int +fr_exclude_config_file(const char *basename); + #ifdef ASCEND_BINARY /* filters.c */ diff -u -r freeradius-server-2.2.0.orig/src/lib/misc.c freeradius-server-2.2.0.configfile/src/lib/misc.c --- freeradius-server-2.2.0.orig/src/lib/misc.c 2012-09-10 07:51:34.000000000 -0400 +++ freeradius-server-2.2.0.configfile/src/lib/misc.c 2012-10-03 15:50:27.717357782 -0400 @@ -28,6 +28,7 @@ #include #include #include +#include int fr_dns_lookups = 0; int fr_debug_flag = 0; @@ -650,3 +651,162 @@ return 1; } + + +/* + * Return true if subject starts with pattern, false otherwise. + * subject and pattern are NULL terminated strings. + */ +int +str_starts_with(const char *subject, const char *pattern) +{ + size_t sbj_len; + size_t pat_len; + + pat_len = strlen(pattern); + sbj_len = strlen(subject); + + return strn_starts_with(subject, pattern, sbj_len, pat_len); +} + +/* + * Return true if subject starts with pattern, false otherwise. + * subject and pattern are terminated by their respective length parameters. + */ +int +strn_starts_with(const char *subject, const char *pattern, size_t sbj_len, size_t pat_len) +{ + const char *s = NULL; + const char *p = NULL; + const char *pat_end = NULL; + + if (subject == NULL || pattern == NULL) return 0; + + if (pat_len > sbj_len) return 0; + + pat_end = pattern + pat_len; + + for (p = pattern, s = subject; p < pat_end; p++, s++) { + if (*p != *s) return 0; + } + return 1; + +} + +/* + * Return true if subject starts with pattern, false otherwise. + * subject and pattern are NULL terminated strings. + */ +int +str_ends_with(const char *subject, const char *pattern) +{ + size_t sbj_len; + size_t pat_len; + + pat_len = strlen(pattern); + sbj_len = strlen(subject); + + return strn_ends_with(subject, pattern, sbj_len, pat_len); +} + +/* + * Return true if subject ends with pattern, false otherwise. + * subject and pattern are terminated by their respective length parameters. + */ +int +strn_ends_with(const char *subject, const char *pattern, size_t sbj_len, size_t pat_len) +{ + const char *s = NULL; + const char *sbj_end = NULL; + const char *p = NULL; + const char *pat_end = NULL; + + if (subject == NULL || pattern == NULL) return 0; + + if (pat_len > sbj_len) return 0; + + pat_end = pattern + pat_len - 1; + sbj_end = subject + sbj_len - 1; + + for (p = pat_end, s = sbj_end; p >= pattern; p--, s--) { + if (*p != *s) return 0; + } + return 1; + +} + +/* + * Tests to see if the basename of a file found in a config directory + * should be excluded from being read because it is not a valid config + * file. The function returns true if the file basename should be + * excluded. + * + * The following basename's are excluded: + * + * Any basename beginning with a dot (.) + * Any basename beginning with a hash (i.e. pound sign, octothorp) (#) + * Any basename ending with a tilde (~) + * Any basename ending with the substring ".rpmsave" + * Any basename ending with the substring ".rpmnew" + * Any basename ending with the substring ".bak" + */ + +#ifdef HAVE_REGEX_H +#include + +/* + * Performs test with a regular expression. The regexp is compiled on + * first use and then saved in a static variable for future use. + */ + +int +fr_exclude_config_file(const char *basename) +{ + char *pattern = "^\\.|^#|~$|\\.rpmsave$|\\.rpmnew$|\\.bak$"; + //char *pattern = "*"; + int status; + static regex_t re; + static int compiled = 0; + + if (!compiled) { + if ((status = regcomp(&re, pattern, REG_NOSUB | REG_EXTENDED)) != 0) { + char error_buf[256]; + + regerror(status, &re, error_buf, sizeof(error_buf)); + fprintf(stderr, "fr_exclude_config_file: failed to compile regular expression \"%s\": %s", + pattern, error_buf); + + return(0); /* Since we can't perform test, accept all files */ + } + compiled = 1; + } + status = regexec(&re, basename, (size_t) 0, NULL, 0); + + if (status == 0) { + return 1; + } else { + return 0; + } +} + +#else + +/* + * Performs the test with starts_with and ends_with string utilities. + */ + +int +fr_exclude_config_file(const char *basename) +{ + if (str_starts_with(basename, ".")) return 1; + if (str_starts_with(basename, "#")) return 1; + + if (str_ends_with(basename, "~")) return 1; + if (str_ends_with(basename, ".rpmsave")) return 1; + if (str_ends_with(basename, ".rpmnew")) return 1; + if (str_ends_with(basename, ".bak")) return 1; + + return 0; +} + +#endif diff -u -r freeradius-server-2.2.0.orig/src/main/client.c freeradius-server-2.2.0.configfile/src/main/client.c --- freeradius-server-2.2.0.orig/src/main/client.c 2012-09-10 07:51:34.000000000 -0400 +++ freeradius-server-2.2.0.configfile/src/main/client.c 2012-10-03 15:52:35.351241760 -0400 @@ -845,13 +845,24 @@ } /* - * Read the directory, ignoring "." files. + * Read the directory, ignoring invalid files. */ while ((dp = readdir(dir)) != NULL) { const char *p; RADCLIENT *dc; - if (dp->d_name[0] == '.') continue; + /* + * Check for invalid file names + */ + if (fr_exclude_config_file(dp->d_name)) { + if (!(strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0)) { + cf_log_info(cs, + "skipping client file, invalid name \"%s/%s\"", + value, dp->d_name); + } + continue; + } /* * Check for valid characters @@ -863,7 +874,12 @@ (*p == '.')) continue; break; } - if (*p != '\0') continue; + if (*p != '\0') { + cf_log_info(cs, + "skipping client file, invalid characters in name \"%s/%s\"", + value, dp->d_name); + continue; + } snprintf(buf2, sizeof(buf2), "%s/%s", value, dp->d_name); diff -u -r freeradius-server-2.2.0.orig/src/main/conffile.c freeradius-server-2.2.0.configfile/src/main/conffile.c --- freeradius-server-2.2.0.orig/src/main/conffile.c 2012-09-10 07:51:34.000000000 -0400 +++ freeradius-server-2.2.0.configfile/src/main/conffile.c 2012-10-03 15:54:17.465348844 -0400 @@ -1512,12 +1512,23 @@ } /* - * Read the directory, ignoring "." files. + * Read the directory, ignoring invalid files. */ while ((dp = readdir(dir)) != NULL) { const char *p; - if (dp->d_name[0] == '.') continue; + /* + * Check for invalid file names + */ + if (fr_exclude_config_file(dp->d_name)) { + if (!(strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0)) { + radlog(L_INFO, "skipping config file, invalid name \"%s%s\"", + value, dp->d_name); + } + continue; + } + /* * Check for valid characters @@ -1530,7 +1541,11 @@ (*p == '.')) continue; break; } - if (*p != '\0') continue; + if (*p != '\0') { + radlog(L_INFO, "skipping config file, invalid characters in name \"%s%s\"", + value, dp->d_name); + continue; + } snprintf(buf2, sizeof(buf2), "%s%s", value, dp->d_name); diff -u -r freeradius-server-2.2.0.orig/src/modules/rlm_policy/parse.c freeradius-server-2.2.0.configfile/src/modules/rlm_policy/parse.c --- freeradius-server-2.2.0.orig/src/modules/rlm_policy/parse.c 2012-09-10 07:51:34.000000000 -0400 +++ freeradius-server-2.2.0.configfile/src/modules/rlm_policy/parse.c 2012-10-03 15:55:29.736715648 -0400 @@ -1584,13 +1584,22 @@ } /* - * Read the directory, ignoring "." files. + * Read the directory, ignoring invalid files. */ while ((dp = readdir(dir)) != NULL) { struct stat buf; - if (dp->d_name[0] == '.') continue; - if (strchr(dp->d_name, '~') != NULL) continue; + /* + * Check for invalid file names + */ + if (fr_exclude_config_file(dp->d_name)) { + if (!(strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0)) { + fprintf(stderr, "skipping policy file, invalid name \"%s%s\"", + buffer, dp->d_name); + } + continue; + } strlcpy(p, dp->d_name, sizeof(buffer) - (p - buffer));