diff --git a/generate.go b/generate.go index 26edc4f402..da50c6e1bd 100644 --- a/generate.go +++ b/generate.go @@ -85,6 +85,7 @@ func (zp *ZoneParser) generate(l lex) (RR, bool) { } zp.sub = NewZoneParser(r, zp.origin, zp.file) zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed + zp.sub.SetGenerateAllowed(false) zp.sub.SetDefaultTTL(defaultTtl) return zp.subNext() } diff --git a/generate_test.go b/generate_test.go index 15ab9c9890..481c9b2811 100644 --- a/generate_test.go +++ b/generate_test.go @@ -61,6 +61,10 @@ $GENERATE 0-1/0 dhcp-${0,4,d} A 10.0.0.$ `, true}, {`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) $GENERATE 0-1 $$INCLUDE ` + tmpdir + string(filepath.Separator) + `${0,4,d}.conf +`, false}, +{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) +$GENERATE 0-1 dhcp-${0,4,d} A 10.0.0.$ +$GENERATE 0-2 dhcp-${0,4,d} A 10.1.0.$ `, false}, } Outer: @@ -214,6 +218,7 @@ func TestCrasherString(t *testing.T) { {"$GENERATE 0-5414137360", "bad range in $GENERATE"}, {"$GENERATE 11522-3668518066406258", "bad range in $GENERATE"}, {"$GENERATE 0-200\"(;00000000000000\n$$GENERATE 0-0", "dns: garbage after $GENERATE range: \"\\\"\" at line: 1:16"}, + {"$GENERATE 6-2048 $$GENERATE 6-036160 $$$$ORIGIN \\$", `dns: nested $GENERATE directive not allowed: "6-036160" at line: 1:19`}, } for _, tc := range tests { t.Run(tc.in, func(t *testing.T) { diff --git a/scan.go b/scan.go index 0f9361af01..be6f037ff6 100644 --- a/scan.go +++ b/scan.go @@ -248,6 +248,7 @@ type ZoneParser struct { includeDepth uint8 includeAllowed bool + generateAllowed bool } // NewZoneParser returns an RFC 1035 style zonefile parser that reads @@ -272,6 +273,7 @@ func NewZoneParser(r io.Reader, origin, file string) *ZoneParser { origin: origin, file: file, + generateAllowed: true, } } @@ -293,6 +295,18 @@ func (zp *ZoneParser) SetIncludeAllowed(v bool) { zp.includeAllowed = v } +// SetGenerateAllowed controls whether $GENERATE directives are +// allowed. $GENERATE directives are supported by default. +// +// The $GENERATE directive is a BIND specific directive which can be used to +// simplify the generation of repetitive sequences of RRs. +// http://www.zytrax.com/books/dns/ch8/generate.html +// +// Only 1 $GENERATE directive is supported by line. +func (zp *ZoneParser) SetGenerateAllowed(v bool) { + zp.generateAllowed = v +} + // Err returns the first non-EOF error that was encountered by the // ZoneParser. func (zp *ZoneParser) Err() error { @@ -547,6 +561,9 @@ func (zp *ZoneParser) Next() (RR, bool) { st = zExpectDirGenerate case zExpectDirGenerate: + if !zp.generateAllowed { + return zp.setParseError("nested $GENERATE directive not allowed", l) + } if l.value != zString { return zp.setParseError("expecting $GENERATE value, not this...", l) }