".join("", map { "$_->[0]->{'host'} : $_->[1]" } @slaveerrs)); } } } elsif ($ex || $out =~ /failed|not found|error/i) { return &text('restart_endc', "".&html_escape($out).""); } &refresh_nscd(); return undef; } # start_bind() # Attempts to start the BIND DNS server, and returns undef on success or an # error message on failure sub start_bind { my $chroot = &get_chroot(); my $user = ""; my $cmd; if ($config{'named_user'}) { $user = "-u $config{'named_user'}"; if ($bind_version < 9) { # Only version 8 takes the -g flag if ($config{'named_group'}) { $user .= " -g $config{'named_group'}"; } else { my @u = getpwnam($config{'named_user'}); my @g = getgrgid($u[3]); $user .= " -g $g[0]"; } } } if ($config{'start_cmd'}) { $cmd = $config{'start_cmd'}; } elsif (!$chroot) { $cmd = "$config{'named_path'} -c $config{'named_conf'} $user &1"; } elsif (`$config{'named_path'} -help 2>&1` =~ /\[-t/) { # use named's chroot option $cmd = "$config{'named_path'} -c $config{'named_conf'} -t $chroot $user &1"; } else { # use the chroot command $cmd = "chroot $chroot $config{'named_path'} -c $config{'named_conf'} $user &1"; } my $out = &backquote_logged("$cmd 2>&1 $out" : "Unknown error"); } return undef; } # stop_bind() # Kills the running DNS server, and returns undef on success or an error message # upon failure sub stop_bind { if ($config{'stop_cmd'}) { # Just use a command my $out = &backquote_logged("($config{'stop_cmd'}) 2>&1"); if ($?) { return "
$out
\n". &ui_form_start(&get_webprefix().'/bind8/fix_trusted.cgi')."\n". &ui_form_end([ [ undef, $text{'trusted_fix'} ] ]); } # list_dnssec_expired_domains() # Returns a list of all DNS zones with DNSSEC enabled that are close to expiry sub list_dnssec_expired_domains { my @rv; my %cache; &read_file($dnssec_expiry_cache, \%cache); my $changed = 0; foreach my $z (&list_zone_names()) { next if ($z->{'type'} ne 'master' && $z->{'type'} ne 'primary'); my ($t, $e); if ($cache{$z->{'name'}}) { ($t, $e) = split(/\s+/, $cache{$z->{'name'}}); } my @st = stat(&make_chroot($z->{'file'})); next if (!@st); if (!defined($t) || $st[9] != $t) { # Not in cache, or file has changed my @recs = &read_zone_file($z->{'file'}, $z->{'name'}); $changed = 1; $e = 0; foreach my $r (@recs) { next if ($r->{'type'} ne 'RRSIG'); next if ($r->{'values'}->[4] !~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/); eval { $e = timegm($6, $5, $4, $3, $2-1, $1-1900); }; last if ($e); } $cache{$z->{'name'}} = "$st[9] $e"; } if ($e && time() > $e - 86400) { # Expires within 1 day my $rvz = { %$z }; $rvz->{'expiry'} = $e; push(@rv, $rvz); } } if ($changed) { &write_file($dnssec_expiry_cache, \%cache); } return @rv; } # flush_dnssec_expired_domains() # Clear the cache of DNSSEC expiry times sub flush_dnssec_expired_domains { &unlink_file($dnssec_expiry_cache); } # get_virtualmin_domains(name) # Returns the Virtualmin domain objects for this zone, if any sub get_virtualmin_domains { my ($name) = @_; my @rv; if (&foreign_check("virtual-server")) { &foreign_require("virtual-server"); my $d = &virtual_server::get_domain_by("dom", $name); push(@rv, $d) if ($d); push(@rv, &virtual_server::get_domain_by("dns_subof", $d->{'id'})) if ($d); } return wantarray ? @rv : $rv[0]; } # zone_subhead(&zone) # Returns a ui_header subtitle for a zone sub zone_subhead { my ($zone) = @_; my $desc = &ip6int_to_net(&arpa_to_ip($zone->{'name'})); my $view = $zone->{'view'}; return $view ? &text('master_inview', $desc, $view) : $desc; } # format_dnssec_public_key(pubkey) # Format public dnssec public key, each on new line sub format_dnssec_public_key { my ($pubkey) = @_; my @krvalues = split(/\s+/, $pubkey); my @kvalues = @krvalues[0..5]; my $kvspace = " " x length("@kvalues"); return join(" ", @kvalues) . " " . join("\n$kvspace ", splice(@krvalues, 6)); } # redirect_url(type, [zone], [view]) # Returns the URL of the appropriate edit_*.cgi page sub redirect_url { my ($type, $zone, $view) = @_; my $r = $type eq "master" || $type eq "primary" ? "edit_master.cgi" : $type eq "forward" ? "edit_forward.cgi" : "edit_slave.cgi"; if ($zone) { $r .= "?zone=".&urlize($zone); if ($view) { $r .= "&view=".&urlize($view); } } return $r; } # find_tls_users(&conf, name) # Find all listen-on or other directives that use a given TLS key name sub find_tls_users { my ($conf, $name) = @_; my @rv; my $opts = &find("options", $conf); if ($opts) { my @listen = ( &find("listen-on", $opts->{'members'}), &find("listen-on-v6", $opts->{'members'}) ); foreach my $l (@listen) { my $idx = &indexof("tls", @{$l->{'values'}}); if ($idx >= 0 && $l->{'values'}->[$idx+1] eq $name) { push(@rv, $l); } } } return @rv; } 1;