Maintained by: NLnet Labs

[Unbound-users] Patch: wildcard for include: statement

Paul Wouters
Wed Sep 26 16:45:17 CEST 2012


Hi,

I wanted to be able to configure unbound along these lines:

 	trusted-keys-file: /etc/unbound/keys.d/*.key

[...]

include: /etc/unbound/conf.d/*.conf

I was a little confused about configlexer.c vs configlexer.lex, so I
just patched both of them. Note that the patch behaves the same as
my other old glob patch that ignores rather then fails an empty glob
(which Wouter rejected :)

The idea is that people should be able to drop in key files and
stub-zone / forward-zone statements in a directory, without needing
to modify unbound.conf itself. This is to better facilitate corporate
non-public zones. As we are looking at rolling out unbound on every
system, it is more important that the stock unbound.conf would not need
to be modified for everyone.

Paul
-------------- next part --------------
diff -Naur unbound-1.4.18-orig/util/config_file.c unbound-1.4.18/util/config_file.c
--- unbound-1.4.18-orig/util/config_file.c	2012-06-18 10:22:29.000000000 -0400
+++ unbound-1.4.18/util/config_file.c	2012-09-26 00:45:37.509190970 -0400
@@ -53,6 +53,10 @@
 #include "util/regional.h"
 #include "util/fptr_wlist.h"
 #include "util/data/dname.h"
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
+
 /** global config during parsing */
 struct config_parser_state* cfg_parser = 0;
 /** lex in file */
@@ -689,6 +693,65 @@
 	char *fname = (char*)filename;
 	if(!fname)
 		return 1;
+
+	/* check for wildcards */
+#ifdef HAVE_GLOB
+        glob_t g;
+        size_t i;
+        int r, flags;
+	if(!(!strchr(fname, '*') && !strchr(fname, '?') && !strchr(fname, '[') &&
+                !strchr(fname, '{') && !strchr(fname, '~'))) {
+		verbose(VERB_QUERY, "wildcard found, processing %s", fname);
+        	flags = 0
+#ifdef GLOB_ERR
+                	| GLOB_ERR
+#endif
+#ifdef GLOB_NOSORT
+                	| GLOB_NOSORT
+#endif
+#ifdef GLOB_BRACE
+                	| GLOB_BRACE
+#endif
+#ifdef GLOB_TILDE
+                	| GLOB_TILDE
+#endif
+        	;
+        	memset(&g, 0, sizeof(g));
+        	r = glob(fname, flags, NULL, &g);
+        	if(r) {
+                	/* some error */
+                	if(r == GLOB_NOMATCH) {
+                        	verbose(VERB_QUERY, "include: "
+                                "no matches for %s", fname);
+                        	return 1; 
+                	} else if(r == GLOB_NOSPACE) {
+                        	log_err("include: %s: "
+                                	"fnametern out of memory", fname);
+                	} else if(r == GLOB_ABORTED) {
+                        	log_err("wildcard include: %s: expansion "
+                                	"aborted (%s)", fname, strerror(errno));
+                	} else {
+                        	log_err("wildcard include: %s: expansion "
+                                	"failed (%s)", fname, strerror(errno));
+                	}
+               		/* ignore globs that yield no files */
+                	return 1;
+        	}
+        	/* process files found, if any */
+        	for(i=0; i<(size_t)g.gl_pathc; i++) {
+                	if(!config_read(cfg, g.gl_pathv[i], chroot)) {
+                        	log_err("error reading wildcard "
+                                	"include: %s", g.gl_pathv[i]);
+                        	globfree(&g);
+                        	return 0;
+                	}
+        	}
+        	globfree(&g);
+        	return 1;
+	}
+#endif
+
+
 	in = fopen(fname, "r");
 	if(!in) {
 		log_err("Could not open %s: %s", fname, strerror(errno));
diff -Naur unbound-1.4.18-orig/util/configlexer.c unbound-1.4.18/util/configlexer.c
--- unbound-1.4.18-orig/util/configlexer.c	2012-08-02 03:26:14.000000000 -0400
+++ unbound-1.4.18/util/configlexer.c	2012-09-26 00:47:40.856511450 -0400
@@ -22,6 +22,10 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
+
 
 /* end standard C headers. */
 
@@ -1827,7 +1831,7 @@
 	}
 	input = fopen(filename, "r");
 	if(!input) {
-		ub_c_error_msg("cannot open include file '%s': %s",
+		ub_c_error_msg("(c)cannot open include file '%s': %s",
 			filename, strerror(errno));
 		return;
 	}
@@ -1841,6 +1845,46 @@
 	++config_include_stack_ptr;
 }
 
+static void config_start_include_glob(const char* filename)
+{
+#ifdef HAVE_GLOB
+        glob_t g;
+        size_t i;
+        int r, flags;
+       if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') &&
+                !strchr(filename, '{') && !strchr(filename, '~'))) {
+               /* verbose(VERB_QUERY, "wildcard found, processing %s", filename); */
+               flags = 0
+#ifdef GLOB_ERR
+                       | GLOB_ERR
+#endif
+#ifdef GLOB_NOSORT
+                       | GLOB_NOSORT
+#endif
+#ifdef GLOB_BRACE
+                       | GLOB_BRACE
+#endif
+#ifdef GLOB_TILDE
+                       | GLOB_TILDE
+#endif
+               ;
+               memset(&g, 0, sizeof(g));
+               r = glob(filename, flags, NULL, &g);
+               if(r) {
+                       /* some error */
+                       return;
+               }
+               /* process files found, if any */
+               for(i=0; i<(size_t)g.gl_pathc; i++) {
+                       config_start_include(g.gl_pathv[i]);
+               }
+               globfree(&g);
+               return;
+       }
+#endif
+       config_start_include(filename);
+}
+
 static void config_end_include(void)
 {
 	--config_include_stack_ptr;
@@ -2875,7 +2919,7 @@
 #line 300 "util/configlexer.lex"
 {
 	LEXOUT(("Iunquotedstr(%s) ", yytext));
-	config_start_include(yytext);
+	config_start_include_glob(yytext);
 	BEGIN(inc_prev);
 }
 	YY_BREAK
@@ -2904,7 +2948,7 @@
 {
 	LEXOUT(("IQE "));
 	yytext[yyleng - 1] = '\0';
-	config_start_include(yytext);
+	config_start_include_glob(yytext);
 	BEGIN(inc_prev);
 }
 	YY_BREAK
diff -Naur unbound-1.4.18-orig/util/configlexer.lex unbound-1.4.18/util/configlexer.lex
--- unbound-1.4.18-orig/util/configlexer.lex	2012-04-10 05:16:39.000000000 -0400
+++ unbound-1.4.18/util/configlexer.lex	2012-09-26 00:46:59.135064805 -0400
@@ -11,6 +11,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <strings.h>
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
 
 #include "util/config_file.h"
 #include "util/configparser.h"
@@ -43,6 +46,7 @@
 static int inc_prev = 0;
 static int num_args = 0;
 
+
 static void config_start_include(const char* filename)
 {
 	FILE *input;
@@ -60,7 +64,7 @@
 	}
 	input = fopen(filename, "r");
 	if(!input) {
-		ub_c_error_msg("cannot open include file '%s': %s",
+		ub_c_error_msg("(lex)cannot open include file '%s': %s",
 			filename, strerror(errno));
 		return;
 	}
@@ -74,6 +78,48 @@
 	++config_include_stack_ptr;
 }
 
+static void config_start_include_glob(const char* filename)
+{
+
+       /* check for wildcards */
+#ifdef HAVE_GLOB
+        glob_t g;
+        size_t i;
+        int r, flags;
+       if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') &&
+                !strchr(filename, '{') && !strchr(filename, '~'))) {
+               /* verbose(VERB_QUERY, "wildcard found, processing %s", filename); */
+               flags = 0
+#ifdef GLOB_ERR
+                       | GLOB_ERR
+#endif
+#ifdef GLOB_NOSORT
+                       | GLOB_NOSORT
+#endif
+#ifdef GLOB_BRACE
+                       | GLOB_BRACE
+#endif
+#ifdef GLOB_TILDE
+                       | GLOB_TILDE
+#endif
+               ;
+               memset(&g, 0, sizeof(g));
+               r = glob(filename, flags, NULL, &g);
+               if(r) {
+                       /* some error */
+                       return config_start_include(filename); /* let original deal with it */
+               }
+               /* process files found, if any */
+               for(i=0; i<(size_t)g.gl_pathc; i++) {
+                       config_start_include(g.gl_pathv[i]);
+               }
+               globfree(&g);
+               return 1;
+       }
+#endif
+
+	config_start_include(filename);
+}
 static void config_end_include(void)
 {
 	--config_include_stack_ptr;
@@ -299,7 +345,7 @@
 <include>\"		{ LEXOUT(("IQS ")); BEGIN(include_quoted); }
 <include>{UNQUOTEDLETTER}*	{
 	LEXOUT(("Iunquotedstr(%s) ", yytext));
-	config_start_include(yytext);
+	config_start_include_glob(yytext);
 	BEGIN(inc_prev);
 }
 <include_quoted><<EOF>>	{
@@ -312,7 +358,7 @@
 <include_quoted>\"	{
 	LEXOUT(("IQE "));
 	yytext[yyleng - 1] = '\0';
-	config_start_include(yytext);
+	config_start_include_glob(yytext);
 	BEGIN(inc_prev);
 }
 <INITIAL,val><<EOF>>	{