xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/nsupdate/tests.sh (revision 782713e6c126f1866c6d9cfdee4ceb49483b5828)
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
14SYSTEMTESTTOP=..
15. $SYSTEMTESTTOP/conf.sh
16
17DIGOPTS="-p ${PORT}"
18RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
19
20#
21# Uncomment when creating credential cache files.
22#
23# KRB5_CONFIG="$(pwd)/krb/krb5.conf"
24#
25# Cd krb and run krb/setup.sh to create new keys.
26# Run nsupdate system test.
27# Kill the krb5kdc server started by krb/setup.sh.
28# Check the expiry date on the cached machine.ccache with klist is in 2038.
29# Comment out KRB5_CONFIG.
30# Re-run nsupdate system test to confirm everything still works.
31# git add and commit the resulting ns*/machine.ccache and ns*/dns.keytab files.
32# Clean up krb.
33#
34
35status=0
36n=0
37
38nextpartreset ns3/named.run
39
40# wait for zone transfer to complete
41tries=0
42while true; do
43    if [ $tries -eq 10 ]
44    then
45        exit 1
46    fi
47
48    if grep "example.nil/IN.*Transfer status" ns2/named.run > /dev/null
49    then
50        break
51    else
52        echo_i "zones are not fully loaded, waiting..."
53        tries=$((tries + 1))
54        sleep 1
55    fi
56done
57
58has_positive_response() {
59	zone=$1
60	type=$2
61	ns=$3
62	$DIG $DIGOPTS +tcp +norec $zone $type @$ns > dig.out.post.test$n || return 1
63	grep "status: NOERROR" dig.out.post.test$n > /dev/null || return 1
64	grep "ANSWER: 0," dig.out.post.test$n > /dev/null && return 1
65	return 0
66}
67
68ret=0
69echo_i "fetching first copy of zone before update"
70$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
71	@10.53.0.1 axfr > dig.out.ns1 || ret=1
72[ $ret = 0 ] || { echo_i "failed"; status=1; }
73
74ret=0
75echo_i "fetching second copy of zone before update"
76$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
77	@10.53.0.2 axfr > dig.out.ns2 || ret=1
78[ $ret = 0 ] || { echo_i "failed"; status=1; }
79
80ret=0
81echo_i "comparing pre-update copies to known good data"
82digcomp knowngood.ns1.before dig.out.ns1 || ret=1
83digcomp knowngood.ns1.before dig.out.ns2 || ret=1
84[ $ret = 0 ] || { echo_i "failed"; status=1; }
85
86ret=0
87echo_i "ensure an unrelated zone is mentioned in its NOTAUTH log"
88$NSUPDATE -k ns1/ddns.key > nsupdate.out 2>&1 << END && ret=1
89server 10.53.0.1 ${PORT}
90zone unconfigured.test
91update add unconfigured.test 600 IN A 10.53.0.1
92send
93END
94grep NOTAUTH nsupdate.out > /dev/null 2>&1 || ret=1
95grep ' unconfigured.test: not authoritative' ns1/named.run \
96     > /dev/null 2>&1 || ret=1
97[ $ret = 0 ] || { echo_i "failed"; status=1; }
98
99ret=0
100echo_i "ensure a subdomain is mentioned in its NOTAUTH log"
101$NSUPDATE -k ns1/ddns.key > nsupdate.out 2>&1 << END && ret=1
102server 10.53.0.1 ${PORT}
103zone sub.sub.example.nil
104update add sub.sub.sub.example.nil 600 IN A 10.53.0.1
105send
106END
107grep NOTAUTH nsupdate.out > /dev/null 2>&1 || ret=1
108grep ' sub.sub.example.nil: not authoritative' ns1/named.run \
109     > /dev/null 2>&1 || ret=1
110[ $ret = 0 ] || { echo_i "failed"; status=1; }
111
112ret=0
113echo_i "updating zone"
114# nsupdate will print a ">" prompt to stdout as it gets each input line.
115$NSUPDATE -k ns1/ddns.key <<END > /dev/null || ret=1
116server 10.53.0.1 ${PORT}
117update add updated.example.nil. 600 A 10.10.10.1
118add updated.example.nil. 600 TXT Foo
119delete t.example.nil.
120
121END
122[ $ret = 0 ] || { echo_i "failed"; status=1; }
123
124echo_i "sleeping 5 seconds for server to incorporate changes"
125sleep 5
126
127ret=0
128echo_i "fetching first copy of zone after update"
129$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
130	@10.53.0.1 axfr > dig.out.ns1 || ret=1
131[ $ret = 0 ] || { echo_i "failed"; status=1; }
132
133ret=0
134echo_i "fetching second copy of zone after update"
135$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
136	@10.53.0.2 axfr > dig.out.ns2 || ret=1
137[ $ret = 0 ] || { echo_i "failed"; status=1; }
138
139ret=0
140echo_i "comparing post-update copies to known good data"
141digcomp knowngood.ns1.after dig.out.ns1 || ret=1
142digcomp knowngood.ns1.after dig.out.ns2 || ret=1
143[ $ret = 0 ] || { echo_i "failed"; status=1; }
144
145ret=0
146echo_i "testing local update policy"
147pre=$($DIG $DIGOPTS +short new.other.nil. @10.53.0.1 a) || ret=1
148[ -z "$pre" ] || ret=1
149[ $ret = 0 ] || { echo_i "failed"; status=1; }
150
151ret=0
152echo_i "updating zone"
153# nsupdate will print a ">" prompt to stdout as it gets each input line.
154$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > /dev/null <<END || ret=1
155zone other.nil.
156update add new.other.nil. 600 IN A 10.10.10.1
157send
158END
159[ $ret = 0 ] || { echo_i "failed"; status=1; }
160
161echo_i "sleeping 5 seconds for server to incorporate changes"
162sleep 5
163
164ret=0
165echo_i "checking result of update"
166post=$($DIG $DIGOPTS +short new.other.nil. @10.53.0.1 a) || ret=1
167[ "$post" = "10.10.10.1" ] || ret=1
168[ $ret = 0 ] || { echo_i "failed"; status=1; }
169
170ret=0
171echo_i "comparing post-update copy to known good data"
172digcomp knowngood.ns1.after dig.out.ns1 || ret=1
173[ $ret = 0 ] || { echo_i "failed"; status=1; }
174
175ret=0
176echo_i "testing zone consistency checks"
177# inserting an NS record without a corresponding A or AAAA record should fail
178$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > nsupdate.out 2>&1 << END && ret=1
179update add other.nil. 600 in ns ns3.other.nil.
180send
181END
182grep REFUSED nsupdate.out > /dev/null 2>&1 || ret=1
183# ...but should work if an A record is inserted first:
184$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1
185update add ns4.other.nil 600 in a 10.53.0.1
186send
187update add other.nil. 600 in ns ns4.other.nil.
188send
189END
190grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1
191# ...or if an AAAA record does:
192$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1
193update add ns5.other.nil 600 in aaaa 2001:db8::1
194send
195update add other.nil. 600 in ns ns5.other.nil.
196send
197END
198grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1
199# ...or if the NS and A/AAAA are inserted together:
200$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1
201update add other.nil. 600 in ns ns6.other.nil.
202update add ns6.other.nil 600 in a 10.53.0.1
203send
204END
205grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1
206[ $ret = 0 ] || { echo_i "failed"; status=1; }
207
208echo_i "sleeping 5 seconds for server to incorporate changes"
209sleep 5
210
211ret=0
212echo_i "checking result of update"
213$DIG $DIGOPTS +short @10.53.0.1 ns other.nil > dig.out.ns1 || ret=1
214grep ns3.other.nil dig.out.ns1 > /dev/null 2>&1 && ret=1
215grep ns4.other.nil dig.out.ns1 > /dev/null 2>&1 || ret=1
216grep ns5.other.nil dig.out.ns1 > /dev/null 2>&1 || ret=1
217grep ns6.other.nil dig.out.ns1 > /dev/null 2>&1 || ret=1
218[ $ret = 0 ] || { echo_i "failed"; status=1; }
219
220ret=0
221echo_i "ensure 'check-mx ignore' allows adding MX records containing an address without a warning"
222$NSUPDATE -k ns1/ddns.key > nsupdate.out 2>&1 << END || ret=1
223server 10.53.0.1 ${PORT}
224update add mx03.example.nil 600 IN MX 10 10.53.0.1
225send
226END
227grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1
228grep "mx03.example.nil/MX:.*MX is an address" ns1/named.run > /dev/null 2>&1 && ret=1
229[ $ret = 0 ] || { echo_i "failed"; status=1; }
230
231ret=0
232echo_i "ensure 'check-mx warn' allows adding MX records containing an address with a warning"
233$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1
234update add mx03.other.nil 600 IN MX 10 10.53.0.1
235send
236END
237grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1
238grep "mx03.other.nil/MX:.*MX is an address" ns1/named.run > /dev/null 2>&1 || ret=1
239[ $ret = 0 ] || { echo_i "failed"; status=1; }
240
241ret=0
242echo_i "ensure 'check-mx fail' prevents adding MX records containing an address with a warning"
243$NSUPDATE > nsupdate.out 2>&1 << END && ret=1
244server 10.53.0.1 ${PORT}
245update add mx03.update.nil 600 IN MX 10 10.53.0.1
246send
247END
248grep REFUSED nsupdate.out > /dev/null 2>&1 || ret=1
249grep "mx03.update.nil/MX:.*MX is an address" ns1/named.run > /dev/null 2>&1 || ret=1
250[ $ret = 0 ] || { echo_i "failed"; status=1; }
251
252ret=0
253echo_i "check SIG(0) key is accepted"
254key=$($KEYGEN -q -a ${DEFAULT_ALGORITHM} -T KEY -n ENTITY xxx)
255echo "" | $NSUPDATE -k ${key}.private > /dev/null 2>&1 || ret=1
256[ $ret = 0 ] || { echo_i "failed"; status=1; }
257
258n=$((n + 1))
259ret=0
260echo_i "check TYPE=0 update is rejected by nsupdate ($n)"
261$NSUPDATE <<END > nsupdate.out 2>&1 && ret=1
262    server 10.53.0.1 ${PORT}
263    ttl 300
264    update add example.nil. in type0 ""
265    send
266END
267grep "unknown class/type" nsupdate.out > /dev/null 2>&1 || ret=1
268[ $ret = 0 ] || { echo_i "failed"; status=1; }
269
270n=$((n + 1))
271ret=0
272echo_i "check TYPE=0 prerequisite is handled ($n)"
273$NSUPDATE -k ns1/ddns.key <<END > nsupdate.out 2>&1 || ret=1
274    server 10.53.0.1 ${PORT}
275    prereq nxrrset example.nil. type0
276    send
277END
278$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 > dig.out.ns1.$n
279grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
280[ $ret = 0 ] || { echo_i "failed"; status=1; }
281
282n=$((n + 1))
283ret=0
284echo_i "check that TYPE=0 update is handled ($n)"
285echo "a0e4280000010000000100000000060001c00c000000fe000000000000" |
286$PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp > /dev/null || ret=1
287$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 > dig.out.ns1.$n
288grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
289[ $ret = 0 ] || { echo_i "failed"; status=1; }
290
291n=$((n + 1))
292ret=0
293echo_i "check that TYPE=0 additional data is handled ($n)"
294echo "a0e4280000010000000000010000060001c00c000000fe000000000000" |
295$PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp > /dev/null || ret=1
296$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 > dig.out.ns1.$n
297grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
298[ $ret = 0 ] || { echo_i "failed"; status=1; }
299
300n=$((n + 1))
301ret=0
302echo_i "check that update to undefined class is handled ($n)"
303echo "a0e4280000010001000000000000060101c00c000000fe000000000000" |
304$PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp > /dev/null || ret=1
305$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 > dig.out.ns1.$n
306grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
307[ $ret = 0 ] || { echo_i "failed"; status=1; }
308
309n=$((n + 1))
310ret=0
311echo_i "check that address family mismatch is handled ($n)"
312$NSUPDATE <<END > /dev/null 2>&1 && ret=1
313server ::1
314local 127.0.0.1
315update add 600 txt.example.nil in txt "test"
316send
317END
318[ $ret = 0 ] || { echo_i "failed"; status=1; }
319
320
321n=$((n + 1))
322ret=0
323echo_i "check that unixtime serial number is correctly generated ($n)"
324$DIG $DIGOPTS +short unixtime.nil. soa @10.53.0.1 > dig.out.old.test$n || ret=1
325oldserial=$(awk '{print $3}' dig.out.old.test$n) || ret=1
326start=$($PERL -e 'print time()."\n";')
327$NSUPDATE <<END > /dev/null 2>&1 || ret=1
328    server 10.53.0.1 ${PORT}
329    ttl 600
330    update add new.unixtime.nil in a 1.2.3.4
331    send
332END
333now=$($PERL -e 'print time()."\n";')
334sleep 1
335$DIG $DIGOPTS +short unixtime.nil. soa @10.53.0.1 > dig.out.new.test$n || ret=1
336serial=$(awk '{print $3}' dig.out.new.test$n) || ret=1
337[ "$oldserial" = "$serial" ] && { echo_i "oldserial == serial"; ret=1; }
338if [ "$serial" -lt "$start" ]; then
339    echo_i "out-of-range serial=$serial < start=$start"; ret=1;
340elif [ "$serial" -gt "$now" ]; then
341    echo_i "out-of-range serial=$serial > now=$now"; ret=1;
342fi
343[ $ret = 0 ] || { echo_i "failed"; status=1; }
344
345if $PERL -e 'use Net::DNS;' 2>/dev/null
346then
347    n=$((n + 1))
348    ret=0
349    echo_i "running update.pl test ($n)"
350    $PERL update_test.pl -s 10.53.0.1 -p ${PORT} update.nil. > perl.update_test.out || ret=1
351    [ $ret -eq 1 ] && { echo_i "failed"; status=1; }
352
353    if $PERL -e 'use Net::DNS; die "Net::DNS too old ($Net::DNS::VERSION < 1.01)" if ($Net::DNS::VERSION < 1.01)' > /dev/null
354    then
355	n=$((n + 1))
356	ret=0
357	echo_i "check for too many NSEC3 iterations log ($n)"
358	grep "updating zone 'update.nil/IN': too many NSEC3 iterations (151)" ns1/named.run > /dev/null || ret=1
359	[ $ret -eq 1 ] && { echo_i "failed"; status=1; }
360    fi
361else
362    echo_i "The second part of this test requires the Net::DNS library." >&2
363fi
364
365n=$((n + 1))
366ret=0
367echo_i "fetching first copy of test zone ($n)"
368$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
369	@10.53.0.1 axfr > dig.out.ns1 || ret=1
370[ $ret = 0 ] || { echo_i "failed"; status=1; }
371
372n=$((n + 1))
373ret=0
374echo_i "fetching second copy of test zone ($n)"
375$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
376	@10.53.0.2 axfr > dig.out.ns2 || ret=1
377[ $ret = 0 ] || { echo_i "failed"; status=1; }
378
379n=$((n + 1))
380ret=0
381echo_i "comparing zones ($n)"
382digcomp dig.out.ns1 dig.out.ns2 || ret=1
383[ $ret = 0 ] || { echo_i "failed"; status=1; }
384
385echo_i "SIGKILL and restart server ns1"
386cd ns1
387$KILL -KILL $(cat named.pid)
388rm named.pid
389cd ..
390sleep 10
391if
392	start_server --noclean --restart --port ${PORT} ns1
393then
394	echo_i "restarted server ns1"
395else
396	echo_i "could not restart server ns1"
397	exit 1
398fi
399sleep 10
400
401n=$((n + 1))
402ret=0
403echo_i "fetching ns1 after hard restart ($n)"
404$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
405	@10.53.0.1 axfr > dig.out.ns1.after || ret=1
406[ $ret = 0 ] || { echo_i "failed"; status=1; }
407
408n=$((n + 1))
409ret=0
410echo_i "comparing zones ($n)"
411digcomp dig.out.ns1 dig.out.ns1.after || ret=1
412[ $ret = 0 ] || { echo_i "failed"; status=1; }
413
414echo_i "begin RT #482 regression test"
415
416n=$((n + 1))
417ret=0
418echo_i "update primary ($n)"
419$NSUPDATE -k ns1/ddns.key <<END > /dev/null || ret=1
420server 10.53.0.1 ${PORT}
421update add updated2.example.nil. 600 A 10.10.10.2
422update add updated2.example.nil. 600 TXT Bar
423update delete c.example.nil.
424send
425END
426[ $ret = 0 ] || { echo_i "failed"; status=1; }
427
428sleep 5
429
430if [ ! "$CYGWIN" ]; then
431    echo_i "SIGHUP secondary"
432    $KILL -HUP $(cat ns2/named.pid)
433else
434    echo_i "reload secondary"
435    rndc_reload ns2 10.53.0.2
436fi
437
438sleep 5
439
440n=$((n + 1))
441ret=0
442echo_i "update primary again ($n)"
443$NSUPDATE -k ns1/ddns.key <<END > /dev/null || ret=1
444server 10.53.0.1 ${PORT}
445update add updated3.example.nil. 600 A 10.10.10.3
446update add updated3.example.nil. 600 TXT Zap
447del d.example.nil.
448send
449END
450[ $ret = 0 ] || { echo_i "failed"; status=1; }
451
452sleep 5
453
454if [ ! "$CYGWIN" ]; then
455    echo_i "SIGHUP secondary again"
456    $KILL -HUP $(cat ns2/named.pid)
457else
458    echo_i "reload secondary again"
459    rndc_reload ns2 10.53.0.2
460fi
461
462sleep 5
463
464n=$((n + 1))
465echo_i "check to 'out of sync' message ($n)"
466if grep "out of sync" ns2/named.run
467then
468	echo_i "failed (found 'out of sync')"
469	status=1
470fi
471
472echo_i "end RT #482 regression test"
473
474n=$((n + 1))
475ret=0
476echo_i "start NSEC3PARAM changes via UPDATE on a unsigned zone test ($n)"
477$NSUPDATE << EOF
478server 10.53.0.3 ${PORT}
479update add example 3600 nsec3param 1 0 0 -
480send
481EOF
482
483# the zone is not signed.  The nsec3param records should be removed.
484# this also proves that the server is still running.
485$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec example.\
486	@10.53.0.3 nsec3param > dig.out.ns3.$n || ret=1
487grep "ANSWER: 0," dig.out.ns3.$n > /dev/null || ret=1
488grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1
489[ $ret = 0 ] || { echo_i "failed"; status=1; }
490
491n=$((n + 1))
492ret=0
493echo_i "change the NSEC3PARAM ttl via update ($n)"
494$NSUPDATE << EOF
495server 10.53.0.3 ${PORT}
496update add nsec3param.test 3600 NSEC3PARAM 1 0 1 -
497send
498EOF
499
500$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec nsec3param.test.\
501        @10.53.0.3 nsec3param > dig.out.ns3.$n || ret=1
502grep "ANSWER: 1," dig.out.ns3.$n > /dev/null || ret=1
503grep "3600.*NSEC3PARAM" dig.out.ns3.$n > /dev/null || ret=1
504grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1
505[ $ret = 0 ] || { echo_i "failed"; status=1; }
506
507n=$((n + 1))
508ret=0
509echo_i "add a new NSEC3PARAM via update ($n)"
510$NSUPDATE << EOF
511server 10.53.0.3 ${PORT}
512update add nsec3param.test 3600 NSEC3PARAM 1 0 4 -
513send
514EOF
515
516_ret=1
517for i in 0 1 2 3 4 5 6 7 8 9; do
518	$DIG $DIGOPTS +tcp +norec +time=1 +tries=1 @10.53.0.3 nsec3param.test. NSEC3PARAM > dig.out.ns3.$n || _ret=1
519	if grep "ANSWER: 2," dig.out.ns3.$n > /dev/null; then
520		_ret=0
521		break
522	fi
523	sleep 1
524done
525
526if [ $_ret -ne 0 ]; then ret=1; fi
527grep "NSEC3PARAM 1 0 4 -" dig.out.ns3.$n > /dev/null || ret=1
528grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1
529if [ $ret != 0 ] ; then echo_i "failed"; status=$((ret + status)); fi
530
531n=$((n + 1))
532ret=0
533echo_i "add, delete and change the ttl of the NSEC3PARAM rrset via update ($n)"
534$NSUPDATE << EOF
535server 10.53.0.3 ${PORT}
536update delete nsec3param.test NSEC3PARAM
537update add nsec3param.test 7200 NSEC3PARAM 1 0 5 -
538send
539EOF
540
541_ret=1
542for i in 0 1 2 3 4 5 6 7 8 9; do
543	$DIG $DIGOPTS +tcp +norec +time=1 +tries=1 @10.53.0.3 nsec3param.test. NSEC3PARAM > dig.out.ns3.$n || _ret=1
544	if grep "ANSWER: 1," dig.out.ns3.$n > /dev/null; then
545		_ret=0
546		break
547	fi
548	sleep 1
549done
550
551if [ $_ret -ne 0 ]; then ret=1; fi
552grep "7200.*NSEC3PARAM 1 0 5 -" dig.out.ns3.$n > /dev/null || ret=1
553grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1
554$JOURNALPRINT ns3/nsec3param.test.db.signed.jnl > jp.out.ns3.$n
555# intermediate TTL changes.
556grep "add nsec3param.test.	7200	IN	NSEC3PARAM 1 0 4 -" jp.out.ns3.$n > /dev/null || ret=1
557grep "add nsec3param.test.	7200	IN	NSEC3PARAM 1 0 1 -" jp.out.ns3.$n > /dev/null || ret=1
558# delayed adds and deletes.
559grep "add nsec3param.test.	0	IN	TYPE65534 .# 6 000180000500" jp.out.ns3.$n > /dev/null || ret=1
560grep "add nsec3param.test.	0	IN	TYPE65534 .# 6 000140000100" jp.out.ns3.$n > /dev/null || ret=1
561grep "add nsec3param.test.	0	IN	TYPE65534 .# 6 000140000400" jp.out.ns3.$n > /dev/null || ret=1
562if [ $ret != 0 ] ; then echo_i "failed"; status=$((ret + status)); fi
563
564
565ret=0
566echo_i "testing that rndc stop updates the file"
567$NSUPDATE -k ns1/ddns.key <<END > /dev/null || ret=1
568server 10.53.0.1 ${PORT}
569update add updated4.example.nil. 600 A 10.10.10.3
570send
571END
572sleep 3
573stop_server --use-rndc --port ${CONTROLPORT} ns1
574sleep 3
575# Removing the journal file and restarting the server means
576# that the data served by the new server process are exactly
577# those dumped to the file by "rndc stop".
578rm -f ns1/*jnl
579start_server --noclean --restart --port ${PORT} ns1
580for try in 0 1 2 3 4 5 6 7 8 9; do
581    iret=0
582    $DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
583	updated4.example.nil. @10.53.0.1 a > dig.out.ns1 || iret=1
584    digcomp knowngood.ns1.afterstop dig.out.ns1 || iret=1
585    [ "$iret" -eq 0 ] && break
586    sleep 1
587done
588[ "$iret" -ne 0 ] && ret=1
589[ "$ret" -eq 0 ] || { echo_i "failed"; status=1; }
590
591ret=0
592echo_i "check that 'nsupdate -l' with a missing keyfile reports the missing file"
593$NSUPDATE -4 -p ${PORT} -l -k ns1/nonexistent.key 2> nsupdate.out < /dev/null
594grep ns1/nonexistent.key nsupdate.out > /dev/null || ret=1
595if test $ret -ne 0
596then
597echo_i "failed"; status=1
598fi
599
600n=$((n + 1))
601ret=0
602echo_i "check that 'update-policy local' works from localhost address ($n)"
603$NSUPDATE -k ns5/session.key > nsupdate.out.$n 2>&1 << END || ret=1
604server 10.53.0.5 ${PORT}
605local 127.0.0.1
606update add fromlocal.local.nil. 600 A 1.2.3.4
607send
608END
609grep REFUSED nsupdate.out.$n > /dev/null 2>&1 && ret=1
610$DIG $DIGOPTS @10.53.0.5 \
611        +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
612        fromlocal.local.nil. > dig.out.ns5.$n || ret=1
613grep fromlocal dig.out.ns5.$n > /dev/null 2>&1 || ret=1
614if test $ret -ne 0
615then
616echo_i "failed"; status=1
617fi
618
619n=$((n + 1))
620ret=0
621echo_i "check that 'update-policy local' fails from non-localhost address ($n)"
622grep 'match on session key not from localhost' ns5/named.run > /dev/null && ret=1
623$NSUPDATE -k ns5/session.key > nsupdate.out.$n 2>&1 << END && ret=1
624server 10.53.0.5 ${PORT}
625local 10.53.0.1
626update add nonlocal.local.nil. 600 A 4.3.2.1
627send
628END
629grep REFUSED nsupdate.out.$n > /dev/null 2>&1 || ret=1
630grep 'match on session key not from localhost' ns5/named.run > /dev/null || ret=1
631$DIG $DIGOPTS @10.53.0.5 \
632        +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
633        nonlocal.local.nil. > dig.out.ns5.$n || ret=1
634grep nonlocal dig.out.ns5.$n > /dev/null 2>&1 && ret=1
635if test $ret -ne 0
636then
637echo_i "failed"; status=1
638fi
639
640n=$((n + 1))
641ret=0
642echo_i "check that 'update-policy tcp-self' refuses update of records via UDP ($n)"
643$NSUPDATE > nsupdate.out.$n 2>&1 << END
644server 10.53.0.6 ${PORT}
645local 127.0.0.1
646update add 1.0.0.127.in-addr.arpa. 600 PTR localhost.
647send
648END
649grep REFUSED nsupdate.out.$n > /dev/null 2>&1 || ret=1
650$DIG $DIGOPTS @10.53.0.6 \
651        +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
652        -x 127.0.0.1 > dig.out.ns6.$n
653grep localhost. dig.out.ns6.$n > /dev/null 2>&1 && ret=1
654if test $ret -ne 0
655then
656echo_i "failed"; status=1
657fi
658
659n=$((n + 1))
660ret=0
661echo_i "check that 'update-policy tcp-self' permits update of records for the client's own address via TCP ($n)"
662$NSUPDATE -v > nsupdate.out.$n 2>&1 << END || ret=1
663server 10.53.0.6 ${PORT}
664local 127.0.0.1
665update add 1.0.0.127.in-addr.arpa. 600 PTR localhost.
666send
667END
668grep REFUSED nsupdate.out.$n > /dev/null 2>&1 && ret=1
669$DIG $DIGOPTS @10.53.0.6 \
670        +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
671        -x 127.0.0.1 > dig.out.ns6.$n || ret=1
672grep localhost. dig.out.ns6.$n > /dev/null 2>&1 || ret=1
673if test $ret -ne 0
674then
675echo_i "failed"; status=1
676fi
677
678n=$((n + 1))
679ret=0
680echo_i "check that 'update-policy tcp-self' refuses update of records for a different address from the client's own address via TCP ($n)"
681$NSUPDATE -v > nsupdate.out.$n 2>&1 << END
682server 10.53.0.6 ${PORT}
683local 127.0.0.1
684update add 1.0.168.192.in-addr.arpa. 600 PTR localhost.
685send
686END
687grep REFUSED nsupdate.out.$n > /dev/null 2>&1 || ret=1
688$DIG $DIGOPTS @10.53.0.6 \
689        +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
690        -x 192.168.0.1 > dig.out.ns6.$n
691grep localhost. dig.out.ns6.$n > /dev/null 2>&1 && ret=1
692if test $ret -ne 0
693then
694echo_i "failed"; status=1
695fi
696
697n=$((n + 1))
698ret=0
699echo_i "check that 'update-policy subdomain' is properly enforced ($n)"
700# "restricted.example.nil" matches "grant ... subdomain restricted.example.nil"
701# and thus this UPDATE should succeed.
702$NSUPDATE -d <<END > nsupdate.out1-$n 2>&1 || ret=1
703server 10.53.0.1 ${PORT}
704key restricted.example.nil 1234abcd8765
705update add restricted.example.nil 0 IN TXT everywhere.
706send
707END
708$DIG $DIGOPTS +tcp @10.53.0.1 restricted.example.nil TXT > dig.out.1.test$n || ret=1
709grep "TXT.*everywhere" dig.out.1.test$n > /dev/null || ret=1
710# "example.nil" does not match "grant ... subdomain restricted.example.nil" and
711# thus this UPDATE should fail.
712$NSUPDATE -d <<END > nsupdate.out2-$n 2>&1 && ret=1
713server 10.53.0.1 ${PORT}
714key restricted.example.nil 1234abcd8765
715update add example.nil 0 IN TXT everywhere.
716send
717END
718$DIG $DIGOPTS +tcp @10.53.0.1 example.nil TXT > dig.out.2.test$n || ret=1
719grep "TXT.*everywhere" dig.out.2.test$n > /dev/null && ret=1
720[ $ret = 0 ] || { echo_i "failed"; status=1; }
721
722n=$((n + 1))
723ret=0
724echo_i "check that 'update-policy zonesub' is properly enforced ($n)"
725# grant zonesub-key.example.nil zonesub TXT;
726# the A record update should be rejected as it is not in the type list
727$NSUPDATE -d <<END > nsupdate.out1-$n 2>&1 && ret=1
728server 10.53.0.1 ${PORT}
729key zonesub-key.example.nil 1234subk8765
730update add zonesub.example.nil 0 IN A 1.2.3.4
731send
732END
733$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil A > dig.out.1.test$n || ret=1
734grep "status: REFUSED" nsupdate.out1-$n > /dev/null || ret=1
735grep "ANSWER: 0," dig.out.1.test$n > /dev/null || ret=1
736# the TXT record update should be accepted as it is in the type list
737$NSUPDATE -d <<END > nsupdate.out2-$n 2>&1 || ret=1
738server 10.53.0.1 ${PORT}
739key zonesub-key.example.nil 1234subk8765
740update add zonesub.example.nil 0 IN TXT everywhere.
741send
742END
743$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil TXT > dig.out.2.test$n || ret=1
744grep "status: REFUSED" nsupdate.out2-$n > /dev/null && ret=1
745grep "ANSWER: 1," dig.out.2.test$n > /dev/null || ret=1
746grep "TXT.*everywhere" dig.out.2.test$n > /dev/null || ret=1
747[ $ret = 0 ] || { echo_i "failed"; status=1; }
748
749n=$((n + 1))
750ret=0
751echo_i "check 'grant' in deny name + grant subdomain ($n)"
752$NSUPDATE << EOF > nsupdate.out-$n 2>&1 || ret=1
753key hmac-sha256:subkey 1234abcd8765
754server 10.53.0.9 ${PORT}
755zone denyname.example
756update add foo.denyname.example 3600 IN TXT added
757send
758EOF
759$DIG $DIGOPTS +tcp @10.53.0.9 foo.denyname.example TXT > dig.out.ns9.test$n
760grep "added" dig.out.ns9.test$n > /dev/null || ret=1
761[ $ret = 0 ] || { echo_i "failed"; status=1; }
762
763n=$((n + 1))
764ret=0
765echo_i "check 'deny' in deny name + grant subdomain ($n)"
766$NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
767key hmac-sha256:subkey 1234abcd8765
768server 10.53.0.9 ${PORT}
769zone denyname.example
770update add denyname.example 3600 IN TXT added
771send
772EOF
773$DIG $DIGOPTS +tcp @10.53.0.9 denyname.example TXT > dig.out.ns9.test$n
774grep "added" dig.out.ns9.test$n > /dev/null && ret=1
775[ $ret = 0 ] || { echo_i "failed"; status=1; }
776
777n=$((n + 1))
778ret=0
779echo_i "check that changes to the DNSKEY RRset TTL do not have side effects ($n)"
780$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd dnskey.test. \
781        @10.53.0.3 dnskey | \
782	awk -v port="${PORT}" 'BEGIN { print "server 10.53.0.3", port; }
783	$2 == 10 && $3 == "IN" && $4 == "DNSKEY" { $2 = 600; print "update add", $0 }
784	END { print "send" }' > update.in.$n
785$NSUPDATE update.in.$n
786
787$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd dnskey.test. \
788	@10.53.0.3 any > dig.out.ns3.$n
789
790grep "600.*DNSKEY" dig.out.ns3.$n > /dev/null || ret=1
791grep TYPE65534 dig.out.ns3.$n > /dev/null && ret=1
792if test $ret -ne 0
793then
794echo_i "failed"; status=1
795fi
796
797n=$((n + 1))
798ret=0
799echo_i "check notify with TSIG worked ($n)"
800# if the alternate view received a notify--meaning, the notify was
801# validly signed by "altkey"--then the zonefile update.alt.bk will
802# will have been created.
803[ -f ns2/update.alt.bk ] || ret=1
804if [ $ret -ne 0 ]; then
805    echo_i "failed"
806    status=1
807fi
808
809n=$((n + 1))
810ret=0
811echo_i "check type list options ($n)"
812$NSUPDATE -T > typelist.out.T.${n} || { ret=1; echo_i "nsupdate -T failed"; }
813$NSUPDATE -P > typelist.out.P.${n} || { ret=1; echo_i "nsupdate -P failed"; }
814$NSUPDATE -TP > typelist.out.TP.${n} || { ret=1; echo_i "nsupdate -TP failed"; }
815grep ANY typelist.out.T.${n} > /dev/null && { ret=1; echo_i "failed: ANY found (-T)"; }
816grep ANY typelist.out.P.${n} > /dev/null && { ret=1; echo_i "failed: ANY found (-P)"; }
817grep ANY typelist.out.TP.${n} > /dev/null && { ret=1; echo_i "failed: ANY found (-TP)"; }
818grep KEYDATA typelist.out.T.${n} > /dev/null && { ret=1; echo_i "failed: KEYDATA found (-T)"; }
819grep KEYDATA typelist.out.P.${n} > /dev/null && { ret=1; echo_i "failed: KEYDATA found (-P)"; }
820grep KEYDATA typelist.out.TP.${n} > /dev/null && { ret=1; echo_i "failed: KEYDATA found (-TP)"; }
821grep AAAA typelist.out.T.${n} > /dev/null || { ret=1; echo_i "failed: AAAA not found (-T)"; }
822grep AAAA typelist.out.P.${n} > /dev/null && { ret=1; echo_i "failed: AAAA found (-P)"; }
823grep AAAA typelist.out.TP.${n} > /dev/null || { ret=1; echo_i "failed: AAAA not found (-TP)"; }
824if [ $ret -ne 0 ]; then
825    echo_i "failed"
826    status=1
827fi
828
829n=$((n + 1))
830ret=0
831echo_i "check command list ($n)"
832(
833while read cmd
834do
835    echo "$cmd" | $NSUPDATE  > /dev/null 2>&1
836    if test $? -gt 1 ; then
837	echo_i "failed ($cmd)"
838	ret=1
839    fi
840    echo "$cmd " | $NSUPDATE  > /dev/null 2>&1
841    if test $? -gt 1 ; then
842	echo_i "failed ($cmd)"
843	ret=1
844    fi
845done
846exit $ret
847) < commandlist || ret=1
848if [ $ret -ne 0 ]; then
849    status=1
850fi
851
852n=$((n + 1))
853ret=0
854echo_i "check TSIG key algorithms (nsupdate -k) ($n)"
855for alg in md5 sha1 sha224 sha256 sha384 sha512; do
856    $NSUPDATE -k ns1/${alg}.key <<END > /dev/null || ret=1
857server 10.53.0.1 ${PORT}
858update add ${alg}.keytests.nil. 600 A 10.10.10.3
859send
860END
861done
862sleep 2
863for alg in md5 sha1 sha224 sha256 sha384 sha512; do
864    $DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.3 > /dev/null 2>&1 || ret=1
865done
866if [ $ret -ne 0 ]; then
867    echo_i "failed"
868    status=1
869fi
870
871n=$((n + 1))
872ret=0
873echo_i "check TSIG key algorithms (nsupdate -y) ($n)"
874for alg in md5 sha1 sha224 sha256 sha384 sha512; do
875    secret=$(sed -n 's/.*secret "\(.*\)";.*/\1/p' ns1/${alg}.key)
876    $NSUPDATE -y "hmac-${alg}:${alg}-key:$secret" <<END > /dev/null || ret=1
877server 10.53.0.1 ${PORT}
878update add ${alg}.keytests.nil. 600 A 10.10.10.50
879send
880END
881done
882sleep 2
883for alg in md5 sha1 sha224 sha256 sha384 sha512; do
884    $DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.50 > /dev/null 2>&1 || ret=1
885done
886if [ $ret -ne 0 ]; then
887    echo_i "failed"
888    status=1
889fi
890
891n=$((n + 1))
892ret=0
893echo_i "check that ttl is capped by max-ttl ($n)"
894$NSUPDATE <<END > /dev/null || ret=1
895server 10.53.0.1 ${PORT}
896update add cap.max-ttl.nil. 600 A 10.10.10.3
897update add nocap.max-ttl.nil. 150 A 10.10.10.3
898send
899END
900sleep 2
901$DIG $DIGOPTS @10.53.0.1  cap.max-ttl.nil | grep "^cap.max-ttl.nil.	300" > /dev/null 2>&1 || ret=1
902$DIG $DIGOPTS @10.53.0.1  nocap.max-ttl.nil | grep "^nocap.max-ttl.nil.	150" > /dev/null 2>&1 || ret=1
903if [ $ret -ne 0 ]; then
904    echo_i "failed"
905    status=1
906fi
907
908n=$((n + 1))
909ret=0
910echo_i "add a record which is truncated when logged. ($n)"
911$NSUPDATE verylarge || ret=1
912$DIG $DIGOPTS +tcp @10.53.0.1 txt txt.update.nil > dig.out.ns1.test$n
913grep "ANSWER: 1," dig.out.ns1.test$n > /dev/null || ret=1
914grep "adding an RR at 'txt.update.nil' TXT .* \[TRUNCATED\]"  ns1/named.run > /dev/null || ret=1
915if [ $ret -ne 0 ]; then
916    echo_i "failed"
917    status=1
918fi
919
920n=$((n + 1))
921ret=0
922echo_i "check that yyyymmddvv serial number is correctly generated ($n)"
923oldserial=$($DIG $DIGOPTS +short yyyymmddvv.nil. soa @10.53.0.1 | awk '{print $3}') || ret=1
924$NSUPDATE <<END > /dev/null 2>&1 || ret=1
925    server 10.53.0.1 ${PORT}
926    ttl 600
927    update add new.yyyymmddvv.nil in a 1.2.3.4
928    send
929END
930now=$($PERL -e '@lt=localtime(); printf "%.4d%0.2d%0.2d00\n",$lt[5]+1900,$lt[4]+1,$lt[3];')
931sleep 1
932serial=$($DIG $DIGOPTS +short yyyymmddvv.nil. soa @10.53.0.1 | awk '{print $3}') || ret=1
933[ "$oldserial" -ne "$serial" ] || ret=1
934[ "$serial" -eq "$now" ] || ret=1
935[ $ret = 0 ] || { echo_i "failed"; status=1; }
936
937#
938#  Refactor to use perl to launch the parallel updates.
939#
940if false
941then
942n=$((n + 1))
943echo_i "send many simultaneous updates via a update forwarder ($n)"
944ret=0
945for i in 0 1 2 3 4 5 6 7
946do
947(
948    for j in 0 1 2 3 4 5 6 7
949    do
950    (
951	$NSUPDATE << EOF
952server 10.53.0.3 ${PORT}
953zone many.test
954update add $i-$j.many.test 0 IN A 1.2.3.4
955send
956EOF
957    ) &
958    done
959    wait
960) &
961done
962wait
963dig axfr many.test @10.53.0.1 > dig.out.test$n
964lines=$(awk '$4 == "A" { l++ } END { print l }' dig.out.test$n)
965test ${lines:-0} -eq 64 || ret=1
966[ $ret = 0 ] || { echo_i "failed"; status=1; }
967fi
968
969n=$((n + 1))
970echo_i "check max-journal-size limits ($n)"
971ret=0
972rm -f nsupdate.out1-$n
973# add one record
974$NSUPDATE << EOF >> nsupdate.out1-$n 2>&1
975server 10.53.0.1 ${PORT}
976zone maxjournal.test
977update add z.maxjournal.test 300 IN A 10.20.30.40
978send
979EOF
980for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
981    # repeatedly add and remove the same set of records to fill up
982    # the journal file without changing the zone content
983    $NSUPDATE << EOF >> nsupdate.out1-$n 2>&1
984server 10.53.0.1 ${PORT}
985zone maxjournal.test
986update add a.maxjournal.test 300 IN A 1.2.3.4
987update add b.maxjournal.test 300 IN A 1.2.3.4
988update add c.maxjournal.test 300 IN A 1.2.3.4
989update add d.maxjournal.test 300 IN A 1.2.3.4
990send
991update del a.maxjournal.test
992update del b.maxjournal.test
993update del c.maxjournal.test
994update del d.maxjournal.test
995send
996EOF
997done
998# check that the journal is big enough to require truncation.
999size=$($PERL -e 'use File::stat; my $sb = stat(@ARGV[0]); printf("%s\n", $sb->size);' ns1/maxjournal.db.jnl)
1000[ "$size" -gt 6000 ] || ret=1
1001sleep 1
1002$RNDCCMD 10.53.0.1 sync maxjournal.test
1003check_size_lt_5000() (
1004    size=$($PERL -e 'use File::stat; my $sb = stat(@ARGV[0]); printf("%s\n", $sb->size);' ns1/maxjournal.db.jnl)
1005    [ "$size" -lt 5000 ]
1006)
1007retry_quiet 20 check_size_lt_5000 || ret=1
1008[ $ret = 0 ] || { echo_i "failed"; status=1; }
1009
1010n=$((n + 1))
1011echo_i "check check-names processing ($n)"
1012ret=0
1013$NSUPDATE << EOF > nsupdate.out1-$n 2>&1
1014update add # 0 in a 1.2.3.4
1015EOF
1016grep "bad owner" nsupdate.out1-$n > /dev/null || ret=1
1017
1018$NSUPDATE << EOF > nsupdate.out2-$n 2>&1
1019check-names off
1020update add # 0 in a 1.2.3.4
1021EOF
1022grep "bad owner" nsupdate.out2-$n > /dev/null && ret=1
1023
1024$NSUPDATE << EOF > nsupdate.out3-$n 2>&1
1025update add . 0 in mx 0 #
1026EOF
1027grep "bad name" nsupdate.out3-$n > /dev/null || ret=1
1028
1029$NSUPDATE << EOF > nsupdate.out4-$n 2>&1
1030check-names off
1031update add . 0 in mx 0 #
1032EOF
1033grep "bad name" nsupdate.out4-$n > /dev/null && ret=1
1034
1035[ $ret = 0 ] || { echo_i "failed"; status=1; }
1036
1037n=$((n + 1))
1038echo_i "check adding of delegating NS records processing ($n)"
1039ret=0
1040$NSUPDATE -v << EOF > nsupdate.out-$n 2>&1 || ret=1
1041server 10.53.0.3 ${PORT}
1042zone delegation.test.
1043update add child.delegation.test. 3600 NS foo.example.net.
1044update add child.delegation.test. 3600 NS bar.example.net.
1045send
1046EOF
1047$DIG $DIGOPTS +tcp @10.53.0.3 ns child.delegation.test > dig.out.ns1.test$n
1048grep "status: NOERROR" dig.out.ns1.test$n > /dev/null 2>&1 || ret=1
1049grep "AUTHORITY: 2" dig.out.ns1.test$n > /dev/null 2>&1 || ret=1
1050[ $ret = 0 ] || { echo_i "failed"; status=1; }
1051
1052n=$((n + 1))
1053echo_i "check deleting of delegating NS records processing ($n)"
1054ret=0
1055$NSUPDATE -v << EOF > nsupdate.out-$n 2>&1 || ret=1
1056server 10.53.0.3 ${PORT}
1057zone delegation.test.
1058update del child.delegation.test. 3600 NS foo.example.net.
1059update del child.delegation.test. 3600 NS bar.example.net.
1060send
1061EOF
1062$DIG $DIGOPTS +tcp @10.53.0.3 ns child.delegation.test > dig.out.ns1.test$n
1063grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null 2>&1 || ret=1
1064[ $ret = 0 ] || { echo_i "failed"; status=1; }
1065
1066n=$((n + 1))
1067echo_i "check that adding too many records is blocked ($n)"
1068ret=0
1069$NSUPDATE -v << EOF > nsupdate.out-$n 2>&1 && ret=1
1070server 10.53.0.3 ${PORT}
1071zone too-big.test.
1072update add r1.too-big.test 3600 IN TXT r1.too-big.test
1073send
1074EOF
1075grep "update failed: SERVFAIL" nsupdate.out-$n > /dev/null || ret=1
1076$DIG $DIGOPTS +tcp @10.53.0.3 r1.too-big.test TXT > dig.out.ns3.test$n
1077grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1
1078grep "records in zone (4) exceeds max-records (3)" ns3/named.run > /dev/null || ret=1
1079[ $ret = 0 ] || { echo_i "failed"; status=1; }
1080
1081n=$((n + 1))
1082ret=0
1083echo_i "check whether valid addresses are used for primary failover ($n)"
1084$NSUPDATE -t 1 <<END > nsupdate.out-$n 2>&1 && ret=1
1085server 10.53.0.4 ${PORT}
1086zone unreachable.
1087update add unreachable. 600 A 192.0.2.1
1088send
1089END
1090grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out-$n > /dev/null 2>&1 || ret=1
1091grep "not implemented" nsupdate.out-$n > /dev/null 2>&1 && ret=1
1092[ $ret = 0 ] || { echo_i "failed"; status=1; }
1093
1094n=$((n + 1))
1095ret=0
1096echo_i "ensure bad owner name is fatal in non-interactive mode ($n)"
1097$NSUPDATE <<END > nsupdate.out 2>&1 && ret=1
1098    update add emptylabel..nil. 600 A 10.10.10.1
1099END
1100grep "invalid owner name: empty label" nsupdate.out > /dev/null || ret=1
1101grep "syntax error" nsupdate.out > /dev/null || ret=1
1102[ $ret = 0 ] || { echo_i "failed"; status=1; }
1103
1104n=$((n + 1))
1105ret=0
1106echo_i "ensure bad owner name is not fatal in interactive mode ($n)"
1107$NSUPDATE -i <<END > nsupdate.out 2>&1 || ret=1
1108    update add emptylabel..nil. 600 A 10.10.10.1
1109END
1110grep "invalid owner name: empty label" nsupdate.out > /dev/null || ret=1
1111[ $ret = 0 ] || { echo_i "failed"; status=1; }
1112
1113n=$((n + 1))
1114ret=0
1115echo_i "ensure invalid key type is fatal in non-interactive mode ($n)"
1116$NSUPDATE <<END > nsupdate.out 2>&1 && ret=1
1117    key badkeytype:example abcd12345678
1118END
1119grep "unknown key type 'badkeytype'" nsupdate.out > /dev/null || ret=1
1120grep "syntax error" nsupdate.out > /dev/null || ret=1
1121[ $ret = 0 ] || { echo_i "failed"; status=1; }
1122
1123n=$((n + 1))
1124ret=0
1125echo_i "ensure invalid key type is not fatal in interactive mode ($n)"
1126$NSUPDATE -i <<END > nsupdate.out 2>&1 || ret=1
1127    key badkeytype:example abcd12345678
1128END
1129grep "unknown key type 'badkeytype'" nsupdate.out > /dev/null || ret=1
1130[ $ret = 0 ] || { echo_i "failed"; status=1; }
1131
1132n=$((n + 1))
1133ret=0
1134echo_i "ensure unresolvable server name is fatal in non-interactive mode ($n)"
1135$NSUPDATE <<END > nsupdate.out 2>&1 && ret=1
1136    server unresolvable..
1137END
1138grep "couldn't get address for 'unresolvable..':" nsupdate.out > /dev/null || ret=1
1139grep "syntax error" nsupdate.out > /dev/null || ret=1
1140[ $ret = 0 ] || { echo_i "failed"; status=1; }
1141
1142n=$((n + 1))
1143ret=0
1144echo_i "ensure unresolvable server name is not fatal in interactive mode ($n)"
1145$NSUPDATE -i <<END > nsupdate.out 2>&1 || ret=1
1146    server unresolvable..
1147END
1148grep "couldn't get address for 'unresolvable..':" nsupdate.out > /dev/null || ret=1
1149grep "syntax error" nsupdate.out > /dev/null && ret=1
1150[ $ret = 0 ] || { echo_i "failed"; status=1; }
1151
1152n=$((n + 1))
1153ret=0
1154echo_i "check nsupdate -4 -6 ($n)"
1155$NSUPDATE -4 -6 <<END > nsupdate.out-$n 2>&1 && ret=1
1156server 10.53.0.3 ${PORT}
1157zone delegation.test.
1158update del child.delegation.test. 3600 NS foo.example.net.
1159update del child.delegation.test. 3600 NS bar.example.net.
1160send
1161END
1162grep "only one of -4 and -6 allowed" nsupdate.out-$n > /dev/null 2>&1 || ret=1
1163[ $ret = 0 ] || { echo_i "failed"; status=1; }
1164
1165n=$((n + 1))
1166ret=0
1167echo_i "check nsupdate -4 with an IPv6 server address ($n)"
1168$NSUPDATE -4 <<END > nsupdate.out-$n 2>&1 && ret=1
1169server fd92:7065:b8e:ffff::2 ${PORT}
1170zone delegation.test.
1171update del child.delegation.test. 3600 NS foo.example.net.
1172update del child.delegation.test. 3600 NS bar.example.net.
1173send
1174END
1175grep "address family not supported" nsupdate.out-$n > /dev/null 2>&1 || ret=1
1176[ $ret = 0 ] || { echo_i "failed"; status=1; }
1177
1178n=$((n + 1))
1179ret=0
1180echo_i "check that TKEY in a update is rejected ($n)"
1181$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 && ret=1
1182server 10.53.0.3 ${PORT}
1183update add tkey.example 0 in tkey invalid.algorithm. 1516055980 1516140801 1 0 16 gRof8D2BFKvl/vrr9Lmnjw== 16 gRof8D2BFKvl/vrr9Lmnjw==
1184send
1185END
1186grep "UPDATE, status: NOERROR" nsupdate.out-$n > /dev/null 2>&1 || ret=1
1187grep "UPDATE, status: FORMERR" nsupdate.out-$n > /dev/null 2>&1 || ret=1
1188[ $ret = 0 ] || { echo_i "failed"; status=1; }
1189
1190n=$((n + 1))
1191ret=0
1192echo_i "check that DS to the zone apex is ignored ($n)"
1193$DIG $DIGOPTS +tcp +norec example DS @10.53.0.3 > dig.out.pre.test$n || ret=1
1194grep "status: NOERROR" dig.out.pre.test$n > /dev/null || ret=1
1195grep "ANSWER: 0," dig.out.pre.test$n > /dev/null || ret=1
1196nextpart ns3/named.run > /dev/null
1197# specify zone to override the default of adding to parent zone
1198$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 || ret=1
1199server 10.53.0.3 ${PORT}
1200zone example
1201update add example 0 in DS 14364 10 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
1202send
1203END
1204msg=": attempt to add a DS record at zone apex ignored"
1205nextpart ns3/named.run | grep "$msg" > /dev/null || ret=1
1206$DIG $DIGOPTS +tcp +norec example DS @10.53.0.3 > dig.out.post.test$n || ret=1
1207grep "status: NOERROR" dig.out.post.test$n > /dev/null || ret=1
1208grep "ANSWER: 0," dig.out.post.test$n > /dev/null || ret=1
1209[ $ret = 0 ] || { echo_i "failed"; status=1; }
1210
1211n=$((n + 1))
1212ret=0
1213echo_i "check that CDS with mismatched algorithm to DNSSEC multisigner zone is not allowed ($n)"
1214$DIG $DIGOPTS +tcp +norec multisigner.test CDS @10.53.0.3 > dig.out.pre.test$n || ret=1
1215grep "status: NOERROR" dig.out.pre.test$n > /dev/null || ret=1
1216grep "ANSWER: 0," dig.out.pre.test$n > /dev/null || ret=1
1217$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 && ret=1
1218server 10.53.0.3 ${PORT}
1219zone multisigner.test
1220update add multisigner.test 3600 IN CDS 14364 14 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
1221send
1222END
1223msg=": bad CDS RRset"
1224nextpart ns3/named.run | grep "$msg" > /dev/null || ret=1
1225$DIG $DIGOPTS +tcp +norec multisigner.test CDS @10.53.0.3 > dig.out.post.test$n || ret=1
1226grep "status: NOERROR" dig.out.post.test$n > /dev/null || ret=1
1227grep "ANSWER: 0," dig.out.post.test$n > /dev/null || ret=1
1228[ $ret = 0 ] || { echo_i "failed"; status=1; }
1229
1230n=$((n + 1))
1231ret=0
1232echo_i "check that CDNSKEY with mismatched algorithm to DNSSEC multisigner zone is not allowed ($n)"
1233$DIG $DIGOPTS +tcp +norec multisigner.test CDNSKEY @10.53.0.3 > dig.out.pre.test$n || ret=1
1234grep "status: NOERROR" dig.out.pre.test$n > /dev/null || ret=1
1235grep "ANSWER: 0," dig.out.pre.test$n > /dev/null || ret=1
1236nextpart ns3/named.run > /dev/null
1237$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 && ret=1
1238server 10.53.0.3 ${PORT}
1239zone multisigner.test
1240update add multisigner.test 3600 IN CDNSKEY 257 3 14 d0NQ5PKmDz6P0B1WPMH9/UKRux/toSFwV2nTJYPA1Cx8pB0sJGTXbVhG U+6gye7VCHDhGIn9CjVfb2RJPW7GnQ==
1241send
1242END
1243msg=": bad CDNSKEY RRset"
1244nextpart ns3/named.run | grep "$msg" > /dev/null || ret=1
1245$DIG $DIGOPTS +tcp +norec multisigner.test CDNSKEY @10.53.0.3 > dig.out.post.test$n || ret=1
1246grep "status: NOERROR" dig.out.post.test$n > /dev/null || ret=1
1247grep "ANSWER: 0," dig.out.post.test$n > /dev/null || ret=1
1248[ $ret = 0 ] || { echo_i "failed"; status=1; }
1249
1250n=$((n + 1))
1251ret=0
1252echo_i "check that CDS to DNSSEC multisigner zone is allowed ($n)"
1253$DIG $DIGOPTS +tcp +norec multisigner.test CDS @10.53.0.3 > dig.out.pre.test$n || ret=1
1254grep "status: NOERROR" dig.out.pre.test$n > /dev/null || ret=1
1255grep "ANSWER: 0," dig.out.pre.test$n > /dev/null || ret=1
1256$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 || ret=1
1257server 10.53.0.3 ${PORT}
1258zone multisigner.test
1259update add multisigner.test 3600 IN CDS 14364 13 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
1260send
1261END
1262retry_quiet 5 has_positive_response multisigner.test CDS 10.53.0.3 || ret=1
1263[ $ret = 0 ] || { echo_i "failed"; status=1; }
1264
1265n=$((n + 1))
1266ret=0
1267echo_i "check that CDNSKEY to DNSSEC multisigner zone is allowed ($n)"
1268$DIG $DIGOPTS +tcp +norec multisigner.test CDNSKEY @10.53.0.3 > dig.out.pre.test$n || ret=1
1269grep "status: NOERROR" dig.out.pre.test$n > /dev/null || ret=1
1270grep "ANSWER: 0," dig.out.pre.test$n > /dev/null || ret=1
1271$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 || ret=1
1272server 10.53.0.3 ${PORT}
1273zone multisigner.test
1274update add multisigner.test 3600 IN CDNSKEY 257 3 13 d0NQ5PKmDz6P0B1WPMH9/UKRux/toSFwV2nTJYPA1Cx8pB0sJGTXbVhG U+6gye7VCHDhGIn9CjVfb2RJPW7GnQ==
1275send
1276END
1277retry_quiet 5 has_positive_response multisigner.test CDNSKEY 10.53.0.3 || ret=1
1278[ $ret = 0 ] || { echo_i "failed"; status=1; }
1279
1280n=$((n + 1))
1281ret=0
1282echo_i "check that excessive NSEC3PARAM iterations are rejected by nsupdate ($n)"
1283$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 && ret=1
1284server 10.53.0.3 ${PORT}
1285zone example
1286update add example 0 in NSEC3PARAM 1 0 151 -
1287END
1288grep "NSEC3PARAM has excessive iterations (> 150)" nsupdate.out-$n >/dev/null || ret=1
1289[ $ret = 0 ] || { echo_i "failed"; status=1; }
1290
1291n=$((n + 1))
1292ret=0
1293echo_i "check that update is rejected if query is not allowed ($n)"
1294{
1295  $NSUPDATE -d <<END
1296  local 10.53.0.2
1297  server 10.53.0.1 ${PORT}
1298  update add reject.other.nil 3600 IN TXT Whatever
1299  send
1300END
1301} > nsupdate.out.test$n 2>&1
1302grep 'failed: REFUSED' nsupdate.out.test$n > /dev/null || ret=1
1303[ $ret = 0 ] || { echo_i "failed"; status=1; }
1304
1305n=$((n + 1))
1306ret=0
1307echo_i "check that update is rejected if quota is exceeded ($n)"
1308for loop in 1 2 3 4 5 6 7 8 9 10; do
1309{
1310  $NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > /dev/null 2>&1 <<END
1311  update add txt-$loop.other.nil 3600 IN TXT Whatever
1312  send
1313END
1314} &
1315done
1316wait_for_log 10 "too many DNS UPDATEs queued" ns1/named.run || ret=1
1317[ $ret = 0 ] || { echo_i "failed"; status=1; }
1318
1319if ! $FEATURETEST --gssapi ; then
1320  echo_i "SKIPPED: GSSAPI tests"
1321else
1322  n=$((n + 1))
1323  ret=0
1324  echo_i "check krb5-self match ($n)"
1325  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
1326  export KRB5CCNAME
1327  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 || ret=1
1328  gsstsig
1329  realm EXAMPLE.COM
1330  server 10.53.0.7 ${PORT}
1331  zone example.com
1332  update add machine.example.com 3600 IN A 10.53.0.7
1333  send
1334EOF
1335  $DIG $DIGOPTS +tcp @10.53.0.7 machine.example.com A > dig.out.ns7.test$n
1336  grep "status: NOERROR" dig.out.ns7.test$n > /dev/null || ret=1
1337  grep "machine.example.com..*A.*10.53.0.7" dig.out.ns7.test$n > /dev/null || ret=1
1338  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1339
1340  n=$((n + 1))
1341  ret=0
1342  echo_i "check krb5-self no-match ($n)"
1343  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
1344  export KRB5CCNAME
1345  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
1346  gsstsig
1347  realm EXAMPLE.COM
1348  server 10.53.0.7 ${PORT}
1349  zone example.com
1350  update add foo.example.com 3600 IN A 10.53.0.7
1351  send
1352EOF
1353  grep "update failed: REFUSED" nsupdate.out-$n > /dev/null || ret=1
1354  $DIG $DIGOPTS +tcp @10.53.0.7 foo.example.com A > dig.out.ns7.test$n
1355  grep "status: NXDOMAIN" dig.out.ns7.test$n > /dev/null || ret=1
1356  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1357
1358  n=$((n + 1))
1359  ret=0
1360  echo_i "check krb5-subdomain match ($n)"
1361  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
1362  export KRB5CCNAME
1363  $NSUPDATE -d << EOF > nsupdate.out-$n 2>&1 || ret=1
1364  gsstsig
1365  realm EXAMPLE.COM
1366  server 10.53.0.7 ${PORT}
1367  zone example.com
1368  update add _xxx._tcp.example.com 3600 IN SRV 0 0 0 machine.example.com
1369  send
1370EOF
1371  $DIG $DIGOPTS +tcp @10.53.0.7 _xxx._tcp.example.com SRV > dig.out.ns7.test$n
1372  grep "status: NOERROR" dig.out.ns7.test$n > /dev/null || ret=1
1373  grep "_xxx._tcp.example.com.*SRV.*0 0 0 machine.example.com" dig.out.ns7.test$n > /dev/null || ret=1
1374  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1375
1376  n=$((n + 1))
1377  ret=0
1378  echo_i "check krb5-subdomain no-match ($n)"
1379  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
1380  export KRB5CCNAME
1381  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
1382  gsstsig
1383  realm EXAMPLE.COM
1384  server 10.53.0.7 ${PORT}
1385  zone example.com
1386  update add _xxx._udp.example.com 3600 IN SRV 0 0 0 machine.example.com
1387  send
1388EOF
1389  grep "update failed: REFUSED" nsupdate.out-$n > /dev/null || ret=1
1390  $DIG $DIGOPTS +tcp @10.53.0.7 _xxx._udp.example.com SRV > dig.out.ns7.test$n
1391  grep "status: NXDOMAIN" dig.out.ns7.test$n > /dev/null || ret=1
1392  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1393
1394  n=$((n+1))
1395  ret=0
1396  echo_i "check krb5-selfsub match ($n)"
1397  KRB5CCNAME="FILE:$(pwd)/ns8/machine.ccache"
1398  export KRB5CCNAME
1399  $NSUPDATE -d << EOF > nsupdate.out-$n 2>&1 || ret=1
1400  gsstsig
1401  realm EXAMPLE.COM
1402  server 10.53.0.8 ${PORT}
1403  zone example.com
1404  update add xxx.machine.example.com 3600 IN A 10.53.0.8
1405  send
1406EOF
1407  $DIG $DIGOPTS +tcp @10.53.0.8 xxx.machine.example.com A > dig.out.ns8.test$n
1408  grep "status: NOERROR" dig.out.ns8.test$n > /dev/null || ret=1
1409  grep "xxx.machine.example.com..*A.*10.53.0.8" dig.out.ns8.test$n > /dev/null || ret=1
1410  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1411
1412  n=$((n + 1))
1413  ret=0
1414  echo_i "check krb5-selfsub no-match ($n)"
1415  KRB5CCNAME="FILE:$(pwd)/ns8/machine.ccache"
1416  export KRB5CCNAME
1417  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
1418  gsstsig
1419  realm EXAMPLE.COM
1420  server 10.53.0.8 ${PORT}
1421  zone example.com
1422  update add foo.example.com 3600 IN A 10.53.0.8
1423  send
1424EOF
1425  grep "update failed: REFUSED" nsupdate.out-$n > /dev/null || ret=1
1426  $DIG $DIGOPTS +tcp @10.53.0.8 foo.example.com A > dig.out.ns8.test$n
1427  grep "status: NXDOMAIN" dig.out.ns8.test$n > /dev/null || ret=1
1428  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1429
1430  n=$((n + 1))
1431  ret=0
1432
1433  echo_i "check ms-self match ($n)"
1434  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
1435  export KRB5CCNAME
1436  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 || ret=1
1437  gsstsig
1438  realm EXAMPLE.COM
1439  server 10.53.0.9 ${PORT}
1440  zone example.com
1441  update add machine.example.com 3600 IN A 10.53.0.9
1442  send
1443EOF
1444  $DIG $DIGOPTS +tcp @10.53.0.9 machine.example.com A > dig.out.ns9.test$n
1445  grep "status: NOERROR" dig.out.ns9.test$n > /dev/null || ret=1
1446  grep "machine.example.com..*A.*10.53.0.9" dig.out.ns9.test$n > /dev/null || ret=1
1447  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1448
1449  n=$((n + 1))
1450  ret=0
1451  echo_i "check ms-self no-match ($n)"
1452  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
1453  export KRB5CCNAME
1454  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
1455  gsstsig
1456  realm EXAMPLE.COM
1457  server 10.53.0.9 ${PORT}
1458  zone example.com
1459  update add foo.example.com 3600 IN A 10.53.0.9
1460  send
1461EOF
1462  grep "update failed: REFUSED" nsupdate.out-$n > /dev/null || ret=1
1463  $DIG $DIGOPTS +tcp @10.53.0.9 foo.example.com A > dig.out.ns9.test$n
1464  grep "status: NXDOMAIN" dig.out.ns9.test$n > /dev/null || ret=1
1465  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1466
1467  n=$((n + 1))
1468  ret=0
1469  echo_i "check ms-subdomain match ($n)"
1470  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
1471  export KRB5CCNAME
1472  $NSUPDATE -d << EOF > nsupdate.out-$n 2>&1 || ret=1
1473  gsstsig
1474  realm EXAMPLE.COM
1475  server 10.53.0.9 ${PORT}
1476  zone example.com
1477  update add _xxx._tcp.example.com 3600 IN SRV 0 0 0 machine.example.com
1478  send
1479EOF
1480  $DIG $DIGOPTS +tcp @10.53.0.9 _xxx._tcp.example.com SRV > dig.out.ns9.test$n
1481  grep "status: NOERROR" dig.out.ns9.test$n > /dev/null || ret=1
1482  grep "_xxx._tcp.example.com.*SRV.*0 0 0 machine.example.com" dig.out.ns9.test$n > /dev/null || ret=1
1483  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1484
1485  n=$((n + 1))
1486  ret=0
1487  echo_i "check ms-subdomain no-match ($n)"
1488  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
1489  export KRB5CCNAME
1490  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
1491  gsstsig
1492  realm EXAMPLE.COM
1493  server 10.53.0.9 ${PORT}
1494  zone example.com
1495  update add _xxx._udp.example.com 3600 IN SRV 0 0 0 machine.example.com
1496  send
1497EOF
1498  grep "update failed: REFUSED" nsupdate.out-$n > /dev/null || ret=1
1499  $DIG $DIGOPTS +tcp @10.53.0.9 _xxx._udp.example.com SRV > dig.out.ns9.test$n
1500  grep "status: NXDOMAIN" dig.out.ns9.test$n > /dev/null || ret=1
1501  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1502
1503  n=$((n+1))
1504  ret=0
1505  echo_i "check ms-selfsub match ($n)"
1506  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
1507  export KRB5CCNAME
1508  $NSUPDATE -d << EOF > nsupdate.out-$n 2>&1 || ret=1
1509  gsstsig
1510  realm EXAMPLE.COM
1511  server 10.53.0.10 ${PORT}
1512  zone example.com
1513  update add xxx.machine.example.com 3600 IN A 10.53.0.10
1514  send
1515EOF
1516  $DIG $DIGOPTS +tcp @10.53.0.10 xxx.machine.example.com A > dig.out.ns10.test$n
1517  grep "status: NOERROR" dig.out.ns10.test$n > /dev/null || ret=1
1518  grep "xxx.machine.example.com..*A.*10.53.0.10" dig.out.ns10.test$n > /dev/null || ret=1
1519  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1520
1521  n=$((n + 1))
1522  ret=0
1523  echo_i "check ms-selfsub no-match ($n)"
1524  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
1525  export KRB5CCNAME
1526  $NSUPDATE << EOF > nsupdate.out-$n 2>&1 && ret=1
1527  gsstsig
1528  realm EXAMPLE.COM
1529  server 10.53.0.10 ${PORT}
1530  zone example.com
1531  update add foo.example.com 3600 IN A 10.53.0.10
1532  send
1533EOF
1534  grep "update failed: REFUSED" nsupdate.out-$n > /dev/null || ret=1
1535  $DIG $DIGOPTS +tcp @10.53.0.10 foo.example.com A > dig.out.ns10.test$n
1536  grep "status: NXDOMAIN" dig.out.ns10.test$n > /dev/null || ret=1
1537  [ $ret = 0 ] || { echo_i "failed"; status=1; }
1538
1539fi
1540
1541echo_i "exit status: $status"
1542[ $status -eq 0 ] || exit 1
1543