xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/addzone/tests.sh (revision 9689912e6b171cbda866ec33f15ae94a04e2c02d)
1#!/bin/sh
2
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# SPDX-License-Identifier: MPL-2.0
6#
7# This Source Code Form is subject to the terms of the Mozilla Public
8# License, v. 2.0.  If a copy of the MPL was not distributed with this
9# file, you can obtain one at https://mozilla.org/MPL/2.0/.
10#
11# See the COPYRIGHT file distributed with this work for additional
12# information regarding copyright ownership.
13
14set -e
15
16. ../conf.sh
17
18DIGOPTS="+tcp +nosea +nostat +nocmd +norec +noques +noauth +noadd +nostats +dnssec -p ${PORT}"
19RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s"
20
21check_zonestatus() (
22  $RNDCCMD "10.53.0.$1" zonestatus -redirect >"zonestatus.out.ns$1.$n" \
23    && grep "type: redirect" "zonestatus.out.ns$1.$n" >/dev/null \
24    && grep "serial: 1" "zonestatus.out.ns$1.$n" >/dev/null
25)
26
27status=0
28n=0
29
30echo_i "checking normally loaded zone ($n)"
31ret=0
32$DIG $DIGOPTS @10.53.0.2 a.normal.example a >dig.out.ns2.$n || ret=1
33grep 'status: NOERROR' dig.out.ns2.$n >/dev/null || ret=1
34grep '^a.normal.example' dig.out.ns2.$n >/dev/null || ret=1
35n=$((n + 1))
36if [ $ret != 0 ]; then echo_i "failed"; fi
37status=$((status + ret))
38
39# When LMDB support is compiled in, this tests that migration from
40# NZF to NZD occurs during named startup
41echo_i "checking previously added zone ($n)"
42ret=0
43$DIG $DIGOPTS @10.53.0.2 a.previous.example a >dig.out.ns2.$n || ret=1
44grep 'status: NOERROR' dig.out.ns2.$n >/dev/null || ret=1
45grep '^a.previous.example' dig.out.ns2.$n >/dev/null || ret=1
46n=$((n + 1))
47if [ $ret != 0 ]; then echo_i "failed"; fi
48status=$((status + ret))
49
50if $FEATURETEST --with-lmdb; then
51  echo_i "checking that existing NZF file was renamed after migration ($n)"
52  [ -e ns2/3bf305731dd26307.nzf~ ] || ret=1
53  n=$((n + 1))
54  if [ $ret != 0 ]; then echo_i "failed"; fi
55  status=$((status + ret))
56fi
57
58echo_i "adding new zone ($n)"
59ret=0
60$RNDCCMD 10.53.0.2 addzone 'added.example { type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /'
61_check_adding_new_zone() (
62  $DIG $DIGOPTS @10.53.0.2 a.added.example a >dig.out.ns2.$n \
63    && grep 'status: NOERROR' dig.out.ns2.$n >/dev/null \
64    && grep '^a.added.example' dig.out.ns2.$n >/dev/null
65)
66retry_quiet 10 _check_adding_new_zone || ret=1
67n=$((n + 1))
68if [ $ret != 0 ]; then echo_i "failed"; fi
69status=$((status + ret))
70
71nextpart ns2/named.run >/dev/null
72echo_i "checking addzone errors are logged correctly"
73ret=0
74$RNDCCMD 10.53.0.2 addzone bad.example '{ type mister; };' 2>&1 | grep 'unexpected token' >/dev/null 2>&1 || ret=1
75wait_for_log_peek 20 "addzone: 'mister' unexpected" ns2/named.run || ret=1
76n=$((n + 1))
77if [ $ret != 0 ]; then echo_i "failed"; fi
78status=$((status + ret))
79
80nextpart ns2/named.run >/dev/null
81echo_i "checking modzone errors are logged correctly"
82ret=0
83$RNDCCMD 10.53.0.2 modzone added.example '{ type mister; };' 2>&1 | grep 'unexpected token' >/dev/null 2>&1 || ret=1
84wait_for_log_peek 20 "modzone: 'mister' unexpected" ns2/named.run || ret=1
85n=$((n + 1))
86if [ $ret != 0 ]; then echo_i "failed"; fi
87status=$((status + ret))
88
89echo_i "adding a zone that requires quotes ($n)"
90ret=0
91$RNDCCMD 10.53.0.2 addzone '"32/1.0.0.127-in-addr.added.example" {
92check-names ignore; type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /'
93_check_zone_that_requires_quotes() (
94  $DIG $DIGOPTS @10.53.0.2 "a.32/1.0.0.127-in-addr.added.example" a >dig.out.ns2.$n \
95    && grep 'status: NOERROR' dig.out.ns2.$n >/dev/null \
96    && grep '^a.32/1.0.0.127-in-addr.added.example' dig.out.ns2.$n >/dev/null
97)
98retry_quiet 10 _check_zone_that_requires_quotes || ret=1
99n=$((n + 1))
100if [ $ret != 0 ]; then echo_i "failed"; fi
101status=$((status + ret))
102
103echo_i "adding a zone with a quote in the name ($n)"
104ret=0
105$RNDCCMD 10.53.0.2 addzone '"foo\"bar.example" { check-names ignore; type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /'
106_check_zone_with_a_quote() (
107  $DIG $DIGOPTS @10.53.0.2 "a.foo\"bar.example" a >dig.out.ns2.$n \
108    && grep 'status: NOERROR' dig.out.ns2.$n >/dev/null \
109    && grep '^a.foo\\"bar.example' dig.out.ns2.$n >/dev/null
110)
111retry_quiet 10 _check_zone_with_a_quote || ret=1
112n=$((n + 1))
113if [ $ret != 0 ]; then echo_i "failed"; fi
114status=$((status + ret))
115
116echo_i "adding new zone with missing file ($n)"
117ret=0
118$DIG $DIGOPTS +all @10.53.0.2 a.missing.example a >dig.out.ns2.pre.$n || ret=1
119grep "status: REFUSED" dig.out.ns2.pre.$n >/dev/null || ret=1
120$RNDCCMD 10.53.0.2 addzone 'missing.example { type primary; file "missing.db"; };' 2>rndc.out.ns2.$n && ret=1
121grep "file not found" rndc.out.ns2.$n >/dev/null || ret=1
122$DIG $DIGOPTS +all @10.53.0.2 a.missing.example a >dig.out.ns2.post.$n || ret=1
123grep "status: REFUSED" dig.out.ns2.post.$n >/dev/null || ret=1
124digcomp dig.out.ns2.pre.$n dig.out.ns2.post.$n || ret=1
125n=$((n + 1))
126if [ $ret != 0 ]; then echo_i "failed"; fi
127status=$((status + ret))
128
129if ! $FEATURETEST --with-lmdb; then
130  echo_i "verifying no comments in NZF file ($n)"
131  ret=0
132  hcount=$(grep "^# New zone file for view: _default" ns2/3bf305731dd26307.nzf | wc -l)
133  [ $hcount -eq 0 ] || ret=1
134  n=$((n + 1))
135  if [ $ret != 0 ]; then echo_i "failed"; fi
136  status=$((status + ret))
137fi
138
139echo_i "checking rndc showzone with previously added zone ($n)"
140ret=0
141$RNDCCMD 10.53.0.2 showzone previous.example >rndc.out.ns2.$n
142expected='zone "previous.example" { type primary; file "previous.db"; };'
143[ "$(cat rndc.out.ns2.$n)" = "$expected" ] || ret=1
144n=$((n + 1))
145if [ $ret != 0 ]; then echo_i "failed"; fi
146status=$((status + ret))
147
148if $FEATURETEST --with-lmdb; then
149  echo_i "checking zone is present in NZD ($n)"
150  ret=0
151  $NZD2NZF ns2/_default.nzd | grep previous.example >/dev/null || ret=1
152  if [ $ret != 0 ]; then echo_i "failed"; fi
153  status=$((status + ret))
154fi
155
156echo_i "deleting previously added zone ($n)"
157ret=0
158$RNDCCMD 10.53.0.2 delzone previous.example 2>&1 | sed 's/^/I:ns2 /'
159_check_deleting_previously_added_zone() (
160  $DIG $DIGOPTS @10.53.0.2 a.previous.example a >dig.out.ns2.$n \
161    && grep 'status: REFUSED' dig.out.ns2.$n >/dev/null \
162    && ! grep '^a.previous.example' dig.out.ns2.$n >/dev/null
163)
164retry_quiet 10 _check_deleting_previously_added_zone || ret=1
165n=$((n + 1))
166if [ $ret != 0 ]; then echo_i "failed"; fi
167status=$((status + ret))
168
169check_nzd2nzf() (
170  $NZD2NZF ns2/_default.nzd >nzd2nzf.out.$n \
171    && ! grep previous.example nzd2nzf.out.$n >/dev/null
172)
173
174if $FEATURETEST --with-lmdb; then
175  echo_i "checking zone was deleted from NZD ($n)"
176  retry_quiet 10 check_nzd2nzf || ret=1
177  if [ $ret != 0 ]; then echo_i "failed"; fi
178  status=$((status + ret))
179fi
180
181if ! $FEATURETEST --with-lmdb; then
182  echo_i "checking NZF file now has comment ($n)"
183  ret=0
184  hcount=$(grep "^# New zone file for view: _default" ns2/3bf305731dd26307.nzf | wc -l)
185  [ $hcount -eq 1 ] || ret=1
186  n=$((n + 1))
187  if [ $ret != 0 ]; then echo_i "failed"; fi
188  status=$((status + ret))
189fi
190
191echo_i "deleting newly added zone added.example ($n)"
192ret=0
193$RNDCCMD 10.53.0.2 delzone added.example 2>&1 | sed 's/^/I:ns2 /'
194_check_deleting_newly_added_zone() (
195  $DIG $DIGOPTS @10.53.0.2 a.added.example a >dig.out.ns2.$n \
196    && grep 'status: REFUSED' dig.out.ns2.$n >/dev/null \
197    && ! grep '^a.added.example' dig.out.ns2.$n >/dev/null
198)
199retry_quiet 10 _check_deleting_newly_added_zone || ret=1
200n=$((n + 1))
201if [ $ret != 0 ]; then echo_i "failed"; fi
202status=$((status + ret))
203
204echo_i "deleting newly added zone with escaped quote ($n)"
205ret=0
206$RNDCCMD 10.53.0.2 delzone "foo\\\"bar.example" 2>&1 | sed 's/^/I:ns2 /'
207_check_deleting_newly_added_zone_quote() (
208  $DIG $DIGOPTS @10.53.0.2 "a.foo\"bar.example" a >dig.out.ns2.$n \
209    && grep 'status: REFUSED' dig.out.ns2.$n >/dev/null \
210    && ! grep "^a.foo\"bar.example" dig.out.ns2.$n >/dev/null
211)
212retry_quiet 10 _check_deleting_newly_added_zone_quote || ret=1
213n=$((n + 1))
214if [ $ret != 0 ]; then echo_i "failed"; fi
215status=$((status + ret))
216
217echo_i "checking rndc showzone with a normally-loaded zone ($n)"
218ret=0
219$RNDCCMD 10.53.0.2 showzone normal.example >rndc.out.ns2.$n
220expected='zone "normal.example" { type primary; file "normal.db"; };'
221[ "$(cat rndc.out.ns2.$n)" = "$expected" ] || ret=1
222n=$((n + 1))
223if [ $ret != 0 ]; then echo_i "failed"; fi
224status=$((status + ret))
225
226echo_i "checking rndc showzone with a normally-loaded zone with trailing dot ($n)"
227ret=0
228$RNDCCMD 10.53.0.2 showzone finaldot.example >rndc.out.ns2.$n
229expected='zone "finaldot.example." { type primary; file "normal.db"; };'
230[ "$(cat rndc.out.ns2.$n)" = "$expected" ] || ret=1
231n=$((n + 1))
232if [ $ret != 0 ]; then echo_i "failed"; fi
233status=$((status + ret))
234
235echo_i "checking rndc showzone with a normally-loaded redirect zone ($n)"
236ret=0
237$RNDCCMD 10.53.0.1 showzone -redirect >rndc.out.ns1.$n
238expected='zone "." { type redirect; file "redirect.db"; };'
239[ "$(cat rndc.out.ns1.$n)" = "$expected" ] || ret=1
240n=$((n + 1))
241if [ $ret != 0 ]; then echo_i "failed"; fi
242status=$((status + ret))
243
244echo_i "checking rndc zonestatus with a normally-loaded redirect zone ($n)"
245ret=0
246$RNDCCMD 10.53.0.1 zonestatus -redirect >rndc.out.ns1.$n
247grep "type: redirect" rndc.out.ns1.$n >/dev/null || ret=1
248grep "serial: 0" rndc.out.ns1.$n >/dev/null || ret=1
249n=$((n + 1))
250if [ $ret != 0 ]; then echo_i "failed"; fi
251status=$((status + ret))
252
253echo_i "checking rndc reload with a normally-loaded redirect zone ($n)"
254ret=0
255sleep 1
256cp -f ns1/redirect.db.2 ns1/redirect.db
257$RNDCCMD 10.53.0.1 reload -redirect >rndc.out.ns1.$n
258retry_quiet 5 check_zonestatus 1 || ret=1
259n=$((n + 1))
260if [ $ret != 0 ]; then echo_i "failed"; fi
261status=$((status + ret))
262
263echo_i "delete a normally-loaded zone ($n)"
264ret=0
265$RNDCCMD 10.53.0.2 delzone normal.example >rndc.out.ns2.$n 2>&1
266grep "is no longer active and will be deleted" rndc.out.ns2.$n >/dev/null || ret=11
267grep "To keep it from returning when the server is restarted" rndc.out.ns2.$n >/dev/null || ret=1
268grep "must also be removed from named.conf." rndc.out.ns2.$n >/dev/null || ret=1
269_check_delete_normally_loaded_zone() (
270  $DIG $DIGOPTS @10.53.0.2 a.normal.example a >dig.out.ns2.$n \
271    && grep 'status: REFUSED' dig.out.ns2.$n >/dev/null
272)
273retry_quiet 5 _check_delete_normally_loaded_zone || ret=1
274
275n=$((n + 1))
276if [ $ret != 0 ]; then echo_i "failed"; fi
277status=$((status + ret))
278
279echo_i "attempting to add primary zone with inline signing ($n)"
280$RNDCCMD 10.53.0.2 addzone 'inline.example { type primary; file "inline.db"; dnssec-policy default; inline-signing yes; };' 2>&1 | sed 's/^/I:ns2 /'
281_check_add_primary_zone_with_inline() (
282  $DIG $DIGOPTS @10.53.0.2 a.inline.example a >dig.out.ns2.$n \
283    && grep 'status: NOERROR' dig.out.ns2.$n >/dev/null \
284    && grep '^a.inline.example' dig.out.ns2.$n >/dev/null
285)
286retry_quiet 5 _check_add_primary_zone_with_inline || ret=1
287n=$((n + 1))
288if [ $ret != 0 ]; then echo_i "failed"; fi
289status=$((status + ret))
290
291echo_i "attempting to add primary zone with inline signing and missing file ($n)"
292ret=0
293$RNDCCMD 10.53.0.2 addzone 'inlinemissing.example { type primary; file "missing.db"; dnssec-policy default; inline-signing yes; };' 2>rndc.out.ns2.$n && ret=1
294grep "file not found" rndc.out.ns2.$n >/dev/null || ret=1
295n=$((n + 1))
296if [ $ret != 0 ]; then echo_i "failed"; fi
297status=$((status + ret))
298
299echo_i "attempting to add secondary zone with inline signing ($n)"
300$RNDCCMD 10.53.0.2 addzone 'inlinesec.example { type secondary; primaries { 10.53.0.1; }; file "inlinesec.bk"; dnssec-policy default; inline-signing yes; };' 2>&1 | sed 's/^/I:ns2 /'
301_check_add_secondary_with_inline() (
302  $DIG $DIGOPTS @10.53.0.2 a.inlinesec.example a >dig.out.ns2.$n \
303    && grep 'status: NOERROR' dig.out.ns2.$n >/dev/null \
304    && grep '^a.inlinesec.example' dig.out.ns2.$n >/dev/null
305)
306retry_quiet 5 _check_add_secondary_with_inline || ret=1
307n=$((n + 1))
308if [ $ret != 0 ]; then echo_i "failed"; fi
309status=$((status + ret))
310
311echo_i "attempting to delete secondary zone with inline signing ($n)"
312ret=0
313retry_quiet 10 test -f ns2/inlinesec.bk.signed -a -f ns2/inlinesec.bk || ret=1
314$RNDCCMD 10.53.0.2 delzone inlinesec.example >rndc.out2.test$n 2>&1 || ret=1
315test -f inlinesec.bk \
316  || grep '^inlinesec.bk$' rndc.out2.test$n >/dev/null || {
317  echo_i "failed to report inlinesec.bk"
318  ret=1
319}
320test ! -f inlinesec.bk.signed \
321  || grep '^inlinesec.bk.signed$' rndc.out2.test$n >/dev/null || {
322  echo_i "failed to report inlinesec.bk.signed"
323  ret=1
324}
325n=$((n + 1))
326status=$((status + ret))
327
328echo_i "restoring secondary zone with inline signing ($n)"
329$RNDCCMD 10.53.0.2 addzone 'inlinesec.example { type secondary; primaries { 10.53.0.1; }; file "inlinesec.bk"; dnssec-policy default; inline-signing yes; };' 2>&1 | sed 's/^/I:ns2 /'
330_check_restoring_secondary_with_inline() (
331  $DIG $DIGOPTS @10.53.0.2 a.inlinesec.example a >dig.out.ns2.$n \
332    && grep 'status: NOERROR' dig.out.ns2.$n >/dev/null \
333    && grep '^a.inlinesec.example' dig.out.ns2.$n >/dev/null
334)
335retry_quiet 5 _check_restoring_secondary_with_inline || ret=1
336n=$((n + 1))
337if [ $ret != 0 ]; then echo_i "failed"; fi
338status=$((status + ret))
339
340echo_i "deleting secondary zone with automatic zone file removal ($n)"
341ret=0
342retry_quiet 10 test -f ns2/inlinesec.bk.signed -a -f ns2/inlinesec.bk || ret=1
343$RNDCCMD 10.53.0.2 delzone -clean inlinesec.example >/dev/null 2>&1
344retry_quiet 10 test ! -f ns2/inlinesec.bk.signed -a ! -f ns2/inlinesec.bk
345n=$((n + 1))
346status=$((status + ret))
347
348echo_i "modifying zone configuration ($n)"
349ret=0
350$RNDCCMD 10.53.0.2 addzone 'mod.example { type primary; file "added.db"; };' 2>&1 | sed 's/^/ns2 /' | cat_i
351$DIG +norec $DIGOPTS @10.53.0.2 mod.example ns >dig.out.ns2.1.$n || ret=1
352grep 'status: NOERROR' dig.out.ns2.1.$n >/dev/null || ret=1
353$RNDCCMD 10.53.0.2 modzone 'mod.example { type primary; file "added.db"; allow-query { none; }; };' 2>&1 | sed 's/^/ns2 /' | cat_i
354$DIG +norec $DIGOPTS @10.53.0.2 mod.example ns >dig.out.ns2.2.$n || ret=1
355$RNDCCMD 10.53.0.2 showzone mod.example | grep 'allow-query { "none"; };' >/dev/null 2>&1 || ret=1
356n=$((n + 1))
357if [ $ret != 0 ]; then echo_i "failed"; fi
358status=$((status + ret))
359
360echo_i "check that adding a 'stub' zone works ($n)"
361ret=0
362$RNDCCMD 10.53.0.2 addzone 'stub.example { type stub; primaries { 1.2.3.4; }; file "stub.example.bk"; };' >rndc.out.ns2.$n 2>&1 || ret=1
363n=$((n + 1))
364if [ $ret != 0 ]; then echo_i "failed"; fi
365status=$((status + ret))
366
367echo_i "check that adding a 'static-stub' zone works ($n)"
368ret=0
369$RNDCCMD 10.53.0.2 addzone 'static-stub.example { type static-stub; server-addresses { 1.2.3.4; }; };' >rndc.out.ns2.$n 2>&1 || ret=1
370n=$((n + 1))
371if [ $ret != 0 ]; then echo_i "failed"; fi
372status=$((status + ret))
373
374echo_i "check that adding a 'primary redirect' zone works ($n)"
375ret=0
376$RNDCCMD 10.53.0.2 addzone '"." { type redirect; file "redirect.db"; };' >rndc.out.ns2.$n 2>&1 || ret=1
377_check_add_primary_redirect() (
378  $RNDCCMD 10.53.0.2 showzone -redirect >showzone.out.ns2.$n 2>&1 \
379    && grep "type redirect;" showzone.out.ns2.$n >/dev/null \
380    && $RNDCCMD 10.53.0.2 zonestatus -redirect >zonestatus.out.ns2.$n 2>&1 \
381    && grep "type: redirect" zonestatus.out.ns2.$n >/dev/null \
382    && grep "serial: 0" zonestatus.out.ns2.$n >/dev/null
383)
384retry_quiet 10 _check_add_primary_redirect || ret=1
385n=$((n + 1))
386if [ $ret != 0 ]; then echo_i "failed"; fi
387status=$((status + ret))
388
389echo_i "check that reloading a added 'primary redirect' zone works ($n)"
390ret=0
391sleep 1
392cp -f ns2/redirect.db.2 ns2/redirect.db
393$RNDCCMD 10.53.0.2 reload -redirect >rndc.out.ns2.$n
394retry_quiet 10 check_zonestatus 2 || ret=1
395n=$((n + 1))
396if [ $ret != 0 ]; then echo_i "failed"; fi
397status=$((status + ret))
398
399echo_i "check that retransfer of a added 'primary redirect' zone fails ($n)"
400ret=0
401$RNDCCMD 10.53.0.2 retransfer -redirect >rndc.out.ns2.$n 2>&1 && ret=1
402n=$((n + 1))
403if [ $ret != 0 ]; then echo_i "failed"; fi
404status=$((status + ret))
405
406echo_i "check that deleting a 'primary redirect' zone works ($n)"
407ret=0
408$RNDCCMD 10.53.0.2 delzone -redirect >rndc.out.ns2.$n 2>&1 || ret=1
409_check_deleting_primary_redirect() (
410  $RNDCCMD 10.53.0.2 showzone -redirect >showzone.out.ns2.$n 2>&1 || true
411  grep 'not found' showzone.out.ns2.$n >/dev/null
412)
413retry_quiet 10 _check_deleting_primary_redirect || ret=1
414n=$((n + 1))
415if [ $ret != 0 ]; then echo_i "failed"; fi
416status=$((status + ret))
417
418echo_i "check that adding a 'secondary redirect' zone works ($n)"
419ret=0
420$RNDCCMD 10.53.0.2 addzone '"." { type redirect; primaries { 10.53.0.3;}; file "redirect.bk"; };' >rndc.out.ns2.$n 2>&1 || ret=1
421_check_adding_secondary_redirect() (
422  $RNDCCMD 10.53.0.2 showzone -redirect >showzone.out.ns2.$n 2>&1 \
423    && grep "type redirect;" showzone.out.ns2.$n >/dev/null \
424    && $RNDCCMD 10.53.0.2 zonestatus -redirect >zonestatus.out.ns2.$n 2>&1 \
425    && grep "type: redirect" zonestatus.out.ns2.$n >/dev/null \
426    && grep "serial: 0" zonestatus.out.ns2.$n >/dev/null
427)
428retry_quiet 10 _check_adding_secondary_redirect || ret=1
429n=$((n + 1))
430if [ $ret != 0 ]; then echo_i "failed"; fi
431status=$((status + ret))
432
433echo_i "check that retransfering a added 'secondary redirect' zone works ($n)"
434ret=0
435cp -f ns3/redirect.db.2 ns3/redirect.db
436$RNDCCMD 10.53.0.3 reload . >showzone.out.ns3.$n 2>&1 || ret=1
437_check_retransfering_secondary_redirect() (
438  $RNDCCMD 10.53.0.2 retransfer -redirect >rndc.out.ns2.$n 2>&1 \
439    && $RNDCCMD 10.53.0.2 zonestatus -redirect >zonestatus.out.ns2.$n 2>&1 \
440    && grep "type: redirect" zonestatus.out.ns2.$n >/dev/null \
441    && grep "serial: 1" zonestatus.out.ns2.$n >/dev/null
442)
443retry_quiet 10 _check_retransfering_secondary_redirect || ret=1
444n=$((n + 1))
445if [ $ret != 0 ]; then echo_i "failed"; fi
446status=$((status + ret))
447
448echo_i "check that deleting a 'secondary redirect' zone works ($n)"
449ret=0
450$RNDCCMD 10.53.0.2 delzone -redirect >rndc.out.ns2.$n 2>&1 || ret=1
451_check_deleting_secondary_redirect() (
452  $RNDCCMD 10.53.0.2 showzone -redirect >showzone.out.ns2.$n 2>&1 || true
453  grep 'not found' showzone.out.ns2.$n >/dev/null
454)
455retry_quiet 10 _check_deleting_secondary_redirect || ret=1
456n=$((n + 1))
457if [ $ret != 0 ]; then echo_i "failed"; fi
458status=$((status + ret))
459
460echo_i "check that zone type 'hint' is properly rejected ($n)"
461ret=0
462$RNDCCMD 10.53.0.2 addzone '"." { type hint; file "hints.db"; };' >rndc.out.ns2.$n 2>&1 && ret=1
463grep "zones not supported by addzone" rndc.out.ns2.$n >/dev/null || ret=1
464n=$((n + 1))
465if [ $ret != 0 ]; then echo_i "failed"; fi
466status=$((status + ret))
467
468echo_i "check that zone type 'forward' is properly rejected ($n)"
469ret=0
470$RNDCCMD 10.53.0.2 addzone 'forward.example { type forward; forwarders { 1.2.3.4; }; forward only; };' >rndc.out.ns2.$n 2>&1 && ret=1
471grep "zones not supported by addzone" rndc.out.ns2.$n >/dev/null || ret=1
472n=$((n + 1))
473if [ $ret != 0 ]; then echo_i "failed"; fi
474status=$((status + ret))
475
476echo_i "check that 'in-view' zones are properly rejected ($n)"
477ret=0
478$RNDCCMD 10.53.0.2 addzone 'in-view.example { in-view "_default"; };' >rndc.out.ns2.$n 2>&1 && ret=1
479grep "zones not supported by addzone" rndc.out.ns2.$n >/dev/null || ret=1
480n=$((n + 1))
481if [ $ret != 0 ]; then echo_i "failed"; fi
482status=$((status + ret))
483
484echo_i "reconfiguring server with multiple views"
485rm -f ns2/named.conf
486copy_setports ns2/named2.conf.in ns2/named.conf
487rndc_reconfig ns2 10.53.0.2
488
489echo_i "adding new zone to external view ($n)"
490# NOTE: The internal view has "recursion yes" set, and so queries for
491# nonexistent zones should return NOERROR.  The external view is
492# "recursion no", so queries for nonexistent zones should return
493# REFUSED.  This behavior should be the same regardless of whether
494# the zone does not exist because a) it has not yet been loaded, b)
495# it failed to load, or c) it has been deleted.
496ret=0
497$DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.intpre.$n || ret=1
498grep 'status: NOERROR' dig.out.ns2.intpre.$n >/dev/null || ret=1
499$DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.extpre.$n || ret=1
500grep 'status: REFUSED' dig.out.ns2.extpre.$n >/dev/null || ret=1
501$RNDCCMD 10.53.0.2 addzone 'added.example in external { type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /'
502$DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.int.$n || ret=1
503grep 'status: NOERROR' dig.out.ns2.int.$n >/dev/null || ret=1
504$DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.ext.$n || ret=1
505grep 'status: NOERROR' dig.out.ns2.ext.$n >/dev/null || ret=1
506grep '^a.added.example' dig.out.ns2.ext.$n >/dev/null || ret=1
507n=$((n + 1))
508if [ $ret != 0 ]; then echo_i "failed"; fi
509status=$((status + ret))
510
511if ! $FEATURETEST --with-lmdb; then
512  echo_i "checking new NZF file has comment ($n)"
513  ret=0
514  hcount=$(grep "^# New zone file for view: external" ns2/external.nzf | wc -l)
515  [ $hcount -eq 1 ] || ret=1
516  n=$((n + 1))
517  if [ $ret != 0 ]; then echo_i "failed"; fi
518  status=$((status + ret))
519fi
520
521if $FEATURETEST --with-lmdb; then
522  echo_i "verifying added.example in external view created an external.nzd DB ($n)"
523  ret=0
524  [ -e ns2/external.nzd ] || ret=1
525  n=$((n + 1))
526  if [ $ret != 0 ]; then echo_i "failed"; fi
527  status=$((status + ret))
528fi
529
530echo_i "checking rndc reload causes named to reload the external view's new zone config ($n)"
531ret=0
532$RNDCCMD 10.53.0.2 reload 2>&1 | sed 's/^/ns2 /' | cat_i
533_check_rndc_reload_external_view_config() (
534  $DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.int.$n \
535    && grep 'status: NOERROR' dig.out.ns2.int.$n >/dev/null \
536    && $DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.ext.$n \
537    && grep 'status: NOERROR' dig.out.ns2.ext.$n >/dev/null \
538    && grep '^a.added.example' dig.out.ns2.ext.$n >/dev/null
539)
540retry_quiet 10 _check_rndc_reload_external_view_config || ret=1
541n=$((n + 1))
542if [ $ret != 0 ]; then echo_i "failed"; fi
543status=$((status + ret))
544
545echo_i "checking rndc showzone with newly added zone ($n)"
546_check_rndc_showzone_newly_added() (
547  if ! $FEATURETEST --with-lmdb; then
548    expected='zone "added.example" in external { type primary; file "added.db"; };'
549  else
550    expected='zone "added.example" { type primary; file "added.db"; };'
551  fi
552  $RNDCCMD 10.53.0.2 showzone added.example in external >rndc.out.ns2.$n 2>/dev/null \
553    && [ "$(cat rndc.out.ns2.$n)" = "$expected" ]
554)
555retry_quiet 10 _check_rndc_showzone_newly_added || ret=1
556n=$((n + 1))
557if [ $ret != 0 ]; then echo_i "failed"; fi
558status=$((status + ret))
559
560echo_i "deleting newly added zone ($n)"
561ret=0
562$RNDCCMD 10.53.0.2 delzone 'added.example in external' 2>&1 | sed 's/^/I:ns2 /'
563_check_deleting_newly_added_zone() (
564  $DIG $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.$n \
565    && grep 'status: REFUSED' dig.out.ns2.$n >/dev/null \
566    && ! grep '^a.added.example' dig.out.ns2.$n >/dev/null
567)
568retry_quiet 10 _check_deleting_newly_added_zone || ret=1
569n=$((n + 1))
570if [ $ret != 0 ]; then echo_i "failed"; fi
571status=$((status + ret))
572
573echo_i "attempting to add zone to internal view ($n)"
574ret=0
575$DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.pre.$n || ret=1
576grep 'status: NOERROR' dig.out.ns2.pre.$n >/dev/null || ret=1
577$RNDCCMD 10.53.0.2 addzone 'added.example in internal { type primary; file "added.db"; };' 2>rndc.out.ns2.$n && ret=1
578grep "permission denied" rndc.out.ns2.$n >/dev/null || ret=1
579$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.int.$n || ret=1
580grep 'status: NOERROR' dig.out.ns2.int.$n >/dev/null || ret=1
581$DIG $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.ext.$n || ret=1
582grep 'status: REFUSED' dig.out.ns2.ext.$n >/dev/null || ret=1
583n=$((n + 1))
584if [ $ret != 0 ]; then echo_i "failed"; fi
585status=$((status + ret))
586
587echo_i "attempting to delete a policy zone ($n)"
588ret=0
589$RNDCCMD 10.53.0.2 delzone 'policy in internal' 2>rndc.out.ns2.$n >&1 && ret=1
590grep 'cannot be deleted' rndc.out.ns2.$n >/dev/null || ret=1
591n=$((n + 1))
592if [ $ret != 0 ]; then echo_i "failed"; fi
593status=$((status + ret))
594
595echo_i "adding new zone again to external view ($n)"
596ret=0
597$RNDCCMD 10.53.0.2 addzone 'added.example in external { type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /'
598_check_adding_new_zone_again_external() (
599  $DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.int.$n \
600    && grep 'status: NOERROR' dig.out.ns2.int.$n >/dev/null \
601    && $DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.ext.$n \
602    && grep 'status: NOERROR' dig.out.ns2.ext.$n >/dev/null \
603    && grep '^a.added.example' dig.out.ns2.ext.$n >/dev/null
604)
605retry_quiet 10 _check_adding_new_zone_again_external || ret=1
606n=$((n + 1))
607if [ $ret != 0 ]; then echo_i "failed"; fi
608status=$((status + ret))
609
610echo_i "reconfiguring server with multiple views and new-zones-directory"
611rm -f ns2/named.conf
612copy_setports ns2/named3.conf.in ns2/named.conf
613rndc_reconfig ns2 10.53.0.2
614
615echo_i "checking new zone is still loaded after dir change ($n)"
616ret=0
617$DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.ext.$n || ret=1
618grep 'status: NOERROR' dig.out.ns2.ext.$n >/dev/null || ret=1
619grep '^a.added.example' dig.out.ns2.ext.$n >/dev/null || ret=1
620n=$((n + 1))
621if [ $ret != 0 ]; then echo_i "failed"; fi
622status=$((status + ret))
623
624echo_i "deleting newly added zone from external ($n)"
625ret=0
626$RNDCCMD 10.53.0.2 delzone 'added.example in external' 2>&1 | sed 's/^/I:ns2 /'
627$DIG $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.$n || ret=1
628grep 'status: REFUSED' dig.out.ns2.$n >/dev/null || ret=1
629grep '^a.added.example' dig.out.ns2.$n >/dev/null && ret=1
630n=$((n + 1))
631if [ $ret != 0 ]; then echo_i "failed"; fi
632status=$((status + ret))
633
634echo_i "adding new zone to directory view ($n)"
635ret=0
636$DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.intpre.$n || ret=1
637grep 'status: NOERROR' dig.out.ns2.intpre.$n >/dev/null || ret=1
638$DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.extpre.$n || ret=1
639grep 'status: REFUSED' dig.out.ns2.extpre.$n >/dev/null || ret=1
640$DIG +norec $DIGOPTS @10.53.0.5 -b 10.53.0.5 a.added.example a >dig.out.ns2.dirpre.$n || ret=1
641grep 'status: REFUSED' dig.out.ns2.dirpre.$n >/dev/null || ret=1
642$RNDCCMD 10.53.0.2 addzone 'added.example in directory { type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /'
643$DIG +norec $DIGOPTS @10.53.0.2 -b 10.53.0.2 a.added.example a >dig.out.ns2.int.$n || ret=1
644grep 'status: NOERROR' dig.out.ns2.int.$n >/dev/null || ret=1
645$DIG +norec $DIGOPTS @10.53.0.4 -b 10.53.0.4 a.added.example a >dig.out.ns2.ext.$n || ret=1
646grep 'status: REFUSED' dig.out.ns2.ext.$n >/dev/null || ret=1
647$DIG +norec $DIGOPTS @10.53.0.5 -b 10.53.0.5 a.added.example a >dig.out.ns2.dir.$n || ret=1
648grep 'status: NOERROR' dig.out.ns2.dir.$n >/dev/null || ret=1
649grep '^a.added.example' dig.out.ns2.dir.$n >/dev/null || ret=1
650n=$((n + 1))
651if [ $ret != 0 ]; then echo_i "failed"; fi
652status=$((status + ret))
653
654if $FEATURETEST --with-lmdb; then
655  echo_i "checking NZD file was created in new-zones-directory ($n)"
656  expect=ns2/new-zones/directory.nzd
657else
658  echo_i "checking NZF file was created in new-zones-directory ($n)"
659  expect=ns2/new-zones/directory.nzf
660fi
661$RNDCCMD 10.53.0.2 sync 'added.example IN directory' 2>&1 | sed 's/^/I:ns2 /'
662sleep 2
663[ -e "$expect" ] || ret=1
664n=$((n + 1))
665if [ $ret != 0 ]; then echo_i "failed"; fi
666status=$((status + ret))
667
668echo_i "deleting newly added zone from directory ($n)"
669ret=0
670$RNDCCMD 10.53.0.2 delzone 'added.example in directory' 2>&1 | sed 's/^/I:ns2 /'
671$DIG $DIGOPTS @10.53.0.5 -b 10.53.0.5 a.added.example a >dig.out.ns2.$n || ret=1
672grep 'status: REFUSED' dig.out.ns2.$n >/dev/null || ret=1
673grep '^a.added.example' dig.out.ns2.$n >/dev/null && ret=1
674n=$((n + 1))
675if [ $ret != 0 ]; then echo_i "failed"; fi
676status=$((status + ret))
677
678echo_i "ensure the configuration context is cleaned up correctly ($n)"
679ret=0
680rndc_reconfig ns2 10.53.0.2
681$RNDCCMD 10.53.0.2 status >/dev/null 2>&1 || ret=1
682n=$((n + 1))
683if [ $ret != 0 ]; then echo_i "failed"; fi
684status=$((status + ret))
685
686echo_i "check delzone after reconfig failure ($n)"
687ret=0
688$RNDCCMD 10.53.0.3 addzone 'inlinesec.example. IN { type secondary; file "inlinesec.db"; masterfile-format text; primaries { test; }; };' >/dev/null 2>&1 || ret=1
689copy_setports ns3/named2.conf.in ns3/named.conf
690rndc_reconfig ns3 10.53.0.3
691$RNDCCMD 10.53.0.3 delzone inlinesec.example >/dev/null 2>&1 || ret=1
692n=$((n + 1))
693if [ $ret != 0 ]; then echo_i "failed"; fi
694status=$((status + ret))
695
696if ! $FEATURETEST --with-lmdb; then
697  echo_i "check that addzone is fully reversed on failure (--with-lmdb=no) ($n)"
698  ret=0
699  $RNDCCMD 10.53.0.3 addzone "test1.baz" '{ type primary; file "e.db"; };' >/dev/null 2>&1 || ret=1
700  $RNDCCMD 10.53.0.3 addzone "test2.baz" '{ type primary; file "dne.db"; };' >/dev/null 2>&1 && ret=1
701  $RNDCCMD 10.53.0.3 addzone "test3.baz" '{ type primary; file "e.db"; };' >/dev/null 2>&1 || ret=1
702  $RNDCCMD 10.53.0.3 delzone "test3.baz" >/dev/null 2>&1 || ret=1
703  grep test2.baz ns3/_default.nzf >/dev/null && ret=1
704  n=$((n + 1))
705  if [ $ret != 0 ]; then echo_i "failed"; fi
706  status=$((status + ret))
707fi
708
709_check_version_bind() (
710  $DIG $DIGOPTS @10.53.0.3 version.bind txt ch >dig.out.test$n \
711    && grep "status: NOERROR" dig.out.test$n >/dev/null
712)
713
714echo_i "check that named restarts with multiple added zones ($n)"
715ret=0
716$RNDCCMD 10.53.0.3 addzone "test4.baz" '{ type primary; file "e.db"; };' >/dev/null 2>&1 || ret=1
717$RNDCCMD 10.53.0.3 addzone "test5.baz" '{ type primary; file "e.db"; };' >/dev/null 2>&1 || ret=1
718$RNDCCMD 10.53.0.3 addzone '"test/.baz"' '{ type primary; check-names ignore; file "e.db"; };' >/dev/null 2>&1 || ret=1
719$RNDCCMD 10.53.0.3 addzone '"test\".baz"' '{ type primary; check-names ignore; file "e.db"; };' >/dev/null 2>&1 || ret=1
720$RNDCCMD 10.53.0.3 addzone '"test\\.baz"' '{ type primary; check-names ignore; file "e.db"; };' >/dev/null 2>&1 || ret=1
721$RNDCCMD 10.53.0.3 addzone '"test\032.baz"' '{ type primary; check-names ignore; file "e.db"; };' >/dev/null 2>&1 || ret=1
722$RNDCCMD 10.53.0.3 addzone '"test\010.baz"' '{ type primary; check-names ignore; file "e.db"; };' >/dev/null 2>&1 || ret=1
723stop_server ns3
724start_server --noclean --restart --port ${PORT} ns3 || ret=1
725retry_quiet 10 _check_version_bind || ret=1
726$DIG $DIGOPTS @10.53.0.3 SOA "test4.baz" >dig.out.1.test$n || ret=1
727grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
728grep "ANSWER: 1," dig.out.1.test$n >/dev/null || ret=1
729$DIG $DIGOPTS @10.53.0.3 SOA "test5.baz" >dig.out.2.test$n || ret=1
730grep "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1
731grep "ANSWER: 1," dig.out.2.test$n >/dev/null || ret=1
732$DIG $DIGOPTS @10.53.0.3 SOA 'test/.baz' >dig.out.3.test$n || ret=1
733grep "status: NOERROR" dig.out.3.test$n >/dev/null || ret=1
734grep "ANSWER: 1," dig.out.3.test$n >/dev/null || ret=1
735$DIG $DIGOPTS @10.53.0.3 SOA 'test\\.baz' >dig.out.4.test$n || ret=1
736grep "status: NOERROR" dig.out.4.test$n >/dev/null || ret=1
737grep "ANSWER: 1," dig.out.4.test$n >/dev/null || ret=1
738$DIG $DIGOPTS @10.53.0.3 SOA 'test\032.baz' >dig.out.5.test$n || ret=1
739grep "status: NOERROR" dig.out.5.test$n >/dev/null || ret=1
740grep "ANSWER: 1," dig.out.5.test$n >/dev/null || ret=1
741$DIG $DIGOPTS @10.53.0.3 SOA 'test\010.baz' >dig.out.6.test$n || ret=1
742grep "status: NOERROR" dig.out.6.test$n >/dev/null || ret=1
743grep "ANSWER: 1," dig.out.6.test$n >/dev/null || ret=1
744if [ $ret != 0 ]; then echo_i "failed"; fi
745status=$((status + ret))
746n=$((n + 1))
747
748echo_i "exit status: $status"
749[ $status -eq 0 ] || exit 1
750