xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/nsupdate/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="-p ${PORT}"
19RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s"
20
21#
22# Uncomment when creating credential cache files.
23#
24# KRB5_CONFIG="$(pwd)/krb/krb5.conf"
25#
26# Cd krb and run krb/setup.sh to create new keys.
27# Run nsupdate system test.
28# Kill the krb5kdc server started by krb/setup.sh.
29# Check the expiry date on the cached machine.ccache with klist is in 2038.
30# Comment out KRB5_CONFIG.
31# Re-run nsupdate system test to confirm everything still works.
32# git add and commit the resulting ns*/machine.ccache and ns*/dns.keytab files.
33# Clean up krb.
34#
35
36status=0
37n=0
38
39nextpartreset ns3/named.run
40
41# wait for zone transfer to complete
42tries=0
43while true; do
44  if [ $tries -eq 10 ]; then
45    exit 1
46  fi
47
48  if grep "example.nil/IN.*Transfer status" ns2/named.run >/dev/null; then
49    break
50  else
51    echo_i "zones are not fully loaded, waiting..."
52    tries=$((tries + 1))
53    sleep 1
54  fi
55done
56
57has_positive_response() {
58  zone=$1
59  type=$2
60  ns=$3
61  $DIG $DIGOPTS +tcp +norec $zone $type @$ns >dig.out.post.test$n || return 1
62  grep "status: NOERROR" dig.out.post.test$n >/dev/null || return 1
63  grep "ANSWER: 0," dig.out.post.test$n >/dev/null && return 1
64  return 0
65}
66
67ret=0
68echo_i "fetching first copy of zone before update"
69$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.1 axfr >dig.out.ns1 || ret=1
70[ $ret = 0 ] || {
71  echo_i "failed"
72  status=1
73}
74
75ret=0
76echo_i "fetching second copy of zone before update"
77$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.2 axfr >dig.out.ns2 || ret=1
78[ $ret = 0 ] || {
79  echo_i "failed"
80  status=1
81}
82
83ret=0
84echo_i "comparing pre-update copies to known good data"
85digcomp knowngood.ns1.before dig.out.ns1 || ret=1
86digcomp knowngood.ns1.before dig.out.ns2 || ret=1
87[ $ret = 0 ] || {
88  echo_i "failed"
89  status=1
90}
91
92ret=0
93echo_i "ensure an unrelated zone is mentioned in its NOTAUTH log"
94$NSUPDATE -k ns1/ddns.key >nsupdate.out 2>&1 <<END && ret=1
95server 10.53.0.1 ${PORT}
96zone unconfigured.test
97update add unconfigured.test 600 IN A 10.53.0.1
98send
99END
100grep NOTAUTH nsupdate.out >/dev/null 2>&1 || ret=1
101grep ' unconfigured.test: not authoritative' ns1/named.run \
102  >/dev/null 2>&1 || ret=1
103[ $ret = 0 ] || {
104  echo_i "failed"
105  status=1
106}
107
108ret=0
109echo_i "ensure a subdomain is mentioned in its NOTAUTH log"
110$NSUPDATE -k ns1/ddns.key >nsupdate.out 2>&1 <<END && ret=1
111server 10.53.0.1 ${PORT}
112zone sub.sub.example.nil
113update add sub.sub.sub.example.nil 600 IN A 10.53.0.1
114send
115END
116grep NOTAUTH nsupdate.out >/dev/null 2>&1 || ret=1
117grep ' sub.sub.example.nil: not authoritative' ns1/named.run \
118  >/dev/null 2>&1 || ret=1
119[ $ret = 0 ] || {
120  echo_i "failed"
121  status=1
122}
123
124ret=0
125echo_i "updating zone"
126# nsupdate will print a ">" prompt to stdout as it gets each input line.
127$NSUPDATE -k ns1/ddns.key <<END >/dev/null || ret=1
128server 10.53.0.1 ${PORT}
129update add updated.example.nil. 600 A 10.10.10.1
130add updated.example.nil. 600 TXT Foo
131delete t.example.nil.
132
133END
134[ $ret = 0 ] || {
135  echo_i "failed"
136  status=1
137}
138
139echo_i "sleeping 5 seconds for server to incorporate changes"
140sleep 5
141
142ret=0
143echo_i "fetching first copy of zone after update"
144$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.1 axfr >dig.out.ns1 || ret=1
145[ $ret = 0 ] || {
146  echo_i "failed"
147  status=1
148}
149
150ret=0
151echo_i "fetching second copy of zone after update"
152$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.2 axfr >dig.out.ns2 || ret=1
153[ $ret = 0 ] || {
154  echo_i "failed"
155  status=1
156}
157
158ret=0
159echo_i "comparing post-update copies to known good data"
160digcomp knowngood.ns1.after dig.out.ns1 || ret=1
161digcomp knowngood.ns1.after dig.out.ns2 || ret=1
162[ $ret = 0 ] || {
163  echo_i "failed"
164  status=1
165}
166
167ret=0
168echo_i "testing local update policy"
169pre=$($DIG $DIGOPTS +short new.other.nil. @10.53.0.1 a) || ret=1
170[ -z "$pre" ] || ret=1
171[ $ret = 0 ] || {
172  echo_i "failed"
173  status=1
174}
175
176ret=0
177echo_i "updating zone"
178# nsupdate will print a ">" prompt to stdout as it gets each input line.
179$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >/dev/null <<END || ret=1
180zone other.nil.
181update add new.other.nil. 600 IN A 10.10.10.1
182send
183END
184[ $ret = 0 ] || {
185  echo_i "failed"
186  status=1
187}
188
189echo_i "sleeping 5 seconds for server to incorporate changes"
190sleep 5
191
192ret=0
193echo_i "checking result of update"
194post=$($DIG $DIGOPTS +short new.other.nil. @10.53.0.1 a) || ret=1
195[ "$post" = "10.10.10.1" ] || ret=1
196[ $ret = 0 ] || {
197  echo_i "failed"
198  status=1
199}
200
201ret=0
202echo_i "comparing post-update copy to known good data"
203digcomp knowngood.ns1.after dig.out.ns1 || ret=1
204[ $ret = 0 ] || {
205  echo_i "failed"
206  status=1
207}
208
209ret=0
210echo_i "testing zone consistency checks"
211# inserting an NS record without a corresponding A or AAAA record should fail
212$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >nsupdate.out 2>&1 <<END && ret=1
213update add other.nil. 600 in ns ns3.other.nil.
214send
215END
216grep REFUSED nsupdate.out >/dev/null 2>&1 || ret=1
217# ...but should work if an A record is inserted first:
218$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >nsupdate.out 2>&1 <<END || ret=1
219update add ns4.other.nil 600 in a 10.53.0.1
220send
221update add other.nil. 600 in ns ns4.other.nil.
222send
223END
224grep REFUSED nsupdate.out >/dev/null 2>&1 && ret=1
225# ...or if an AAAA record does:
226$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >nsupdate.out 2>&1 <<END || ret=1
227update add ns5.other.nil 600 in aaaa 2001:db8::1
228send
229update add other.nil. 600 in ns ns5.other.nil.
230send
231END
232grep REFUSED nsupdate.out >/dev/null 2>&1 && ret=1
233# ...or if the NS and A/AAAA are inserted together:
234$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >nsupdate.out 2>&1 <<END || ret=1
235update add other.nil. 600 in ns ns6.other.nil.
236update add ns6.other.nil 600 in a 10.53.0.1
237send
238END
239grep REFUSED nsupdate.out >/dev/null 2>&1 && ret=1
240[ $ret = 0 ] || {
241  echo_i "failed"
242  status=1
243}
244
245echo_i "sleeping 5 seconds for server to incorporate changes"
246sleep 5
247
248ret=0
249echo_i "checking result of update"
250$DIG $DIGOPTS +short @10.53.0.1 ns other.nil >dig.out.ns1 || ret=1
251grep ns3.other.nil dig.out.ns1 >/dev/null 2>&1 && ret=1
252grep ns4.other.nil dig.out.ns1 >/dev/null 2>&1 || ret=1
253grep ns5.other.nil dig.out.ns1 >/dev/null 2>&1 || ret=1
254grep ns6.other.nil dig.out.ns1 >/dev/null 2>&1 || ret=1
255[ $ret = 0 ] || {
256  echo_i "failed"
257  status=1
258}
259
260ret=0
261echo_i "ensure 'check-mx ignore' allows adding MX records containing an address without a warning"
262$NSUPDATE -k ns1/ddns.key >nsupdate.out 2>&1 <<END || ret=1
263server 10.53.0.1 ${PORT}
264update add mx03.example.nil 600 IN MX 10 10.53.0.1
265send
266END
267grep REFUSED nsupdate.out >/dev/null 2>&1 && ret=1
268grep "mx03.example.nil/MX:.*MX is an address" ns1/named.run >/dev/null 2>&1 && ret=1
269[ $ret = 0 ] || {
270  echo_i "failed"
271  status=1
272}
273
274ret=0
275echo_i "ensure 'check-mx warn' allows adding MX records containing an address with a warning"
276$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >nsupdate.out 2>&1 <<END || ret=1
277update add mx03.other.nil 600 IN MX 10 10.53.0.1
278send
279END
280grep REFUSED nsupdate.out >/dev/null 2>&1 && ret=1
281grep "mx03.other.nil/MX:.*MX is an address" ns1/named.run >/dev/null 2>&1 || ret=1
282[ $ret = 0 ] || {
283  echo_i "failed"
284  status=1
285}
286
287ret=0
288echo_i "ensure 'check-mx fail' prevents adding MX records containing an address with a warning"
289$NSUPDATE >nsupdate.out 2>&1 <<END && ret=1
290server 10.53.0.1 ${PORT}
291update add mx03.update.nil 600 IN MX 10 10.53.0.1
292send
293END
294grep REFUSED nsupdate.out >/dev/null 2>&1 || ret=1
295grep "mx03.update.nil/MX:.*MX is an address" ns1/named.run >/dev/null 2>&1 || ret=1
296[ $ret = 0 ] || {
297  echo_i "failed"
298  status=1
299}
300
301ret=0
302echo_i "check SIG(0) key is accepted"
303key=$($KEYGEN -q -a ${DEFAULT_ALGORITHM} -T KEY -n ENTITY xxx)
304echo "" | $NSUPDATE -k ${key}.private >/dev/null 2>&1 || ret=1
305[ $ret = 0 ] || {
306  echo_i "failed"
307  status=1
308}
309
310n=$((n + 1))
311ret=0
312echo_i "check TYPE=0 update is rejected by nsupdate ($n)"
313$NSUPDATE <<END >nsupdate.out 2>&1 && ret=1
314    server 10.53.0.1 ${PORT}
315    ttl 300
316    update add example.nil. in type0 ""
317    send
318END
319grep "unknown class/type" nsupdate.out >/dev/null 2>&1 || ret=1
320[ $ret = 0 ] || {
321  echo_i "failed"
322  status=1
323}
324
325n=$((n + 1))
326ret=0
327echo_i "check TYPE=0 prerequisite is handled ($n)"
328$NSUPDATE -k ns1/ddns.key <<END >nsupdate.out 2>&1 || ret=1
329    server 10.53.0.1 ${PORT}
330    prereq nxrrset example.nil. type0
331    send
332END
333$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1
334grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1
335[ $ret = 0 ] || {
336  echo_i "failed"
337  status=1
338}
339
340n=$((n + 1))
341ret=0
342echo_i "check that TYPE=0 update is handled ($n)"
343echo "a0e4280000010000000100000000060001c00c000000fe000000000000" \
344  | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp >/dev/null || ret=1
345$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1
346grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1
347[ $ret = 0 ] || {
348  echo_i "failed"
349  status=1
350}
351
352n=$((n + 1))
353ret=0
354echo_i "check that TYPE=0 additional data is handled ($n)"
355echo "a0e4280000010000000000010000060001c00c000000fe000000000000" \
356  | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp >/dev/null || ret=1
357$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1
358grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1
359[ $ret = 0 ] || {
360  echo_i "failed"
361  status=1
362}
363
364n=$((n + 1))
365ret=0
366echo_i "check that update to undefined class is handled ($n)"
367echo "a0e4280000010001000000000000060101c00c000000fe000000000000" \
368  | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp >/dev/null || ret=1
369$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1
370grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1
371[ $ret = 0 ] || {
372  echo_i "failed"
373  status=1
374}
375
376n=$((n + 1))
377ret=0
378echo_i "check that address family mismatch is handled ($n)"
379$NSUPDATE <<END >/dev/null 2>&1 && ret=1
380server ::1
381local 127.0.0.1
382update add 600 txt.example.nil in txt "test"
383send
384END
385[ $ret = 0 ] || {
386  echo_i "failed"
387  status=1
388}
389
390n=$((n + 1))
391ret=0
392echo_i "check that unixtime serial number is correctly generated ($n)"
393$DIG $DIGOPTS +short unixtime.nil. soa @10.53.0.1 >dig.out.old.test$n || ret=1
394oldserial=$(awk '{print $3}' dig.out.old.test$n) || ret=1
395start=$($PERL -e 'print time()."\n";')
396$NSUPDATE <<END >/dev/null 2>&1 || ret=1
397    server 10.53.0.1 ${PORT}
398    ttl 600
399    update add new.unixtime.nil in a 1.2.3.4
400    send
401END
402now=$($PERL -e 'print time()."\n";')
403sleep 1
404$DIG $DIGOPTS +short unixtime.nil. soa @10.53.0.1 >dig.out.new.test$n || ret=1
405serial=$(awk '{print $3}' dig.out.new.test$n) || ret=1
406[ "$oldserial" = "$serial" ] && {
407  echo_i "oldserial == serial"
408  ret=1
409}
410if [ "$serial" -lt "$start" ]; then
411  echo_i "out-of-range serial=$serial < start=$start"
412  ret=1
413elif [ "$serial" -gt "$now" ]; then
414  echo_i "out-of-range serial=$serial > now=$now"
415  ret=1
416fi
417[ $ret = 0 ] || {
418  echo_i "failed"
419  status=1
420}
421
422if $PERL -e 'use Net::DNS;' 2>/dev/null; then
423  n=$((n + 1))
424  ret=0
425  echo_i "running update.pl test ($n)"
426  $PERL update_test.pl -s 10.53.0.1 -p ${PORT} update.nil. >perl.update_test.out || ret=1
427  [ $ret -eq 1 ] && {
428    echo_i "failed"
429    status=1
430  }
431
432  if $PERL -e 'use Net::DNS; die "Net::DNS too old ($Net::DNS::VERSION < 1.01)" if ($Net::DNS::VERSION < 1.01)' >/dev/null; then
433    n=$((n + 1))
434    ret=0
435    echo_i "check for too many NSEC3 iterations log ($n)"
436    grep "updating zone 'update.nil/IN': too many NSEC3 iterations (51)" ns1/named.run >/dev/null || ret=1
437    [ $ret -eq 1 ] && {
438      echo_i "failed"
439      status=1
440    }
441  fi
442else
443  echo_i "The second part of this test requires the Net::DNS library." >&2
444fi
445
446n=$((n + 1))
447ret=0
448echo_i "fetching first copy of test zone ($n)"
449$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.1 axfr >dig.out.ns1 || ret=1
450[ $ret = 0 ] || {
451  echo_i "failed"
452  status=1
453}
454
455n=$((n + 1))
456ret=0
457echo_i "fetching second copy of test zone ($n)"
458$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.2 axfr >dig.out.ns2 || ret=1
459[ $ret = 0 ] || {
460  echo_i "failed"
461  status=1
462}
463
464n=$((n + 1))
465ret=0
466echo_i "comparing zones ($n)"
467digcomp dig.out.ns1 dig.out.ns2 || ret=1
468[ $ret = 0 ] || {
469  echo_i "failed"
470  status=1
471}
472
473echo_i "SIGKILL and restart server ns1"
474cd ns1
475kill -KILL $(cat named.pid)
476rm named.pid
477cd ..
478sleep 10
479if
480  start_server --noclean --restart --port ${PORT} ns1
481then
482  echo_i "restarted server ns1"
483else
484  echo_i "could not restart server ns1"
485  exit 1
486fi
487sleep 10
488
489n=$((n + 1))
490ret=0
491echo_i "fetching ns1 after hard restart ($n)"
492$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil. @10.53.0.1 axfr >dig.out.ns1.after || ret=1
493[ $ret = 0 ] || {
494  echo_i "failed"
495  status=1
496}
497
498n=$((n + 1))
499ret=0
500echo_i "comparing zones ($n)"
501digcomp dig.out.ns1 dig.out.ns1.after || ret=1
502[ $ret = 0 ] || {
503  echo_i "failed"
504  status=1
505}
506
507echo_i "begin RT #482 regression test"
508
509n=$((n + 1))
510ret=0
511echo_i "update primary ($n)"
512$NSUPDATE -k ns1/ddns.key <<END >/dev/null || ret=1
513server 10.53.0.1 ${PORT}
514update add updated2.example.nil. 600 A 10.10.10.2
515update add updated2.example.nil. 600 TXT Bar
516update delete c.example.nil.
517send
518END
519[ $ret = 0 ] || {
520  echo_i "failed"
521  status=1
522}
523
524sleep 5
525
526echo_i "SIGHUP secondary"
527kill -HUP $(cat ns2/named.pid)
528
529sleep 5
530
531n=$((n + 1))
532ret=0
533echo_i "update primary again ($n)"
534$NSUPDATE -k ns1/ddns.key <<END >/dev/null || ret=1
535server 10.53.0.1 ${PORT}
536update add updated3.example.nil. 600 A 10.10.10.3
537update add updated3.example.nil. 600 TXT Zap
538del d.example.nil.
539send
540END
541[ $ret = 0 ] || {
542  echo_i "failed"
543  status=1
544}
545
546sleep 5
547
548echo_i "SIGHUP secondary again"
549kill -HUP $(cat ns2/named.pid)
550
551sleep 5
552
553n=$((n + 1))
554echo_i "check to 'out of sync' message ($n)"
555if grep "out of sync" ns2/named.run >/dev/null; then
556  echo_i "failed (found 'out of sync')"
557  status=1
558fi
559
560echo_i "end RT #482 regression test"
561
562n=$((n + 1))
563ret=0
564echo_i "remove nonexistent PTR record ($n)"
565$NSUPDATE -k ns1/ddns.key -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
566server 10.53.0.1 ${PORT}
567zone example.nil.
568update delete nonexistent.example.nil. 0 IN PTR foo.
569send
570EOF
571[ $ret = 0 ] || {
572  echo_i "failed"
573  status=1
574}
575
576n=$((n + 1))
577ret=0
578echo_i "remove nonexistent SRV record ($n)"
579$NSUPDATE -k ns1/ddns.key -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
580server 10.53.0.1 ${PORT}
581zone example.nil.
582update delete nonexistent.example.nil. 0 IN SRV 0 0 0 foo.
583send
584EOF
585[ $ret = 0 ] || {
586  echo_i "failed"
587  status=1
588}
589
590n=$((n + 1))
591ret=0
592echo_i "start NSEC3PARAM changes via UPDATE on a unsigned zone test ($n)"
593$NSUPDATE <<EOF
594server 10.53.0.3 ${PORT}
595update add example 3600 nsec3param 1 0 0 -
596send
597EOF
598
599# the zone is not signed.  The nsec3param records should be removed.
600# this also proves that the server is still running.
601$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec example. @10.53.0.3 nsec3param >dig.out.ns3.$n || ret=1
602grep "ANSWER: 0," dig.out.ns3.$n >/dev/null || ret=1
603grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n >/dev/null || ret=1
604[ $ret = 0 ] || {
605  echo_i "failed"
606  status=1
607}
608
609n=$((n + 1))
610ret=0
611echo_i "change the NSEC3PARAM ttl via update ($n)"
612$NSUPDATE <<EOF
613server 10.53.0.3 ${PORT}
614update add nsec3param.test 3600 NSEC3PARAM 1 0 1 -
615send
616EOF
617
618$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec nsec3param.test. @10.53.0.3 nsec3param >dig.out.ns3.$n || ret=1
619grep "ANSWER: 1," dig.out.ns3.$n >/dev/null || ret=1
620grep "3600.*NSEC3PARAM" dig.out.ns3.$n >/dev/null || ret=1
621grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n >/dev/null || ret=1
622[ $ret = 0 ] || {
623  echo_i "failed"
624  status=1
625}
626
627ret=0
628echo_i "testing that rndc stop updates the file"
629$NSUPDATE -k ns1/ddns.key <<END >/dev/null || ret=1
630server 10.53.0.1 ${PORT}
631update add updated4.example.nil. 600 A 10.10.10.3
632send
633END
634sleep 3
635stop_server --use-rndc --port ${CONTROLPORT} ns1
636sleep 3
637# Removing the journal file and restarting the server means
638# that the data served by the new server process are exactly
639# those dumped to the file by "rndc stop".
640rm -f ns1/*jnl
641start_server --noclean --restart --port ${PORT} ns1
642for try in 0 1 2 3 4 5 6 7 8 9; do
643  iret=0
644  $DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
645    updated4.example.nil. @10.53.0.1 a >dig.out.ns1 || iret=1
646  digcomp knowngood.ns1.afterstop dig.out.ns1 || iret=1
647  [ "$iret" -eq 0 ] && break
648  sleep 1
649done
650[ "$iret" -ne 0 ] && ret=1
651[ "$ret" -eq 0 ] || {
652  echo_i "failed"
653  status=1
654}
655
656ret=0
657echo_i "check that 'nsupdate -l' with a missing keyfile reports the missing file"
658$NSUPDATE -4 -p ${PORT} -l -k ns1/nonexistent.key 2>nsupdate.out </dev/null && ret=1
659grep ns1/nonexistent.key nsupdate.out >/dev/null || ret=1
660if test $ret -ne 0; then
661  echo_i "failed"
662  status=1
663fi
664
665n=$((n + 1))
666ret=0
667echo_i "check that 'update-policy local' works from localhost address ($n)"
668$NSUPDATE -k ns5/session.key >nsupdate.out.$n 2>&1 <<END || ret=1
669server 10.53.0.5 ${PORT}
670local 127.0.0.1
671update add fromlocal.local.nil. 600 A 1.2.3.4
672send
673END
674grep REFUSED nsupdate.out.$n >/dev/null 2>&1 && ret=1
675$DIG $DIGOPTS @10.53.0.5 \
676  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
677  fromlocal.local.nil. >dig.out.ns5.$n || ret=1
678grep fromlocal dig.out.ns5.$n >/dev/null 2>&1 || ret=1
679if test $ret -ne 0; then
680  echo_i "failed"
681  status=1
682fi
683
684n=$((n + 1))
685ret=0
686echo_i "check that 'update-policy local' fails from non-localhost address ($n)"
687grep 'match on session key not from localhost' ns5/named.run >/dev/null && ret=1
688$NSUPDATE -k ns5/session.key >nsupdate.out.$n 2>&1 <<END && ret=1
689server 10.53.0.5 ${PORT}
690local 10.53.0.1
691update add nonlocal.local.nil. 600 A 4.3.2.1
692send
693END
694grep REFUSED nsupdate.out.$n >/dev/null 2>&1 || ret=1
695grep 'match on session key not from localhost' ns5/named.run >/dev/null || ret=1
696$DIG $DIGOPTS @10.53.0.5 \
697  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
698  nonlocal.local.nil. >dig.out.ns5.$n || ret=1
699grep nonlocal dig.out.ns5.$n >/dev/null 2>&1 && ret=1
700if test $ret -ne 0; then
701  echo_i "failed"
702  status=1
703fi
704
705n=$((n + 1))
706ret=0
707echo_i "check that 'update-policy tcp-self' refuses update of records via UDP ($n)"
708$NSUPDATE >nsupdate.out.$n 2>&1 <<END && ret=1
709server 10.53.0.6 ${PORT}
710local 127.0.0.1
711update add 1.0.0.127.in-addr.arpa. 600 PTR localhost.
712send
713END
714grep REFUSED nsupdate.out.$n >/dev/null 2>&1 || ret=1
715$DIG $DIGOPTS @10.53.0.6 \
716  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
717  -x 127.0.0.1 >dig.out.ns6.$n
718grep localhost. dig.out.ns6.$n >/dev/null 2>&1 && ret=1
719if test $ret -ne 0; then
720  echo_i "failed"
721  status=1
722fi
723
724n=$((n + 1))
725ret=0
726echo_i "check that 'update-policy tcp-self' permits update of records for the client's own address via TCP ($n)"
727$NSUPDATE -v >nsupdate.out.$n 2>&1 <<END || ret=1
728server 10.53.0.6 ${PORT}
729local 127.0.0.1
730update add 1.0.0.127.in-addr.arpa. 600 PTR localhost.
731send
732END
733grep REFUSED nsupdate.out.$n >/dev/null 2>&1 && ret=1
734$DIG $DIGOPTS @10.53.0.6 \
735  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
736  -x 127.0.0.1 >dig.out.ns6.$n || ret=1
737grep localhost. dig.out.ns6.$n >/dev/null 2>&1 || ret=1
738if test $ret -ne 0; then
739  echo_i "failed"
740  status=1
741fi
742
743n=$((n + 1))
744ret=0
745echo_i "check that 'update-policy tcp-self' refuses update of records for a different address from the client's own address via TCP ($n)"
746$NSUPDATE -v >nsupdate.out.$n 2>&1 <<END && ret=1
747server 10.53.0.6 ${PORT}
748local 127.0.0.1
749update add 1.0.168.192.in-addr.arpa. 600 PTR localhost.
750send
751END
752grep REFUSED nsupdate.out.$n >/dev/null 2>&1 || ret=1
753$DIG $DIGOPTS @10.53.0.6 \
754  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
755  -x 192.168.0.1 >dig.out.ns6.$n
756grep localhost. dig.out.ns6.$n >/dev/null 2>&1 && ret=1
757if test $ret -ne 0; then
758  echo_i "failed"
759  status=1
760fi
761
762n=$((n + 1))
763ret=0
764echo_i "check that 'update-policy 6to4-self' refuses update of records via UDP over IPv4 ($n)"
765REVERSE_NAME=6.0.0.0.5.3.a.0.2.0.0.2.ip6.arpa
766$NSUPDATE >nsupdate.out.$n 2>&1 <<END && ret=1
767server 10.53.0.6 ${PORT}
768local 10.53.0.6
769zone 2.0.0.2.ip6.arpa
770update add ${REVERSE_NAME} 600 NS localhost.
771send
772END
773grep REFUSED nsupdate.out.$n >/dev/null 2>&1 || ret=1
774$DIG $DIGOPTS @10.53.0.6 \
775  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
776  $REVERSE_NAME NS >dig.out.ns6.$n
777grep localhost. dig.out.ns6.$n >/dev/null 2>&1 && ret=1
778if test $ret -ne 0; then
779  echo_i "failed"
780  status=1
781fi
782
783n=$((n + 1))
784echo_i "check that 'update-policy 6to4-self' permits update of records for the client's own address via TCP over IPv4 ($n)"
785ret=0
786REVERSE_NAME=6.0.0.0.5.3.a.0.2.0.0.2.ip6.arpa
787$NSUPDATE -v >nsupdate.out.$n 2>&1 <<END || ret=1
788server 10.53.0.6 ${PORT}
789local 10.53.0.6
790zone 2.0.0.2.ip6.arpa
791update add ${REVERSE_NAME} 600 NS localhost.
792send
793END
794grep REFUSED nsupdate.out.$n >/dev/null 2>&1 && ret=1
795$DIG $DIGOPTS @10.53.0.6 \
796  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
797  $REVERSE_NAME NS >dig.out.ns6.$n || ret=1
798grep localhost. dig.out.ns6.$n >/dev/null 2>&1 || ret=1
799if test $ret -ne 0; then
800  echo_i "failed"
801  status=1
802fi
803
804n=$((n + 1))
805ret=0
806echo_i "check that 'update-policy 6to4-self' refuses update of records via UDP over IPv6 ($n)"
807REVERSE_NAME=7.0.0.0.5.3.a.0.2.0.0.2.ip6.arpa
808$NSUPDATE >nsupdate.out.$n 2>&1 <<END && ret=1
809server fd92:7065:b8e:ffff::6 ${PORT}
810local 2002:a35:7::1
811zone 2.0.0.2.ip6.arpa
812update add ${REVERSE_NAME} 600 NS localhost.
813send
814END
815grep REFUSED nsupdate.out.$n >/dev/null 2>&1 || ret=1
816$DIG $DIGOPTS @fd92:7065:b8e:ffff::6 \
817  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
818  $REVERSE_NAME NS >dig.out.ns6.$n
819grep localhost. dig.out.ns6.$n >/dev/null 2>&1 && ret=1
820if test $ret -ne 0; then
821  echo_i "failed"
822  status=1
823fi
824
825n=$((n + 1))
826echo_i "check that 'update-policy 6to4-self' permits update of records for the client's own address via TCP over IPv6 ($n)"
827ret=0
828REVERSE_NAME=7.0.0.0.5.3.a.0.2.0.0.2.ip6.arpa
829$NSUPDATE -v >nsupdate.out.$n 2>&1 <<END || ret=1
830server fd92:7065:b8e:ffff::6 ${PORT}
831local 2002:a35:7::1
832zone 2.0.0.2.ip6.arpa
833update add ${REVERSE_NAME} 600 NS localhost.
834send
835END
836grep REFUSED nsupdate.out.$n >/dev/null 2>&1 && ret=1
837$DIG $DIGOPTS @fd92:7065:b8e:ffff::6 \
838  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
839  $REVERSE_NAME NS >dig.out.ns6.$n || ret=1
840grep localhost. dig.out.ns6.$n >/dev/null 2>&1 || ret=1
841if test $ret -ne 0; then
842  echo_i "failed"
843  status=1
844fi
845
846n=$((n + 1))
847ret=0
848echo_i "check that 'update-policy subdomain' is properly enforced ($n)"
849# "restricted.example.nil" matches "grant ... subdomain restricted.example.nil"
850# and thus this UPDATE should succeed.
851$NSUPDATE -d <<END >nsupdate.out1-$n 2>&1 || ret=1
852server 10.53.0.1 ${PORT}
853key $DEFAULT_HMAC:restricted.example.nil 1234abcd8765
854update add restricted.example.nil 0 IN TXT everywhere.
855send
856END
857$DIG $DIGOPTS +tcp @10.53.0.1 restricted.example.nil TXT >dig.out.1.test$n || ret=1
858grep "TXT.*everywhere" dig.out.1.test$n >/dev/null || ret=1
859# "example.nil" does not match "grant ... subdomain restricted.example.nil" and
860# thus this UPDATE should fail.
861$NSUPDATE -d <<END >nsupdate.out2-$n 2>&1 && ret=1
862server 10.53.0.1 ${PORT}
863key $DEFAULT_HMAC:restricted.example.nil 1234abcd8765
864update add example.nil 0 IN TXT everywhere.
865send
866END
867$DIG $DIGOPTS +tcp @10.53.0.1 example.nil TXT >dig.out.2.test$n || ret=1
868grep "TXT.*everywhere" dig.out.2.test$n >/dev/null && ret=1
869[ $ret = 0 ] || {
870  echo_i "failed"
871  status=1
872}
873
874n=$((n + 1))
875ret=0
876echo_i "check that 'update-policy zonesub' is properly enforced ($n)"
877# grant zonesub-key.example.nil zonesub TXT;
878# the A record update should be rejected as it is not in the type list
879$NSUPDATE -d <<END >nsupdate.out1-$n 2>&1 && ret=1
880server 10.53.0.1 ${PORT}
881key $DEFAULT_HMAC:zonesub-key.example.nil 1234subk8765
882update add zonesub.example.nil 0 IN A 1.2.3.4
883send
884END
885$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil A >dig.out.1.test$n || ret=1
886grep "status: REFUSED" nsupdate.out1-$n >/dev/null || ret=1
887grep "ANSWER: 0," dig.out.1.test$n >/dev/null || ret=1
888# the TXT record update should be accepted as it is in the type list
889$NSUPDATE -d <<END >nsupdate.out2-$n 2>&1 || ret=1
890server 10.53.0.1 ${PORT}
891key $DEFAULT_HMAC:zonesub-key.example.nil 1234subk8765
892update add zonesub.example.nil 0 IN TXT everywhere.
893send
894END
895$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil TXT >dig.out.2.test$n || ret=1
896grep "status: REFUSED" nsupdate.out2-$n >/dev/null && ret=1
897grep "ANSWER: 1," dig.out.2.test$n >/dev/null || ret=1
898grep "TXT.*everywhere" dig.out.2.test$n >/dev/null || ret=1
899[ $ret = 0 ] || {
900  echo_i "failed"
901  status=1
902}
903
904n=$((n + 1))
905ret=0
906echo_i "check 'grant' in deny name + grant subdomain ($n)"
907$NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
908key $DEFAULT_HMAC:subkey 1234abcd8765
909server 10.53.0.9 ${PORT}
910zone denyname.example
911update add foo.denyname.example 3600 IN TXT added
912send
913EOF
914$DIG $DIGOPTS +tcp @10.53.0.9 foo.denyname.example TXT >dig.out.ns9.test$n || ret=1
915grep "added" dig.out.ns9.test$n >/dev/null || ret=1
916[ $ret = 0 ] || {
917  echo_i "failed"
918  status=1
919}
920
921n=$((n + 1))
922ret=0
923echo_i "check 'deny' in deny name + grant subdomain ($n)"
924$NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
925key $DEFAULT_HMAC:subkey 1234abcd8765
926server 10.53.0.9 ${PORT}
927zone denyname.example
928update add denyname.example 3600 IN TXT added
929send
930EOF
931$DIG $DIGOPTS +tcp @10.53.0.9 denyname.example TXT >dig.out.ns9.test$n || ret=1
932grep "added" dig.out.ns9.test$n >/dev/null && ret=1
933[ $ret = 0 ] || {
934  echo_i "failed"
935  status=1
936}
937
938n=$((n + 1))
939ret=0
940echo_i "check that changes to the DNSKEY RRset TTL do not have side effects ($n)"
941$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd dnskey.test. \
942  @10.53.0.3 dnskey \
943  | awk -v port="${PORT}" 'BEGIN { print "server 10.53.0.3", port; }
944	$2 == 10 && $3 == "IN" && $4 == "DNSKEY" { $2 = 600; print "update add", $0 }
945	END { print "send" }' >update.in.$n || ret=1
946$NSUPDATE update.in.$n
947
948$DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd dnskey.test. \
949  @10.53.0.3 any >dig.out.ns3.$n || ret=1
950
951grep "600.*DNSKEY" dig.out.ns3.$n >/dev/null || ret=1
952grep TYPE65534 dig.out.ns3.$n >/dev/null && ret=1
953if test $ret -ne 0; then
954  echo_i "failed"
955  status=1
956fi
957
958n=$((n + 1))
959ret=0
960echo_i "check notify with TSIG worked ($n)"
961# if the alternate view received a notify--meaning, the notify was
962# validly signed by "altkey"--then the zonefile update.alt.bk will
963# will have been created.
964[ -f ns2/update.alt.bk ] || ret=1
965if [ $ret -ne 0 ]; then
966  echo_i "failed"
967  status=1
968fi
969
970n=$((n + 1))
971ret=0
972echo_i "check type list options ($n)"
973$NSUPDATE -T >typelist.out.T.${n} || {
974  ret=1
975  echo_i "nsupdate -T failed"
976}
977$NSUPDATE -P >typelist.out.P.${n} || {
978  ret=1
979  echo_i "nsupdate -P failed"
980}
981$NSUPDATE -TP >typelist.out.TP.${n} || {
982  ret=1
983  echo_i "nsupdate -TP failed"
984}
985grep ANY typelist.out.T.${n} >/dev/null && {
986  ret=1
987  echo_i "failed: ANY found (-T)"
988}
989grep ANY typelist.out.P.${n} >/dev/null && {
990  ret=1
991  echo_i "failed: ANY found (-P)"
992}
993grep ANY typelist.out.TP.${n} >/dev/null && {
994  ret=1
995  echo_i "failed: ANY found (-TP)"
996}
997grep KEYDATA typelist.out.T.${n} >/dev/null && {
998  ret=1
999  echo_i "failed: KEYDATA found (-T)"
1000}
1001grep KEYDATA typelist.out.P.${n} >/dev/null && {
1002  ret=1
1003  echo_i "failed: KEYDATA found (-P)"
1004}
1005grep KEYDATA typelist.out.TP.${n} >/dev/null && {
1006  ret=1
1007  echo_i "failed: KEYDATA found (-TP)"
1008}
1009grep AAAA typelist.out.T.${n} >/dev/null || {
1010  ret=1
1011  echo_i "failed: AAAA not found (-T)"
1012}
1013grep AAAA typelist.out.P.${n} >/dev/null && {
1014  ret=1
1015  echo_i "failed: AAAA found (-P)"
1016}
1017grep AAAA typelist.out.TP.${n} >/dev/null || {
1018  ret=1
1019  echo_i "failed: AAAA not found (-TP)"
1020}
1021if [ $ret -ne 0 ]; then
1022  echo_i "failed"
1023  status=1
1024fi
1025
1026n=$((n + 1))
1027ret=0
1028echo_i "check command list ($n)"
1029(
1030  while read cmd; do
1031    {
1032      echo "$cmd" | $NSUPDATE >/dev/null 2>&1
1033      rc=$?
1034    } || true
1035    if test $rc -gt 1; then
1036      echo_i "failed ($cmd)"
1037      ret=1
1038    fi
1039    {
1040      echo "$cmd " | $NSUPDATE >/dev/null 2>&1
1041      rc=$?
1042    } || true
1043    if test $rc -gt 1; then
1044      echo_i "failed ($cmd)"
1045      ret=1
1046    fi
1047  done
1048  exit $ret
1049) <commandlist || ret=1
1050if [ $ret -ne 0 ]; then
1051  status=1
1052fi
1053
1054n=$((n + 1))
1055ret=0
1056echo_i "check DoT (opportunistic-tls) ($n)"
1057if $FEATURETEST --have-fips-dh; then
1058  $NSUPDATE -D -S -O -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 || ret=1
1059    server 10.53.0.1 ${TLSPORT}
1060    update add dot-non-auth-client-o.example.nil. 600 A 10.10.10.3
1061    send
1062END
1063  sleep 2
1064  $DIG $DIGOPTS +short @10.53.0.1 dot-non-auth-client-o.example.nil >dig.out.test$n 2>&1 || ret=1
1065  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1
1066  if [ $ret -ne 0 ]; then
1067    echo_i "failed"
1068    status=1
1069  fi
1070else
1071  echo_i "skipped: DH not supported in FIPS mode"
1072fi
1073
1074n=$((n + 1))
1075ret=0
1076echo_i "check DoT (strict-tls) with an implicit hostname (by IP address) ($n)"
1077if $FEATURETEST --have-fips-dh; then
1078  $NSUPDATE -D -S -A CA/CA.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 || ret=1
1079    server 10.53.0.1 ${EXTRAPORT1}
1080    update add dot-non-auth-client.example.nil. 600 A 10.10.10.3
1081    send
1082END
1083  sleep 2
1084  $DIG $DIGOPTS +short @10.53.0.1 dot-non-auth-client.example.nil >dig.out.test$n 2>&1 || ret=1
1085  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1
1086  if [ $ret -ne 0 ]; then
1087    echo_i "failed"
1088    status=1
1089  fi
1090else
1091  echo_i "skipped: DH not supported in FIPS mode"
1092fi
1093
1094n=$((n + 1))
1095ret=0
1096echo_i "check DoT (strict-tls) with an implicit hostname (by IP address) ($n)"
1097if $FEATURETEST --have-fips-dh; then
1098  $NSUPDATE -D -S -A CA/CA.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 || ret=1
1099    server 10.53.0.1 ${EXTRAPORT1}
1100    update add dot-fs.example.nil. 600 A 10.10.10.3
1101    send
1102END
1103  sleep 2
1104  $DIG $DIGOPTS +short @10.53.0.1 dot-fs.example.nil >dig.out.test$n 2>&1 || ret=1
1105  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1
1106  if [ $ret -ne 0 ]; then
1107    echo_i "failed"
1108    status=1
1109  fi
1110else
1111  echo_i "skipped: DH not supported in FIPS mode"
1112fi
1113
1114n=$((n + 1))
1115ret=0
1116echo_i "check DoT (strict-tls) with a correct hostname ($n)"
1117if $FEATURETEST --have-fips-dh; then
1118  $NSUPDATE -D -S -A CA/CA.pem -H srv01.crt01.example.nil -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 || ret=1
1119    server 10.53.0.1 ${EXTRAPORT1}
1120    update add dot-fs-h.example.nil. 600 A 10.10.10.3
1121    send
1122END
1123  sleep 2
1124  $DIG $DIGOPTS +short @10.53.0.1 dot-fs-h.example.nil >dig.out.test$n 2>&1 || ret=1
1125  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1
1126  if [ $ret -ne 0 ]; then
1127    echo_i "failed"
1128    status=1
1129  fi
1130else
1131  echo_i "skipped: DH not supported in FIPS mode"
1132fi
1133
1134n=$((n + 1))
1135ret=0
1136echo_i "check DoT (strict-tls) with an incorrect hostname (failure expected) ($n)"
1137if $FEATURETEST --have-fips-dh; then
1138  $NSUPDATE -D -S -A CA/CA.pem -H srv01.crt01.example.bad -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 && ret=1
1139    server 10.53.0.1 ${EXTRAPORT1}
1140    update add dot-fs-h-bad.example.nil. 600 A 10.10.10.3
1141    send
1142END
1143  sleep 2
1144  $DIG $DIGOPTS +short @10.53.0.1 dot-fs-h-bad.example.nil >dig.out.test$n 2>&1 || ret=1
1145  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1
1146  if [ $ret -ne 0 ]; then
1147    echo_i "failed"
1148    status=1
1149  fi
1150else
1151  echo_i "skipped: DH not supported in FIPS mode"
1152fi
1153
1154n=$((n + 1))
1155ret=0
1156echo_i "check DoT (strict-tls) with a wrong authority (failure expected) ($n)"
1157if $FEATURETEST --have-fips-dh; then
1158  $NSUPDATE -D -S -A CA/CA-other.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 && ret=1
1159    server 10.53.0.1 ${EXTRAPORT1}
1160    update add dot-fs-auth-bad.example.nil. 600 A 10.10.10.3
1161    send
1162END
1163  sleep 2
1164  $DIG $DIGOPTS +short @10.53.0.1 dot-fs-auth-bad.example.nil >dig.out.test$n 2>&1 || ret=1
1165  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1
1166  if [ $ret -ne 0 ]; then
1167    echo_i "failed"
1168    status=1
1169  fi
1170else
1171  echo_i "skipped: DH not supported in FIPS mode"
1172fi
1173
1174n=$((n + 1))
1175ret=0
1176echo_i "check DoT (mutual-tls) with a valid client certificate ($n)"
1177if $FEATURETEST --have-fips-dh; then
1178  $NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/srv01.client01.example.nil.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 || ret=1
1179    server 10.53.0.1 ${EXTRAPORT2}
1180    update add dot-fsmt.example.nil. 600 A 10.10.10.3
1181    send
1182END
1183  sleep 2
1184  $DIG $DIGOPTS +short @10.53.0.1 dot-fsmt.example.nil >dig.out.test$n 2>&1 || ret=1
1185  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1
1186  if [ $ret -ne 0 ]; then
1187    echo_i "failed"
1188    status=1
1189  fi
1190else
1191  echo_i "skipped: DH not supported in FIPS mode"
1192fi
1193
1194n=$((n + 1))
1195ret=0
1196echo_i "check DoT (mutual-tls) with a valid client certificate but with an incorrect hostname (failure expected) ($n)"
1197if $FEATURETEST --have-fips-dh; then
1198  $NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/srv01.client01.example.nil.pem -H srv01.crt01.example.bad -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 && ret=1
1199    server 10.53.0.1 ${EXTRAPORT2}
1200    update add dot-fsmt-h-bad.example.nil. 600 A 10.10.10.3
1201    send
1202END
1203  sleep 2
1204  $DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-h-bad.example.nil >dig.out.test$n 2>&1 || ret=1
1205  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1
1206  if [ $ret -ne 0 ]; then
1207    echo_i "failed"
1208    status=1
1209  fi
1210else
1211  echo_i "skipped: DH not supported in FIPS mode"
1212fi
1213
1214n=$((n + 1))
1215ret=0
1216echo_i "check DoT (mutual-tls) with a valid client certificate but with a wrong authority (failure expected) ($n)"
1217if $FEATURETEST --have-fips-dh; then
1218  $NSUPDATE -D -S -A CA/CA-other.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/client01.crt01.example.nil.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 && ret=1
1219    server 10.53.0.1 ${EXTRAPORT2}
1220    update add dot-fsmt-auth-bad.example.nil. 600 A 10.10.10.3
1221    send
1222END
1223  sleep 2
1224  $DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-auth-bad.example.nil >dig.out.test$n 2>&1 || ret=1
1225  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1
1226  if [ $ret -ne 0 ]; then
1227    echo_i "failed"
1228    status=1
1229  fi
1230else
1231  echo_i "skipped: DH not supported in FIPS mode"
1232fi
1233
1234n=$((n + 1))
1235ret=0
1236echo_i "check DoT (mutual-tls) with an expired client certificate (failure expected) ($n)"
1237if $FEATURETEST --have-fips-dh; then
1238  $NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client02-expired.example.nil.key -E CA/certs/srv01.client02-expired.example.nil.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 && ret=1
1239    server 10.53.0.1 ${EXTRAPORT2}
1240    update add dot-fsmt-exp-bad.example.nil. 600 A 10.10.10.3
1241    send
1242END
1243  sleep 2
1244  $DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-exp-bad.example.nil >dig.out.test$n 2>&1 || ret=1
1245  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1
1246  if [ $ret -ne 0 ]; then
1247    echo_i "failed"
1248    status=1
1249  fi
1250else
1251  echo_i "skipped: DH not supported in FIPS mode"
1252fi
1253
1254n=$((n + 1))
1255ret=0
1256echo_i "check DoT (mutual-tls) with a valid client certificate and an expired server certificate (failure expected) ($n)"
1257if $FEATURETEST --have-fips-dh; then
1258  $NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/srv01.client01.example.nil.pem -k ns1/ddns.key <<END >nsupdate.out.test$n 2>&1 && ret=1
1259    server 10.53.0.1 ${EXTRAPORT3}
1260    update add dot-fsmt-exp-bad.example.nil. 600 A 10.10.10.3
1261    send
1262END
1263  sleep 2
1264  $DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-exp-bad.example.nil >dig.out.test$n 2>&1 || ret=1
1265  grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1
1266  if [ $ret -ne 0 ]; then
1267    echo_i "failed"
1268    status=1
1269  fi
1270else
1271  echo_i "skipped: DH not supported in FIPS mode"
1272fi
1273
1274n=$((n + 1))
1275ret=0
1276echo_i "check TSIG key algorithms using legacy K file pairs (nsupdate -k) ($n)"
1277if $FEATURETEST --md5; then
1278  ALGS="157 161 162 163 164 165"
1279else
1280  ALGS="161 162 163 164 165"
1281  echo_i "skipping disabled md5 (157) algorithm"
1282fi
1283for alg in $ALGS; do
1284  $NSUPDATE -k ns1/legacy/Klegacy-${alg}.+${alg}+*.key <<END >nsupdate.alg-$alg.out 2>&1 || ret=1
1285server 10.53.0.1 ${PORT}
1286update add ${alg}.keytests.nil. 600 A 10.10.10.3
1287send
1288END
1289done
1290sleep 2
1291for alg in $ALGS; do
1292  $DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.3 >/dev/null 2>&1 || ret=1
1293  grep "Use of K\* file pairs for HMAC is deprecated" nsupdate.alg-$alg.out >/dev/null || ret=1
1294done
1295if [ $ret -ne 0 ]; then
1296  echo_i "failed"
1297  status=1
1298fi
1299
1300n=$((n + 1))
1301ret=0
1302echo_i "check TSIG key algorithms (nsupdate -k) ($n)"
1303if $FEATURETEST --md5; then
1304  ALGS="md5 sha1 sha224 sha256 sha384 sha512"
1305else
1306  ALGS="sha1 sha224 sha256 sha384 sha512"
1307  echo_i "skipping disabled md5 algorithm"
1308fi
1309for alg in $ALGS; do
1310  $NSUPDATE -k ns1/${alg}.key <<END >/dev/null || ret=1
1311server 10.53.0.1 ${PORT}
1312update add ${alg}.keytests.nil. 600 A 10.10.10.3
1313send
1314END
1315done
1316sleep 2
1317for alg in $ALGS; do
1318  $DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.3 >/dev/null 2>&1 || ret=1
1319done
1320if [ $ret -ne 0 ]; then
1321  echo_i "failed"
1322  status=1
1323fi
1324
1325n=$((n + 1))
1326ret=0
1327echo_i "check TSIG key algorithms (nsupdate -y) ($n)"
1328for alg in $ALGS; do
1329  secret=$(sed -n 's/.*secret "\(.*\)";.*/\1/p' ns1/${alg}.key)
1330  $NSUPDATE -y "hmac-${alg}:${alg}-key:$secret" <<END >/dev/null || ret=1
1331server 10.53.0.1 ${PORT}
1332update add ${alg}.keytests.nil. 600 A 10.10.10.50
1333send
1334END
1335done
1336sleep 2
1337for alg in $ALGS; do
1338  $DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.50 >/dev/null 2>&1 || ret=1
1339done
1340if [ $ret -ne 0 ]; then
1341  echo_i "failed"
1342  status=1
1343fi
1344
1345n=$((n + 1))
1346ret=0
1347echo_i "check that ttl is capped by max-ttl ($n)"
1348$NSUPDATE <<END >/dev/null || ret=1
1349server 10.53.0.1 ${PORT}
1350update add cap.max-ttl.nil. 600 A 10.10.10.3
1351update add nocap.max-ttl.nil. 150 A 10.10.10.3
1352send
1353END
1354sleep 2
1355$DIG $DIGOPTS @10.53.0.1 cap.max-ttl.nil | grep "^cap.max-ttl.nil.	300" >/dev/null 2>&1 || ret=1
1356$DIG $DIGOPTS @10.53.0.1 nocap.max-ttl.nil | grep "^nocap.max-ttl.nil.	150" >/dev/null 2>&1 || ret=1
1357if [ $ret -ne 0 ]; then
1358  echo_i "failed"
1359  status=1
1360fi
1361
1362n=$((n + 1))
1363echo_i "check adding more records than max-records-per-type fails ($n)"
1364ret=0
1365$NSUPDATE <<END >nsupdate.out.test$n 2>&1 && ret=1
1366server 10.53.0.1 ${PORT}
1367zone max-ttl.nil.
1368update add a.max-ttl.nil. 60 IN A 192.0.2.1
1369update add a.max-ttl.nil. 60 IN A 192.0.2.2
1370update add a.max-ttl.nil. 60 IN A 192.0.2.3
1371update add a.max-ttl.nil. 60 IN A 192.0.2.4
1372send
1373END
1374grep "update failed: SERVFAIL" nsupdate.out.test$n >/dev/null || ret=1
1375msg="error updating 'a.max-ttl.nil/A' in 'max-ttl.nil/IN' (zone): too many records (must not exceed 3)"
1376wait_for_log 10 "$msg" ns1/named.run || ret=1
1377[ $ret = 0 ] || {
1378  echo_i "failed"
1379  status=1
1380}
1381nextpart ns1/named.run >/dev/null
1382
1383n=$((n + 1))
1384ret=0
1385echo_i "add a record which is truncated when logged. ($n)"
1386$NSUPDATE verylarge || ret=1
1387$DIG $DIGOPTS +tcp @10.53.0.1 txt txt.update.nil >dig.out.ns1.test$n || ret=1
1388grep "ANSWER: 1," dig.out.ns1.test$n >/dev/null || ret=1
1389grep "adding an RR at 'txt.update.nil' TXT .* \[TRUNCATED\]" ns1/named.run >/dev/null || ret=1
1390if [ $ret -ne 0 ]; then
1391  echo_i "failed"
1392  status=1
1393fi
1394
1395n=$((n + 1))
1396ret=0
1397echo_i "check that yyyymmddvv serial number is correctly generated ($n)"
1398oldserial=$($DIG $DIGOPTS +short yyyymmddvv.nil. soa @10.53.0.1 | awk '{print $3}') || ret=1
1399$NSUPDATE <<END >/dev/null 2>&1 || ret=1
1400    server 10.53.0.1 ${PORT}
1401    ttl 600
1402    update add new.yyyymmddvv.nil in a 1.2.3.4
1403    send
1404END
1405now=$($PERL -e '@lt=localtime(); printf "%.4d%0.2d%0.2d00\n",$lt[5]+1900,$lt[4]+1,$lt[3];')
1406sleep 1
1407serial=$($DIG $DIGOPTS +short yyyymmddvv.nil. soa @10.53.0.1 | awk '{print $3}') || ret=1
1408[ "$oldserial" -ne "$serial" ] || ret=1
1409[ "$serial" -eq "$now" ] || ret=1
1410[ $ret = 0 ] || {
1411  echo_i "failed"
1412  status=1
1413}
1414
1415#
1416#  Refactor to use perl to launch the parallel updates.
1417#
1418if false; then
1419  n=$((n + 1))
1420  echo_i "send many simultaneous updates via a update forwarder ($n)"
1421  ret=0
1422  for i in 0 1 2 3 4 5 6 7; do
1423    (
1424      for j in 0 1 2 3 4 5 6 7; do
1425        (
1426          $NSUPDATE <<EOF
1427server 10.53.0.3 ${PORT}
1428zone many.test
1429update add $i-$j.many.test 0 IN A 1.2.3.4
1430send
1431EOF
1432        ) &
1433      done
1434      wait
1435    ) &
1436  done
1437  wait
1438  dig axfr many.test @10.53.0.1 >dig.out.test$n
1439  lines=$(awk '$4 == "A" { l++ } END { print l }' dig.out.test$n)
1440  test ${lines:-0} -eq 64 || ret=1
1441  [ $ret = 0 ] || {
1442    echo_i "failed"
1443    status=1
1444  }
1445fi
1446
1447n=$((n + 1))
1448echo_i "check max-journal-size limits ($n)"
1449ret=0
1450rm -f nsupdate.out1-$n
1451# add one record
1452$NSUPDATE <<EOF >>nsupdate.out1-$n 2>&1
1453server 10.53.0.1 ${PORT}
1454zone maxjournal.test
1455update add z.maxjournal.test 300 IN A 10.20.30.40
1456send
1457EOF
1458for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
1459  # repeatedly add and remove the same set of records to fill up
1460  # the journal file without changing the zone content
1461  $NSUPDATE <<EOF >>nsupdate.out1-$n 2>&1
1462server 10.53.0.1 ${PORT}
1463zone maxjournal.test
1464update add a.maxjournal.test 300 IN A 1.2.3.4
1465update add b.maxjournal.test 300 IN A 1.2.3.4
1466update add c.maxjournal.test 300 IN A 1.2.3.4
1467update add d.maxjournal.test 300 IN A 1.2.3.4
1468send
1469update del a.maxjournal.test
1470update del b.maxjournal.test
1471update del c.maxjournal.test
1472update del d.maxjournal.test
1473send
1474EOF
1475done
1476# check that the journal is big enough to require truncation.
1477size=$($PERL -e 'use File::stat; my $sb = stat(@ARGV[0]); printf("%s\n", $sb->size);' ns1/maxjournal.db.jnl)
1478[ "$size" -gt 6000 ] || ret=1
1479sleep 1
1480$RNDCCMD 10.53.0.1 sync maxjournal.test
1481check_size_lt_5000() (
1482  size=$($PERL -e 'use File::stat; my $sb = stat(@ARGV[0]); printf("%s\n", $sb->size);' ns1/maxjournal.db.jnl)
1483  [ "$size" -lt 5000 ]
1484)
1485retry_quiet 20 check_size_lt_5000 || ret=1
1486[ $ret = 0 ] || {
1487  echo_i "failed"
1488  status=1
1489}
1490
1491n=$((n + 1))
1492echo_i "check check-names processing ($n)"
1493ret=0
1494$NSUPDATE <<EOF >nsupdate.out1-$n 2>&1 && ret=1
1495update add # 0 in a 1.2.3.4
1496EOF
1497grep "bad owner" nsupdate.out1-$n >/dev/null || ret=1
1498
1499$NSUPDATE <<EOF >nsupdate.out2-$n 2>&1 || ret=1
1500check-names off
1501update add # 0 in a 1.2.3.4
1502EOF
1503grep "bad owner" nsupdate.out2-$n >/dev/null && ret=1
1504
1505$NSUPDATE <<EOF >nsupdate.out3-$n 2>&1 && ret=1
1506update add . 0 in mx 0 #
1507EOF
1508grep "bad name" nsupdate.out3-$n >/dev/null || ret=1
1509
1510$NSUPDATE <<EOF >nsupdate.out4-$n 2>&1 || ret=1
1511check-names off
1512update add . 0 in mx 0 #
1513EOF
1514grep "bad name" nsupdate.out4-$n >/dev/null && ret=1
1515
1516[ $ret = 0 ] || {
1517  echo_i "failed"
1518  status=1
1519}
1520
1521n=$((n + 1))
1522echo_i "check check-svcb processing ($n)"
1523ret=0
1524$NSUPDATE <<EOF >nsupdate.out1-$n 2>&1 && ret=1
1525update add _dns.ns.example 0 in svcb 1 ns.example dohpath=/{?dns}
1526EOF
1527grep "check-svcb failed: no ALPN" nsupdate.out1-$n >/dev/null || ret=1
1528
1529$NSUPDATE <<EOF >nsupdate.out2-$n 2>&1 || ret=1
1530check-svcb off
1531update add _dns.ns.example 0 in svcb 1 ns.example dohpath=/{?dns}
1532EOF
1533grep "check-svcb failed: no ALPN" nsupdate.out2-$n >/dev/null && ret=1
1534
1535$NSUPDATE <<EOF >nsupdate.out3-$n 2>&1 && ret=1
1536update add _dns.ns.example 0 in svcb 1 ns.example alpn=h2
1537EOF
1538grep "check-svcb failed: no DOHPATH" nsupdate.out3-$n >/dev/null || ret=1
1539
1540$NSUPDATE <<EOF >nsupdate.out4-$n 2>&1 || ret=1
1541check-svcb off
1542update add _dns.ns.example 0 in svcb 1 ns.example alpn=h2
1543EOF
1544grep "check-svcb failed: no DOHPATH" nsupdate.out4-$n >/dev/null && ret=1
1545
1546[ $ret = 0 ] || {
1547  echo_i "failed"
1548  status=1
1549}
1550
1551n=$((n + 1))
1552echo_i "check adding of delegating NS records processing ($n)"
1553ret=0
1554$NSUPDATE -v <<EOF >nsupdate.out.test$n 2>&1 || ret=1
1555server 10.53.0.3 ${PORT}
1556zone delegation.test.
1557update add child.delegation.test. 3600 NS foo.example.net.
1558update add child.delegation.test. 3600 NS bar.example.net.
1559send
1560EOF
1561$DIG $DIGOPTS +tcp @10.53.0.3 ns child.delegation.test >dig.out.ns1.test$n || ret=1
1562grep "status: NOERROR" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1
1563grep "AUTHORITY: 2" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1
1564[ $ret = 0 ] || {
1565  echo_i "failed"
1566  status=1
1567}
1568
1569n=$((n + 1))
1570echo_i "check deleting of delegating NS records processing ($n)"
1571ret=0
1572$NSUPDATE -v <<EOF >nsupdate.out.test$n 2>&1 || ret=1
1573server 10.53.0.3 ${PORT}
1574zone delegation.test.
1575update del child.delegation.test. 3600 NS foo.example.net.
1576update del child.delegation.test. 3600 NS bar.example.net.
1577send
1578EOF
1579$DIG $DIGOPTS +tcp @10.53.0.3 ns child.delegation.test >dig.out.ns1.test$n || ret=1
1580grep "status: NXDOMAIN" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1
1581[ $ret = 0 ] || {
1582  echo_i "failed"
1583  status=1
1584}
1585
1586n=$((n + 1))
1587echo_i "check that adding too many records is blocked ($n)"
1588ret=0
1589$NSUPDATE -v <<EOF >nsupdate.out.test$n 2>&1 && ret=1
1590server 10.53.0.3 ${PORT}
1591zone too-big.test.
1592update add r1.too-big.test 3600 IN TXT r1.too-big.test
1593send
1594EOF
1595grep "update failed: SERVFAIL" nsupdate.out.test$n >/dev/null || ret=1
1596$DIG $DIGOPTS +tcp @10.53.0.3 r1.too-big.test TXT >dig.out.ns3.test$n || ret=1
1597grep "status: NXDOMAIN" dig.out.ns3.test$n >/dev/null || ret=1
1598grep "records in zone (4) exceeds max-records (3)" ns3/named.run >/dev/null || ret=1
1599[ $ret = 0 ] || {
1600  echo_i "failed"
1601  status=1
1602}
1603
1604n=$((n + 1))
1605ret=0
1606echo_i "check whether valid addresses are used for primary failover (UDP with defaults) ($n)"
1607t1=$($PERL -e 'print time()')
1608$NSUPDATE <<END >nsupdate.out.test$n 2>&1 && ret=1
1609server 10.53.0.4 ${PORT}
1610zone unreachable.
1611update add unreachable. 600 A 192.0.2.1
1612send
1613END
1614t2=$($PERL -e 'print time()')
1615grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1616grep "not implemented" nsupdate.out.test$n >/dev/null 2>&1 && ret=1
1617elapsed=$((t2 - t1))
1618# Check that default timeout value is respected, there should be 4 tries with 3 seconds each.
1619test $elapsed -lt 12 && ret=1
1620test $elapsed -gt 15 && ret=1
1621[ $ret = 0 ] || {
1622  echo_i "failed"
1623  status=1
1624}
1625
1626n=$((n + 1))
1627ret=0
1628echo_i "check whether valid addresses are used for primary failover (UDP with -u udptimeout) ($n)"
1629t1=$($PERL -e 'print time()')
1630$NSUPDATE -u 4 -r 1 <<END >nsupdate.out.test$n 2>&1 && ret=1
1631server 10.53.0.4 ${PORT}
1632zone unreachable.
1633update add unreachable. 600 A 192.0.2.1
1634send
1635END
1636t2=$($PERL -e 'print time()')
1637grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1638grep "not implemented" nsupdate.out.test$n >/dev/null 2>&1 && ret=1
1639elapsed=$((t2 - t1))
1640# Check that given timeout value is respected, there should be 2 tries with 4 seconds each.
1641test $elapsed -lt 8 && ret=1
1642test $elapsed -gt 12 && ret=1
1643[ $ret = 0 ] || {
1644  echo_i "failed"
1645  status=1
1646}
1647
1648n=$((n + 1))
1649ret=0
1650echo_i "check whether valid addresses are used for primary failover (UDP with -t timeout) ($n)"
1651t1=$($PERL -e 'print time()')
1652$NSUPDATE -u 0 -t 8 -r 1 <<END >nsupdate.out.test$n 2>&1 && ret=1
1653server 10.53.0.4 ${PORT}
1654zone unreachable.
1655update add unreachable. 600 A 192.0.2.1
1656send
1657END
1658t2=$($PERL -e 'print time()')
1659grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1660grep "not implemented" nsupdate.out.test$n >/dev/null 2>&1 && ret=1
1661elapsed=$((t2 - t1))
1662# Check that given timeout value is respected, there should be 2 tries with 4 seconds each.
1663test $elapsed -lt 8 && ret=1
1664test $elapsed -gt 12 && ret=1
1665[ $ret = 0 ] || {
1666  echo_i "failed"
1667  status=1
1668}
1669
1670n=$((n + 1))
1671ret=0
1672echo_i "check whether valid addresses are used for primary failover (UDP with -u udptimeout -t timeout) ($n)"
1673t1=$($PERL -e 'print time()')
1674$NSUPDATE -u 4 -t 30 -r 1 <<END >nsupdate.out.test$n 2>&1 && ret=1
1675server 10.53.0.4 ${PORT}
1676zone unreachable.
1677update add unreachable. 600 A 192.0.2.1
1678send
1679END
1680t2=$($PERL -e 'print time()')
1681grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1682grep "not implemented" nsupdate.out.test$n >/dev/null 2>&1 && ret=1
1683elapsed=$((t2 - t1))
1684# Check that given timeout value is respected, there should be 2 tries with 4 seconds each, as -u takes precedence over -t.
1685test $elapsed -lt 8 && ret=1
1686test $elapsed -gt 12 && ret=1
1687[ $ret = 0 ] || {
1688  echo_i "failed"
1689  status=1
1690}
1691
1692n=$((n + 1))
1693ret=0
1694echo_i "check whether valid addresses are used for primary failover (TCP with -t timeout) ($n)"
1695t1=$($PERL -e 'print time()')
1696$NSUPDATE -t 8 -v <<END >nsupdate.out.test$n 2>&1 && ret=1
1697server 10.53.0.4 ${PORT}
1698zone unreachable.
1699update add unreachable. 600 A 192.0.2.1
1700send
1701END
1702t2=$($PERL -e 'print time()')
1703grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1704grep "not implemented" nsupdate.out.test$n >/dev/null 2>&1 && ret=1
1705elapsed=$((t2 - t1))
1706# Check that given timeout value is respected, there should be 1 try with 8 seconds.
1707test $elapsed -lt 8 && ret=1
1708test $elapsed -gt 12 && ret=1
1709[ $ret = 0 ] || {
1710  echo_i "failed"
1711  status=1
1712}
1713
1714n=$((n + 1))
1715ret=0
1716echo_i "ensure bad owner name is fatal in non-interactive mode ($n)"
1717$NSUPDATE <<END >nsupdate.out 2>&1 && ret=1
1718    update add emptylabel..nil. 600 A 10.10.10.1
1719END
1720grep "invalid owner name: empty label" nsupdate.out >/dev/null || ret=1
1721grep "syntax error" nsupdate.out >/dev/null || ret=1
1722[ $ret = 0 ] || {
1723  echo_i "failed"
1724  status=1
1725}
1726
1727n=$((n + 1))
1728ret=0
1729echo_i "ensure bad owner name is not fatal in interactive mode ($n)"
1730$NSUPDATE -i <<END >nsupdate.out 2>&1 || ret=1
1731    update add emptylabel..nil. 600 A 10.10.10.1
1732END
1733grep "invalid owner name: empty label" nsupdate.out >/dev/null || ret=1
1734[ $ret = 0 ] || {
1735  echo_i "failed"
1736  status=1
1737}
1738
1739n=$((n + 1))
1740ret=0
1741echo_i "ensure invalid key type is fatal in non-interactive mode ($n)"
1742$NSUPDATE <<END >nsupdate.out 2>&1 && ret=1
1743    key badkeytype:example abcd12345678
1744END
1745grep "unknown key type 'badkeytype'" nsupdate.out >/dev/null || ret=1
1746grep "syntax error" nsupdate.out >/dev/null || ret=1
1747[ $ret = 0 ] || {
1748  echo_i "failed"
1749  status=1
1750}
1751
1752n=$((n + 1))
1753ret=0
1754echo_i "ensure invalid key type is not fatal in interactive mode ($n)"
1755$NSUPDATE -i <<END >nsupdate.out 2>&1 || ret=1
1756    key badkeytype:example abcd12345678
1757END
1758grep "unknown key type 'badkeytype'" nsupdate.out >/dev/null || ret=1
1759[ $ret = 0 ] || {
1760  echo_i "failed"
1761  status=1
1762}
1763
1764n=$((n + 1))
1765ret=0
1766echo_i "ensure unresolvable server name is fatal in non-interactive mode ($n)"
1767$NSUPDATE <<END >nsupdate.out 2>&1 && ret=1
1768    server unresolvable..
1769END
1770grep "couldn't get address for 'unresolvable..':" nsupdate.out >/dev/null || ret=1
1771grep "syntax error" nsupdate.out >/dev/null || ret=1
1772[ $ret = 0 ] || {
1773  echo_i "failed"
1774  status=1
1775}
1776
1777n=$((n + 1))
1778ret=0
1779echo_i "ensure unresolvable server name is not fatal in interactive mode ($n)"
1780$NSUPDATE -i <<END >nsupdate.out 2>&1 || ret=1
1781    server unresolvable..
1782END
1783grep "couldn't get address for 'unresolvable..':" nsupdate.out >/dev/null || ret=1
1784grep "syntax error" nsupdate.out >/dev/null && ret=1
1785[ $ret = 0 ] || {
1786  echo_i "failed"
1787  status=1
1788}
1789
1790n=$((n + 1))
1791ret=0
1792echo_i "check nsupdate -4 -6 ($n)"
1793$NSUPDATE -4 -6 <<END >nsupdate.out.test$n 2>&1 && ret=1
1794server 10.53.0.3 ${PORT}
1795zone delegation.test.
1796update del child.delegation.test. 3600 NS foo.example.net.
1797update del child.delegation.test. 3600 NS bar.example.net.
1798send
1799END
1800grep "only one of -4 and -6 allowed" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1801[ $ret = 0 ] || {
1802  echo_i "failed"
1803  status=1
1804}
1805
1806n=$((n + 1))
1807ret=0
1808echo_i "check nsupdate -4 with an IPv6 server address ($n)"
1809$NSUPDATE -4 <<END >nsupdate.out.test$n 2>&1 && ret=1
1810server fd92:7065:b8e:ffff::2 ${PORT}
1811zone delegation.test.
1812update del child.delegation.test. 3600 NS foo.example.net.
1813update del child.delegation.test. 3600 NS bar.example.net.
1814send
1815END
1816grep "address family not supported" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1817[ $ret = 0 ] || {
1818  echo_i "failed"
1819  status=1
1820}
1821
1822n=$((n + 1))
1823ret=0
1824echo_i "check that TKEY in a update is rejected ($n)"
1825$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 && ret=1
1826server 10.53.0.3 ${PORT}
1827update add tkey.example 0 in tkey invalid.algorithm. 1516055980 1516140801 1 0 16 gRof8D2BFKvl/vrr9Lmnjw== 16 gRof8D2BFKvl/vrr9Lmnjw==
1828send
1829END
1830grep "UPDATE, status: NOERROR" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1831grep "UPDATE, status: FORMERR" nsupdate.out.test$n >/dev/null 2>&1 || ret=1
1832[ $ret = 0 ] || {
1833  echo_i "failed"
1834  status=1
1835}
1836
1837n=$((n + 1))
1838ret=0
1839echo_i "check that max records is enforced ($n)"
1840nextpart ns6/named.run >/dev/null
1841$NSUPDATE -v >nsupdate.out.$n 2>&1 <<END
1842server 10.53.0.6 ${PORT}
1843local 10.53.0.5
1844update del 5.0.53.10.in-addr.arpa.
1845update add 5.0.53.10.in-addr.arpa. 600 PTR localhost.
1846update add 5.0.53.10.in-addr.arpa. 600 PTR other.
1847send
1848END
1849$DIG $DIGOPTS @10.53.0.6 \
1850  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
1851  -x 10.53.0.5 >dig.out.ns6.$n || ret=1
1852# the policy is 'grant * tcp-self . PTR(1) ANY(2) A;' so only the
1853# first PTR record should be added.
1854grep localhost. dig.out.ns6.$n >/dev/null 2>&1 || ret=1
1855grep other. dig.out.ns6.$n >/dev/null 2>&1 && ret=1
1856nextpart ns6/named.run >nextpart.out.$n
1857grep "attempt to add more records than permitted by policy" nextpart.out.$n >/dev/null || ret=1
1858if test $ret -ne 0; then
1859  echo_i "failed"
1860  status=1
1861fi
1862
1863n=$((n + 1))
1864ret=0
1865echo_i "check that max records for ANY is enforced ($n)"
1866nextpart ns6/named.run >/dev/null
1867$NSUPDATE -v >nsupdate.out.$n 2>&1 <<END
1868server 10.53.0.6 ${PORT}
1869local 10.53.0.5
1870update del 5.0.53.10.in-addr.arpa.
1871update add 5.0.53.10.in-addr.arpa. 600 A 1.2.3.4
1872update add 5.0.53.10.in-addr.arpa. 600 A 1.2.3.3
1873update add 5.0.53.10.in-addr.arpa. 600 A 1.2.3.2
1874update add 5.0.53.10.in-addr.arpa. 600 AAAA ::ffff:1.2.3.4
1875update add 5.0.53.10.in-addr.arpa. 600 AAAA ::ffff:1.2.3.3
1876update add 5.0.53.10.in-addr.arpa. 600 AAAA ::ffff:1.2.3.2
1877send
1878END
1879$DIG $DIGOPTS @10.53.0.6 \
1880  +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
1881  ANY -x 10.53.0.5 >dig.out.ns6.test$n || ret=1
1882nextpart ns6/named.run >nextpart.out.test$n
1883grep "attempt to add more records than permitted by policy" nextpart.out.test$n >/dev/null || ret=1
1884# the policy is 'grant * tcp-self . PTR(1) ANY(2) A;' so all the A
1885# records should have been added as there is no limit and the first 2
1886# of the AAAA records added as they match ANY(2).
1887c1=$(awk '$4 == "A" { print }' dig.out.ns6.test$n | wc -l)
1888c2=$(awk '$4 == "AAAA" { print }' dig.out.ns6.test$n | wc -l)
1889test "$c1" -eq 3 -a "$c2" -eq 2 || ret=1
1890grep "::ffff:1.2.3.2" dig.out.ns6.test$n >/dev/null && ret=1
1891if test $ret -ne 0; then
1892  echo_i "failed"
1893  status=1
1894fi
1895
1896n=$((n + 1))
1897ret=0
1898echo_i "check that DS to the zone apex is ignored ($n)"
1899$DIG $DIGOPTS +tcp +norec example DS @10.53.0.3 >dig.out.pre.test$n || ret=1
1900grep "status: NOERROR" dig.out.pre.test$n >/dev/null || ret=1
1901grep "ANSWER: 0," dig.out.pre.test$n >/dev/null || ret=1
1902nextpart ns3/named.run >/dev/null
1903# specify zone to override the default of adding to parent zone
1904$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 || ret=1
1905server 10.53.0.3 ${PORT}
1906zone example
1907update add example 0 in DS 14364 10 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
1908send
1909END
1910msg=": attempt to add a DS record at zone apex ignored"
1911nextpart ns3/named.run | grep "$msg" >/dev/null || ret=1
1912$DIG $DIGOPTS +tcp +norec example DS @10.53.0.3 >dig.out.post.test$n || ret=1
1913grep "status: NOERROR" dig.out.post.test$n >/dev/null || ret=1
1914grep "ANSWER: 0," dig.out.post.test$n >/dev/null || ret=1
1915[ $ret = 0 ] || {
1916  echo_i "failed"
1917  status=1
1918}
1919
1920n=$((n + 1))
1921ret=0
1922echo_i "check that CDS with mismatched algorithm to DNSSEC multisigner zone is not allowed ($n)"
1923$DIG $DIGOPTS +tcp +norec multisigner.test CDS @10.53.0.3 >dig.out.pre.test$n || ret=1
1924grep "status: NOERROR" dig.out.pre.test$n >/dev/null || ret=1
1925grep "ANSWER: 0," dig.out.pre.test$n >/dev/null || ret=1
1926$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 && ret=1
1927server 10.53.0.3 ${PORT}
1928zone multisigner.test
1929update add multisigner.test 3600 IN CDS 14364 14 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
1930send
1931END
1932msg=": bad CDS RRset"
1933nextpart ns3/named.run | grep "$msg" >/dev/null || ret=1
1934$DIG $DIGOPTS +tcp +norec multisigner.test CDS @10.53.0.3 >dig.out.post.test$n || ret=1
1935grep "status: NOERROR" dig.out.post.test$n >/dev/null || ret=1
1936grep "ANSWER: 0," dig.out.post.test$n >/dev/null || ret=1
1937[ $ret = 0 ] || {
1938  echo_i "failed"
1939  status=1
1940}
1941
1942n=$((n + 1))
1943ret=0
1944echo_i "check that CDNSKEY with mismatched algorithm to DNSSEC multisigner zone is not allowed ($n)"
1945$DIG $DIGOPTS +tcp +norec multisigner.test CDNSKEY @10.53.0.3 >dig.out.pre.test$n || ret=1
1946grep "status: NOERROR" dig.out.pre.test$n >/dev/null || ret=1
1947grep "ANSWER: 0," dig.out.pre.test$n >/dev/null || ret=1
1948nextpart ns3/named.run >/dev/null
1949$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 && ret=1
1950server 10.53.0.3 ${PORT}
1951zone multisigner.test
1952update add multisigner.test 3600 IN CDNSKEY 257 3 14 d0NQ5PKmDz6P0B1WPMH9/UKRux/toSFwV2nTJYPA1Cx8pB0sJGTXbVhG U+6gye7VCHDhGIn9CjVfb2RJPW7GnQ==
1953send
1954END
1955msg=": bad CDNSKEY RRset"
1956nextpart ns3/named.run | grep "$msg" >/dev/null || ret=1
1957$DIG $DIGOPTS +tcp +norec multisigner.test CDNSKEY @10.53.0.3 >dig.out.post.test$n || ret=1
1958grep "status: NOERROR" dig.out.post.test$n >/dev/null || ret=1
1959grep "ANSWER: 0," dig.out.post.test$n >/dev/null || ret=1
1960[ $ret = 0 ] || {
1961  echo_i "failed"
1962  status=1
1963}
1964
1965n=$((n + 1))
1966ret=0
1967echo_i "check that CDS to DNSSEC multisigner zone is allowed ($n)"
1968$DIG $DIGOPTS +tcp +norec multisigner.test CDS @10.53.0.3 >dig.out.pre.test$n || ret=1
1969grep "status: NOERROR" dig.out.pre.test$n >/dev/null || ret=1
1970grep "ANSWER: 0," dig.out.pre.test$n >/dev/null || ret=1
1971$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 || ret=1
1972server 10.53.0.3 ${PORT}
1973zone multisigner.test
1974update add multisigner.test 3600 IN CDS 14364 13 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
1975send
1976END
1977retry_quiet 5 has_positive_response multisigner.test CDS 10.53.0.3 || ret=1
1978[ $ret = 0 ] || {
1979  echo_i "failed"
1980  status=1
1981}
1982
1983n=$((n + 1))
1984ret=0
1985echo_i "check that CDNSKEY to DNSSEC multisigner zone is allowed ($n)"
1986$DIG $DIGOPTS +tcp +norec multisigner.test CDNSKEY @10.53.0.3 >dig.out.pre.test$n || ret=1
1987grep "status: NOERROR" dig.out.pre.test$n >/dev/null || ret=1
1988grep "ANSWER: 0," dig.out.pre.test$n >/dev/null || ret=1
1989$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 || ret=1
1990server 10.53.0.3 ${PORT}
1991zone multisigner.test
1992update add multisigner.test 3600 IN CDNSKEY 257 3 13 d0NQ5PKmDz6P0B1WPMH9/UKRux/toSFwV2nTJYPA1Cx8pB0sJGTXbVhG U+6gye7VCHDhGIn9CjVfb2RJPW7GnQ==
1993send
1994END
1995retry_quiet 5 has_positive_response multisigner.test CDNSKEY 10.53.0.3 || ret=1
1996[ $ret = 0 ] || {
1997  echo_i "failed"
1998  status=1
1999}
2000
2001n=$((n + 1))
2002ret=0
2003echo_i "check that excessive NSEC3PARAM iterations are rejected by nsupdate ($n)"
2004$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 && ret=1
2005server 10.53.0.3 ${PORT}
2006zone example
2007update add example 0 in NSEC3PARAM 1 0 51 -
2008END
2009grep "NSEC3PARAM has excessive iterations (> 50)" nsupdate.out.test$n >/dev/null || ret=1
2010[ $ret = 0 ] || {
2011  echo_i "failed"
2012  status=1
2013}
2014
2015n=$((n + 1))
2016ret=0
2017echo_i "check nsupdate retries with another server on REFUSED response ($n)"
2018# resolv.conf uses 10.53.0.1 followed by 10.53.0.3; example is only
2019# served by 10.53.0.3, so we should fail over to the second server;
2020# that's what we're testing for. (failure is still expected, however,
2021# because the address lookup for the primary doesn't use the overridden
2022# resolv.conf file).
2023$NSUPDATE -D -C resolv.conf -p ${PORT} <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2024zone example
2025update add a 3600 IN A 1.2.3.4
2026send
2027EOF
2028grep '10.53.0.1.*REFUSED' nsupdate.out.test$n >/dev/null || ret=1
2029grep 'Reply from SOA query' nsupdate.out.test$n >/dev/null || ret=1
2030[ $ret = 0 ] || {
2031  echo_i "failed"
2032  status=1
2033}
2034
2035n=$((n + 1))
2036ret=0
2037echo_i "check that named rejects '_dns' SVCB with missing ALPN ($n)"
2038nextpart ns3/named.run >/dev/null
2039$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 && ret=1
2040server 10.53.0.3 ${PORT}
2041zone example
2042check-svcb no
2043update add _dns.ns.example 0 in SVCB 1 ns.example dohpath=/{?dns}
2044send
2045END
2046grep 'status: REFUSED' nsupdate.out.test$n >/dev/null || ret=1
2047msg="update failed: _dns.ns.example/SVCB: no ALPN (REFUSED)"
2048nextpart ns3/named.run | grep "$msg" >/dev/null || ret=1
2049[ $ret = 0 ] || {
2050  echo_i "failed"
2051  status=1
2052}
2053
2054n=$((n + 1))
2055ret=0
2056echo_i "check that named accepts '_dns' SVCB with missing ALPN (check-svcb no) ($n)"
2057$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 || ret=1
2058server 10.53.0.3 ${PORT}
2059zone relaxed
2060check-svcb no
2061update add _dns.ns.relaxed 0 in SVCB 1 ns.relaxed dohpath=/{?dns}
2062send
2063END
2064$DIG $DIGOPTS +tcp @10.53.0.3 _dns.ns.relaxed SVCB >dig.out.ns3.test$n || ret=1
2065grep '1 ns.relaxed. key7="/{?dns}"' dig.out.ns3.test$n >/dev/null || ret=1
2066[ $ret = 0 ] || {
2067  echo_i "failed"
2068  status=1
2069}
2070
2071n=$((n + 1))
2072ret=0
2073echo_i "check that named rejects '_dns' SVCB with missing DOHPATH ($n)"
2074nextpart ns3/named.run >/dev/null
2075$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 && ret=1
2076server 10.53.0.3 ${PORT}
2077zone example
2078check-svcb no
2079update add _dns.ns.example 0 in SVCB 1 ns.example alpn=h2
2080send
2081END
2082grep 'status: REFUSED' nsupdate.out.test$n >/dev/null || ret=1
2083msg="update failed: _dns.ns.example/SVCB: no DOHPATH (REFUSED)"
2084nextpart ns3/named.run | grep "$msg" >/dev/null || ret=1
2085[ $ret = 0 ] || {
2086  echo_i "failed"
2087  status=1
2088}
2089
2090n=$((n + 1))
2091ret=0
2092echo_i "check that named accepts '_dns' SVCB with missing DOHPATH (check-svcb no) ($n)"
2093$NSUPDATE -d <<END >nsupdate.out.test$n 2>&1 || ret=1
2094server 10.53.0.3 ${PORT}
2095zone relaxed
2096check-svcb no
2097update add _dns.ns.relaxed 0 in SVCB 1 ns.relaxed alpn=h2
2098send
2099END
2100$DIG $DIGOPTS +tcp @10.53.0.3 _dns.ns.relaxed SVCB >dig.out.ns3.test$n || ret=1
2101grep '1 ns.relaxed. alpn="h2"' dig.out.ns3.test$n >/dev/null || ret=1
2102[ $ret = 0 ] || {
2103  echo_i "failed"
2104  status=1
2105}
2106
2107n=$((n + 1))
2108ret=0
2109echo_i "check that update is rejected if query is not allowed ($n)"
2110{
2111  $NSUPDATE -d <<END && ret=1
2112  local 10.53.0.2
2113  server 10.53.0.1 ${PORT}
2114  update add reject.other.nil 3600 IN TXT Whatever
2115  send
2116END
2117} >nsupdate.out.test$n 2>&1
2118grep 'failed: REFUSED' nsupdate.out.test$n >/dev/null || ret=1
2119[ $ret = 0 ] || {
2120  echo_i "failed"
2121  status=1
2122}
2123
2124n=$((n + 1))
2125ret=0
2126echo_i "check that update is rejected if quota is exceeded ($n)"
2127for loop in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
2128  {
2129    $NSUPDATE -4 -l -p ${PORT} -k ns1/session.key >/dev/null 2>&1 <<END
2130  update add txt-$loop.other.nil 3600 IN TXT Whatever
2131  send
2132END
2133  } &
2134done
2135wait_for_log 10 "too many DNS UPDATEs queued" ns1/named.run || ret=1
2136[ $ret = 0 ] || {
2137  echo_i "failed"
2138  status=1
2139}
2140
2141if ! $FEATURETEST --gssapi; then
2142  echo_i "SKIPPED: GSSAPI tests"
2143else
2144  n=$((n + 1))
2145  ret=0
2146  echo_i "check GSS-API TKEY request rcode against a non configured server ($n)"
2147  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2148  export KRB5CCNAME
2149  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2150  gsstsig
2151  realm EXAMPLE.COM
2152  server 10.53.0.7 ${PORT}
2153  zone example.com
2154  send
2155EOF
2156  grep "response to GSS-TSIG query was unsuccessful (REFUSED)" nsupdate.out.test$n >/dev/null || ret=1
2157  [ $ret = 0 ] || {
2158    echo_i "failed"
2159    status=1
2160  }
2161
2162  copy_setports ns7/named2.conf.in ns7/named.conf
2163  rndc_reload ns7 10.53.0.7
2164
2165  n=$((n + 1))
2166  ret=0
2167  echo_i "check krb5-self match ($n)"
2168  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2169  export KRB5CCNAME
2170  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2171  gsstsig
2172  realm EXAMPLE.COM
2173  server 10.53.0.7 ${PORT}
2174  zone example.com
2175  update add machine.example.com 3600 IN A 10.53.0.7
2176  send
2177EOF
2178  $DIG $DIGOPTS +tcp @10.53.0.7 machine.example.com A >dig.out.ns7.test$n || ret=1
2179  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2180  grep "machine.example.com..*A.*10.53.0.7" dig.out.ns7.test$n >/dev/null || ret=1
2181  [ $ret = 0 ] || {
2182    echo_i "failed"
2183    status=1
2184  }
2185
2186  n=$((n + 1))
2187  ret=0
2188  echo_i "check krb5-self no-match ($n)"
2189  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2190  export KRB5CCNAME
2191  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2192  gsstsig
2193  realm EXAMPLE.COM
2194  server 10.53.0.7 ${PORT}
2195  zone example.com
2196  update add foo.example.com 3600 IN A 10.53.0.7
2197  send
2198EOF
2199  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2200  $DIG $DIGOPTS +tcp @10.53.0.7 foo.example.com A >dig.out.ns7.test$n || ret=1
2201  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2202  [ $ret = 0 ] || {
2203    echo_i "failed"
2204    status=1
2205  }
2206
2207  n=$((n + 1))
2208  ret=0
2209  echo_i "check krb5-subdomain match ($n)"
2210  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2211  export KRB5CCNAME
2212  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2213  gsstsig
2214  realm EXAMPLE.COM
2215  server 10.53.0.7 ${PORT}
2216  zone example.com
2217  update add _xxx._tcp.example.com 3600 IN SRV 0 0 0 machine.example.com
2218  send
2219EOF
2220  $DIG $DIGOPTS +tcp @10.53.0.7 _xxx._tcp.example.com SRV >dig.out.ns7.test$n || ret=1
2221  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2222  grep "_xxx._tcp.example.com.*SRV.*0 0 0 machine.example.com" dig.out.ns7.test$n >/dev/null || ret=1
2223  [ $ret = 0 ] || {
2224    echo_i "failed"
2225    status=1
2226  }
2227
2228  n=$((n + 1))
2229  ret=0
2230  echo_i "check krb5-subdomain no-match ($n)"
2231  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2232  export KRB5CCNAME
2233  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2234  gsstsig
2235  realm EXAMPLE.COM
2236  server 10.53.0.7 ${PORT}
2237  zone example.com
2238  update add _xxx._udp.example.com 3600 IN SRV 0 0 0 machine.example.com
2239  send
2240EOF
2241  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2242  $DIG $DIGOPTS +tcp @10.53.0.7 _xxx._udp.example.com SRV >dig.out.ns7.test$n || ret=1
2243  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2244  [ $ret = 0 ] || {
2245    echo_i "failed"
2246    status=1
2247  }
2248
2249  n=$((n + 1))
2250  ret=0
2251  echo_i "check krb5-subdomain-self-rhs match PTR ($n)"
2252  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2253  export KRB5CCNAME
2254  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2255  gsstsig
2256  realm EXAMPLE.COM
2257  server 10.53.0.7 ${PORT}
2258  zone in-addr.arpa
2259  update add 4.3.2.1.in-addr.arpa 3600 IN PTR machine.example.com
2260  send
2261EOF
2262  $DIG $DIGOPTS +tcp @10.53.0.7 4.3.2.1.in-addr.arpa PTR >dig.out.ns7.test$n || ret=1
2263  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2264  grep "4.3.2.1.in-addr.arpa.*PTR.*machine.example.com" dig.out.ns7.test$n >/dev/null || ret=1
2265  [ $ret = 0 ] || {
2266    echo_i "failed"
2267    status=1
2268  }
2269
2270  n=$((n + 1))
2271  ret=0
2272  echo_i "check krb5-subdomain-self-rhs no-match PTR ($n)"
2273  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2274  export KRB5CCNAME
2275  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2276  gsstsig
2277  realm EXAMPLE.COM
2278  server 10.53.0.7 ${PORT}
2279  zone in-addr.arpa
2280  update add 5.3.2.1.in-addr.arpa 3600 IN PTR notme.example.com
2281  send
2282EOF
2283  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2284  $DIG $DIGOPTS +tcp @10.53.0.7 5.3.2.1.in-addr.arpa PTR >dig.out.ns7.test$n || ret=1
2285  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2286  [ $ret = 0 ] || {
2287    echo_i "failed"
2288    status=1
2289  }
2290
2291  n=$((n + 1))
2292  ret=0
2293  echo_i "check krb5-subdomain-self-rhs match SRV ($n)"
2294  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2295  export KRB5CCNAME
2296  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2297  gsstsig
2298  realm EXAMPLE.COM
2299  server 10.53.0.7 ${PORT}
2300  zone example.com
2301  update add _xxx.self-srv.example.com 3600 IN SRV 0 0 0 machine.example.com
2302  send
2303EOF
2304  $DIG $DIGOPTS +tcp @10.53.0.7 _xxx.self-srv.example.com ANY >dig.out.ns7.test$n || ret=1
2305  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2306  grep "_xxx.self-srv.example.com.*SRV.*0 0 0 machine.example.com" dig.out.ns7.test$n >/dev/null || ret=1
2307  [ $ret = 0 ] || {
2308    echo_i "failed"
2309    status=1
2310  }
2311
2312  n=$((n + 1))
2313  ret=0
2314  echo_i "check krb5-subdomain-self-rhs no listed types match (SRV & TXT) ($n)"
2315  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2316  export KRB5CCNAME
2317  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2318  gsstsig
2319  realm EXAMPLE.COM
2320  server 10.53.0.7 ${PORT}
2321  zone example.com
2322  update add _xxx.self-srv-no-type.example.com 3600 IN SRV 0 0 0 machine.example.com
2323  update add _xxx.self-srv-no-type.example.com 3600 IN TXT a txt record
2324  send
2325EOF
2326  $DIG $DIGOPTS +tcp @10.53.0.7 _xxx.self-srv-no-type.example.com ANY >dig.out.ns7.test$n || ret=1
2327  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2328  grep '_xxx.self-srv-no-type.example.com.*SRV.*0 0 0 machine.example.com' dig.out.ns7.test$n >/dev/null || ret=1
2329  grep '_xxx.self-srv-no-type.example.com.*TXT.*"a" "txt" "record"' dig.out.ns7.test$n >/dev/null || ret=1
2330  [ $ret = 0 ] || {
2331    echo_i "failed"
2332    status=1
2333  }
2334
2335  n=$((n + 1))
2336  ret=0
2337  echo_i "check krb5-subdomain-self-rhs no-match RDATA (SRV) ($n)"
2338  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2339  export KRB5CCNAME
2340  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2341  gsstsig
2342  realm EXAMPLE.COM
2343  server 10.53.0.7 ${PORT}
2344  zone example.com
2345  update add _yyy.self-srv.example.com 3600 IN SRV 0 0 0 notme.example.com
2346  send
2347EOF
2348  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2349  $DIG $DIGOPTS +tcp @10.53.0.7 _yyy.self-srv.example.com SRV >dig.out.ns7.test$n || ret=1
2350  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2351  [ $ret = 0 ] || {
2352    echo_i "failed"
2353    status=1
2354  }
2355
2356  n=$((n + 1))
2357  ret=0
2358  echo_i "check krb5-subdomain-self-rhs no-match TYPE (TXT) ($n)"
2359  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2360  export KRB5CCNAME
2361  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2362  gsstsig
2363  realm EXAMPLE.COM
2364  server 10.53.0.7 ${PORT}
2365  zone example.com
2366  update add _yyy.self-srv.example.com 3600 IN TXT a-txt-record
2367  send
2368EOF
2369  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2370  $DIG $DIGOPTS +tcp @10.53.0.7 _yyy.self-srv.example.com TXT >dig.out.ns7.test$n || ret=1
2371  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2372  [ $ret = 0 ] || {
2373    echo_i "failed"
2374    status=1
2375  }
2376
2377  n=$((n + 1))
2378  ret=0
2379  echo_i "check krb5-subdomain-self-rhs delete PTR (matching PTR) ($n)"
2380  $DIG $DIGOPTS +tcp @10.53.0.7 single.ptr.self-ptr.in-addr.arpa PTR >dig.out.ns7.pre.test$n || ret=1
2381  grep "status: NOERROR" dig.out.ns7.pre.test$n >/dev/null || ret=1
2382  grep "ANSWER: 1," dig.out.ns7.pre.test$n >/dev/null || ret=1
2383  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2384  export KRB5CCNAME
2385  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2386  gsstsig
2387  realm EXAMPLE.COM
2388  server 10.53.0.7 ${PORT}
2389  zone in-addr.arpa
2390  update delete single.ptr.self-ptr.in-addr.arpa PTR
2391  send
2392EOF
2393  $DIG $DIGOPTS +tcp @10.53.0.7 single.ptr.self-ptr.in-addr.arpa PTR >dig.out.ns7.test$n || ret=1
2394  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2395  [ $ret = 0 ] || {
2396    echo_i "failed"
2397    status=1
2398  }
2399
2400  n=$((n + 1))
2401  ret=0
2402  echo_i "check krb5-subdomain-self-rhs delete PTR (matching PTR with non-matching PTR) ($n)"
2403  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2404  export KRB5CCNAME
2405  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2406  gsstsig
2407  realm EXAMPLE.COM
2408  server 10.53.0.7 ${PORT}
2409  zone in-addr.arpa
2410  update delete many.ptr.self-ptr.in-addr.arpa PTR
2411  send
2412EOF
2413  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2414  $DIG $DIGOPTS +tcp @10.53.0.7 many.ptr.self-ptr.in-addr.arpa PTR >dig.out.ns7.test$n || ret=1
2415  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2416  grep "ANSWER: 2," dig.out.ns7.test$n >/dev/null || ret=1
2417  [ $ret = 0 ] || {
2418    echo_i "failed"
2419    status=1
2420  }
2421
2422  n=$((n + 1))
2423  ret=0
2424  echo_i "check krb5-subdomain-self-rhs delete ANY (matching PTR) ($n)"
2425  $DIG $DIGOPTS +tcp @10.53.0.7 single.any.self-ptr.in-addr.arpa PTR >dig.out.ns7.pre.test$n || ret=1
2426  grep "status: NOERROR" dig.out.ns7.pre.test$n >/dev/null || ret=1
2427  grep "ANSWER: 1," dig.out.ns7.pre.test$n >/dev/null || ret=1
2428  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2429  export KRB5CCNAME
2430  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2431  gsstsig
2432  realm EXAMPLE.COM
2433  server 10.53.0.7 ${PORT}
2434  zone in-addr.arpa
2435  update delete single.any.self-ptr.in-addr.arpa
2436  send
2437EOF
2438  $DIG $DIGOPTS +tcp @10.53.0.7 single.any.self-ptr.in-addr.arpa PTR >dig.out.ns7.test$n || ret=1
2439  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2440  [ $ret = 0 ] || {
2441    echo_i "failed"
2442    status=1
2443  }
2444
2445  n=$((n + 1))
2446  ret=0
2447  echo_i "check krb5-subdomain-self-rhs delete ANY (matching PTR with non-matching PTR) ($n)"
2448  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2449  export KRB5CCNAME
2450  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2451  gsstsig
2452  realm EXAMPLE.COM
2453  server 10.53.0.7 ${PORT}
2454  zone in-addr.arpa
2455  update delete many.any.self-ptr.in-addr.arpa
2456  send
2457EOF
2458  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2459  $DIG $DIGOPTS +tcp @10.53.0.7 many.any.self-ptr.in-addr.arpa PTR >dig.out.ns7.test$n || ret=1
2460  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2461  grep "ANSWER: 2," dig.out.ns7.test$n >/dev/null || ret=1
2462  [ $ret = 0 ] || {
2463    echo_i "failed"
2464    status=1
2465  }
2466
2467  n=$((n + 1))
2468  ret=0
2469  echo_i "check krb5-subdomain-self-rhs delete SRV (matching SRV) ($n)"
2470  $DIG $DIGOPTS +tcp @10.53.0.7 single.srv.self-srv.example.com SRV >dig.out.ns7.pre.test$n || ret=1
2471  grep "status: NOERROR" dig.out.ns7.pre.test$n >/dev/null || ret=1
2472  grep "ANSWER: 1," dig.out.ns7.pre.test$n >/dev/null || ret=1
2473  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2474  export KRB5CCNAME
2475  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2476  gsstsig
2477  realm EXAMPLE.COM
2478  server 10.53.0.7 ${PORT}
2479  zone example.com
2480  update delete single.srv.self-srv.example.com SRV
2481  send
2482EOF
2483  $DIG $DIGOPTS +tcp @10.53.0.7 single.srv.self-srv.example.com SRV >dig.out.ns7.test$n || ret=1
2484  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2485  [ $ret = 0 ] || {
2486    echo_i "failed"
2487    status=1
2488  }
2489
2490  n=$((n + 1))
2491  ret=0
2492  echo_i "check krb5-subdomain-self-rhs delete SRV (matching SRV with non-matching SRV) ($n)"
2493  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2494  export KRB5CCNAME
2495  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2496  gsstsig
2497  realm EXAMPLE.COM
2498  server 10.53.0.7 ${PORT}
2499  zone example.com
2500  update delete many.srv.self-srv.example.com SRV
2501  send
2502EOF
2503  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2504  $DIG $DIGOPTS +tcp @10.53.0.7 many.srv.self-srv.example.com SRV >dig.out.ns7.test$n || ret=1
2505  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2506  grep "ANSWER: 2," dig.out.ns7.test$n >/dev/null || ret=1
2507  [ $ret = 0 ] || {
2508    echo_i "failed"
2509    status=1
2510  }
2511
2512  n=$((n + 1))
2513  ret=0
2514  echo_i "check krb5-subdomain-self-rhs delete ANY (matching SRV) ($n)"
2515  $DIG $DIGOPTS +tcp @10.53.0.7 single.any.self-srv.example.com SRV >dig.out.ns7.pre.test$n || ret=1
2516  grep "status: NOERROR" dig.out.ns7.pre.test$n >/dev/null || ret=1
2517  grep "ANSWER: 1," dig.out.ns7.pre.test$n >/dev/null || ret=1
2518  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2519  export KRB5CCNAME
2520  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2521  gsstsig
2522  realm EXAMPLE.COM
2523  server 10.53.0.7 ${PORT}
2524  zone example.com
2525  update delete single.any.self-srv.example.com
2526  send
2527EOF
2528  $DIG $DIGOPTS +tcp @10.53.0.7 single.any.self-srv.example.com SRV >dig.out.ns7.test$n || ret=1
2529  grep "status: NXDOMAIN" dig.out.ns7.test$n >/dev/null || ret=1
2530  [ $ret = 0 ] || {
2531    echo_i "failed"
2532    status=1
2533  }
2534
2535  n=$((n + 1))
2536  ret=0
2537  echo_i "check krb5-subdomain-self-rhs delete ANY (matching SRV with non-matching SRV) ($n)"
2538  KRB5CCNAME="FILE:$(pwd)/ns7/machine.ccache"
2539  export KRB5CCNAME
2540  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2541  gsstsig
2542  realm EXAMPLE.COM
2543  server 10.53.0.7 ${PORT}
2544  zone example.com
2545  update delete many.any.self-srv.example.com
2546  send
2547EOF
2548  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2549  $DIG $DIGOPTS +tcp @10.53.0.7 many.any.self-srv.example.com SRV >dig.out.ns7.test$n || ret=1
2550  grep "status: NOERROR" dig.out.ns7.test$n >/dev/null || ret=1
2551  grep "ANSWER: 2," dig.out.ns7.test$n >/dev/null || ret=1
2552  [ $ret = 0 ] || {
2553    echo_i "failed"
2554    status=1
2555  }
2556
2557  n=$((n + 1))
2558  ret=0
2559  echo_i "check krb5-selfsub match ($n)"
2560  KRB5CCNAME="FILE:$(pwd)/ns8/machine.ccache"
2561  export KRB5CCNAME
2562  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2563  gsstsig
2564  realm EXAMPLE.COM
2565  server 10.53.0.8 ${PORT}
2566  zone example.com
2567  update add xxx.machine.example.com 3600 IN A 10.53.0.8
2568  send
2569EOF
2570  $DIG $DIGOPTS +tcp @10.53.0.8 xxx.machine.example.com A >dig.out.ns8.test$n || ret=1
2571  grep "status: NOERROR" dig.out.ns8.test$n >/dev/null || ret=1
2572  grep "xxx.machine.example.com..*A.*10.53.0.8" dig.out.ns8.test$n >/dev/null || ret=1
2573  [ $ret = 0 ] || {
2574    echo_i "failed"
2575    status=1
2576  }
2577
2578  n=$((n + 1))
2579  ret=0
2580  echo_i "check krb5-selfsub no-match ($n)"
2581  KRB5CCNAME="FILE:$(pwd)/ns8/machine.ccache"
2582  export KRB5CCNAME
2583  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2584  gsstsig
2585  realm EXAMPLE.COM
2586  server 10.53.0.8 ${PORT}
2587  zone example.com
2588  update add foo.example.com 3600 IN A 10.53.0.8
2589  send
2590EOF
2591  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2592  $DIG $DIGOPTS +tcp @10.53.0.8 foo.example.com A >dig.out.ns8.test$n || ret=1
2593  grep "status: NXDOMAIN" dig.out.ns8.test$n >/dev/null || ret=1
2594  [ $ret = 0 ] || {
2595    echo_i "failed"
2596    status=1
2597  }
2598
2599  n=$((n + 1))
2600  ret=0
2601  echo_i "check ms-self match ($n)"
2602  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
2603  export KRB5CCNAME
2604  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2605  gsstsig
2606  realm EXAMPLE.COM
2607  server 10.53.0.9 ${PORT}
2608  zone example.com
2609  update add machine.example.com 3600 IN A 10.53.0.9
2610  send
2611EOF
2612  $DIG $DIGOPTS +tcp @10.53.0.9 machine.example.com A >dig.out.ns9.test$n || ret=1
2613  grep "status: NOERROR" dig.out.ns9.test$n >/dev/null || ret=1
2614  grep "machine.example.com..*A.*10.53.0.9" dig.out.ns9.test$n >/dev/null || ret=1
2615  [ $ret = 0 ] || {
2616    echo_i "failed"
2617    status=1
2618  }
2619
2620  n=$((n + 1))
2621  ret=0
2622  echo_i "check ms-self no-match ($n)"
2623  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
2624  export KRB5CCNAME
2625  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2626  gsstsig
2627  realm EXAMPLE.COM
2628  server 10.53.0.9 ${PORT}
2629  zone example.com
2630  update add foo.example.com 3600 IN A 10.53.0.9
2631  send
2632EOF
2633  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2634  $DIG $DIGOPTS +tcp @10.53.0.9 foo.example.com A >dig.out.ns9.test$n || ret=1
2635  grep "status: NXDOMAIN" dig.out.ns9.test$n >/dev/null || ret=1
2636  [ $ret = 0 ] || {
2637    echo_i "failed"
2638    status=1
2639  }
2640
2641  n=$((n + 1))
2642  ret=0
2643  echo_i "check ms-subdomain match ($n)"
2644  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
2645  export KRB5CCNAME
2646  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2647  gsstsig
2648  realm EXAMPLE.COM
2649  server 10.53.0.9 ${PORT}
2650  zone example.com
2651  update add _xxx._tcp.example.com 3600 IN SRV 0 0 0 machine.example.com
2652  send
2653EOF
2654  $DIG $DIGOPTS +tcp @10.53.0.9 _xxx._tcp.example.com SRV >dig.out.ns9.test$n || ret=1
2655  grep "status: NOERROR" dig.out.ns9.test$n >/dev/null || ret=1
2656  grep "_xxx._tcp.example.com.*SRV.*0 0 0 machine.example.com" dig.out.ns9.test$n >/dev/null || ret=1
2657  [ $ret = 0 ] || {
2658    echo_i "failed"
2659    status=1
2660  }
2661
2662  n=$((n + 1))
2663  ret=0
2664  echo_i "check ms-subdomain no-match ($n)"
2665  KRB5CCNAME="FILE:$(pwd)/ns9/machine.ccache"
2666  export KRB5CCNAME
2667  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2668  gsstsig
2669  realm EXAMPLE.COM
2670  server 10.53.0.9 ${PORT}
2671  zone example.com
2672  update add _xxx._udp.example.com 3600 IN SRV 0 0 0 machine.example.com
2673  send
2674EOF
2675  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2676  $DIG $DIGOPTS +tcp @10.53.0.9 _xxx._udp.example.com SRV >dig.out.ns9.test$n || ret=1
2677  grep "status: NXDOMAIN" dig.out.ns9.test$n >/dev/null || ret=1
2678  [ $ret = 0 ] || {
2679    echo_i "failed"
2680    status=1
2681  }
2682
2683  n=$((n + 1))
2684  ret=0
2685  echo_i "check ms-subdomain-self-rhs match (PTR) ($n)"
2686  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2687  export KRB5CCNAME
2688  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2689  gsstsig
2690  realm EXAMPLE.COM
2691  server 10.53.0.10 ${PORT}
2692  zone in-addr.arpa
2693  update add 4.3.2.1.in-addr.arpa 3600 IN PTR machine.example.com
2694  send
2695EOF
2696  $DIG $DIGOPTS +tcp @10.53.0.10 4.3.2.1.in-addr.arpa PTR >dig.out.ns10.test$n || ret=1
2697  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2698  grep "4.3.2.1.in-addr.arpa.*PTR.*machine.example.com" dig.out.ns10.test$n >/dev/null || ret=1
2699  [ $ret = 0 ] || {
2700    echo_i "failed"
2701    status=1
2702  }
2703
2704  n=$((n + 1))
2705  ret=0
2706  echo_i "check ms-subdomain-self-rhs no-match (PTR) ($n)"
2707  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2708  export KRB5CCNAME
2709  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2710  gsstsig
2711  realm EXAMPLE.COM
2712  server 10.53.0.10 ${PORT}
2713  zone in-addr.arpa
2714  update add 5.3.2.1.in-addr.arpa 3600 IN PTR notme.example.com
2715  send
2716EOF
2717  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2718  $DIG $DIGOPTS +tcp @10.53.0.10 5.3.2.1.in-addr.arpa PTR >dig.out.ns10.test$n || ret=1
2719  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2720  [ $ret = 0 ] || {
2721    echo_i "failed"
2722    status=1
2723  }
2724
2725  n=$((n + 1))
2726  ret=0
2727  echo_i "check ms-subdomain-self-rhs match (SRV) ($n)"
2728  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2729  export KRB5CCNAME
2730  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2731  gsstsig
2732  realm EXAMPLE.COM
2733  server 10.53.0.10 ${PORT}
2734  zone example.com
2735  update add _xxx.self-srv.example.com 3600 IN SRV 0 0 0 machine.example.com
2736  send
2737EOF
2738  $DIG $DIGOPTS +tcp @10.53.0.10 _xxx.self-srv.example.com SRV >dig.out.ns10.test$n || ret=1
2739  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2740  grep "_xxx.self-srv.example.com.*SRV.*0 0 0 machine.example.com" dig.out.ns10.test$n >/dev/null || ret=1
2741  [ $ret = 0 ] || {
2742    echo_i "failed"
2743    status=1
2744  }
2745
2746  n=$((n + 1))
2747  ret=0
2748  echo_i "check ms-subdomain-self-rhs no-match (SRV) ($n)"
2749  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2750  export KRB5CCNAME
2751  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2752  gsstsig
2753  realm EXAMPLE.COM
2754  server 10.53.0.10 ${PORT}
2755  zone example.com
2756  update add _yyy.self-srv.example.com 3600 IN SRV 0 0 0 notme.example.com
2757  send
2758EOF
2759  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2760  $DIG $DIGOPTS +tcp @10.53.0.10 _yyy.self-srv.example.com SRV >dig.out.ns10.test$n || ret=1
2761  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2762  [ $ret = 0 ] || {
2763    echo_i "failed"
2764    status=1
2765  }
2766
2767  n=$((n + 1))
2768  ret=0
2769  echo_i "check ms-subdomain-self-rhs delete SRV (matching SRV) ($n)"
2770  $DIG $DIGOPTS +tcp @10.53.0.10 single.srv.self-srv.example.com SRV >dig.out.ns10.pre.test$n || ret=1
2771  grep "status: NOERROR" dig.out.ns10.pre.test$n >/dev/null || ret=1
2772  grep "ANSWER: 1," dig.out.ns10.pre.test$n >/dev/null || ret=1
2773  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2774  export KRB5CCNAME
2775  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2776  gsstsig
2777  realm EXAMPLE.COM
2778  server 10.53.0.10 ${PORT}
2779  zone example.com
2780  update delete single.srv.self-srv.example.com SRV
2781  send
2782EOF
2783  $DIG $DIGOPTS +tcp @10.53.0.10 single.srv.self-srv.example.com SRV >dig.out.ns10.test$n || ret=1
2784  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2785  [ $ret = 0 ] || {
2786    echo_i "failed"
2787    status=1
2788  }
2789
2790  n=$((n + 1))
2791  ret=0
2792  echo_i "check ms-subdomain-self-rhs delete SRV (matching SRV with non-matching SRV) ($n)"
2793  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2794  export KRB5CCNAME
2795  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2796  gsstsig
2797  realm EXAMPLE.COM
2798  server 10.53.0.10 ${PORT}
2799  zone example.com
2800  update delete many.srv.self-srv.example.com SRV
2801  send
2802EOF
2803  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2804  $DIG $DIGOPTS +tcp @10.53.0.10 many.srv.self-srv.example.com SRV >dig.out.ns10.test$n || ret=1
2805  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2806  grep "ANSWER: 2," dig.out.ns10.test$n >/dev/null || ret=1
2807  [ $ret = 0 ] || {
2808    echo_i "failed"
2809    status=1
2810  }
2811
2812  n=$((n + 1))
2813  ret=0
2814  echo_i "check ms-subdomain-self-rhs delete PTR (matching PTR) ($n)"
2815  $DIG $DIGOPTS +tcp @10.53.0.10 single.ptr.self-ptr.in-addr.arpa PTR >dig.out.ns10.pre.test$n || ret=1
2816  grep "status: NOERROR" dig.out.ns10.pre.test$n >/dev/null || ret=1
2817  grep "ANSWER: 1," dig.out.ns10.pre.test$n >/dev/null || ret=1
2818  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2819  export KRB5CCNAME
2820  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2821  gsstsig
2822  realm EXAMPLE.COM
2823  server 10.53.0.10 ${PORT}
2824  zone in-addr.arpa
2825  update delete single.ptr.self-ptr.in-addr.arpa PTR
2826  send
2827EOF
2828  $DIG $DIGOPTS +tcp @10.53.0.10 single.ptr.self-ptr.in-addr.arpa PTR >dig.out.ns10.test$n || ret=1
2829  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2830  [ $ret = 0 ] || {
2831    echo_i "failed"
2832    status=1
2833  }
2834
2835  n=$((n + 1))
2836  ret=0
2837  echo_i "check ms-subdomain-self-rhs delete PTR (matching PTR with non-matching PTR) ($n)"
2838  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2839  export KRB5CCNAME
2840  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2841  gsstsig
2842  realm EXAMPLE.COM
2843  server 10.53.0.10 ${PORT}
2844  zone in-addr.arpa
2845  update delete many.ptr.self-ptr.in-addr.arpa PTR
2846  send
2847EOF
2848  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2849  $DIG $DIGOPTS +tcp @10.53.0.10 many.ptr.self-ptr.in-addr.arpa PTR >dig.out.ns10.test$n || ret=1
2850  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2851  grep "ANSWER: 2," dig.out.ns10.test$n >/dev/null || ret=1
2852  [ $ret = 0 ] || {
2853    echo_i "failed"
2854    status=1
2855  }
2856
2857  n=$((n + 1))
2858  ret=0
2859  echo_i "check ms-subdomain-self-rhs delete ANY (matching PTR) ($n)"
2860  $DIG $DIGOPTS +tcp @10.53.0.10 single.any.self-ptr.in-addr.arpa PTR >dig.out.ns10.pre.test$n || ret=1
2861  grep "status: NOERROR" dig.out.ns10.pre.test$n >/dev/null || ret=1
2862  grep "ANSWER: 1," dig.out.ns10.pre.test$n >/dev/null || ret=1
2863  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2864  export KRB5CCNAME
2865  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2866  gsstsig
2867  realm EXAMPLE.COM
2868  server 10.53.0.10 ${PORT}
2869  zone in-addr.arpa
2870  update delete single.any.self-ptr.in-addr.arpa
2871  send
2872EOF
2873  $DIG $DIGOPTS +tcp @10.53.0.10 single.any.self-ptr.in-addr.arpa PTR >dig.out.ns10.test$n || ret=1
2874  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2875  [ $ret = 0 ] || {
2876    echo_i "failed"
2877    status=1
2878  }
2879
2880  n=$((n + 1))
2881  ret=0
2882  echo_i "check ms-subdomain-self-rhs delete ANY (matching PTR with non-matching PTR) ($n)"
2883  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2884  export KRB5CCNAME
2885  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2886  gsstsig
2887  realm EXAMPLE.COM
2888  server 10.53.0.10 ${PORT}
2889  zone in-addr.arpa
2890  update delete many.any.self-ptr.in-addr.arpa
2891  send
2892EOF
2893  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2894  $DIG $DIGOPTS +tcp @10.53.0.10 many.any.self-ptr.in-addr.arpa PTR >dig.out.ns10.test$n || ret=1
2895  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2896  grep "ANSWER: 2," dig.out.ns10.test$n >/dev/null || ret=1
2897  [ $ret = 0 ] || {
2898    echo_i "failed"
2899    status=1
2900  }
2901
2902  n=$((n + 1))
2903  ret=0
2904  echo_i "check ms-subdomain-self-rhs delete ANY (matching SRV) ($n)"
2905  $DIG $DIGOPTS +tcp @10.53.0.10 single.any.self-srv.example.com SRV >dig.out.ns10.pre.test$n || ret=1
2906  grep "status: NOERROR" dig.out.ns10.pre.test$n >/dev/null || ret=1
2907  grep "ANSWER: 1," dig.out.ns10.pre.test$n >/dev/null || ret=1
2908  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2909  export KRB5CCNAME
2910  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2911  gsstsig
2912  realm EXAMPLE.COM
2913  server 10.53.0.10 ${PORT}
2914  zone example.com
2915  update delete single.any.self-srv.example.com
2916  send
2917EOF
2918  $DIG $DIGOPTS +tcp @10.53.0.10 single.any.self-srv.example.com SRV >dig.out.ns10.test$n || ret=1
2919  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2920  [ $ret = 0 ] || {
2921    echo_i "failed"
2922    status=1
2923  }
2924
2925  n=$((n + 1))
2926  ret=0
2927  echo_i "check ms-subdomain-self-rhs delete ANY (matching SRV with non-matching SRV) ($n)"
2928  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2929  export KRB5CCNAME
2930  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2931  gsstsig
2932  realm EXAMPLE.COM
2933  server 10.53.0.10 ${PORT}
2934  zone example.com
2935  update delete many.any.self-srv.example.com
2936  send
2937EOF
2938  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2939  $DIG $DIGOPTS +tcp @10.53.0.10 many.any.self-srv.example.com SRV >dig.out.ns10.test$n || ret=1
2940  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2941  grep "ANSWER: 2," dig.out.ns10.test$n >/dev/null || ret=1
2942  [ $ret = 0 ] || {
2943    echo_i "failed"
2944    status=1
2945  }
2946
2947  n=$((n + 1))
2948  ret=0
2949  echo_i "check ms-selfsub match ($n)"
2950  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2951  export KRB5CCNAME
2952  $NSUPDATE -d <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2953  gsstsig
2954  realm EXAMPLE.COM
2955  server 10.53.0.10 ${PORT}
2956  zone example.com
2957  update add xxx.machine.example.com 3600 IN A 10.53.0.10
2958  send
2959EOF
2960  $DIG $DIGOPTS +tcp @10.53.0.10 xxx.machine.example.com A >dig.out.ns10.test$n || ret=1
2961  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
2962  grep "xxx.machine.example.com..*A.*10.53.0.10" dig.out.ns10.test$n >/dev/null || ret=1
2963  [ $ret = 0 ] || {
2964    echo_i "failed"
2965    status=1
2966  }
2967
2968  n=$((n + 1))
2969  ret=0
2970  echo_i "check ms-selfsub no-match ($n)"
2971  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2972  export KRB5CCNAME
2973  $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 && ret=1
2974  gsstsig
2975  realm EXAMPLE.COM
2976  server 10.53.0.10 ${PORT}
2977  zone example.com
2978  update add foo.example.com 3600 IN A 10.53.0.10
2979  send
2980EOF
2981  grep "update failed: REFUSED" nsupdate.out.test$n >/dev/null || ret=1
2982  $DIG $DIGOPTS +tcp @10.53.0.10 foo.example.com A >dig.out.ns10.test$n || ret=1
2983  grep "status: NXDOMAIN" dig.out.ns10.test$n >/dev/null || ret=1
2984  [ $ret = 0 ] || {
2985    echo_i "failed"
2986    status=1
2987  }
2988
2989  n=$((n + 1))
2990  ret=0
2991  echo_i "check ms-selfsub match using DoT (opportunistic-tls) ($n)"
2992  KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache"
2993  export KRB5CCNAME
2994  $NSUPDATE -d -S -O <<EOF >nsupdate.out.test$n 2>&1 || ret=1
2995  gsstsig
2996  realm EXAMPLE.COM
2997  server 10.53.0.10 ${TLSPORT}
2998  zone example.com
2999  update add dot.machine.example.com 3600 IN A 10.53.0.10
3000  send
3001EOF
3002  $DIG $DIGOPTS +tcp @10.53.0.10 dot.machine.example.com A >dig.out.ns10.test$n || ret=1
3003  grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
3004  grep "dot.machine.example.com..*A.*10.53.0.10" dig.out.ns10.test$n >/dev/null || ret=1
3005  [ $ret = 0 ] || {
3006    echo_i "failed"
3007    status=1
3008  }
3009fi
3010
3011echo_i "exit status: $status"
3012[ $status -eq 0 ] || exit 1
3013