mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-05 00:55:24 +00:00
Merge branch '68-rpz-system-test-fails-intermittently' into 'master'
Prevent rpz system test from wiping out forensic data See merge request isc-projects/bind9!51
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
|||||||
|
4897. [test] Update to rpz system test so that it doesn't recurse.
|
||||||
|
[GL #68]
|
||||||
|
|
||||||
4896. [test] cacheclean system test was not robust. [GL #82]
|
4896. [test] cacheclean system test was not robust. [GL #82]
|
||||||
|
|
||||||
4895. [test] Allow some system tests to run in parallel.
|
4895. [test] Allow some system tests to run in parallel.
|
||||||
|
@@ -21,6 +21,7 @@ while getopts "Dx" c; do
|
|||||||
case $c in
|
case $c in
|
||||||
x) set -x; DEBUG=-x;;
|
x) set -x; DEBUG=-x;;
|
||||||
D) TEST_DNSRPS="-D";;
|
D) TEST_DNSRPS="-D";;
|
||||||
|
N) NOCLEAN=set;;
|
||||||
*) echo "$USAGE" 1>&2; exit 1;;
|
*) echo "$USAGE" 1>&2; exit 1;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
@@ -30,7 +31,7 @@ if test "$#" -ne 0; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$SHELL clean.sh $DEBUG
|
[ ${NOCLEAN:-unset} = unset ] && $SHELL clean.sh $DEBUG
|
||||||
|
|
||||||
# decide whether to test DNSRPS
|
# decide whether to test DNSRPS
|
||||||
# Note that dnsrps.conf and dnsrps-slave.conf are included in named.conf
|
# Note that dnsrps.conf and dnsrps-slave.conf are included in named.conf
|
||||||
@@ -135,6 +136,9 @@ $PERL -e 'for ($cnt = $val = 1; $cnt <= 3000; ++$cnt) {
|
|||||||
cp ns2/bl.tld2.db.in ns2/bl.tld2.db
|
cp ns2/bl.tld2.db.in ns2/bl.tld2.db
|
||||||
cp ns5/empty.db.in ns5/empty.db
|
cp ns5/empty.db.in ns5/empty.db
|
||||||
cp ns5/empty.db.in ns5/policy2.db
|
cp ns5/empty.db.in ns5/policy2.db
|
||||||
|
rm -f ns2/bl.tld2.db.jnl
|
||||||
|
rm -f ns5/empty.db.jnl
|
||||||
|
rm -f cp ns5/policy2.db.jnl
|
||||||
|
|
||||||
# Run dnsrpzd to get the license and prime the static policy zones
|
# Run dnsrpzd to get the license and prime the static policy zones
|
||||||
if test -n "$TEST_DNSRPS"; then
|
if test -n "$TEST_DNSRPS"; then
|
||||||
|
@@ -26,6 +26,7 @@ ns7=$ns.7 # another rewriting resolver
|
|||||||
HAVE_CORE=
|
HAVE_CORE=
|
||||||
|
|
||||||
status=0
|
status=0
|
||||||
|
t=0
|
||||||
|
|
||||||
DEBUG=
|
DEBUG=
|
||||||
SAVE_RESULTS=
|
SAVE_RESULTS=
|
||||||
@@ -60,39 +61,6 @@ comment () {
|
|||||||
DNSRPSCMD=./dnsrps
|
DNSRPSCMD=./dnsrps
|
||||||
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s"
|
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s"
|
||||||
|
|
||||||
# Run the tests twice, first without DNSRPS and then with if it is available
|
|
||||||
if [ -z "$DNSRPS_TEST_MODE" ]; then
|
|
||||||
if [ -e dnsrps-only ]; then
|
|
||||||
echo "I:'dnsrps-only' found: skipping native RPZ sub-test"
|
|
||||||
else
|
|
||||||
echo "I:running native RPZ sub-test"
|
|
||||||
$SHELL ./$0 -D1 $ARGS || status=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e dnsrps-off ]; then
|
|
||||||
echo "I:'dnsrps-off' found: skipping DNSRPS sub-test"
|
|
||||||
else
|
|
||||||
echo "I:attempting to configure servers with DNSRPS..."
|
|
||||||
$PERL $SYSTEMTESTTOP/stop.pl .
|
|
||||||
$SHELL ./setup.sh -D $DEBUG
|
|
||||||
sed -n 's/^## /I:/p' dnsrps.conf
|
|
||||||
if grep '^#fail' dnsrps.conf >/dev/null; then
|
|
||||||
echo "I:exit status: 1"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if test -z "`grep '^#skip' dnsrps.conf`"; then
|
|
||||||
echo "I:running DNSRPS sub-test"
|
|
||||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart .
|
|
||||||
$SHELL ./$0 $ARGS -D2 || status=1
|
|
||||||
else
|
|
||||||
echo "I:DNSRPS sub-test skipped"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "I:exit status: $status"
|
|
||||||
exit $status
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -x $DNSRPSCMD; then
|
if test -x $DNSRPSCMD; then
|
||||||
# speed up the many delays for dnsrpzd by waiting only 0.1 seconds
|
# speed up the many delays for dnsrpzd by waiting only 0.1 seconds
|
||||||
WAIT_CMD="$DNSRPSCMD -w 0.1"
|
WAIT_CMD="$DNSRPSCMD -w 0.1"
|
||||||
@@ -159,7 +127,7 @@ get_sn_fast () {
|
|||||||
# $1=domain $2=DNS server IP address
|
# $1=domain $2=DNS server IP address
|
||||||
FZONES=`sed -n -e 's/^zone "\(.*\)".*\(10.53.0..\).*/Z=\1;M=\2/p' dnsrpzd.conf`
|
FZONES=`sed -n -e 's/^zone "\(.*\)".*\(10.53.0..\).*/Z=\1;M=\2/p' dnsrpzd.conf`
|
||||||
dnsrps_loaded() {
|
dnsrps_loaded() {
|
||||||
test "$DNSRPS_TEST_MODE" = 2 || return
|
test "$DNSRPS_TEST_MODE" = dnsrps || return
|
||||||
n=0
|
n=0
|
||||||
for V in $FZONES; do
|
for V in $FZONES; do
|
||||||
eval "$V"
|
eval "$V"
|
||||||
@@ -186,7 +154,7 @@ dnsrps_loaded() {
|
|||||||
ck_soa() {
|
ck_soa() {
|
||||||
n=0
|
n=0
|
||||||
while true; do
|
while true; do
|
||||||
if test "$DNSRPS_TEST_MODE" = 2; then
|
if test "$DNSRPS_TEST_MODE" = dnsrps; then
|
||||||
get_sn_fast "$2"
|
get_sn_fast "$2"
|
||||||
test "$RSN" -eq "$1" && return
|
test "$RSN" -eq "$1" && return
|
||||||
else
|
else
|
||||||
@@ -291,7 +259,8 @@ ckstatsrange () {
|
|||||||
# $1=message $2=optional test file name
|
# $1=message $2=optional test file name
|
||||||
start_group () {
|
start_group () {
|
||||||
ret=0
|
ret=0
|
||||||
test -n "$1" && date "+I:${TS}checking $1"
|
t=`expr $t + 1`
|
||||||
|
test -n "$1" && date "+I:${TS}checking $1 (${t})"
|
||||||
TEST_FILE=$2
|
TEST_FILE=$2
|
||||||
if test -n "$TEST_FILE"; then
|
if test -n "$TEST_FILE"; then
|
||||||
GROUP_NM="-$TEST_FILE"
|
GROUP_NM="-$TEST_FILE"
|
||||||
@@ -423,228 +392,271 @@ drop () {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsd() {
|
||||||
|
$NSUPDATE -p 5300 << EOF
|
||||||
|
server $1
|
||||||
|
ttl 300
|
||||||
|
update $2 $3 IN CNAME .
|
||||||
|
update $2 $4 IN CNAME .
|
||||||
|
send
|
||||||
|
EOF
|
||||||
|
sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
# make prototype files to check against rewritten results
|
# make prototype files to check against rewritten results
|
||||||
digcmd nonexistent @$ns2 >proto.nxdomain
|
digcmd nonexistent @$ns2 >proto.nxdomain
|
||||||
digcmd txt-only.tld2 @$ns2 >proto.nodata
|
digcmd txt-only.tld2 @$ns2 >proto.nodata
|
||||||
|
|
||||||
start_group "QNAME rewrites" test1
|
case "$DNSRPS_TEST_MODE" in
|
||||||
nochange . # 1 do not crash or rewrite root
|
''|native|dnsrps);;
|
||||||
nxdomain a0-1.tld2 # 2
|
*)
|
||||||
nodata a3-1.tld2 # 3
|
echo "bad test mode'${DNSRPS_TEST_MODE}' should be 'native' or 'dnsrps'"
|
||||||
nodata a3-2.tld2 # 4 nodata at DNAME itself
|
exit 1
|
||||||
nochange sub.a3-2.tld2 # 5 miss where DNAME might work
|
;;
|
||||||
nxdomain a4-2.tld2 # 6 rewrite based on CNAME target
|
esac
|
||||||
nxdomain a4-2-cname.tld2 # 7
|
|
||||||
nodata a4-3-cname.tld2 # 8
|
for mode in ${DNSRPS_TEST_MODE:-native dnsrps}
|
||||||
addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement
|
do
|
||||||
addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard
|
status=0
|
||||||
addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME
|
case ${mode} in
|
||||||
addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain
|
native)
|
||||||
addr 127.4.4.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone
|
if [ ${DNSRPS_TEST_MODE:-unset} = unset -a -e dnsrps-only ] ; then
|
||||||
nochange a6-1.tld2 # 14
|
echo "I:'dnsrps-only' found: skipping native RPZ sub-test"
|
||||||
addr 127.6.2.1 a6-2.tld2 # 15
|
continue
|
||||||
addr 56.56.56.56 a3-6.tld2 # 16 wildcard CNAME
|
fi
|
||||||
addr 57.57.57.57 a3-7.sub1.tld2 # 17 wildcard CNAME
|
;;
|
||||||
addr 127.0.0.16 a4-5-cname3.tld2 # 18 CNAME chain
|
dnsrps)
|
||||||
addr 127.0.0.17 a4-6-cname3.tld2 # 19 stop short in CNAME chain
|
if [ ${DNSRPS_TEST_MODE:-unset} = unset -a -e dnsrps-off ] ; then
|
||||||
nochange a5-2.tld2 +norecurse # 20 check that RD=1 is required
|
echo "I:'dnsrps-off' found: skipping DNSRPS sub-test"
|
||||||
nochange a5-3.tld2 +norecurse # 21
|
continue
|
||||||
nochange a5-4.tld2 +norecurse # 22
|
fi
|
||||||
nochange sub.a5-4.tld2 +norecurse # 23
|
if grep '^#skip' dnsrps.conf > /dev/null ; then
|
||||||
nxdomain c1.crash2.tld3 # 24 assert in rbtdb.c
|
echo "I:DNSRPS sub-test skipped"
|
||||||
nxdomain a0-1.tld2 +dnssec # 25 simple DO=1 without signatures
|
continue
|
||||||
nxdomain a0-1.tld2s +nodnssec # 26 simple DO=0 with signatures
|
fi
|
||||||
nochange a0-1.tld2s +dnssec # 27 simple DO=1 with signatures
|
$PERL $SYSTEMTESTTOP/stop.pl .
|
||||||
nxdomain a0-1s-cname.tld2s +dnssec # 28 DNSSEC too early in CNAME chain
|
$SHELL ./setup.sh -N -D $DEBUG
|
||||||
nochange a0-1-scname.tld2 +dnssec # 29 DNSSEC on target in CNAME chain
|
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart .
|
||||||
nochange a0-1.tld2s srv +auth +dnssec # 30 no write for DNSSEC and no record
|
;;
|
||||||
nxdomain a0-1.tld2s srv +nodnssec # 31
|
esac
|
||||||
drop a3-8.tld2 any # 32 drop
|
sed -n 's/^## /I:/p' dnsrps.conf
|
||||||
nochange tcp a3-9.tld2 # 33 tcp-only
|
|
||||||
here x.servfail <<'EOF' # 34 qname-wait-recurse yes
|
start_group "QNAME rewrites" test1
|
||||||
|
nochange . # 1 do not crash or rewrite root
|
||||||
|
nxdomain a0-1.tld2 # 2
|
||||||
|
nodata a3-1.tld2 # 3
|
||||||
|
nodata a3-2.tld2 # 4 nodata at DNAME itself
|
||||||
|
nochange sub.a3-2.tld2 # 5 miss where DNAME might work
|
||||||
|
nxdomain a4-2.tld2 # 6 rewrite based on CNAME target
|
||||||
|
nxdomain a4-2-cname.tld2 # 7
|
||||||
|
nodata a4-3-cname.tld2 # 8
|
||||||
|
addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement
|
||||||
|
addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard
|
||||||
|
addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME
|
||||||
|
addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain
|
||||||
|
addr 127.4.4.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone
|
||||||
|
nochange a6-1.tld2 # 14
|
||||||
|
addr 127.6.2.1 a6-2.tld2 # 15
|
||||||
|
addr 56.56.56.56 a3-6.tld2 # 16 wildcard CNAME
|
||||||
|
addr 57.57.57.57 a3-7.sub1.tld2 # 17 wildcard CNAME
|
||||||
|
addr 127.0.0.16 a4-5-cname3.tld2 # 18 CNAME chain
|
||||||
|
addr 127.0.0.17 a4-6-cname3.tld2 # 19 stop short in CNAME chain
|
||||||
|
nochange a5-2.tld2 +norecurse # 20 check that RD=1 is required
|
||||||
|
nochange a5-3.tld2 +norecurse # 21
|
||||||
|
nochange a5-4.tld2 +norecurse # 22
|
||||||
|
nochange sub.a5-4.tld2 +norecurse # 23
|
||||||
|
nxdomain c1.crash2.tld3 # 24 assert in rbtdb.c
|
||||||
|
nxdomain a0-1.tld2 +dnssec # 25 simple DO=1 without signatures
|
||||||
|
nxdomain a0-1.tld2s +nodnssec # 26 simple DO=0 with signatures
|
||||||
|
nochange a0-1.tld2s +dnssec # 27 simple DO=1 with signatures
|
||||||
|
nxdomain a0-1s-cname.tld2s +dnssec # 28 DNSSEC too early in CNAME chain
|
||||||
|
nochange a0-1-scname.tld2 +dnssec # 29 DNSSEC on target in CNAME chain
|
||||||
|
nochange a0-1.tld2s srv +auth +dnssec # 30 no write for DNSSEC and no record
|
||||||
|
nxdomain a0-1.tld2s srv +nodnssec # 31
|
||||||
|
drop a3-8.tld2 any # 32 drop
|
||||||
|
nochange tcp a3-9.tld2 # 33 tcp-only
|
||||||
|
here x.servfail <<'EOF' # 34 qname-wait-recurse yes
|
||||||
;; status: SERVFAIL, x
|
;; status: SERVFAIL, x
|
||||||
EOF
|
EOF
|
||||||
addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no
|
addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no
|
||||||
end_group
|
end_group
|
||||||
ckstats $ns3 test1 ns3 22
|
ckstats $ns3 test1 ns3 22
|
||||||
ckstats $ns5 test1 ns5 1
|
ckstats $ns5 test1 ns5 1
|
||||||
ckstats $ns6 test1 ns6 0
|
ckstats $ns6 test1 ns6 0
|
||||||
|
|
||||||
start_group "NXDOMAIN/NODATA action on QNAME trigger" test1
|
start_group "NXDOMAIN/NODATA action on QNAME trigger" test1
|
||||||
nxdomain a0-1.tld2 @$ns6 # 1
|
nxdomain a0-1.tld2 @$ns6 # 1
|
||||||
nodata a3-1.tld2 @$ns6 # 2
|
nodata a3-1.tld2 @$ns6 # 2
|
||||||
nodata a3-2.tld2 @$ns6 # 3 nodata at DNAME itself
|
nodata a3-2.tld2 @$ns6 # 3 nodata at DNAME itself
|
||||||
nxdomain a4-2.tld2 @$ns6 # 4 rewrite based on CNAME target
|
nxdomain a4-2.tld2 @$ns6 # 4 rewrite based on CNAME target
|
||||||
nxdomain a4-2-cname.tld2 @$ns6 # 5
|
nxdomain a4-2-cname.tld2 @$ns6 # 5
|
||||||
nodata a4-3-cname.tld2 @$ns6 # 6
|
nodata a4-3-cname.tld2 @$ns6 # 6
|
||||||
addr 12.12.12.12 "a4-1.sub1.tld2 @$ns6" # 7 A replacement
|
addr 12.12.12.12 "a4-1.sub1.tld2 @$ns6" # 7 A replacement
|
||||||
addr 12.12.12.12 "a4-1.sub2.tld2 @$ns6" # 8 A replacement with wildcard
|
addr 12.12.12.12 "a4-1.sub2.tld2 @$ns6" # 8 A replacement with wildcard
|
||||||
addr 127.4.4.1 "a4-4.tld2 @$ns6" # 9 prefer 1st conflicting QNAME zone
|
addr 127.4.4.1 "a4-4.tld2 @$ns6" # 9 prefer 1st conflicting QNAME zone
|
||||||
addr 12.12.12.12 "nxc1.sub1.tld2 @$ns6" # 10 replace NXDOMAIN w/ CNAME
|
addr 12.12.12.12 "nxc1.sub1.tld2 @$ns6" # 10 replace NXDOMAIN w/ CNAME
|
||||||
addr 12.12.12.12 "nxc2.sub1.tld2 @$ns6" # 11 replace NXDOMAIN w/ CNAME chain
|
addr 12.12.12.12 "nxc2.sub1.tld2 @$ns6" # 11 replace NXDOMAIN w/ CNAME chain
|
||||||
addr 127.6.2.1 "a6-2.tld2 @$ns6" # 12
|
addr 127.6.2.1 "a6-2.tld2 @$ns6" # 12
|
||||||
addr 56.56.56.56 "a3-6.tld2 @$ns6" # 13 wildcard CNAME
|
addr 56.56.56.56 "a3-6.tld2 @$ns6" # 13 wildcard CNAME
|
||||||
addr 57.57.57.57 "a3-7.sub1.tld2 @$ns6" # 14 wildcard CNAME
|
addr 57.57.57.57 "a3-7.sub1.tld2 @$ns6" # 14 wildcard CNAME
|
||||||
addr 127.0.0.16 "a4-5-cname3.tld2 @$ns6" # 15 CNAME chain
|
addr 127.0.0.16 "a4-5-cname3.tld2 @$ns6" # 15 CNAME chain
|
||||||
addr 127.0.0.17 "a4-6-cname3.tld2 @$ns6" # 16 stop short in CNAME chain
|
addr 127.0.0.17 "a4-6-cname3.tld2 @$ns6" # 16 stop short in CNAME chain
|
||||||
nxdomain c1.crash2.tld3 @$ns6 # 17 assert in rbtdb.c
|
nxdomain c1.crash2.tld3 @$ns6 # 17 assert in rbtdb.c
|
||||||
nxdomain a0-1.tld2 +dnssec @$ns6 # 18 simple DO=1 without sigs
|
nxdomain a0-1.tld2 +dnssec @$ns6 # 18 simple DO=1 without sigs
|
||||||
nxdomain a0-1s-cname.tld2s +dnssec @$ns6 # 19
|
nxdomain a0-1s-cname.tld2s +dnssec @$ns6 # 19
|
||||||
drop a3-8.tld2 any @$ns6 # 20 drop
|
drop a3-8.tld2 any @$ns6 # 20 drop
|
||||||
end_group
|
end_group
|
||||||
ckstatsrange $ns3 test1 ns3 22 30
|
ckstatsrange $ns3 test1 ns3 22 30
|
||||||
ckstats $ns5 test1 ns5 0
|
ckstats $ns5 test1 ns5 0
|
||||||
ckstats $ns6 test1 ns6 0
|
ckstats $ns6 test1 ns6 0
|
||||||
|
|
||||||
start_group "IP rewrites" test2
|
start_group "IP rewrites" test2
|
||||||
nodata a3-1.tld2 # 1 NODATA
|
nodata a3-1.tld2 # 1 NODATA
|
||||||
nochange a3-2.tld2 # 2 no policy record so no change
|
nochange a3-2.tld2 # 2 no policy record so no change
|
||||||
nochange a4-1.tld2 # 3 obsolete PASSTHRU record style
|
nochange a4-1.tld2 # 3 obsolete PASSTHRU record style
|
||||||
nxdomain a4-2.tld2 # 4
|
nxdomain a4-2.tld2 # 4
|
||||||
nochange a4-2.tld2 -taaaa # 5 no A => no policy rewrite
|
nochange a4-2.tld2 -taaaa # 5 no A => no policy rewrite
|
||||||
nochange a4-2.tld2 -ttxt # 6 no A => no policy rewrite
|
nochange a4-2.tld2 -ttxt # 6 no A => no policy rewrite
|
||||||
nxdomain a4-2.tld2 -tany # 7 no A => no policy rewrite
|
nxdomain a4-2.tld2 -tany # 7 no A => no policy rewrite
|
||||||
nodata a4-3.tld2 # 8
|
nodata a4-3.tld2 # 8
|
||||||
nxdomain a3-1.tld2 -taaaa # 9 IPv6 policy
|
nxdomain a3-1.tld2 -taaaa # 9 IPv6 policy
|
||||||
nochange a4-1-aaaa.tld2 -taaaa # 10
|
nochange a4-1-aaaa.tld2 -taaaa # 10
|
||||||
addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address
|
addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address
|
||||||
addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone
|
addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone
|
||||||
nochange a5-4.tld2 +norecurse # 13 check that RD=1 is required for #14
|
nochange a5-4.tld2 +norecurse # 13 check that RD=1 is required for #14
|
||||||
addr 14.14.14.14 a5-4.tld2 # 14 prefer QNAME to IP
|
addr 14.14.14.14 a5-4.tld2 # 14 prefer QNAME to IP
|
||||||
nochange a4-4.tld2 # 15 PASSTHRU
|
nochange a4-4.tld2 # 15 PASSTHRU
|
||||||
nxdomain c2.crash2.tld3 # 16 assert in rbtdb.c
|
nxdomain c2.crash2.tld3 # 16 assert in rbtdb.c
|
||||||
addr 127.0.0.17 "a4-4.tld2 -b $ns1" # 17 client-IP address trigger
|
addr 127.0.0.17 "a4-4.tld2 -b $ns1" # 17 client-IP address trigger
|
||||||
nxdomain a7-1.tld2 # 18 slave policy zone (RT34450)
|
nxdomain a7-1.tld2 # 18 slave policy zone (RT34450)
|
||||||
cp ns2/blv2.tld2.db.in ns2/bl.tld2.db
|
cp ns2/blv2.tld2.db.in ns2/bl.tld2.db
|
||||||
$RNDCCMD $ns2 reload bl.tld2
|
$RNDCCMD $ns2 reload bl.tld2
|
||||||
ck_soa 2 bl.tld2 $ns3
|
ck_soa 2 bl.tld2 $ns3
|
||||||
nochange a7-1.tld2 # 19 PASSTHRU
|
nochange a7-1.tld2 # 19 PASSTHRU
|
||||||
sleep 1 # ensure that a clock tick has occured so that named will do the reload
|
sleep 1 # ensure that a clock tick has occured so that named will do the reload
|
||||||
cp ns2/blv3.tld2.db.in ns2/bl.tld2.db
|
cp ns2/blv3.tld2.db.in ns2/bl.tld2.db
|
||||||
$RNDCCMD $ns2 reload bl.tld2
|
$RNDCCMD $ns2 reload bl.tld2
|
||||||
ck_soa 3 bl.tld2 $ns3
|
ck_soa 3 bl.tld2 $ns3
|
||||||
nxdomain a7-1.tld2 # 20 slave policy zone (RT34450)
|
nxdomain a7-1.tld2 # 20 slave policy zone (RT34450)
|
||||||
end_group
|
end_group
|
||||||
ckstats $ns3 test2 ns3 12
|
ckstats $ns3 test2 ns3 12
|
||||||
|
|
||||||
# check that IP addresses for previous group were deleted from the radix tree
|
# check that IP addresses for previous group were deleted from the radix tree
|
||||||
start_group "radix tree deletions"
|
start_group "radix tree deletions"
|
||||||
nochange a3-1.tld2
|
nochange a3-1.tld2
|
||||||
nochange a3-2.tld2
|
nochange a3-2.tld2
|
||||||
nochange a4-1.tld2
|
nochange a4-1.tld2
|
||||||
nochange a4-2.tld2
|
nochange a4-2.tld2
|
||||||
nochange a4-2.tld2 -taaaa
|
nochange a4-2.tld2 -taaaa
|
||||||
nochange a4-2.tld2 -ttxt
|
nochange a4-2.tld2 -ttxt
|
||||||
nochange a4-2.tld2 -tany
|
nochange a4-2.tld2 -tany
|
||||||
nochange a4-3.tld2
|
nochange a4-3.tld2
|
||||||
nochange a3-1.tld2 -tAAAA
|
nochange a3-1.tld2 -tAAAA
|
||||||
nochange a4-1-aaaa.tld2 -tAAAA
|
nochange a4-1-aaaa.tld2 -tAAAA
|
||||||
nochange a5-1-2.tld2
|
nochange a5-1-2.tld2
|
||||||
end_group
|
end_group
|
||||||
ckstats $ns3 'radix tree deletions' ns3 0
|
ckstats $ns3 'radix tree deletions' ns3 0
|
||||||
|
|
||||||
# these tests assume "min-ns-dots 0"
|
# these tests assume "min-ns-dots 0"
|
||||||
start_group "NSDNAME rewrites" test3
|
start_group "NSDNAME rewrites" test3
|
||||||
nochange a3-1.tld2 # 1
|
nochange a3-1.tld2 # 1
|
||||||
nochange a3-1.tld2 +dnssec # 2 this once caused problems
|
nochange a3-1.tld2 +dnssec # 2 this once caused problems
|
||||||
nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME
|
nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME
|
||||||
nxdomain a3-1.subsub.sub1.tld2
|
nxdomain a3-1.subsub.sub1.tld2
|
||||||
nxdomain a3-1.subsub.sub1.tld2 -tany
|
nxdomain a3-1.subsub.sub1.tld2 -tany
|
||||||
addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2
|
addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2
|
||||||
nochange a3-2.tld2. # 7 exempt rewrite by name
|
nochange a3-2.tld2. # 7 exempt rewrite by name
|
||||||
nochange a0-1.tld2. # 8 exempt rewrite by address block
|
nochange a0-1.tld2. # 8 exempt rewrite by address block
|
||||||
addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME
|
addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME
|
||||||
addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME
|
addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME
|
||||||
addr 127.0.0.2 a3-1.subsub.sub3.tld2
|
addr 127.0.0.2 a3-1.subsub.sub3.tld2
|
||||||
nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash
|
nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash
|
||||||
if [ "$DNSRPS_TEST_MODE" = 2 ]; then
|
if [ "$DNSRPS_TEST_MODE" = dnsrps ]; then
|
||||||
addr 12.12.12.12 as-ns.tld5. # 13 qname-as-ns
|
addr 12.12.12.12 as-ns.tld5. # 13 qname-as-ns
|
||||||
fi
|
fi
|
||||||
end_group
|
end_group
|
||||||
if [ "$DNSRPS_TEST_MODE" = 2 ]; then
|
if [ "$DNSRPS_TEST_MODE" = dnsrps ]; then
|
||||||
ckstats $ns3 test3 ns3 8
|
ckstats $ns3 test3 ns3 8
|
||||||
else
|
else
|
||||||
ckstats $ns3 test3 ns3 7
|
ckstats $ns3 test3 ns3 7
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# these tests assume "min-ns-dots 0"
|
# these tests assume "min-ns-dots 0"
|
||||||
start_group "NSIP rewrites" test4
|
start_group "NSIP rewrites" test4
|
||||||
nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2
|
nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2
|
||||||
nochange a3-2.tld2. # 2 exempt rewrite by name
|
nochange a3-2.tld2. # 2 exempt rewrite by name
|
||||||
nochange a0-1.tld2. # 3 exempt rewrite by address block
|
nochange a0-1.tld2. # 3 exempt rewrite by address block
|
||||||
nochange a3-1.tld4 # 4 different NS IP address
|
nochange a3-1.tld4 # 4 different NS IP address
|
||||||
if [ "$DNSRPS_TEST_MODE" = 2 ]; then
|
if [ "$DNSRPS_TEST_MODE" = dnsrps ]; then
|
||||||
addr 12.12.12.12 as-ns.tld5. # 5 ip-as-ns
|
addr 12.12.12.12 as-ns.tld5. # 5 ip-as-ns
|
||||||
fi
|
fi
|
||||||
end_group
|
end_group
|
||||||
|
|
||||||
start_group "walled garden NSIP rewrites" test4a
|
start_group "walled garden NSIP rewrites" test4a
|
||||||
addr 41.41.41.41 a3-1.tld2 # 1 walled garden for all of tld2
|
addr 41.41.41.41 a3-1.tld2 # 1 walled garden for all of tld2
|
||||||
addr 2041::41 'a3-1.tld2 AAAA' # 2 walled garden for all of tld2
|
addr 2041::41 'a3-1.tld2 AAAA' # 2 walled garden for all of tld2
|
||||||
here a3-1.tld2 TXT <<'EOF' # 3 text message for all of tld2
|
here a3-1.tld2 TXT <<'EOF' # 3 text message for all of tld2
|
||||||
;; status: NOERROR, x
|
;; status: NOERROR, x
|
||||||
a3-1.tld2. x IN TXT "NSIP walled garden"
|
a3-1.tld2. x IN TXT "NSIP walled garden"
|
||||||
EOF
|
EOF
|
||||||
end_group
|
end_group
|
||||||
if [ "$DNSRPS_TEST_MODE" = 2 ]; then
|
if [ "$DNSRPS_TEST_MODE" = dnsrps ]; then
|
||||||
ckstats $ns3 test4 ns3 5
|
ckstats $ns3 test4 ns3 5
|
||||||
else
|
else
|
||||||
ckstats $ns3 test4 ns3 4
|
ckstats $ns3 test4 ns3 4
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# policies in ./test5 overridden by response-policy{} in ns3/named.conf
|
# policies in ./test5 overridden by response-policy{} in ns3/named.conf
|
||||||
# and in ns5/named.conf
|
# and in ns5/named.conf
|
||||||
start_group "policy overrides" test5
|
start_group "policy overrides" test5
|
||||||
addr 127.0.0.1 a3-1.tld2 # 1 bl-given
|
addr 127.0.0.1 a3-1.tld2 # 1 bl-given
|
||||||
nochange a3-2.tld2 # 2 bl-passthru
|
nochange a3-2.tld2 # 2 bl-passthru
|
||||||
nochange a3-3.tld2 # 3 bl-no-op obsolete for passthru
|
nochange a3-3.tld2 # 3 bl-no-op obsolete for passthru
|
||||||
nochange a3-4.tld2 # 4 bl-disabled
|
nochange a3-4.tld2 # 4 bl-disabled
|
||||||
nodata a3-5.tld2 # 5 bl-nodata zone recursive-only no
|
nodata a3-5.tld2 # 5 bl-nodata zone recursive-only no
|
||||||
nodata a3-5.tld2 +norecurse # 6 bl-nodata zone recursive-only no
|
nodata a3-5.tld2 +norecurse # 6 bl-nodata zone recursive-only no
|
||||||
nodata a3-5.tld2 # 7 bl-nodata not needed
|
nodata a3-5.tld2 # 7 bl-nodata not needed
|
||||||
nxdomain a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata global recursive-only no
|
nxdomain a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata global recursive-only no
|
||||||
nxdomain a3-5.tld2s @$ns5 # 9 bl-nodata global break-dnssec
|
nxdomain a3-5.tld2s @$ns5 # 9 bl-nodata global break-dnssec
|
||||||
nxdomain a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata global break-dnssec
|
nxdomain a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata global break-dnssec
|
||||||
nxdomain a3-6.tld2 # 11 bl-nxdomain
|
nxdomain a3-6.tld2 # 11 bl-nxdomain
|
||||||
here a3-7.tld2 -tany <<'EOF'
|
here a3-7.tld2 -tany <<'EOF'
|
||||||
;; status: NOERROR, x
|
;; status: NOERROR, x
|
||||||
a3-7.tld2. x IN CNAME txt-only.tld2.
|
a3-7.tld2. x IN CNAME txt-only.tld2.
|
||||||
txt-only.tld2. x IN TXT "txt-only-tld2"
|
txt-only.tld2. x IN TXT "txt-only-tld2"
|
||||||
EOF
|
EOF
|
||||||
addr 58.58.58.58 a3-8.tld2 # 13 bl_wildcname
|
addr 58.58.58.58 a3-8.tld2 # 13 bl_wildcname
|
||||||
addr 59.59.59.59 a3-9.sub9.tld2 # 14 bl_wildcname
|
addr 59.59.59.59 a3-9.sub9.tld2 # 14 bl_wildcname
|
||||||
addr 12.12.12.12 a3-15.tld2 # 15 bl-garden via CNAME to a12.tld2
|
addr 12.12.12.12 a3-15.tld2 # 15 bl-garden via CNAME to a12.tld2
|
||||||
addr 127.0.0.16 a3-16.tld2 100 # 16 bl max-policy-ttl 100
|
addr 127.0.0.16 a3-16.tld2 100 # 16 bl max-policy-ttl 100
|
||||||
addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl max-policy-ttl 90
|
addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl max-policy-ttl 90
|
||||||
drop a3-18.tld2 any # 18 bl-drop
|
drop a3-18.tld2 any # 18 bl-drop
|
||||||
nxdomain TCP a3-19.tld2 # 19 bl-tcp-only
|
nxdomain TCP a3-19.tld2 # 19 bl-tcp-only
|
||||||
end_group
|
end_group
|
||||||
ckstats $ns3 test5 ns3 12
|
ckstats $ns3 test5 ns3 12
|
||||||
ckstats $ns5 test5 ns5 4
|
ckstats $ns5 test5 ns5 4
|
||||||
|
|
||||||
|
# check that miscellaneous bugs are still absent
|
||||||
# check that miscellaneous bugs are still absent
|
start_group "crashes" test6
|
||||||
start_group "crashes" test6
|
for Q in RRSIG SIG ANY 'ANY +dnssec'; do
|
||||||
for Q in RRSIG SIG ANY 'ANY +dnssec'; do
|
|
||||||
nocrash a3-1.tld2 -t$Q
|
nocrash a3-1.tld2 -t$Q
|
||||||
nocrash a3-2.tld2 -t$Q
|
nocrash a3-2.tld2 -t$Q
|
||||||
nocrash a3-5.tld2 -t$Q
|
nocrash a3-5.tld2 -t$Q
|
||||||
nocrash www.redirect -t$Q
|
nocrash www.redirect -t$Q
|
||||||
nocrash www.credirect -t$Q
|
nocrash www.credirect -t$Q
|
||||||
done
|
done
|
||||||
|
|
||||||
# This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip
|
# This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip
|
||||||
# (or whatever) is available by publishing "foo A 10.2.3.4" and then
|
# (or whatever) is available by publishing "foo A 10.2.3.4" and then
|
||||||
# resolving foo.
|
# resolving foo.
|
||||||
# nxdomain 32.3.2.1.127.rpz-ip
|
# nxdomain 32.3.2.1.127.rpz-ip
|
||||||
end_group
|
end_group
|
||||||
ckstats $ns3 bugs ns3 8
|
ckstats $ns3 bugs ns3 8
|
||||||
|
|
||||||
|
|
||||||
# superficial test for major performance bugs
|
# superficial test for major performance bugs
|
||||||
QPERF=`sh qperf.sh`
|
QPERF=`sh qperf.sh`
|
||||||
if test -n "$QPERF"; then
|
if test -n "$QPERF"; then
|
||||||
perf () {
|
perf () {
|
||||||
date "+I:${TS}checking performance $1"
|
date "+I:${TS}checking performance $1"
|
||||||
# Dry run to prime everything
|
# Dry run to prime everything
|
||||||
@@ -689,11 +701,11 @@ if test -n "$QPERF"; then
|
|||||||
|
|
||||||
ckstats $ns5 performance ns5 200
|
ckstats $ns5 performance ns5 200
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "I:performance not checked; queryperf not available"
|
echo "I:performance not checked; queryperf not available"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DNSRPS_TEST_MODE" = 2 ]; then
|
if [ "$DNSRPS_TEST_MODE" = dnsrps ]; then
|
||||||
echo "I:checking that dnsrpzd is automatically restarted"
|
echo "I:checking that dnsrpzd is automatically restarted"
|
||||||
OLD_PID=`cat dnsrpzd.pid`
|
OLD_PID=`cat dnsrpzd.pid`
|
||||||
$KILL "$OLD_PID"
|
$KILL "$OLD_PID"
|
||||||
@@ -712,78 +724,77 @@ if [ "$DNSRPS_TEST_MODE" = 2 ]; then
|
|||||||
fi
|
fi
|
||||||
$WAIT_CMD
|
$WAIT_CMD
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# restart the main test RPZ server to see if that creates a core file
|
||||||
# restart the main test RPZ server to see if that creates a core file
|
if test -z "$HAVE_CORE"; then
|
||||||
if test -z "$HAVE_CORE"; then
|
|
||||||
$PERL $SYSTEMTESTTOP/stop.pl . ns3
|
$PERL $SYSTEMTESTTOP/stop.pl . ns3
|
||||||
restart 3
|
restart 3
|
||||||
HAVE_CORE=`find ns* -name '*core*' -print`
|
HAVE_CORE=`find ns* -name '*core*' -print`
|
||||||
test -z "$HAVE_CORE" || setret "I:found $HAVE_CORE; memory leak?"
|
test -z "$HAVE_CORE" || setret "I:found $HAVE_CORE; memory leak?"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# look for complaints from lib/dns/rpz.c and bin/name/query.c
|
# look for complaints from lib/dns/rpz.c and bin/name/query.c
|
||||||
EMSGS=`egrep -l 'invalid rpz|rpz.*failed' ns*/named.run`
|
EMSGS=`egrep -l 'invalid rpz|rpz.*failed' ns*/named.run`
|
||||||
if test -n "$EMSGS"; then
|
if test -n "$EMSGS"; then
|
||||||
setret "I:error messages in $EMSGS starting with:"
|
setret "I:error messages in $EMSGS starting with:"
|
||||||
egrep 'invalid rpz|rpz.*failed' ns*/named.run | sed -e '10,$d' -e 's/^/I: /'
|
egrep 'invalid rpz|rpz.*failed' ns*/named.run | sed -e '10,$d' -e 's/^/I: /'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "I:checking that ttl values are not zeroed when qtype is '*'"
|
t=`expr $t + 1`
|
||||||
$DIG +noall +answer -p 5300 @$ns3 any a3-2.tld2 > dig.out.any
|
echo "I:checking that ttl values are not zeroed when qtype is '*' (${t})"
|
||||||
ttl=`awk '/a3-2 tld2 text/ {print $2}' dig.out.any`
|
$DIG +noall +answer -p 5300 @$ns3 any a3-2.tld2 > dig.out.$t
|
||||||
if test ${ttl:=0} -eq 0; then setret I:failed; fi
|
ttl=`awk '/a3-2 tld2 text/ {print $2}' dig.out.$t`
|
||||||
|
if test ${ttl:=0} -eq 0; then setret I:failed; fi
|
||||||
|
|
||||||
|
t=`expr $t + 1`
|
||||||
echo "I:checking rpz updates/transfers with parent nodes added after children" \
|
echo "I:checking rpz updates/transfers with parent nodes added after children" \
|
||||||
| tr -d '\n'
|
| tr -d '\n'
|
||||||
# regression test for RT #36272: the success condition
|
# regression test for RT #36272: the success condition
|
||||||
# is the slave server not crashing.
|
# is the slave server not crashing.
|
||||||
nsd() {
|
for i in 1 2 3 4 5; do
|
||||||
$NSUPDATE -p 5300 << EOF
|
|
||||||
server $1
|
|
||||||
ttl 300
|
|
||||||
update $2 $3 IN CNAME .
|
|
||||||
update $2 $4 IN CNAME .
|
|
||||||
send
|
|
||||||
EOF
|
|
||||||
sleep 2
|
|
||||||
}
|
|
||||||
for i in 1 2 3 4 5; do
|
|
||||||
nsd $ns5 add example.com.policy1. '*.example.com.policy1.'
|
nsd $ns5 add example.com.policy1. '*.example.com.policy1.'
|
||||||
echo . | tr -d '\n'
|
echo . | tr -d '\n'
|
||||||
nsd $ns5 delete example.com.policy1. '*.example.com.policy1.'
|
nsd $ns5 delete example.com.policy1. '*.example.com.policy1.'
|
||||||
echo . | tr -d '\n'
|
echo . | tr -d '\n'
|
||||||
done
|
done
|
||||||
for i in 1 2 3 4 5; do
|
for i in 1 2 3 4 5; do
|
||||||
nsd $ns5 add '*.example.com.policy1.' example.com.policy1.
|
nsd $ns5 add '*.example.com.policy1.' example.com.policy1.
|
||||||
echo . | tr -d '\n'
|
echo . | tr -d '\n'
|
||||||
nsd $ns5 delete '*.example.com.policy1.' example.com.policy1.
|
nsd $ns5 delete '*.example.com.policy1.' example.com.policy1.
|
||||||
echo . | tr -d '\n'
|
echo . | tr -d '\n'
|
||||||
|
done
|
||||||
|
echo " (${t})"
|
||||||
|
|
||||||
|
t=`expr $t + 1`
|
||||||
|
echo "I:checking that going from an empty policy zone works (${t})"
|
||||||
|
nsd $ns5 add '*.x.servfail.policy2.' x.servfail.policy2.
|
||||||
|
sleep 1
|
||||||
|
$RNDCCMD $ns7 reload policy2
|
||||||
|
$DIG z.x.servfail -p 5300 @$ns7 > dig.out.${t}
|
||||||
|
grep NXDOMAIN dig.out.${t} > /dev/null || setret I:failed
|
||||||
|
|
||||||
|
# dnsrps does not allow NS RRs in policy zones, so this check
|
||||||
|
# with dnsrps results in no rewriting.
|
||||||
|
if [ "$DNSRPS_TEST_MODE" = native ]; then
|
||||||
|
t=`expr $t + 1`
|
||||||
|
echo "I:checking rpz with delegation fails correctly (${t})"
|
||||||
|
$DIG -p 5300 @$ns3 ns example.com > dig.out.$t
|
||||||
|
grep "status: SERVFAIL" dig.out.$t > /dev/null || setret "I:failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ $status -ne 0 ] && pf=fail || pf=pass
|
||||||
|
case $DNSRPS_TEST_MODE in
|
||||||
|
native)
|
||||||
|
native=$status
|
||||||
|
echo "I:status (native RPZ sub-test): $status ($pf)";;
|
||||||
|
|
||||||
|
dnsrps)
|
||||||
|
dnsrps=$status
|
||||||
|
echo "I:status (DNSRPS sub-test): $status ($pf)";;
|
||||||
|
*) echo "I:invalid test mode";;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
echo
|
status=`expr ${native:-0} + ${dnsrps:-0}`
|
||||||
|
|
||||||
|
|
||||||
echo "I:checking that going from an empty policy zone works"
|
|
||||||
nsd $ns5 add '*.x.servfail.policy2.' x.servfail.policy2.
|
|
||||||
sleep 1
|
|
||||||
$RNDCCMD $ns7 reload policy2
|
|
||||||
$DIG z.x.servfail -p 5300 @$ns7 > dig.out.ns7
|
|
||||||
grep NXDOMAIN dig.out.ns7 > /dev/null || setret I:failed
|
|
||||||
|
|
||||||
# dnsrps does not allow NS RRs in policy zones, so this check
|
|
||||||
# with dnsrps results in no rewriting.
|
|
||||||
if [ "$DNSRPS_TEST_MODE" = 1 ]; then
|
|
||||||
echo "I:checking rpz with delegation fails correctly"
|
|
||||||
$DIG -p 5300 @$ns3 ns example.com > dig.out.delegation
|
|
||||||
grep "status: SERVFAIL" dig.out.delegation > /dev/null || setret "I:failed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ $status -ne 0 ] && pf=fail || pf=pass
|
|
||||||
case $DNSRPS_TEST_MODE in
|
|
||||||
1) echo "I:status (native RPZ sub-test): $status ($pf)";;
|
|
||||||
2) echo "I:status (DNSRPS sub-test): $status ($pf)";;
|
|
||||||
*) echo "I:invalid test mode";;
|
|
||||||
esac
|
|
||||||
[ $status -eq 0 ] || exit 1
|
[ $status -eq 0 ] || exit 1
|
||||||
|
Reference in New Issue
Block a user