From 1a7a28f1927f5e5feca9b168274e8fe54a0a7cf9 Mon Sep 17 00:00:00 2001 From: Joe Cooper Date: Fri, 22 May 2026 23:54:11 -0500 Subject: [PATCH 1/6] Add bind8 tests, perlcritic, minor fixes --- bind8/acl_security.pl | 2 +- bind8/backup_config.pl | 8 +- bind8/bind8-lib.pl | 115 ++++---- bind8/cgi_args.pl | 2 +- bind8/check_zone.cgi | 2 +- bind8/close.cgi | 2 +- bind8/conf_acls.cgi | 2 +- bind8/conf_controls.cgi | 2 +- bind8/conf_dnssec.cgi | 2 +- bind8/conf_dnssectools.cgi | 2 +- bind8/conf_files.cgi | 2 +- bind8/conf_forwarding.cgi | 2 +- bind8/conf_keys.cgi | 2 +- bind8/conf_logging.cgi | 2 +- bind8/conf_manual.cgi | 2 +- bind8/conf_misc.cgi | 2 +- bind8/conf_ncheck.cgi | 2 +- bind8/conf_net.cgi | 2 +- bind8/conf_rndc.cgi | 2 +- bind8/conf_servers.cgi | 2 +- bind8/conf_trusted.cgi | 2 +- bind8/conf_zonedef.cgi | 2 +- bind8/convert_master.cgi | 2 +- bind8/convert_slave.cgi | 2 +- bind8/cpan_modules.pl | 4 +- bind8/create_delegation.cgi | 2 +- bind8/create_forward.cgi | 2 +- bind8/create_hint.cgi | 2 +- bind8/create_master.cgi | 2 +- bind8/create_slave.cgi | 2 +- bind8/create_view.cgi | 2 +- bind8/delegation_form.cgi | 2 +- bind8/delete_recs.cgi | 2 +- bind8/delete_view.cgi | 2 +- bind8/delete_zone.cgi | 2 +- bind8/disable_zonedt.cgi | 2 +- bind8/disable_zonekey.cgi | 2 +- bind8/dns_boot.cgi | 2 +- bind8/edit_delegation.cgi | 2 +- bind8/edit_forward.cgi | 2 +- bind8/edit_hint.cgi | 2 +- bind8/edit_master.cgi | 2 +- bind8/edit_options.cgi | 2 +- bind8/edit_record.cgi | 2 +- bind8/edit_recs.cgi | 2 +- bind8/edit_slave.cgi | 2 +- bind8/edit_soa.cgi | 4 +- bind8/edit_soptions.cgi | 2 +- bind8/edit_text.cgi | 2 +- bind8/edit_tls.cgi | 2 +- bind8/edit_view.cgi | 2 +- bind8/edit_zonedt.cgi | 2 +- bind8/edit_zonekey.cgi | 2 +- bind8/enable_zonedt.cgi | 2 +- bind8/enable_zonekey.cgi | 2 +- bind8/find_free.cgi | 2 +- bind8/find_zones.cgi | 2 +- bind8/fix_trusted.cgi | 2 +- bind8/forward_form.cgi | 2 +- bind8/free_chooser.cgi | 2 +- bind8/freeze_zone.cgi | 2 +- bind8/hint_form.cgi | 2 +- bind8/index.cgi | 2 +- bind8/list_gen.cgi | 2 +- bind8/list_slaves.cgi | 2 +- bind8/list_tls.cgi | 2 +- bind8/log_parser.pl | 9 +- bind8/mass_create.cgi | 2 +- bind8/mass_delete.cgi | 2 +- bind8/mass_form.cgi | 2 +- bind8/mass_rcreate.cgi | 2 +- bind8/mass_rcreate_form.cgi | 2 +- bind8/mass_rdelete.cgi | 2 +- bind8/mass_rdelete_form.cgi | 2 +- bind8/mass_update.cgi | 2 +- bind8/mass_update_form.cgi | 13 +- bind8/master_form.cgi | 2 +- bind8/move_zone.cgi | 2 +- bind8/old_save_controls.cgi | 2 +- bind8/open.cgi | 2 +- bind8/records-lib.pl | 10 +- bind8/refetch.cgi | 2 +- bind8/resign.pl | 2 +- bind8/resign_zone.cgi | 2 +- bind8/restart.cgi | 2 +- bind8/restart_zone.cgi | 2 +- bind8/save_acls.cgi | 2 +- bind8/save_controls.cgi | 2 +- bind8/save_dnssec.cgi | 2 +- bind8/save_dnssectools.cgi | 2 +- bind8/save_files.cgi | 2 +- bind8/save_forward.cgi | 2 +- bind8/save_forwarding.cgi | 2 +- bind8/save_gen.cgi | 2 +- bind8/save_keys.cgi | 2 +- bind8/save_logging.cgi | 2 +- bind8/save_manual.cgi | 2 +- bind8/save_master.cgi | 2 +- bind8/save_misc.cgi | 2 +- bind8/save_net.cgi | 2 +- bind8/save_record.cgi | 2 +- bind8/save_rndc.cgi | 2 +- bind8/save_servers.cgi | 2 +- bind8/save_slave.cgi | 2 +- bind8/save_soa.cgi | 2 +- bind8/save_text.cgi | 2 +- bind8/save_tls.cgi | 2 +- bind8/save_trusted.cgi | 2 +- bind8/save_view.cgi | 2 +- bind8/save_zonedef.cgi | 2 +- bind8/sign_zone.cgi | 2 +- bind8/slave_add.cgi | 2 +- bind8/slave_delete.cgi | 2 +- bind8/slave_form.cgi | 2 +- bind8/start.cgi | 2 +- bind8/stop.cgi | 8 +- bind8/syslog_logs.pl | 2 +- bind8/system_info.pl | 5 +- bind8/t/perlcritic.t | 64 +++++ bind8/t/run-tests.t | 481 ++++++++++++++++++++++++++++++++ bind8/unfreeze_zone.cgi | 2 +- bind8/view_form.cgi | 2 +- bind8/view_text.cgi | 2 +- bind8/whois.cgi | 2 +- bind8/xfer.cgi | 2 +- bind8/zone_dnssecmgt_dt.cgi | 2 +- bind8/zone_dnssecmigrate_dt.cgi | 2 +- 127 files changed, 763 insertions(+), 190 deletions(-) create mode 100644 bind8/t/perlcritic.t create mode 100644 bind8/t/run-tests.t diff --git a/bind8/acl_security.pl b/bind8/acl_security.pl index 450b6eb29..45656aec4 100755 --- a/bind8/acl_security.pl +++ b/bind8/acl_security.pl @@ -3,7 +3,7 @@ use warnings; no warnings 'redefine'; no warnings 'uninitialized'; -require 'bind8-lib.pl'; +require 'bind8-lib.pl'; ## no critic # Globals from bind8-lib.pl our (%config, %text, %in); diff --git a/bind8/backup_config.pl b/bind8/backup_config.pl index af1f71e1f..08a6ab928 100755 --- a/bind8/backup_config.pl +++ b/bind8/backup_config.pl @@ -45,21 +45,21 @@ return map { &make_chroot($_) } &unique(@rv); # Called before the files are actually read sub pre_backup { -return undef; +return; } # post_backup(&files) # Called after the files are actually read sub post_backup { -return undef; +return; } # pre_restore(&files) # Called before the files are restored from a backup sub pre_restore { -return undef; +return; } # post_restore(&files) @@ -71,7 +71,7 @@ my $pidfile = &get_pid_file(); if (&check_pid_file(&make_chroot($pidfile, 1))) { return &restart_bind(); } -return undef; +return; } 1; diff --git a/bind8/bind8-lib.pl b/bind8/bind8-lib.pl index c81ee4304..c496f80fd 100755 --- a/bind8/bind8-lib.pl +++ b/bind8/bind8-lib.pl @@ -12,16 +12,28 @@ use WebminCore; our (%text, %config, %gconfig, $module_name, $module_var_directory, $module_config_file, $module_config_directory); my $dnssec_tools_minver = 1.13; -my $have_dnssec_tools = eval "require Net::DNS::SEC::Tools::dnssectools;"; +my $have_dnssec_tools = eval { + require Net::DNS::SEC::Tools::dnssectools; + 1; + }; my %freeze_zone_count; if ($have_dnssec_tools) { - eval "use Net::DNS::SEC::Tools::dnssectools; - use Net::DNS::SEC::Tools::rollmgr; - use Net::DNS::SEC::Tools::rollrec; - use Net::DNS::SEC::Tools::keyrec; - use Net::DNS::RR::DS; - use Net::DNS;"; + eval { + require Net::DNS::SEC::Tools::dnssectools; + Net::DNS::SEC::Tools::dnssectools->import; + require Net::DNS::SEC::Tools::rollmgr; + Net::DNS::SEC::Tools::rollmgr->import; + require Net::DNS::SEC::Tools::rollrec; + Net::DNS::SEC::Tools::rollrec->import; + require Net::DNS::SEC::Tools::keyrec; + Net::DNS::SEC::Tools::keyrec->import; + require Net::DNS::RR::DS; + Net::DNS::RR::DS->import; + require Net::DNS; + Net::DNS->import; + 1; + }; } &init_config(); @@ -78,7 +90,7 @@ if ($gconfig{'os_type'} =~ /-linux$/ && # Version: 9.14.2 deprecated the use of -r option # in favor of using /dev/random [bugs:#5370]. So no # entropy generation is needed. - return undef; + return; } } # No random flag, and entropy is needed @@ -97,13 +109,13 @@ sub have_dnssec_tools_support # dnssectools_rollrec # dnssectools_keydir # dnssectools_rollmgr_pidfile - return undef if (!$config{'dnssectools_conf'} || + return if (!$config{'dnssectools_conf'} || !$config{'dnssectools_rollrec'} || !$config{'dnssectools_keydir'} || !$config{'dnssectools_rollmgr_pidfile'}); return 1; } - return undef; + return; } # get_bind_version() @@ -116,7 +128,7 @@ if (&has_command($config{'named_path'})) { return $2; } } -return undef; +return; } our @get_config_cache; @@ -330,7 +342,7 @@ else { while(1) { $t = $_[0]->[++$i]; if ($t eq "{" || $t eq ";" || $t eq "}") { last; } - elsif (!defined($t)) { ${$_[2]} = $i; return undef; } + elsif (!defined($t)) { ${$_[2]} = $i; return; } else { push(@vals, $t); } } $str{'values'} = \@vals; @@ -342,7 +354,7 @@ else { $str{'type'} = 1; $j = 0; while($_[0]->[$i] ne "}") { - if (!defined($_[0]->[$i])) { ${$_[2]} = $i; return undef; } + if (!defined($_[0]->[$i])) { ${$_[2]} = $i; return; } my $substr = &parse_struct( $_[0], $_[1], \$i, $j++, $_[4]); if ($substr) { @@ -388,7 +400,7 @@ sub find_value { my @v = &find($_[0], $_[1]); if (!@v) { - return undef; + return wantarray ? () : undef; } elsif (wantarray) { return map { &extract_value($_) } @v; @@ -2075,9 +2087,9 @@ foreach my $v (&find("view", $conf)) { push(@zones, &find("zone", $v->{'members'})); } my ($z) = grep { lc($_->{'value'}) eq lc($name) } @zones; -return undef if (!$z); +return if (!$z); my $file = &find("file", $z->{'members'}); -return undef if (!$file); +return if (!$file); my $filename = &absolute_path($file->{'values'}->[0]); $filename = &make_chroot($filename) if ($chroot); return $filename; @@ -2256,7 +2268,7 @@ else { } } &refresh_nscd(); -return undef; +return; } # before_editing(&zone) @@ -2330,7 +2342,7 @@ elsif ($ex || $out =~ /failed|not found|error/i) { return &text('restart_endc', "".&html_escape($out).""); } &refresh_nscd(); -return undef; +return; } # start_bind() @@ -2375,7 +2387,7 @@ my $rv = $?; if ($rv || $out =~ /chroot.*not available/i) { return &text('start_error', $out ? "$out" : "Unknown error"); } -return undef; +return; } # stop_bind() @@ -2398,7 +2410,7 @@ else { return $text{'stop_epid'}; } } -return undef; +return; } # is_bind_running() @@ -2437,7 +2449,7 @@ foreach my $c (@$vconf) { return $c->{'index'}; } } -return undef; +return; } # create_zone(&zone, &conf, [view-idx]) @@ -2641,7 +2653,7 @@ foreach my $z (@zones) { return $z; } } -return undef; +return; } # get_zone_name_or_error(index|name, [viewindex|"any"]) @@ -2870,7 +2882,7 @@ if ($config{'tmpl_dnssec'} && &supports_dnssec()) { if ($secerr) { return &text('mcreate_ednssec', $secerr); } -return undef; +return; } # automatic_filename(domain, is-reverse, base, [viewname]) @@ -3305,7 +3317,7 @@ if ($view eq '' && @views || $view ne '' && @views > 1) { [ map { [ $_->{'index'}, $_->{'value'} ] } grep { $_->{'index'} ne $view } @views ])); } -return undef; +return; } # download_root_zone(file) @@ -3344,7 +3356,7 @@ if ($temp) { quotemeta($rootfile)." ".&html_escape($out)."") if ($?); } -return undef; +return; } # restart_links([&zone-name]) @@ -3458,13 +3470,13 @@ $fn || return "Could not work out keys directory!"; my $dom = $z->{'members'} ? $z->{'values'}->[0] : $z->{'name'}; # Remove all keys for the same zone -opendir(ZONEDIR, $fn); -foreach my $f (readdir(ZONEDIR)) { +opendir(my $zonedir, $fn); +foreach my $f (readdir($zonedir)) { if ($f =~ /^K\Q$dom\E\.\+(\d+)\+(\d+)\.(key|private)$/) { &unlink_file("$fn/$f"); } } -closedir(ZONEDIR); +closedir($zonedir); # Fork a background job to do lots of IO, to generate entropy my $pid; @@ -3570,7 +3582,7 @@ foreach my $key (@keys) { } &bump_soa_record($chrootfn, \@recs); -return undef; +return; } # resign_dnssec_key(&zone|&zone-name) @@ -3643,7 +3655,7 @@ $newzonekey || return "Could not find new DNSSEC zone key"; my $err = &sign_dnssec_zone($z); return "Re-signing failed : $err" if ($err); -return undef; +return; } # delete_dnssec_key(&zone|&zone-name, [save-key]) @@ -3753,7 +3765,7 @@ foreach my $r (@signedrecs) { } &create_multiple_records($fn, \@addrecs); &unlink_file($signed); -return undef; +return; } # check_if_dnssec_tools_managed(&domain) @@ -3801,7 +3813,7 @@ if (&check_if_dnssec_tools_managed($dom)) { my $err = &dt_resign_zone($dom, $zonefile, $krfile, 0); &unlock_file(&make_chroot($zonefile)); &error($err) if ($err); - return undef; + return; } my $keyrec = &get_dnskey_record($z, $recs); @@ -3820,8 +3832,8 @@ my ($z, $saved) = @_; my $dir = &get_keys_dir($z); my $dom = $z->{'members'} ? $z->{'values'}->[0] : $z->{'name'}; my %keymap; -opendir(ZONEDIR, $dir); -foreach my $f (readdir(ZONEDIR)) { +opendir(my $zonedir, $dir); +foreach my $f (readdir($zonedir)) { if ($f =~ /^K\Q$dom\E\.\+(\d+)\+(\d+)\.key(\.saved)?$/) { # Found the public key file .. read it next if ($3 && !$saved); @@ -3867,7 +3879,7 @@ foreach my $f (readdir(ZONEDIR)) { while($rv->{'privatetext'} =~ s/^;.*\r?\n//) { } } } -closedir(ZONEDIR); +closedir($zonedir); # Sort to put KSK first my @rv = values %keymap; @@ -4155,7 +4167,7 @@ sub dt_sign_zone &dt_rollerd_restart(); &restart_bind(); - return undef; + return; } # dt_resign_zone(zone-name, zonefile, krfile, threshold) @@ -4212,7 +4224,7 @@ sub dt_resign_zone &restart_zone($d); - return undef; + return; } # dt_zskroll_zone(zone-name) @@ -4220,12 +4232,13 @@ sub dt_resign_zone sub dt_zskroll_zone { my ($d) = @_; - no strict "subs"; + # Constants exported by Net::DNS::SEC::Tools::rollmgr, + # which is only loaded when dnssec-tools is installed. + no strict "subs"; ## no critic (ProhibitNoStrict) if (!rollmgr_sendcmd(CHANNEL_WAIT,ROLLCMD_ROLLZSK,$d)) { return $text{'dt_zone_erollctl'}; } - use strict "subs"; - return undef; + return; } # dt_kskroll_zone(zone-name) @@ -4233,12 +4246,11 @@ sub dt_zskroll_zone sub dt_kskroll_zone { my ($d) = @_; - no strict "subs"; + no strict "subs"; ## no critic (ProhibitNoStrict) if (!rollmgr_sendcmd(CHANNEL_WAIT,ROLLCMD_ROLLKSK,$d)) { return $text{'dt_zone_erollctl'}; } - use strict "subs"; - return undef; + return; } # dt_notify_parentzone(zone-name) @@ -4246,12 +4258,11 @@ sub dt_kskroll_zone sub dt_notify_parentzone { my ($d) = @_; - no strict "subs"; + no strict "subs"; ## no critic (ProhibitNoStrict) if (!rollmgr_sendcmd(CHANNEL_WAIT,ROLLCMD_DSPUB,$d)) { return $text{'dt_zone_erollctl'}; } - use strict "subs"; - return undef; + return; } # dt_rollerd_restart() @@ -4270,7 +4281,7 @@ sub dt_rollerd_restart $r = $config{"dnssectools_rollrec"}; $cmd = "$rollerd -rrfile ".quotemeta($r); &execute_command($cmd); - return undef; + return; } # dt_genkrf() @@ -4329,7 +4340,7 @@ sub dt_genkrf $out = &backquote_logged("$cmd 2>&1"); return $out if ($?); - return undef; + return; } @@ -4400,7 +4411,7 @@ sub dt_delete_dnssec_state &unlink_file($z_dir."/dsset-".$dom."."); } - return undef; + return; } # get_ds_record(&zone|&zone-name) @@ -4424,7 +4435,7 @@ else { if (&has_command("dnssec-dsfromkey")) { # Generate with a command my $out = &backquote_command("dnssec-dsfromkey -f ".quotemeta(&make_chroot(&absolute_path($zonefile)))." ".quotemeta($dom)." 2>/dev/null"); - return undef if ($?); + return if ($?); $out =~ s/\r|\n//g; return $out; } @@ -4445,9 +4456,9 @@ my $conf = &get_config(); my $options = &find("options", $conf); my $mems = $options ? $options->{'members'} : [ ]; my $en = &find_value("dnssec-enable", $mems); -return undef if (!$en || $en !~ /yes/i); +return if (!$en || $en !~ /yes/i); my $tkeys = &find("trusted-keys", $conf); -return undef if (!$tkeys || !@{$tkeys->{'members'}}); +return if (!$tkeys || !@{$tkeys->{'members'}}); return &text('trusted_warning', &get_webprefix().'/bind8/conf_trusted.cgi')."

\n". &ui_form_start(&get_webprefix().'/bind8/fix_trusted.cgi')."\n". diff --git a/bind8/cgi_args.pl b/bind8/cgi_args.pl index b1d850cae..fbc4d42cb 100755 --- a/bind8/cgi_args.pl +++ b/bind8/cgi_args.pl @@ -62,5 +62,5 @@ elsif ($cgi eq 'view_text.cgi' || $cgi eq 'edit_soptions.cgi') { return $z ? 'zone='.$z->{'zone'}. ($z->{'view'} ? '&view='.$z->{'viewindex'} : '') : 'none'; } -return undef; +return; } diff --git a/bind8/check_zone.cgi b/bind8/check_zone.cgi index cb6c5d6ce..4cea7c99f 100755 --- a/bind8/check_zone.cgi +++ b/bind8/check_zone.cgi @@ -5,7 +5,7 @@ use warnings; no warnings 'redefine'; no warnings 'uninitialized'; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic # Globals from bind8-lib.pl our (%access, %text, %in); diff --git a/bind8/close.cgi b/bind8/close.cgi index a9cdade96..4b0db178d 100755 --- a/bind8/close.cgi +++ b/bind8/close.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my @heiropen = &get_heiropen(); @heiropen = grep { $_ ne $in{'what'} } @heiropen; diff --git a/bind8/conf_acls.cgi b/bind8/conf_acls.cgi index 4bed2015b..d3bf295fe 100755 --- a/bind8/conf_acls.cgi +++ b/bind8/conf_acls.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%text, %access); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'acls_ecannot'}); &ui_print_header(undef, $text{'acls_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_controls.cgi b/bind8/conf_controls.cgi index af8dcf85e..f3e2e60eb 100755 --- a/bind8/conf_controls.cgi +++ b/bind8/conf_controls.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%text, %access); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'controls_ecannot'}); &ui_print_header(undef, $text{'controls_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_dnssec.cgi b/bind8/conf_dnssec.cgi index b47450430..52575abee 100755 --- a/bind8/conf_dnssec.cgi +++ b/bind8/conf_dnssec.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%text, %access, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'defaults'} || &error($text{'dnssec_ecannot'}); &ui_print_header(undef, $text{'dnssec_title'}, "", diff --git a/bind8/conf_dnssectools.cgi b/bind8/conf_dnssectools.cgi index c367f2871..b93dd7b1a 100755 --- a/bind8/conf_dnssectools.cgi +++ b/bind8/conf_dnssectools.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'defaults'} || &error($text{'dt_conf_ecannot'}); diff --git a/bind8/conf_files.cgi b/bind8/conf_files.cgi index a2522d118..908587f46 100755 --- a/bind8/conf_files.cgi +++ b/bind8/conf_files.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'files_ecannot'}); &ui_print_header(undef, $text{'files_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_forwarding.cgi b/bind8/conf_forwarding.cgi index 7e7928fbf..2309a8370 100755 --- a/bind8/conf_forwarding.cgi +++ b/bind8/conf_forwarding.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'forwarding_ecannot'}); &ui_print_header(undef, $text{'forwarding_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_keys.cgi b/bind8/conf_keys.cgi index a928384f7..a6dbb1ddf 100755 --- a/bind8/conf_keys.cgi +++ b/bind8/conf_keys.cgi @@ -6,7 +6,7 @@ use warnings; no warnings 'redefine'; no warnings 'uninitialized'; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic # Globals our (%access, %text); diff --git a/bind8/conf_logging.cgi b/bind8/conf_logging.cgi index 1d9dd2a68..9bafc1a20 100755 --- a/bind8/conf_logging.cgi +++ b/bind8/conf_logging.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; our (%access, %text, %in); our (@syslog_levels, @severities, @cat_list); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'logging_ecannot'}); &ui_print_header(undef, $text{'logging_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_manual.cgi b/bind8/conf_manual.cgi index 92ab1bd57..feb8e0e3e 100755 --- a/bind8/conf_manual.cgi +++ b/bind8/conf_manual.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'manual_ecannot'}); &ReadParse(); &ui_print_header(undef, $text{'manual_title'}, "", diff --git a/bind8/conf_misc.cgi b/bind8/conf_misc.cgi index e1d1c1728..7c6a46c14 100755 --- a/bind8/conf_misc.cgi +++ b/bind8/conf_misc.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'misc_ecannot'}); &ui_print_header(undef, $text{'misc_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_ncheck.cgi b/bind8/conf_ncheck.cgi index e3dfd4dbd..04b2c5bd8 100755 --- a/bind8/conf_ncheck.cgi +++ b/bind8/conf_ncheck.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'defaults'} || &error($text{'ncheck_ecannot'}); diff --git a/bind8/conf_net.cgi b/bind8/conf_net.cgi index 1417262eb..4ba1f1130 100755 --- a/bind8/conf_net.cgi +++ b/bind8/conf_net.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'net_ecannot'}); &ui_print_header(undef, $text{'net_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_rndc.cgi b/bind8/conf_rndc.cgi index 1444f13ea..5e5c94e24 100755 --- a/bind8/conf_rndc.cgi +++ b/bind8/conf_rndc.cgi @@ -9,7 +9,7 @@ no warnings 'uninitialized'; our (%access, %text, %config); our $module_name; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'rndc_ecannot'}); &ui_print_header(undef, $text{'rndc_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_servers.cgi b/bind8/conf_servers.cgi index 1b33fc3d3..43588c387 100755 --- a/bind8/conf_servers.cgi +++ b/bind8/conf_servers.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'servers_ecannot'}); &ui_print_header(undef, $text{'servers_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/conf_trusted.cgi b/bind8/conf_trusted.cgi index b61961d95..8fe0e8f27 100755 --- a/bind8/conf_trusted.cgi +++ b/bind8/conf_trusted.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; our (%access, %text, $bind_version); our $dnssec_dlv_zone; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'defaults'} || &error($text{'trusted_ecannot'}); &supports_dnssec_client() || &error($text{'trusted_esupport'}); diff --git a/bind8/conf_zonedef.cgi b/bind8/conf_zonedef.cgi index 9f6467cf6..a17937b63 100755 --- a/bind8/conf_zonedef.cgi +++ b/bind8/conf_zonedef.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'zonedef_ecannot'}); &ui_print_header(undef, $text{'zonedef_title'}, "", undef, undef, undef, undef, &restart_links()); diff --git a/bind8/convert_master.cgi b/bind8/convert_master.cgi index 70c450fbc..b4c9312e6 100755 --- a/bind8/convert_master.cgi +++ b/bind8/convert_master.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'convert_err'}); diff --git a/bind8/convert_slave.cgi b/bind8/convert_slave.cgi index 456c8f177..8795a12ca 100755 --- a/bind8/convert_slave.cgi +++ b/bind8/convert_slave.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'convert_err'}); diff --git a/bind8/cpan_modules.pl b/bind8/cpan_modules.pl index d15a08da6..42396acd9 100644 --- a/bind8/cpan_modules.pl +++ b/bind8/cpan_modules.pl @@ -1,4 +1,6 @@ -require 'bind8-lib.pl'; +use strict; +use warnings; +require 'bind8-lib.pl'; ## no critic sub cpan_recommended { diff --git a/bind8/create_delegation.cgi b/bind8/create_delegation.cgi index dc209fdfa..409d58c3b 100755 --- a/bind8/create_delegation.cgi +++ b/bind8/create_delegation.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'dcreate_err'}); $access{'delegation'} || &error($text{'dcreate_ecannot'}); diff --git a/bind8/create_forward.cgi b/bind8/create_forward.cgi index 4be6b5ee8..5922b760d 100755 --- a/bind8/create_forward.cgi +++ b/bind8/create_forward.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'fcreate_err'}); $access{'forward'} || &error($text{'fcreate_ecannot'}); diff --git a/bind8/create_hint.cgi b/bind8/create_hint.cgi index b11ef844b..b7cffaf73 100755 --- a/bind8/create_hint.cgi +++ b/bind8/create_hint.cgi @@ -9,7 +9,7 @@ no warnings 'uninitialized'; our (%access, %text, %in); our $module_root_directory; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'hcreate_err'}); $access{'master'} || &error($text{'hcreate_ecannot'}); diff --git a/bind8/create_master.cgi b/bind8/create_master.cgi index dd6fd951e..dbfd5d03d 100755 --- a/bind8/create_master.cgi +++ b/bind8/create_master.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'mcreate_err'}); $access{'master'} || &error($text{'mcreate_ecannot'}); diff --git a/bind8/create_slave.cgi b/bind8/create_slave.cgi index 4518a74dc..a63d6225b 100755 --- a/bind8/create_slave.cgi +++ b/bind8/create_slave.cgi @@ -11,7 +11,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($in{'type'} ? $text{'screate_err1'} : $text{'screate_err2'}); $access{'slave'} || &error($in{'type'} ? $text{'screate_ecannot1'} diff --git a/bind8/create_view.cgi b/bind8/create_view.cgi index 95ed24a44..e0468e449 100755 --- a/bind8/create_view.cgi +++ b/bind8/create_view.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'vcreate_err'}); &ReadParse(); my $add_to_file = &add_to_file(); diff --git a/bind8/delegation_form.cgi b/bind8/delegation_form.cgi index 7c62a43d2..8ef4c4305 100755 --- a/bind8/delegation_form.cgi +++ b/bind8/delegation_form.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'delegation'} || &error($text{'dcreate_ecannot'}); $access{'ro'} && &error($text{'master_ero'}); &ui_print_header(undef, $text{'dcreate_title'}, "", diff --git a/bind8/delete_recs.cgi b/bind8/delete_recs.cgi index 1a751643a..7d707b1f6 100755 --- a/bind8/delete_recs.cgi +++ b/bind8/delete_recs.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'drecs_err'}); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/delete_view.cgi b/bind8/delete_view.cgi index 8cea84e10..400a3710b 100755 --- a/bind8/delete_view.cgi +++ b/bind8/delete_view.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; # Globals our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $parent = &get_config_parent(); my $conf = $parent->{'members'}; diff --git a/bind8/delete_zone.cgi b/bind8/delete_zone.cgi index f8501e58b..c2198b4e5 100755 --- a/bind8/delete_zone.cgi +++ b/bind8/delete_zone.cgi @@ -11,7 +11,7 @@ our (%access, %text, %in, %config); # Globals from records-lib.pl our $ipv6revzone; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/disable_zonedt.cgi b/bind8/disable_zonedt.cgi index b5f52ca45..3baacf711 100755 --- a/bind8/disable_zonedt.cgi +++ b/bind8/disable_zonedt.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'dt_zone_err'}); &ReadParse(); diff --git a/bind8/disable_zonekey.cgi b/bind8/disable_zonekey.cgi index 52d54b901..c933f8fc8 100755 --- a/bind8/disable_zonekey.cgi +++ b/bind8/disable_zonekey.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'zonekey_err'}); &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/dns_boot.cgi b/bind8/dns_boot.cgi index 649df338b..570521d74 100755 --- a/bind8/dns_boot.cgi +++ b/bind8/dns_boot.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %config, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'boot_err'}); &ReadParse(); diff --git a/bind8/edit_delegation.cgi b/bind8/edit_delegation.cgi index 0bb1a1c41..7ecb15478 100755 --- a/bind8/edit_delegation.cgi +++ b/bind8/edit_delegation.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %in, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $in{'view'} = 'any' if ($in{'view'} eq ''); diff --git a/bind8/edit_forward.cgi b/bind8/edit_forward.cgi index ecd109394..450de8538 100755 --- a/bind8/edit_forward.cgi +++ b/bind8/edit_forward.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %in, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $in{'view'} = 'any' if ($in{'view'} eq ''); diff --git a/bind8/edit_hint.cgi b/bind8/edit_hint.cgi index 1f9a22b52..83002389c 100755 --- a/bind8/edit_hint.cgi +++ b/bind8/edit_hint.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%in, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $dom = $zone->{'name'}; diff --git a/bind8/edit_master.cgi b/bind8/edit_master.cgi index 942110ad7..2428d7c76 100755 --- a/bind8/edit_master.cgi +++ b/bind8/edit_master.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config, %is_extra); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); our $ipv6revzone; $in{'view'} = 'any' if (!$in{'view'} || $in{'view'} eq ''); diff --git a/bind8/edit_options.cgi b/bind8/edit_options.cgi index 855ee34b1..43ec3742b 100755 --- a/bind8/edit_options.cgi +++ b/bind8/edit_options.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/edit_record.cgi b/bind8/edit_record.cgi index 48ce82b7a..ba78f727a 100755 --- a/bind8/edit_record.cgi +++ b/bind8/edit_record.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $dom = $zone->{'name'}; diff --git a/bind8/edit_recs.cgi b/bind8/edit_recs.cgi index dde047222..2141c0a12 100755 --- a/bind8/edit_recs.cgi +++ b/bind8/edit_recs.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config, %is_extra); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $dom = $zone->{'name'}; diff --git a/bind8/edit_slave.cgi b/bind8/edit_slave.cgi index 35c01e119..ac6c0b23e 100755 --- a/bind8/edit_slave.cgi +++ b/bind8/edit_slave.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); our $ipv6revzone; diff --git a/bind8/edit_soa.cgi b/bind8/edit_soa.cgi index 88cb363df..41d0bf6af 100755 --- a/bind8/edit_soa.cgi +++ b/bind8/edit_soa.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %in, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $dom = $zone->{'name'}; @@ -65,7 +65,7 @@ print &ui_table_row($text{'master_minimum'}, &time_unit_choice("minunit", $u[3])); # Default TTL -my $ttl = $defttl->{'defttl'} if ($defttl); +my $ttl = $defttl ? $defttl->{'defttl'} : undef; my ($ttlu) = &extract_time_units($ttl); print &ui_table_row($text{'master_defttl'}, &ui_radio("defttl_def", $defttl ? 0 : 1, diff --git a/bind8/edit_soptions.cgi b/bind8/edit_soptions.cgi index 963810f6c..da3ca06fb 100755 --- a/bind8/edit_soptions.cgi +++ b/bind8/edit_soptions.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; our (%access, %in, %text); our $scriptname; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/edit_text.cgi b/bind8/edit_text.cgi index c5f7b2200..12d6a5414 100755 --- a/bind8/edit_text.cgi +++ b/bind8/edit_text.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $file = &absolute_path($zone->{'file'}); diff --git a/bind8/edit_tls.cgi b/bind8/edit_tls.cgi index 41daeb09f..b50e0913c 100755 --- a/bind8/edit_tls.cgi +++ b/bind8/edit_tls.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'tls_ecannot'}); &supports_tls() || &error($text{'tls_esupport'}); &ReadParse(); diff --git a/bind8/edit_view.cgi b/bind8/edit_view.cgi index 792868233..051088ac3 100755 --- a/bind8/edit_view.cgi +++ b/bind8/edit_view.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $conf = &get_config(); my $view = $conf->[$in{'index'}]; diff --git a/bind8/edit_zonedt.cgi b/bind8/edit_zonedt.cgi index c663d2ed1..a9f7cb3fb 100755 --- a/bind8/edit_zonedt.cgi +++ b/bind8/edit_zonedt.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config, $in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/edit_zonekey.cgi b/bind8/edit_zonekey.cgi index 838e05d1d..ea03994e2 100755 --- a/bind8/edit_zonekey.cgi +++ b/bind8/edit_zonekey.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %in, %text, $in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $dom = $zone->{'name'}; diff --git a/bind8/enable_zonedt.cgi b/bind8/enable_zonedt.cgi index 52b342630..430b7adaf 100755 --- a/bind8/enable_zonedt.cgi +++ b/bind8/enable_zonedt.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'dt_zone_err'}); &ReadParse(); diff --git a/bind8/enable_zonekey.cgi b/bind8/enable_zonekey.cgi index bff9591ec..cc51a084d 100755 --- a/bind8/enable_zonekey.cgi +++ b/bind8/enable_zonekey.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'zonekey_err'}); &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/find_free.cgi b/bind8/find_free.cgi index 9889a7dba..76b76b21c 100755 --- a/bind8/find_free.cgi +++ b/bind8/find_free.cgi @@ -8,7 +8,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/find_zones.cgi b/bind8/find_zones.cgi index 9c5538730..cedd47b9d 100755 --- a/bind8/find_zones.cgi +++ b/bind8/find_zones.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%in, %config, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); if (&have_dnssec_tools_support()) { diff --git a/bind8/fix_trusted.cgi b/bind8/fix_trusted.cgi index 38c3681a9..a0afbea3c 100755 --- a/bind8/fix_trusted.cgi +++ b/bind8/fix_trusted.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'trusted_ecannot'}); &error_setup($text{'trusted_err'}); &ReadParse(); diff --git a/bind8/forward_form.cgi b/bind8/forward_form.cgi index 3f350ea8b..78f71b155 100755 --- a/bind8/forward_form.cgi +++ b/bind8/forward_form.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'forward'} || &error($text{'fcreate_ecannot'}); $access{'ro'} && &error($text{'master_ero'}); &ui_print_header(undef, $text{'fcreate_title'}, "", diff --git a/bind8/free_chooser.cgi b/bind8/free_chooser.cgi index b730f6fbd..cf6769b57 100755 --- a/bind8/free_chooser.cgi +++ b/bind8/free_chooser.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%config, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic # Go through all zones to find IPs in use, and networks my $conf = &get_config(); diff --git a/bind8/freeze_zone.cgi b/bind8/freeze_zone.cgi index e81310f82..038412885 100755 --- a/bind8/freeze_zone.cgi +++ b/bind8/freeze_zone.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'ro'} && &error($text{'restart_ecannot'}); $access{'apply'} || &error($text{'restart_ecannot'}); diff --git a/bind8/hint_form.cgi b/bind8/hint_form.cgi index 9f0212771..a17c37ee8 100755 --- a/bind8/hint_form.cgi +++ b/bind8/hint_form.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'master'} || &error($text{'hcreate_ecannot'}); $access{'ro'} && &error($text{'master_ero'}); &ui_print_header(undef, $text{'hcreate_title'}, "", diff --git a/bind8/index.cgi b/bind8/index.cgi index cca1dce14..31dd5ae3c 100755 --- a/bind8/index.cgi +++ b/bind8/index.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; our (%access, %text, %config, %gconfig, %in); our ($module_name, $module_config_directory); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $need_create = !-r &make_chroot($config{'named_conf'}) || diff --git a/bind8/list_gen.cgi b/bind8/list_gen.cgi index 64001e2c7..d3fd9d893 100755 --- a/bind8/list_gen.cgi +++ b/bind8/list_gen.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; our(%access, %text, %in); our $bind_version; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'gen'} || &error($text{'gen_ecannot'}); diff --git a/bind8/list_slaves.cgi b/bind8/list_slaves.cgi index 0d2b4544d..2585adc58 100755 --- a/bind8/list_slaves.cgi +++ b/bind8/list_slaves.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'slaves'} || &error($text{'slaves_ecannot'}); &foreign_require("servers", "servers-lib.pl"); &ReadParse(); diff --git a/bind8/list_tls.cgi b/bind8/list_tls.cgi index 804a629ee..563e23c78 100755 --- a/bind8/list_tls.cgi +++ b/bind8/list_tls.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'tls_ecannot'}); &supports_tls() || &error($text{'tls_esupport'}); my $conf = &get_config(); diff --git a/bind8/log_parser.pl b/bind8/log_parser.pl index bb4f5f569..301b80cf0 100755 --- a/bind8/log_parser.pl +++ b/bind8/log_parser.pl @@ -1,13 +1,16 @@ # log_parser.pl # Functions for parsing this module's logs +use strict; +use warnings; -do 'bind8-lib.pl'; +do 'bind8-lib.pl'; ## no critic +our (%text); # parse_webmin_log(user, script, action, type, object, ¶ms) # Converts logged information from this module into human-readable form sub parse_webmin_log { -local ($user, $script, $action, $type, $object, $p) = @_; +my ($user, $script, $action, $type, $object, $p) = @_; if ($type eq 'record') { if ($p->{'type'} eq 'PTR') { return &text("log_${action}_record", $text{"type_$p->{'type'}"}, @@ -88,7 +91,7 @@ elsif ($text{"log_${action}"}) { return $text{"log_${action}"}; } else { - return undef; + return; } } diff --git a/bind8/mass_create.cgi b/bind8/mass_create.cgi index 1c3868b33..a7b7c0e2a 100755 --- a/bind8/mass_create.cgi +++ b/bind8/mass_create.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %in, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParseMime(); &ui_print_unbuffered_header(undef, $text{'mass_title'}, ""); &error_setup($text{'mass_err'}); diff --git a/bind8/mass_delete.cgi b/bind8/mass_delete.cgi index a310465a4..5343d0481 100755 --- a/bind8/mass_delete.cgi +++ b/bind8/mass_delete.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $conf = &get_config(); diff --git a/bind8/mass_form.cgi b/bind8/mass_form.cgi index c04390814..c95963c5c 100755 --- a/bind8/mass_form.cgi +++ b/bind8/mass_form.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &ui_print_header(undef, $text{'mass_title'}, ""); diff --git a/bind8/mass_rcreate.cgi b/bind8/mass_rcreate.cgi index 208d4d96b..ae271ed64 100755 --- a/bind8/mass_rcreate.cgi +++ b/bind8/mass_rcreate.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'rmass_err'}); diff --git a/bind8/mass_rcreate_form.cgi b/bind8/mass_rcreate_form.cgi index 36a36b2c9..1ca4567d0 100755 --- a/bind8/mass_rcreate_form.cgi +++ b/bind8/mass_rcreate_form.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'rmass_err'}); my @d = split(/\0/, $in{'d'}); diff --git a/bind8/mass_rdelete.cgi b/bind8/mass_rdelete.cgi index ec7c953d1..438fa5562 100755 --- a/bind8/mass_rdelete.cgi +++ b/bind8/mass_rdelete.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'umass_err'}); diff --git a/bind8/mass_rdelete_form.cgi b/bind8/mass_rdelete_form.cgi index 207e2a1be..ef5489de3 100755 --- a/bind8/mass_rdelete_form.cgi +++ b/bind8/mass_rdelete_form.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'rdmass_err'}); my @d = split(/\0/, $in{'d'}); diff --git a/bind8/mass_update.cgi b/bind8/mass_update.cgi index 6c5ec0d25..9e6187650 100755 --- a/bind8/mass_update.cgi +++ b/bind8/mass_update.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'umass_err'}); diff --git a/bind8/mass_update_form.cgi b/bind8/mass_update_form.cgi index 4fec6d771..f35a6af87 100755 --- a/bind8/mass_update_form.cgi +++ b/bind8/mass_update_form.cgi @@ -1,16 +1,21 @@ #!/usr/local/bin/perl # Show a form for changing the IPs in multiple zones +use strict; +use warnings; +no warnings 'uninitialized'; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic +our (%text, %in, %config); &ReadParse(); &error_setup($text{'umass_err'}); -@d = split(/\0/, $in{'d'}); +my @d = split(/\0/, $in{'d'}); @d || &error($text{'umass_enone'}); &ui_print_header(undef, $text{'umass_title'}, ""); print &ui_form_start("mass_update.cgi", "post"); -foreach $d (@d) { +my $dc = 0; +foreach my $d (@d) { print &ui_hidden("d", $d),"\n"; $dc++; } @@ -20,7 +25,7 @@ print &ui_table_start($text{'umass_header'}, undef, 2); print &ui_table_row($text{'umass_sel'}, $dc); # Type to change -@rtypes = ( 'ttl', 'A', 'CNAME', 'NS', 'MX', 'PTR', 'TXT', 'SPF', +my @rtypes = ( 'ttl', 'A', 'CNAME', 'NS', 'MX', 'PTR', 'TXT', 'SPF', $config{'support_aaaa'} ? ( "AAAA" ) : ( ) ); print &ui_table_row($text{'umass_type'}, &ui_select("type", "A", diff --git a/bind8/master_form.cgi b/bind8/master_form.cgi index d4a8274d7..b72a303cc 100755 --- a/bind8/master_form.cgi +++ b/bind8/master_form.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'master'} || &error($text{'mcreate_ecannot'}); &ui_print_header(undef, $text{'mcreate_title'}, "", diff --git a/bind8/move_zone.cgi b/bind8/move_zone.cgi index 8e115dc1a..413d81fbd 100755 --- a/bind8/move_zone.cgi +++ b/bind8/move_zone.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/old_save_controls.cgi b/bind8/old_save_controls.cgi index 1cfb283f6..fce62507b 100755 --- a/bind8/old_save_controls.cgi +++ b/bind8/old_save_controls.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'misc_ecannot'}); &error_setup($text{'controls_err'}); &ReadParse(); diff --git a/bind8/open.cgi b/bind8/open.cgi index 61ca345d2..989b2935b 100755 --- a/bind8/open.cgi +++ b/bind8/open.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my @heiropen = &get_heiropen(); push(@heiropen, $in{'what'}); diff --git a/bind8/records-lib.pl b/bind8/records-lib.pl index 9a28be1c6..21e0ee3ea 100755 --- a/bind8/records-lib.pl +++ b/bind8/records-lib.pl @@ -830,7 +830,7 @@ if ($txt =~ /^v=spf1/) { } return $spf; } -return undef; +return; } # join_spf(&spf) @@ -898,7 +898,7 @@ if ($txt =~ /^v=dmarc1/i) { } return $dmarc; } -return undef; +return; } # join_dmarc(&dmarc) @@ -1018,13 +1018,13 @@ $abs ||= 0; my $fn; if ($z->{'members'}) { my $file = &find("file", $z->{'members'}); - return undef if (!$file); + return if (!$file); $fn = $file->{'values'}->[0]; } else { $fn = $z->{'file'}; } -return undef if (!$fn); +return if (!$fn); if ($abs) { $fn = &absolute_path($fn); } @@ -1075,7 +1075,7 @@ sub find_record_by_id my ($recs, $id, $num) = @_; my @rv = grep { &record_id($_) eq $id } @$recs; if (!@rv) { - return undef; + return; } elsif (@rv == 1) { return $rv[0]; diff --git a/bind8/refetch.cgi b/bind8/refetch.cgi index e2cc4a2da..8bb6d5c85 100755 --- a/bind8/refetch.cgi +++ b/bind8/refetch.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'refetch_err'}); &ReadParse(); diff --git a/bind8/resign.pl b/bind8/resign.pl index 387ef60c2..ac56cc27a 100755 --- a/bind8/resign.pl +++ b/bind8/resign.pl @@ -7,7 +7,7 @@ no warnings 'uninitialized'; our %config; my $no_acl_check++; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic my $zonefile; my $krfile; diff --git a/bind8/resign_zone.cgi b/bind8/resign_zone.cgi index 174537bf5..c241978ea 100755 --- a/bind8/resign_zone.cgi +++ b/bind8/resign_zone.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'resign_err'}); &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/restart.cgi b/bind8/restart.cgi index e370ec510..e8b70cb26 100755 --- a/bind8/restart.cgi +++ b/bind8/restart.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'ro'} && &error($text{'restart_ecannot'}); $access{'apply'} == 1 || $access{'apply'} == 3 || diff --git a/bind8/restart_zone.cgi b/bind8/restart_zone.cgi index 45f0cd6ce..3d180c7d7 100755 --- a/bind8/restart_zone.cgi +++ b/bind8/restart_zone.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'ro'} && &error($text{'restart_ecannot'}); $access{'apply'} || &error($text{'restart_ecannot'}); diff --git a/bind8/save_acls.cgi b/bind8/save_acls.cgi index fbd24763d..882d58820 100755 --- a/bind8/save_acls.cgi +++ b/bind8/save_acls.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'acls_ecannot'}); &error_setup($text{'acls_err'}); &ReadParse(); diff --git a/bind8/save_controls.cgi b/bind8/save_controls.cgi index a7f888a76..cdb9bd778 100755 --- a/bind8/save_controls.cgi +++ b/bind8/save_controls.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'controls_ecannot'}); &error_setup($text{'controls_err'}); &ReadParse(); diff --git a/bind8/save_dnssec.cgi b/bind8/save_dnssec.cgi index 3dd9ff9c3..586e698a7 100755 --- a/bind8/save_dnssec.cgi +++ b/bind8/save_dnssec.cgi @@ -9,7 +9,7 @@ our $dnssec_cron_cmd; our $module_name; our $module_config_file; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &foreign_require("cron", "cron-lib.pl"); &ReadParse(); &error_setup($text{'dnssec_err'}); diff --git a/bind8/save_dnssectools.cgi b/bind8/save_dnssectools.cgi index 3aa3002fc..371a93be0 100755 --- a/bind8/save_dnssectools.cgi +++ b/bind8/save_dnssectools.cgi @@ -7,7 +7,7 @@ no warnings 'uninitialized'; our (%access, %text, %in, %config); our $module_config_file; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'dt_conf_err'}); diff --git a/bind8/save_files.cgi b/bind8/save_files.cgi index 6c0a4f68b..22b219bc8 100755 --- a/bind8/save_files.cgi +++ b/bind8/save_files.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'files_ecannot'}); &error_setup($text{'files_err'}); &ReadParse(); diff --git a/bind8/save_forward.cgi b/bind8/save_forward.cgi index f57d77d1c..d196ee216 100755 --- a/bind8/save_forward.cgi +++ b/bind8/save_forward.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'fwd_err'}); diff --git a/bind8/save_forwarding.cgi b/bind8/save_forwarding.cgi index 9cfd3cd8b..9834c6467 100755 --- a/bind8/save_forwarding.cgi +++ b/bind8/save_forwarding.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'forwarding_ecannot'}); &error_setup($text{'forwarding_err'}); &ReadParse(); diff --git a/bind8/save_gen.cgi b/bind8/save_gen.cgi index 46074b12a..7cedf8a56 100755 --- a/bind8/save_gen.cgi +++ b/bind8/save_gen.cgi @@ -10,7 +10,7 @@ our (%access, %text, %in); # From records-lib.pl our ($uscore, $star); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'gen'} || &error($text{'gen_ecannot'}); diff --git a/bind8/save_keys.cgi b/bind8/save_keys.cgi index a7bc14ef0..cda7f7987 100755 --- a/bind8/save_keys.cgi +++ b/bind8/save_keys.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'keys_ecannot'}); &error_setup($text{'keys_err'}); &ReadParse(); diff --git a/bind8/save_logging.cgi b/bind8/save_logging.cgi index 08b68104c..6c03d926d 100755 --- a/bind8/save_logging.cgi +++ b/bind8/save_logging.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'logging_ecannot'}); &error_setup($text{'files_err'}); &ReadParse(); diff --git a/bind8/save_manual.cgi b/bind8/save_manual.cgi index c46be74d8..d93cf6c05 100755 --- a/bind8/save_manual.cgi +++ b/bind8/save_manual.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'manual_err'}); $access{'defaults'} || &error($text{'manual_ecannot'}); &ReadParseMime(); diff --git a/bind8/save_master.cgi b/bind8/save_master.cgi index ad3ec931a..e32677eec 100755 --- a/bind8/save_master.cgi +++ b/bind8/save_master.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'master_err'}); diff --git a/bind8/save_misc.cgi b/bind8/save_misc.cgi index 19d319fbb..846b8fdc0 100755 --- a/bind8/save_misc.cgi +++ b/bind8/save_misc.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'misc_ecannot'}); &error_setup($text{'misc_err'}); &ReadParse(); diff --git a/bind8/save_net.cgi b/bind8/save_net.cgi index f13eaa815..25b4fd700 100755 --- a/bind8/save_net.cgi +++ b/bind8/save_net.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'net_ecannot'}); &error_setup($text{'net_err'}); &ReadParse(); diff --git a/bind8/save_record.cgi b/bind8/save_record.cgi index 69c1a352a..406eb71a6 100755 --- a/bind8/save_record.cgi +++ b/bind8/save_record.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic our $ipv6revzone; &ReadParse(); &error_setup($text{'edit_err'}); diff --git a/bind8/save_rndc.cgi b/bind8/save_rndc.cgi index fcbd71d41..20b9b6e50 100755 --- a/bind8/save_rndc.cgi +++ b/bind8/save_rndc.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'rndc_ecannot'}); &error_setup($text{'rndc_err'}); my $cfile = &make_chroot($config{'named_conf'}); diff --git a/bind8/save_servers.cgi b/bind8/save_servers.cgi index 1151a9457..a3634ae33 100755 --- a/bind8/save_servers.cgi +++ b/bind8/save_servers.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'servers_ecannot'}); &error_setup($text{'servers_err'}); &ReadParse(); diff --git a/bind8/save_slave.cgi b/bind8/save_slave.cgi index 28299d347..aa42dabac 100755 --- a/bind8/save_slave.cgi +++ b/bind8/save_slave.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'slave_err'}); diff --git a/bind8/save_soa.cgi b/bind8/save_soa.cgi index 84b5a77d7..af86bf25e 100755 --- a/bind8/save_soa.cgi +++ b/bind8/save_soa.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'master_err2'}); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/save_text.cgi b/bind8/save_text.cgi index 0b8610e98..6bb4fa818 100755 --- a/bind8/save_text.cgi +++ b/bind8/save_text.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParseMime(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $file = &absolute_path($zone->{'file'}); diff --git a/bind8/save_tls.cgi b/bind8/save_tls.cgi index dbb247848..a2356d808 100755 --- a/bind8/save_tls.cgi +++ b/bind8/save_tls.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'tls_ecannot'}); &supports_tls() || &error($text{'tls_esupport'}); &ReadParse(); diff --git a/bind8/save_trusted.cgi b/bind8/save_trusted.cgi index f080e65c5..77009be90 100755 --- a/bind8/save_trusted.cgi +++ b/bind8/save_trusted.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config, $bind_version); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'defaults'} || &error($text{'trusted_ecannot'}); &error_setup($text{'trusted_err'}); &ReadParse(); diff --git a/bind8/save_view.cgi b/bind8/save_view.cgi index 5f01ca621..8cde644ed 100755 --- a/bind8/save_view.cgi +++ b/bind8/save_view.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'view_err'}); my $pconf = &get_config_parent(); diff --git a/bind8/save_zonedef.cgi b/bind8/save_zonedef.cgi index 04b2009b7..51f41f64a 100755 --- a/bind8/save_zonedef.cgi +++ b/bind8/save_zonedef.cgi @@ -8,7 +8,7 @@ no warnings 'uninitialized'; our (%access, %text, %in, %config); our $module_config_directory; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'zonedef_err'}); $access{'defaults'} || &error($text{'zonedef_ecannot'}); diff --git a/bind8/sign_zone.cgi b/bind8/sign_zone.cgi index a6ba534f7..f91238b67 100755 --- a/bind8/sign_zone.cgi +++ b/bind8/sign_zone.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'sign_err'}); &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); diff --git a/bind8/slave_add.cgi b/bind8/slave_add.cgi index f4df33321..3de0f3315 100755 --- a/bind8/slave_add.cgi +++ b/bind8/slave_add.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'slaves'} || &error($text{'slaves_ecannot'}); &ReadParse(); &foreign_require("servers", "servers-lib.pl"); diff --git a/bind8/slave_delete.cgi b/bind8/slave_delete.cgi index 6b73b3956..a27d36059 100755 --- a/bind8/slave_delete.cgi +++ b/bind8/slave_delete.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic $access{'slaves'} || &error($text{'slaves_ecannot'}); &ReadParse(); &foreign_require("servers", "servers-lib.pl"); diff --git a/bind8/slave_form.cgi b/bind8/slave_form.cgi index 3f954b835..3ab9a8d2f 100755 --- a/bind8/slave_form.cgi +++ b/bind8/slave_form.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic my $type = ($0 =~ /slave_form/); $access{'slave'} || &error($type ? $text{'screate_ecannot1'} : $text{'screate_ecannot2'}); diff --git a/bind8/start.cgi b/bind8/start.cgi index 7f0b36d09..5e178fca6 100755 --- a/bind8/start.cgi +++ b/bind8/start.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'ro'} && &error($text{'start_ecannot'}); $access{'apply'} || &error($text{'start_ecannot'}); diff --git a/bind8/stop.cgi b/bind8/stop.cgi index 054b16c2b..a9be690fa 100755 --- a/bind8/stop.cgi +++ b/bind8/stop.cgi @@ -1,11 +1,15 @@ #!/usr/local/bin/perl # Stop bind 8 +use strict; +use warnings; +no warnings 'uninitialized'; -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic +our (%access, %text, %in); &ReadParse(); $access{'ro'} && &error($text{'stop_ecannot'}); $access{'apply'} || &error($text{'stop_ecannot'}); -$err = &stop_bind(); +my $err = &stop_bind(); &error($err) if ($err); &webmin_log("stop"); &redirect($in{'zone'} && $in{'return'} ? diff --git a/bind8/syslog_logs.pl b/bind8/syslog_logs.pl index 4e0ac538b..d92a39586 100755 --- a/bind8/syslog_logs.pl +++ b/bind8/syslog_logs.pl @@ -5,7 +5,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text); -require 'bind8-lib.pl'; +require 'bind8-lib.pl'; ## no critic # syslog_getlogs() # Returns a list of structures containing extra log files known to this module diff --git a/bind8/system_info.pl b/bind8/system_info.pl index 9c22d8885..f51997890 100644 --- a/bind8/system_info.pl +++ b/bind8/system_info.pl @@ -1,5 +1,8 @@ +use strict; +use warnings; -do 'bind8-lib.pl'; +do 'bind8-lib.pl'; ## no critic +our (%text, %config, %access, $module_name); sub list_system_info { diff --git a/bind8/t/perlcritic.t b/bind8/t/perlcritic.t new file mode 100644 index 000000000..96269cc54 --- /dev/null +++ b/bind8/t/perlcritic.t @@ -0,0 +1,64 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Test::More; + +BEGIN { + eval { require Perl::Critic; 1 } + or plan skip_all => 'Perl::Critic not installed'; +} + +use File::Find; + +sub script_dir +{ + my $path = $0; + if ($path =~ m{^/}) { + $path =~ s{/[^/]+$}{}; + return $path; + } + my $cwd = `pwd`; + chomp($cwd); + if ($path =~ m{/}) { + $path =~ s{/[^/]+$}{}; + return $cwd.'/'.$path; + } + return $cwd; +} + +my $bindir = script_dir(); +my $module_dir = "$bindir/.."; +chdir($module_dir) or die "chdir: $!"; + +my @files; +find( + sub { + return if -d; + return unless /\.(pl|cgi)\z/; + # config.info.pl and module.info.pl are Webmin data files, + # not Perl source (the .pl suffix is overloaded for Polish + # translations). + return if $_ eq 'config.info.pl' || $_ eq 'module.info.pl'; + push(@files, $File::Find::name); + }, + '.' +); + +@files = sort @files; +if (!@files) { + plan skip_all => 'no perl files to check'; +} + +my $critic = Perl::Critic->new( + -profile => "$bindir/../../.perlcriticrc", +); + +foreach my $file (@files) { + my @violations = $critic->critique($file); + is(scalar @violations, 0, "$file perlcritic"); + if (@violations) { + diag join("", @violations); + } +} + +done_testing(); diff --git a/bind8/t/run-tests.t b/bind8/t/run-tests.t new file mode 100644 index 000000000..1e9806803 --- /dev/null +++ b/bind8/t/run-tests.t @@ -0,0 +1,481 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Test::More; +use Cwd qw(abs_path); +use File::Temp qw(tempdir); + +sub script_dir +{ + my $path = $0; + if ($path =~ m{^/}) { + $path =~ s{/[^/]+$}{}; + return $path; + } + my $cwd = `pwd`; + chomp($cwd); + if ($path =~ m{/}) { + $path =~ s{/[^/]+$}{}; + return $cwd.'/'.$path; + } + return $cwd; +} + +my $bindir = script_dir(); +my $rootdir = abs_path("$bindir/../..") or die "rootdir: $!"; + +my $confdir = tempdir(CLEANUP => 1); +my $vardir = tempdir(CLEANUP => 1); + +# Global Webmin config +open(my $cfh, ">", "$confdir/config") or die "config: $!"; +print $cfh "os_type=linux\nos_version=0\n"; +close($cfh); +open(my $vfh, ">", "$confdir/var-path") or die "var-path: $!"; +print $vfh "$vardir\n"; +close($vfh); + +# Per-module config +mkdir "$confdir/bind8" or die "bind8 confdir: $!"; +my $named_conf = "$confdir/named.conf"; +open(my $mfh, ">", "$confdir/bind8/config") or die "bind8 config: $!"; +print $mfh "named_conf=$named_conf\n"; +print $mfh "named_path=/usr/sbin/named\n"; +print $mfh "short_names=0\n"; +print $mfh "ipv6_mode=1\n"; +print $mfh "spf_record=0\n"; +print $mfh "soa_style=0\n"; +print $mfh "soa_start=0\n"; +print $mfh "updserial_on=1\n"; +print $mfh "allow_underscore=0\n"; +print $mfh "allow_wild=1\n"; +close($mfh); + +# Avoid spawning `named -v`: bind8-lib reads version from this file. +open(my $verfh, ">", "$confdir/bind8/version") or die "version: $!"; +print $verfh "9.18.0\n"; +close($verfh); + +$ENV{'WEBMIN_CONFIG'} = $confdir; +$ENV{'WEBMIN_VAR'} = $vardir; +$ENV{'FOREIGN_MODULE_NAME'} = 'bind8'; +$ENV{'FOREIGN_ROOT_DIRECTORY'} = $rootdir; + +chdir("$bindir/..") or die "chdir: $!"; + +require "$bindir/../bind8-lib.pl"; +our (%config, %access, $bind_version); + +# Sanity check: globals populated by lib. +is($bind_version, '9.18', 'bind_version normalized from version file'); +ok($config{'named_conf'}, 'named_conf loaded from module config'); + +# --- IPv4 reverse helpers -------------------------------------------------- +is(ip_to_arpa('1.2.3.4'), '4.3.2.1.in-addr.arpa.', 'ip_to_arpa basic'); +is(arpa_to_ip('4.3.2.1.in-addr.arpa.'), '1.2.3.4', 'arpa_to_ip basic'); +is(arpa_to_ip(ip_to_arpa('192.0.2.55')), '192.0.2.55', + 'ip_to_arpa round-trips through arpa_to_ip'); +# Pass-through for non-matching input +is(arpa_to_ip('not.an.arpa.name'), 'not.an.arpa.name', + 'arpa_to_ip leaves non-arpa input alone'); +is(ip_to_arpa('not.an.ip'), 'not.an.ip', + 'ip_to_arpa leaves non-IPv4 input alone'); + +# --- IPv6 helpers ---------------------------------------------------------- +is(expand_ip6('2001:db8::1'), '2001:db8:0:0:0:0:0:1', + 'expand_ip6 expands ::'); +is(expand_ip6('::1'), '0:0:0:0:0:0:0:1', 'expand_ip6 leading ::'); +is(expand_ip6('fe80::'), 'fe80:0:0:0:0:0:0:0', 'expand_ip6 trailing ::'); +is(expand_ip6('FE80::1'), 'fe80:0:0:0:0:0:0:1', 'expand_ip6 lowercases'); +is(expandall_ip6('2001:db8::1'), + '2001:0db8:0000:0000:0000:0000:0000:0001', + 'expandall_ip6 pads zeros'); + +# net_to_ip6int with default ipv6_mode=1 should produce ip6.arpa names +my $rev6 = net_to_ip6int('2001:db8::1'); +like($rev6, qr/\.ip6\.arpa\.$/, 'net_to_ip6int returns ip6.arpa'); +# Round-trip from ip6.arpa back to a canonical address +my $back = ip6int_to_net($rev6); +$back =~ s{/\d+$}{}; +like($back, qr/^2001:.*::?1$/i, + 'ip6int_to_net inverts net_to_ip6int for full address'); + +# Bits parameter trims labels (and so encodes a /prefix length) +my $rev6_short = net_to_ip6int('2001:db8::', 32); +like($rev6_short, qr/^8\.b\.d\.0\.1\.0\.0\.2\.ip6\.arpa\.$/i, + 'net_to_ip6int with /32 truncates to 8 nibbles'); + +# --- email <-> dotted notation -------------------------------------------- +is(email_to_dotted('admin@example.com'), 'admin.example.com.', + 'simple email -> dotted'); +is(dotted_to_email('admin.example.com.'), 'admin@example.com', + 'simple dotted -> email'); +is(dotted_to_email(email_to_dotted('hostmaster@example.com')), + 'hostmaster@example.com', 'email <-> dotted round-trip'); +# Dots in local-part must be escaped, per RFC 1183 +is(email_to_dotted('first.last@example.com'), + 'first\\.last.example.com.', + 'email_to_dotted escapes dots in local part'); +is(dotted_to_email('first\\.last.example.com.'), 'first.last@example.com', + 'dotted_to_email unescapes dots in local part'); +is(dotted_to_email('.'), '.', 'root domain dotted form preserved'); + +# --- valdnsname / valemail ------------------------------------------------- +ok(valdnsname('host.example.com', 0), 'valid hostname accepted'); +ok(valdnsname('_dmarc.example.com', 0, 'example.com', 'TXT'), + 'underscore allowed for TXT owner name'); +ok(!valdnsname('_dmarc.example.com', 0, 'example.com', 'A'), + 'underscore rejected for A owner name when allow_underscore off'); +ok(!valdnsname('-leading.example.com', 0), + 'leading dash rejected'); +ok(!valdnsname('trailing-.example.com', 0), + 'trailing dash rejected'); +ok(!valdnsname('a..b.example.com', 0), + 'double dot rejected'); +ok(valdnsname('*.example.com', 1), + 'wildcard accepted when wild flag set'); + +ok(valemail('admin@example.com'), 'simple email valid'); +ok(valemail('admin.test@example.com'), 'email with dot in local valid'); +ok(valemail('.'), 'root marker email valid'); +# valemail also accepts the SOA RNAME dotted form (no @), so "no-at-sign" +# parses successfully; the rejection cases are syntactically invalid input. +ok(!valemail('contains spaces'), + 'free-form text with spaces rejected'); + +# --- check_net_ip ---------------------------------------------------------- +ok(check_net_ip('192.168.1.0/24'), 'CIDR /24 accepted'); +ok(check_net_ip('192.168.1.5'), 'plain IP accepted'); +ok(check_net_ip('10.0.1-100'), 'range syntax accepted'); +ok(!check_net_ip('999.1.1.1'), 'out-of-range octet rejected'); + +# --- compute_serial -------------------------------------------------------- +$config{'soa_style'} = 0; +is(compute_serial(2024010100), 2024010101, + 'soa_style 0 increments by one'); +$config{'soa_style'} = 2; +my $now = time(); +my $serial2 = compute_serial($now - 10); +ok($serial2 > $now - 10, 'soa_style 2 unix-time serial advances'); +$config{'soa_style'} = 1; +$config{'soa_start'} = 0; +my $today = date_serial(); +my $serial1 = compute_serial($today.'00'); +is($serial1, $today.'01', 'soa_style 1 increments within day'); +# Rollover: same date, counter at 99 -> next day, counter reset to soa_start. +my $rolled = compute_serial($today.'99'); +is($rolled, sprintf("%d%02d", $today + 1, 0), + 'soa_style 1 rolls counter past 99 to next day'); +# Older-dated serial gets bumped forward to today regardless. +my $caught_up = compute_serial('1999010199'); +is($caught_up, $today.'00', + 'soa_style 1 catches up to current date when old serial is stale'); + +# --- make_record / record_id / find_record_by_id -------------------------- +my $rec = make_record('www', 3600, 'IN', 'A', '192.0.2.1', 'web server'); +like($rec, qr/^www\t3600\tIN\tA\t192\.0\.2\.1\t;web server$/, + 'make_record renders A record line'); +my $rec_notlt = make_record('www', '', 'IN', 'A', '192.0.2.1'); +is($rec_notlt, "www\tIN\tA\t192.0.2.1", + 'make_record omits TTL when blank'); +# SPF gets mapped down to TXT when spf_record is 0 (default) +my $spfline = make_record('foo', '', 'IN', 'SPF', '"v=spf1 -all"'); +like($spfline, qr/\tTXT\t/, + 'make_record maps SPF to TXT when spf_record=0'); + +my $r = { 'name' => 'a.example.com.', 'type' => 'A', + 'values' => [ '10.0.0.1' ] }; +is(record_id($r), 'a.example.com./A/10.0.0.1', 'record_id basic'); +my $soa = { 'name' => 'example.com.', 'type' => 'SOA', + 'values' => [ 'ns', 'admin', 1, 2, 3, 4, 5 ] }; +is(record_id($soa), 'example.com./SOA', + 'record_id omits values for SOA'); + +my @recs = ( + { 'name' => 'a.example.com.', 'type' => 'A', + 'values' => [ '10.0.0.1' ], 'num' => 0 }, + { 'name' => 'a.example.com.', 'type' => 'A', + 'values' => [ '10.0.0.1' ], 'num' => 1 }, + { 'name' => 'b.example.com.', 'type' => 'A', + 'values' => [ '10.0.0.2' ], 'num' => 2 }, +); +my $found = find_record_by_id(\@recs, 'b.example.com./A/10.0.0.2', 2); +ok($found && $found->{'num'} == 2, 'find_record_by_id unique match'); +my $found_dup = find_record_by_id(\@recs, 'a.example.com./A/10.0.0.1', 1); +ok($found_dup && $found_dup->{'num'} == 1, + 'find_record_by_id picks correct duplicate by num'); + +# --- join_record_values --------------------------------------------------- +is(join_record_values({ 'type' => 'A', 'values' => [ '192.0.2.1' ] }), + '192.0.2.1', 'join_record_values single A value'); +is(join_record_values({ 'type' => 'TXT', 'values' => [ 'hello' ] }), + '"hello"', 'join_record_values quotes TXT'); +is(join_record_values({ 'type' => 'MX', 'values' => [ '10', 'mail.example.com.' ] }), + '10 mail.example.com.', 'join_record_values MX preference and host'); + +# --- SPF parsing / serialization ------------------------------------------ +my $spf = parse_spf('v=spf1 mx a:relay.example.com ip4:192.0.2.0/24 -all'); +ok($spf, 'parse_spf returns hash'); +is($spf->{'mx'}, 1, 'spf flag mx set'); +is_deeply($spf->{'a:'}, [ 'relay.example.com' ], 'spf a: list'); +is_deeply($spf->{'ip4:'}, [ '192.0.2.0/24' ], 'spf ip4: list'); +is($spf->{'all'}, 3, 'spf -all maps to 3'); +my $spf_str = join_spf($spf); +like($spf_str, qr/v=spf1/, 'join_spf starts with v=spf1'); +like($spf_str, qr/-all/, 'join_spf preserves -all'); +my $spf2 = parse_spf($spf_str); +is($spf2->{'all'}, 3, 'spf round-trips -all'); +is_deeply($spf2->{'a:'}, [ 'relay.example.com' ], 'spf round-trips a:'); +is_deeply($spf2->{'ip4:'}, [ '192.0.2.0/24' ], 'spf round-trips ip4:'); + +# Not an SPF record +is(parse_spf('just some text'), undef, 'parse_spf returns undef for non-SPF'); + +# --- DMARC parsing / serialization ---------------------------------------- +my $dmarc = parse_dmarc('v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100'); +ok($dmarc, 'parse_dmarc returns hash'); +is($dmarc->{'p'}, 'reject', 'dmarc policy'); +is($dmarc->{'pct'}, '100', 'dmarc pct'); +is($dmarc->{'rua'}, 'mailto:dmarc@example.com', 'dmarc rua'); +my $dmarc_str = join_dmarc($dmarc); +like($dmarc_str, qr/v=DMARC1/, 'join_dmarc starts with v=DMARC1'); +like($dmarc_str, qr/p=reject/, 'join_dmarc preserves policy'); +my $dmarc2 = parse_dmarc($dmarc_str); +is($dmarc2->{'p'}, 'reject', 'dmarc round-trips policy'); +is($dmarc2->{'pct'}, '100', 'dmarc round-trips pct'); + +# --- extract_time_units ---------------------------------------------------- +my @ev = ('3600', '5M', '2H', '1D', '7W'); +my @units = extract_time_units(@ev); +is_deeply(\@units, ['', 'M', 'H', 'D', 'W'], 'extract_time_units returns units'); +is_deeply(\@ev, ['3600', '5', '2', '1', '7'], + 'extract_time_units strips trailing unit char in place'); + +# --- version_atleast ------------------------------------------------------- +ok(version_atleast(9), 'bind 9.18 is >= 9'); +ok(version_atleast(9, 18), 'bind 9.18 is >= 9.18'); +ok(!version_atleast(9, 19), 'bind 9.18 is not >= 9.19'); + +# --- wrap_lines / convert_to_absolute ------------------------------------- +is_deeply([ wrap_lines('abcdefghij', 3) ], + [ 'abc', 'def', 'ghi', 'j' ], + 'wrap_lines splits text'); +is_deeply([ wrap_lines('', 5) ], [], + 'wrap_lines returns empty list for empty input'); + +is(convert_to_absolute('www', 'example.com'), 'www.example.com.', + 'convert_to_absolute short name'); +is(convert_to_absolute('@', 'example.com'), 'example.com.', + 'convert_to_absolute @ name'); +is(convert_to_absolute('www.example.com', 'example.com'), + 'www.example.com.', 'convert_to_absolute name already in zone'); +is(convert_to_absolute('www.other.', 'example.com'), 'www.other.', + 'convert_to_absolute keeps fully qualified name'); + +# --- make_reverse_name ---------------------------------------------------- +is(make_reverse_name('192.0.2.1', 'A', { 'name' => '2.0.192.in-addr.arpa' }), + '1.2.0.192.in-addr.arpa.', 'make_reverse_name IPv4'); +# Partial reverse delegation: zone name encodes a /27 inside a /24 +my $partial = { 'name' => '0/27.2.0.192.in-addr.arpa' }; +is(make_reverse_name('192.0.2.5', 'A', $partial), + '5.0/27.2.0.192.in-addr.arpa.', + 'make_reverse_name partial reverse delegation'); + +# --- dnssec_size_range / list_dnssec_algorithms --------------------------- +is_deeply([ dnssec_size_range('RSASHA256') ], [ 2048, 4096 ], + 'dnssec_size_range RSASHA256'); +is_deeply([ dnssec_size_range('DSA') ], [ 512, 1024, 64 ], + 'dnssec_size_range DSA includes divisor'); +is_deeply([ dnssec_size_range('NOPE') ], [], + 'dnssec_size_range unknown alg returns empty'); +my @algs = list_dnssec_algorithms(); +ok((grep { $_ eq 'ED25519' } @algs), + 'list_dnssec_algorithms includes ED25519'); + +# --- can_edit_zone access control ------------------------------------------ +{ + local %access = ( 'zones' => '*', 'inviews' => '*', 'dironly' => 0 ); + ok(can_edit_zone({ 'name' => 'example.com', 'file' => '/etc/named/example.com' }), + 'wildcard ACL allows any zone'); + + %access = ( 'zones' => 'example.com', 'inviews' => '*' ); + ok(can_edit_zone({ 'name' => 'example.com' }), + 'allow-list ACL accepts named zone'); + ok(!can_edit_zone({ 'name' => 'other.com' }), + 'allow-list ACL rejects unlisted zone'); + + # Deny-list convention: leading "!" is a separate token (see acl_security.pl). + %access = ( 'zones' => '! banned.com', 'inviews' => '*' ); + ok(can_edit_zone({ 'name' => 'allowed.com' }), + 'deny-list ACL allows unbanned zone'); + ok(!can_edit_zone({ 'name' => 'banned.com' }), + 'deny-list ACL rejects banned zone'); + + %access = ( 'zones' => '*', 'inviews' => 'internal' ); + ok(can_edit_zone({ 'name' => 'z.com', 'view' => 'internal' }), + 'view ACL accepts matching view'); + ok(!can_edit_zone({ 'name' => 'z.com', 'view' => 'external' }), + 'view ACL rejects mismatched view'); +} + +# --- can_edit_view --------------------------------------------------------- +{ + local %access = ( 'vlist' => '*' ); + ok(can_edit_view({ 'name' => 'anyview' }), + 'wildcard view ACL allows all'); + %access = ( 'vlist' => 'public private' ); + ok(can_edit_view({ 'name' => 'public' }), + 'allow-list view ACL accepts listed view'); + ok(!can_edit_view({ 'name' => 'hidden' }), + 'allow-list view ACL rejects unlisted view'); + %access = ( 'vlist' => '! hidden' ); + ok(can_edit_view({ 'name' => 'public' }), + 'deny-list view ACL allows non-listed view'); + ok(!can_edit_view({ 'name' => 'hidden' }), + 'deny-list view ACL rejects listed view'); +} + +# --- config-file parser round-trip ---------------------------------------- +my $sample = <<'EOF'; +// Test BIND config +options { + directory "/var/named"; + listen-on port 53 { 127.0.0.1; 192.0.2.1; }; + allow-query { localhost; }; +}; + +zone "example.com" IN { + type master; + file "example.com.hosts"; + allow-transfer { 192.0.2.2; }; +}; + +zone "0.0.127.in-addr.arpa" { + type master; + file "named.local"; +}; +EOF +$config{'named_conf'} = $named_conf; +open(my $nfh, ">", $named_conf) or die "named.conf: $!"; +print $nfh $sample; +close($nfh); +clear_config_cache(); + +my $conf = get_config(); +ok(ref($conf) eq 'ARRAY' && @$conf >= 3, + 'read_config_file returned >= 3 top-level structures'); + +my ($opts) = find('options', $conf); +ok($opts && $opts->{'members'}, 'options block parsed'); +my $dir = find_value('directory', $opts->{'members'}); +is($dir, '/var/named', 'directory option value'); + +my ($lo) = find('listen-on', $opts->{'members'}); +ok($lo, 'listen-on directive present'); +is($lo->{'value'}, 'port', 'listen-on first value'); +is_deeply($lo->{'values'}, [ 'port', '53' ], + 'listen-on values before block'); +is(scalar @{$lo->{'members'}}, 2, + 'listen-on inner block has 2 addresses'); + +my @zones = find('zone', $conf); +is(scalar @zones, 2, 'two zone directives found'); +my ($z) = grep { $_->{'value'} eq 'example.com' } @zones; +ok($z, 'example.com zone found'); +is(find_value('type', $z->{'members'}), 'master', + 'example.com zone type'); +is(find_value('file', $z->{'members'}), 'example.com.hosts', + 'example.com zone file'); + +# extract_value handles directives with no separate 'value' +my $no_value = { 'values' => [ 'first', 'second' ] }; +is(extract_value($no_value), 'first', + 'extract_value falls back to first values entry'); + +# directive_lines renders a structure back to text that can be re-parsed +my @lines = directive_lines($z, 0); +ok(scalar @lines >= 1, 'directive_lines emits at least one line'); +like($lines[0], qr/^zone "example\.com"/, + 'directive_lines quotes zone name'); + +# Write rendered config back out and verify it re-parses identically +my $named_conf2 = "$confdir/named-roundtrip.conf"; +open(my $rfh, ">", $named_conf2) or die "rt: $!"; +foreach my $top (@$conf) { + print $rfh join("\n", directive_lines($top, 0)), "\n"; +} +close($rfh); +my @reparsed = read_config_file($named_conf2); +my ($z2) = grep { $_->{'name'} eq 'zone' && + $_->{'value'} eq 'example.com' } @reparsed; +ok($z2, 'example.com zone present after round-trip'); +is(find_value('file', $z2->{'members'}), 'example.com.hosts', + 'example.com zone file survives round-trip'); +my ($opts2) = grep { $_->{'name'} eq 'options' } @reparsed; +is(find_value('directory', $opts2->{'members'}), '/var/named', + 'options directory survives round-trip'); + +# --- zone-file parser ------------------------------------------------------ +my $zonefile = "$confdir/example.com.hosts"; +open(my $zfh, ">", $zonefile) or die "zonefile: $!"; +print $zfh <<'EOF'; +$TTL 3600 +@ IN SOA ns1.example.com. hostmaster.example.com. ( + 2024010101 ; serial + 3600 ; refresh + 600 ; retry + 1209600 ; expire + 3600 ) ; minimum +@ IN NS ns1.example.com. +@ IN NS ns2.example.com. +ns1 IN A 192.0.2.1 +ns2 IN A 192.0.2.2 +www IN CNAME @ +mail IN A 192.0.2.10 +@ IN MX 10 mail +_dmarc IN TXT "v=DMARC1; p=none" +EOF +close($zfh); + +my @zrecs = read_zone_file($zonefile, 'example.com', undef, 0, 1); +ok(scalar @zrecs >= 8, 'read_zone_file parsed multiple records') + or diag("got ".scalar(@zrecs)." records"); + +my ($soa_rec) = grep { $_->{'type'} eq 'SOA' } @zrecs; +ok($soa_rec, 'SOA record parsed'); +is(scalar @{$soa_rec->{'values'}}, 7, + 'SOA has mname rname and 5 numeric fields'); +is($soa_rec->{'values'}->[2], '2024010101', 'SOA serial parsed'); + +my @ns = grep { $_->{'type'} eq 'NS' } @zrecs; +is(scalar @ns, 2, 'two NS records parsed'); + +my @a = grep { $_->{'type'} eq 'A' } @zrecs; +is(scalar @a, 3, 'three A records parsed'); + +my ($mx) = grep { $_->{'type'} eq 'MX' } @zrecs; +ok($mx, 'MX record parsed'); +is_deeply($mx->{'values'}, [ '10', 'mail' ], + 'MX values: preference + host'); + +# DMARC underneath an underscore name: zone parser classifies as DMARC +my ($dmarc_rec) = grep { uc($_->{'type'}) eq 'DMARC' } @zrecs; +ok($dmarc_rec, 'DMARC record reclassified from TXT'); + +# --- only-soa fast path ---------------------------------------------------- +my @soaonly = read_zone_file($zonefile, 'example.com', undef, 1, 1); +my @soas = grep { $_->{'type'} eq 'SOA' } @soaonly; +is(scalar @soas, 1, 'only-soa mode finds the SOA record'); + +# --- is_raw_format_records ------------------------------------------------- +ok(!is_raw_format_records($zonefile), + 'text-format zone file not classified as raw'); +my $rawfile = "$confdir/raw.zone"; +open(my $rfh2, ">", $rawfile) or die "rawfile: $!"; +binmode $rfh2; +print $rfh2 "\0\0\0xxx"; +close($rfh2); +ok(is_raw_format_records($rawfile), + 'three-NUL preamble classified as raw format'); + +done_testing(); diff --git a/bind8/unfreeze_zone.cgi b/bind8/unfreeze_zone.cgi index c45b9dff5..b46c023ca 100755 --- a/bind8/unfreeze_zone.cgi +++ b/bind8/unfreeze_zone.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'ro'} && &error($text{'restart_ecannot'}); $access{'apply'} || &error($text{'restart_ecannot'}); diff --git a/bind8/view_form.cgi b/bind8/view_form.cgi index 5bfab8714..40dcee26a 100755 --- a/bind8/view_form.cgi +++ b/bind8/view_form.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $conf = &get_config(); $access{'views'} == 1 || &error($text{'vcreate_ecannot'}); diff --git a/bind8/view_text.cgi b/bind8/view_text.cgi index 690d60d48..683263fcb 100755 --- a/bind8/view_text.cgi +++ b/bind8/view_text.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $file = &absolute_path($zone->{'file'}); diff --git a/bind8/whois.cgi b/bind8/whois.cgi index bf081f9e3..7cefe6245 100755 --- a/bind8/whois.cgi +++ b/bind8/whois.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); $access{'whois'} || &error($text{'whois_ecannot'}); diff --git a/bind8/xfer.cgi b/bind8/xfer.cgi index 66f64e551..462a61bf9 100755 --- a/bind8/xfer.cgi +++ b/bind8/xfer.cgi @@ -7,7 +7,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &ReadParse(); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $z = &zone_to_config($zone); diff --git a/bind8/zone_dnssecmgt_dt.cgi b/bind8/zone_dnssecmgt_dt.cgi index ba9b9239c..040574c1f 100755 --- a/bind8/zone_dnssecmgt_dt.cgi +++ b/bind8/zone_dnssecmgt_dt.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'dt_zone_err'}); &ReadParse(); diff --git a/bind8/zone_dnssecmigrate_dt.cgi b/bind8/zone_dnssecmigrate_dt.cgi index 5b95a8f7f..c0b93cb8c 100755 --- a/bind8/zone_dnssecmigrate_dt.cgi +++ b/bind8/zone_dnssecmigrate_dt.cgi @@ -6,7 +6,7 @@ no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); -require './bind8-lib.pl'; +require './bind8-lib.pl'; ## no critic &error_setup($text{'dt_zone_err'}); &ReadParse(); From 87536b42a1561d30d9a2f27de36e221de28366f2 Mon Sep 17 00:00:00 2001 From: Joe Cooper Date: Sat, 23 May 2026 00:18:57 -0500 Subject: [PATCH 2/6] Fix date_serial race in test --- bind8/t/run-tests.t | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/bind8/t/run-tests.t b/bind8/t/run-tests.t index 1e9806803..e4ab499dd 100644 --- a/bind8/t/run-tests.t +++ b/bind8/t/run-tests.t @@ -159,17 +159,24 @@ my $serial2 = compute_serial($now - 10); ok($serial2 > $now - 10, 'soa_style 2 unix-time serial advances'); $config{'soa_style'} = 1; $config{'soa_start'} = 0; -my $today = date_serial(); -my $serial1 = compute_serial($today.'00'); -is($serial1, $today.'01', 'soa_style 1 increments within day'); -# Rollover: same date, counter at 99 -> next day, counter reset to soa_start. -my $rolled = compute_serial($today.'99'); -is($rolled, sprintf("%d%02d", $today + 1, 0), - 'soa_style 1 rolls counter past 99 to next day'); -# Older-dated serial gets bumped forward to today regardless. -my $caught_up = compute_serial('1999010199'); -is($caught_up, $today.'00', - 'soa_style 1 catches up to current date when old serial is stale'); +{ + # Pin date_serial() to a fixed value so a midnight rollover during the + # test run can't desynchronize the "today" computed here from the one + # computed inside compute_serial(). + my $today = '20260101'; + no warnings qw(redefine once); + local *date_serial = sub { $today }; + my $serial1 = compute_serial($today.'00'); + is($serial1, $today.'01', 'soa_style 1 increments within day'); + # Rollover: same date, counter at 99 -> next day, counter resets to soa_start. + my $rolled = compute_serial($today.'99'); + is($rolled, sprintf("%d%02d", $today + 1, 0), + 'soa_style 1 rolls counter past 99 to next day'); + # Older-dated serial gets bumped forward to today regardless. + my $caught_up = compute_serial('1999010199'); + is($caught_up, $today.'00', + 'soa_style 1 catches up to current date when old serial is stale'); +} # --- make_record / record_id / find_record_by_id -------------------------- my $rec = make_record('www', 3600, 'IN', 'A', '192.0.2.1', 'web server'); From 4bb0cda0b5d81dbca1483fe8c31485569b9a5da8 Mon Sep 17 00:00:00 2001 From: Joe Cooper Date: Sat, 23 May 2026 00:49:41 -0500 Subject: [PATCH 3/6] Fix missing error check on opendir --- bind8/bind8-lib.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bind8/bind8-lib.pl b/bind8/bind8-lib.pl index c496f80fd..47f2dd8cc 100755 --- a/bind8/bind8-lib.pl +++ b/bind8/bind8-lib.pl @@ -3470,7 +3470,8 @@ $fn || return "Could not work out keys directory!"; my $dom = $z->{'members'} ? $z->{'values'}->[0] : $z->{'name'}; # Remove all keys for the same zone -opendir(my $zonedir, $fn); +opendir(my $zonedir, $fn) + || return "Failed to open keys directory $fn : $!"; foreach my $f (readdir($zonedir)) { if ($f =~ /^K\Q$dom\E\.\+(\d+)\+(\d+)\.(key|private)$/) { &unlink_file("$fn/$f"); @@ -3832,7 +3833,8 @@ my ($z, $saved) = @_; my $dir = &get_keys_dir($z); my $dom = $z->{'members'} ? $z->{'values'}->[0] : $z->{'name'}; my %keymap; -opendir(my $zonedir, $dir); +opendir(my $zonedir, $dir) + || return "Failed to open keys directory $dir : $!"; foreach my $f (readdir($zonedir)) { if ($f =~ /^K\Q$dom\E\.\+(\d+)\+(\d+)\.key(\.saved)?$/) { # Found the public key file .. read it From 4b33d8bc3f8e6c04e2be8abd285c1e3d97667f78 Mon Sep 17 00:00:00 2001 From: Joe Cooper Date: Sat, 23 May 2026 00:59:53 -0500 Subject: [PATCH 4/6] catch failed dnssec-tools import --- bind8/bind8-lib.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bind8/bind8-lib.pl b/bind8/bind8-lib.pl index 47f2dd8cc..3f2741787 100755 --- a/bind8/bind8-lib.pl +++ b/bind8/bind8-lib.pl @@ -19,7 +19,10 @@ my $have_dnssec_tools = eval { my %freeze_zone_count; if ($have_dnssec_tools) { - eval { + # All companion modules must load cleanly. A partial install would + # otherwise leave unqualified calls like rollmgr_sendcmd / rollrec_* + # undefined, causing runtime death deep inside dnssec helpers. + my $ok = eval { require Net::DNS::SEC::Tools::dnssectools; Net::DNS::SEC::Tools::dnssectools->import; require Net::DNS::SEC::Tools::rollmgr; @@ -34,6 +37,7 @@ if ($have_dnssec_tools) { Net::DNS->import; 1; }; + $have_dnssec_tools = 0 if (!$ok); } &init_config(); From 1e773434825eafddfa78e16b494b33fa447075cd Mon Sep 17 00:00:00 2001 From: Joe Cooper Date: Sat, 23 May 2026 01:04:05 -0500 Subject: [PATCH 5/6] Don't use temp var for eval result, not idiomatic --- bind8/bind8-lib.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bind8/bind8-lib.pl b/bind8/bind8-lib.pl index 3f2741787..116ab62ee 100755 --- a/bind8/bind8-lib.pl +++ b/bind8/bind8-lib.pl @@ -22,7 +22,7 @@ if ($have_dnssec_tools) { # All companion modules must load cleanly. A partial install would # otherwise leave unqualified calls like rollmgr_sendcmd / rollrec_* # undefined, causing runtime death deep inside dnssec helpers. - my $ok = eval { + $have_dnssec_tools = eval { require Net::DNS::SEC::Tools::dnssectools; Net::DNS::SEC::Tools::dnssectools->import; require Net::DNS::SEC::Tools::rollmgr; @@ -37,7 +37,6 @@ if ($have_dnssec_tools) { Net::DNS->import; 1; }; - $have_dnssec_tools = 0 if (!$ok); } &init_config(); From 09bdd71c8c237a865922830acaee7dfdbeb5ad31 Mon Sep 17 00:00:00 2001 From: Joe Cooper Date: Sat, 23 May 2026 01:15:14 -0500 Subject: [PATCH 6/6] Fix the opendir fix for list context --- bind8/bind8-lib.pl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bind8/bind8-lib.pl b/bind8/bind8-lib.pl index 116ab62ee..3559fd644 100755 --- a/bind8/bind8-lib.pl +++ b/bind8/bind8-lib.pl @@ -3836,8 +3836,16 @@ my ($z, $saved) = @_; my $dir = &get_keys_dir($z); my $dom = $z->{'members'} ? $z->{'values'}->[0] : $z->{'name'}; my %keymap; -opendir(my $zonedir, $dir) - || return "Failed to open keys directory $dir : $!"; +my $zonedir; +if (!opendir($zonedir, $dir)) { + # A missing keys directory is the normal state before any DNSSEC + # keys have been generated for this zone; an unreadable one is a + # real error, but we can't return a string here because several + # list-context callers would treat it as a key hashref. Fall back + # to "no keys" and leave a breadcrumb in the error log. + warn "get_dnssec_key: opendir $dir failed: $!\n" if (-e $dir); + return wantarray ? () : undef; + } foreach my $f (readdir($zonedir)) { if ($f =~ /^K\Q$dom\E\.\+(\d+)\+(\d+)\.key(\.saved)?$/) { # Found the public key file .. read it