#!/usr/bin/perl # save_record.cgi # Adds or updates a record of some type use strict; use warnings; no warnings 'redefine'; no warnings 'uninitialized'; our (%access, %text, %in, %config); require './bind8-lib.pl'; our $ipv6revzone; &ReadParse(); &error_setup($text{'edit_err'}); my $zone = &get_zone_name_or_error($in{'zone'}, $in{'view'}); my $dom = $zone->{'name'}; my @zl = &list_zone_names(); my $reverse = ($in{'origin'} =~ /\.in-addr\.arpa/i || $in{'origin'} =~ /\.$ipv6revzone/i); &can_edit_zone($zone) || &error($text{'recs_ecannot'}); &can_edit_type($in{'type'}) || &error($text{'recs_ecannottype'}); $access{'ro'} && &error($text{'master_ero'}); &lock_file(&make_chroot(&absolute_path($zone->{'file'}))); # Read the existing records &before_editing($zone); my @recs; if ($config{'largezones'} && !defined($in{'num'})) { # Adding to a large zone, so only read the SOA @recs = &read_zone_file($in{'file'}, $in{'origin'}, undef, 1); } else { # Read all records @recs = &read_zone_file($in{'file'}, $in{'origin'}); } # get the old record if needed my $r; if (defined($in{'num'})) { $r = &find_record_by_id(\@recs, $in{'id'}, $in{'num'}); $r || &error($text{'edit_egone'}); } # check for deletion my ($fulloldvalue0, $fulloldname); if ($in{'delete'}) { # Check if confirmation is needed if (!$in{'confirm'} && $config{'confirm_rec'}) { &ui_print_header(undef, $text{'edit_dtitle'}, ""); print &ui_confirmation_form("save_record.cgi", &text('edit_rusure', "<tt>$r->{'name'}</tt>", "<tt>$in{'origin'}</tt>"), [ map { [ $_, $in{$_} ] } (keys %in) ], [ [ 'confirm', $text{'edit_dok'} ] ], ); &ui_print_footer("edit_recs.cgi?zone=$in{'zone'}&view=$in{'view'}&type=$in{'redirtype'}&sort=$in{'sort'}", $text{'recs_return'}); } else { # Delete the record &lock_file(&make_chroot($r->{'file'})); &delete_record($r->{'file'}, $r); &bump_soa_record($in{'file'}, \@recs); &sign_dnssec_zone_if_key($zone, \@recs); # Update reverse $fulloldvalue0 = &convert_to_absolute( $in{'oldvalue0'}, $in{'origin'}); $fulloldname = &convert_to_absolute( $in{'oldname'}, $in{'origin'}); my ($orevconf, $orevfile, $orevrec) = &find_reverse( $in{'oldvalue0'}, $in{'view'}); if ($in{'rev'} && $orevrec && &can_edit_reverse($orevconf) && $fulloldname eq $orevrec->{'values'}->[0] && ($in{'type'} eq "A" || $in{'type'} eq "AAAA" && &expandall_ip6($in{'oldvalue0'}) eq &expandall_ip6(&ip6int_to_net($orevrec->{'name'})))) { &before_editing($orevconf); &lock_file(&make_chroot($orevrec->{'file'})); &delete_record($orevrec->{'file'} , $orevrec); &lock_file(&make_chroot($orevfile)); my @orrecs = &read_zone_file($orevfile, $orevconf->{'name'}); &bump_soa_record($orevfile, \@orrecs); &sign_dnssec_zone_if_key($orevconf, \@orrecs); &after_editing($orevconf); } # Update forward my $ipv6; ($ipv6 = ($fulloldvalue0 =~ /\.$ipv6revzone/i)); my ($ofwdconf, $ofwdfile, $ofwdrec) = &find_forward($fulloldvalue0, $ipv6); if ($in{'fwd'} && $ofwdrec && &can_edit_zone($ofwdconf) && (!$ipv6 && &arpa_to_ip($in{'oldname'}) eq $ofwdrec->{'values'}->[0] || $ipv6 && &expandall_ip6(&ip6int_to_net($in{'oldname'})) eq &expandall_ip6($ofwdrec->{'values'}->[0])) && $fulloldvalue0 eq $ofwdrec->{'name'}) { &before_editing($ofwdconf); &lock_file(&make_chroot($ofwdrec->{'file'})); &delete_record($ofwdrec->{'file'}, $ofwdrec); &lock_file(&make_chroot($ofwdfile)); my @ofrecs = &read_zone_file($ofwdfile, $ofwdconf->{'name'}); &bump_soa_record($ofwdfile, \@ofrecs); &sign_dnssec_zone_if_key($ofwdconf, \@ofrecs); &after_editing($ofwdconf); } &redirect("edit_recs.cgi?zone=$in{'zone'}&view=$in{'view'}&type=$in{'redirtype'}&sort=$in{'sort'}"); &unlock_all_files(); &webmin_log('delete', 'record', $in{'origin'}, $r); } exit; } # Create values string based on inputs my $ttl; if (!$in{'ttl_def'}) { $in{'ttl'} =~ /^\d+$/ || &error(&text('edit_ettl', $in{'ttl'})); $ttl = $in{'ttl'}.$in{'ttlunit'}; } my $vals = $in{'value0'}; for(my $i=1; defined($in{"value$i"}); $i++) { $vals .= " ".$in{"value$i"}; } $vals =~ s/^\s+//; $vals =~ s/\s+$//; my ($name, $fullname); if ($in{'type'} eq "PTR" && $reverse) { # a reverse address my $ipv4; ($ipv4 = $in{'origin'} =~ /in-addr\.arpa/i) || $in{'origin'} =~ /\.$ipv6revzone/i || &error(&text('edit_eip', $in{'name'})); if ($ipv4) { if ($in{'name'} =~ /^\d+$/) { $in{'name'} = &arpa_to_ip($in{'origin'}).".".$in{'name'}; } &check_ipaddress($in{'name'}) || ($in{'name'} =~ /^(.*)\.(\d+)$/ && &check_ipaddress("$1")) || ($in{'name'} =~ /^(.*)\.(\d+)$/ && $1 eq &arpa_to_ip($in{'origin'})) || &error(&text('edit_eip', $in{'name'})); $name = &ip_to_arpa($in{'name'}); } else { &check_ip6address($in{'name'}) || &error(&text('edit_eip6', $in{'name'})); $name = &net_to_ip6int($in{'name'}); } &valname($in{'value0'}) || &error(&text('edit_ehost', $vals)); if ($in{'value0'} !~ /\.$/) { $vals .= "."; } } else { # some other kind of record $in{'name'} eq "" || $in{'name'} eq "@" || &valnamewild($in{'name'}) || &error(&text('edit_ename', $in{'name'})); if ($in{'type'} eq "A") { &check_ipaddress($vals) || &error(&text('edit_eip', $vals)); if (!$access{'multiple'}) { # Is this address already in use? Search all domains # to find out.. foreach my $z (@zl) { next if ($z->{'type'} ne "master" && $z->{'type'} ne "primary"); next if ($z->{'name'} =~ /in-addr\.arpa/i); my $file = $z->{'file'}; my @frecs = &read_zone_file($file, $z->{'name'}); foreach my $fr (@frecs) { if ($fr->{'type'} eq "A" && $fr->{'values'}->[0] eq $vals && $fr->{'name'} ne $r->{'name'}) { &error(&text('edit_edupip', $vals)); } } } } } elsif ($in{'type'} eq "AAAA") { &check_ip6address($vals) || &error(&text('edit_eip6', $vals)); if (!$access{'multiple'}) { # Is this address already in use? Search all domains # to find out.. foreach my $z (@zl) { next if ($z->{'type'} ne "master" && $z->{'type'} ne "primary"); next if ($z->{'name'} =~ /\.$ipv6revzone/i); my $file = $z->{'file'}; my @frecs = &read_zone_file($file, $z->{'name'}); foreach my $fr (@frecs) { if ($fr->{'type'} eq "AAAA" && &expandall_ip6($fr->{'values'}->[0]) eq &expandall_ip6($vals) && $fr->{'name'} ne $r->{'name'}) { &error(&text('edit_edupip', $vals)); } } } } } elsif ($in{'type'} eq "NS") { &valname($vals) || &error(&text('edit_ens', $vals)); if ($vals =~ /\.\Q$in{'origin'}\E$/) { # Make absolute $vals .= "."; } } elsif ($in{'type'} eq "CNAME") { &valname($vals) || $vals eq '@' || &error(&text('edit_ecname', $vals)); if ($vals =~ /\.\Q$in{'origin'}\E$/) { $vals .= "."; } } elsif ($in{'type'} eq "MX") { &valname($in{'value1'}) || &error(&text('edit_emx', $in{'value1'})); $in{'value0'} =~ /^\d+$/ || &error(&text('edit_epri', $in{'value0'})); if ($vals =~ /\.\Q$in{'origin'}\E$/) { $vals .= "."; } } elsif ($in{'type'} eq "HINFO") { $in{'value0'} =~ /\S/ || &error($text{'edit_ehard'}); $in{'value1'} =~ /\S/ || &error($text{'edit_eos'}); $in{'value0'} = "\"$in{'value0'}\"" if ($in{'value0'} =~ /\s/); $in{'value1'} = "\"$in{'value1'}\"" if ($in{'value1'} =~ /\s/); $vals = $in{'value0'}." ".$in{'value1'}; } elsif ($in{'type'} eq "TXT") { my $fullvals = $in{'value0'}; $fullvals =~ s/\r//g; $fullvals =~ s/\n/ /g; $fullvals =~ s/((?:^|[^\\])(?:\\\\)*)[\"]/$1\\\"/g; my @splitvals = ( ); while($fullvals) { push(@splitvals, substr($fullvals, 0, 255)); $fullvals = substr($fullvals, 255); } $vals = join(" ", map { "\"$_\"" } @splitvals); } elsif ($in{'type'} eq "WKS") { &check_ipaddress($in{'value0'}) || &error(&text('edit_eip', $in{'value0'})); if (!$in{'value2'}) { &error($text{'edit_eserv'}); } my @ws = split(/[\r\n]+|\s+/, $in{'value2'}); $vals = "$in{'value0'} $in{'value1'} ("; foreach my $ws (@ws) { $ws =~ /^[a-z]([\w\-]*\w)?$/i || &error(&text('edit_ebadserv', $ws)); $vals .= "\n\t\t\t\t\t$ws"; } $vals .= " )"; } elsif ($in{'type'} eq "RP") { if (!$in{'value0'}) { $in{'value0'} = "."; } elsif (!&valemail($in{'value0'})) { &error(&text('edit_eemail', $in{'value0'})); } &valname($in{'value1'}) || &error(&text('edit_etxt', $in{'value1'})); $in{'value0'} = &email_to_dotted($in{'value0'}); $vals = "$in{'value0'} $in{'value1'}"; } elsif ($in{'type'} eq "LOC") { $in{'value0'} =~ /\S/ || &error($text{'edit_eloc'}); } elsif ($in{'type'} eq 'SRV') { $in{'serv'} =~ /^[A-Za-z0-9\-\_]+$/ || &error(&text('edit_eserv2', $in{'serv'})); $in{'name'} = join(".", "_".$in{'serv'}, "_".$in{'proto'}, $in{'name'} ? ( $in{'name'} ) : ( )); $in{'value0'} =~ /^\d+$/ || &error(text('edit_epri', $in{'value0'})); $in{'value1'} =~ /^\d+$/ || &error(text('edit_eweight', $in{'value1'})); $in{'value2'} =~ /^\d+$/ || &error(text('edit_eport', $in{'value2'})); &valname($in{'value3'}) || &error(&text('edit_etarget', $in{'value3'})); } elsif ($in{'type'} eq 'TLSA') { $in{'serv'} =~ /^[A-Za-z0-9\-\_]+$/ || &error(&text('edit_eserv2', $in{'serv'})); $in{'name'} = join(".", "_".$in{'serv'}, "_".$in{'proto'}, $in{'name'} ? ( $in{'name'} ) : ( )); $in{'value0'} =~ /^\d+$/ || &error(text('edit_eusage', $in{'value0'})); $in{'value1'} =~ /^\d+$/ || &error(text('edit_eselector', $in{'value1'})); $in{'value2'} =~ /^\d+$/ || &error(text('edit_ematch', $in{'value2'})); $in{'value3'} =~ /^[a-f0-9]+$/ && length($in{'value3'}) % 2 == 0 || &error(&text('edit_etlsa', $in{'value3'})); } elsif ($in{'type'} eq 'SSHFP') { $in{'value0'} =~ /^\d+$/ || &error(text('edit_ealg', $in{'value0'})); $in{'value1'} =~ /^\d+$/ || &error(text('edit_efp', $in{'value1'})); $in{'value2'} =~ /^[a-f0-9]+$/ || &error(&text('edit_esshfp', $in{'value2'})); } elsif ($in{'type'} eq 'KEY') { $in{'value0'} =~ /^(\d+|0x[0-9a-f]+={0,2})$/i || &error(text('edit_eflags', $in{'value0'})); $in{'value1'} =~ /^\d+$/ || &error(text('edit_eproto', $in{'value1'})); $in{'value2'} =~ /^\d+$/ || &error(text('edit_ealg2', $in{'value2'})); $in{'value3'} =~ s/[ \r\n]//g; $in{'value3'} =~ /^[a-zA-Z0-9\/\+]+$/ || &error(text('edit_ekey')); $vals = join(" ", $in{'value0'}, $in{'value1'}, $in{'value2'}, $in{'value3'}); } elsif ($in{'type'} eq 'PTR') { $vals = $in{'value0'}; &valname($vals) || &error(&text('edit_eptr', $vals)); } elsif ($in{'type'} eq 'SPF') { # For SPF records, build the SPF string from the inputs my $spf = $r ? &parse_spf(@{$r->{'values'}}) : { }; $spf->{'a'} = $in{'spfa'}; $spf->{'mx'} = $in{'spfmx'}; $spf->{'ptr'} = $in{'spfptr'}; $spf->{'a:'} = [ split(/\s+/, $in{'spfas'}) ]; foreach my $a (@{$spf->{'a:'}}) { &to_ipaddress($a) || &error(&text('edit_espfa', $a)); &check_ipaddress($a) && &error(&text('edit_espfa2',$a)); } $spf->{'mx:'} = [ split(/\s+/, $in{'spfmxs'}) ]; foreach my $mx (@{$spf->{'mx:'}}) { &valname($mx) || &error(&text('edit_espfmx', $mx)); } @{$spf->{'mx:'}} <= 10 || &error(&text('edit_espfmxmax', 10)); $spf->{'ip4:'} = [ split(/\s+/, $in{'spfip4s'}) ]; foreach my $ip (@{$spf->{'ip4:'}}) { &check_ipaddress($ip) || ($ip =~ /^(\S+)\/\d+$/ && &check_ipaddress($1)) || &error(&text('edit_espfip', $ip)); } $spf->{'ip6:'} = [ split(/\s+/, $in{'spfip6s'}) ]; foreach my $ip (@{$spf->{'ip6:'}}) { &check_ip6address($ip) || ($ip =~ /^(\S+)\/\d+$/ && &check_ip6address($1)) || &error(&text('edit_espfip6', $ip)); } $spf->{'include:'} = [ split(/\s+/, $in{'spfincludes'}) ]; foreach my $i (@{$spf->{'include:'}}) { &valname($i) || &error(&text('edit_espfinclude', $i)); } $spf->{'all'} = $in{'spfall'}; foreach my $m ('redirect', 'exp') { if ($in{'spf'.$m.'_def'}) { delete($spf->{$m}); } else { &valname($in{'spf'.$m}) || &error(&text('edit_espf'.$m, $in{'spf'.$m})); $spf->{$m} = $in{'spf'.$m}; if ($m eq 'redirect') { delete($spf->{'all'}); } } } $vals = "\"".&join_spf($spf)."\""; } elsif ($in{'type'} eq 'DMARC') { # Build DMARC record from inputs my $dmarc = $r ? &parse_dmarc(@{$r->{'values'}}) : { }; $dmarc->{'p'} = $in{'dmarcp'}; $in{'dmarcpct'} =~ /^\d+$/ && $in{'dmarcpct'} >= 0 && $in{'dmarcpct'} <= 100 || &error($text{'edit_edmarcpct'}); $dmarc->{'pct'} = $in{'dmarcpct'}; if ($in{'dmarcsp'}) { $dmarc->{'sp'} = $in{'dmarcsp'}; } else { delete($dmarc->{'sp'}); } $dmarc->{'aspf'} = $in{'dmarcaspf'} ? 's' : 'r'; $dmarc->{'adkim'} = $in{'dmarcadkim'} ? 's' : 'r'; if ($in{'dmarcrua_def'}) { delete($dmarc->{'rua'}); } else { $in{'dmarcrua'} =~ /^\S+$/ || &error($text{'edit_edmarcrua'}); $in{'dmarcrua'} = 'mailto:'.$in{'dmarcrua'} if ($in{'dmarcrua'} !~ /^[a-z]+:/i); $dmarc->{'rua'} = $in{'dmarcrua'}; } if ($in{'dmarcruf_def'}) { delete($dmarc->{'ruf'}); } else { $in{'dmarcruf'} =~ /^\S+$/ || &error($text{'edit_edmarcruf'}); $in{'dmarcruf'} = 'mailto:'.$in{'dmarcruf'} if ($in{'dmarcruf'} !~ /^[a-z]+:/i); $dmarc->{'ruf'} = $in{'dmarcruf'}; } if ($in{'dmarcfo'} eq '') { delete($dmarc->{'fo'}); } else { $dmarc->{'fo'} = $in{'dmarcfo'}; } if ($in{'dmarcrf'} eq '') { delete($dmarc->{'rf'}); } else { $dmarc->{'rf'} = $in{'dmarcrf'}; } if ($in{'dmarcri'} eq '') { delete($dmarc->{'ri'}); } else { $dmarc->{'ri'} = $in{'dmarcri'}; } $vals = "\"".&join_dmarc($dmarc)."\""; } elsif ($in{'type'} eq 'NSEC3PARAM') { # Save DNSSEC parameters $in{'value2'} =~ /^\d+$/ || &error($text{'edit_ensec3value2'}); $in{'value3'} =~ /^[a-zA-Z0-9\+\/]+$/ || &error($text{'edit_ensec3value2'}); $vals = join(" ", "(", $in{'value0'}, $in{'value1'}, $in{'value2'}, $in{'value3'}, ")"); } elsif ($in{'type'} eq 'CAA') { $in{'value2'} =~ /^\S+$/ || &error($text{'edit_ecaavalue2'}); $vals = join(" ", $in{'value0'}, $in{'value1'}, "\"$in{'value2'}\""); } elsif ($in{'type'} eq 'NAPTR') { my $flags = join("", split(/\0/, $in{'value2'})); $in{'value0'} =~ /^\d+$/ || &error($text{'edit_enaptrvalue0'}); $in{'value1'} =~ /^\d+$/ || &error($text{'edit_enaptrvalue1'}); $in{'value3'} =~ /^\S+$/ || &error($text{'edit_enaptrvalue3'}); if (!$in{'value4_def'} && !$in{'value5_def'}) { &error($text{'edit_enaptrvalue4'}); } $vals = join(" ", $in{'value0'}, $in{'value1'}, "\"$flags\"", "\"$in{'value3'}\"", $in{'value4_def'} ? "\"\"" : "\"$in{'value4'}\"", $in{'value5_def'} ? "." : $in{'value5'}); } else { # For other record types, just save the lines $in{'values'} =~ s/\r//g; my @vlines = split(/\n/, $in{'values'}); $vals = join(" ",map { $_ =~ /\s|;/ ? "\"$_\"" : $_ } @vlines); } $fullname = &convert_to_absolute($in{'name'}, $in{'origin'}); if ($config{'short_names'}) { $name = $in{'name'}; } else { $name = $fullname; } } # check for CNAME collision if (!defined($in{'num'}) || $name ne $r->{'name'}) { foreach my $cr (@recs) { if ($cr->{'name'} eq $name) { if ($in{'type'} eq 'CNAME') { &error($text{'edit_ecname1'}); } elsif ($cr->{'type'} eq 'CNAME') { &error($text{'edit_ecname2'}); } } } } if ($in{'new'}) { # adding a new record my ($revconf, $revfile, $revrec) = &find_reverse($in{'value0'}, $in{'view'}); if ($in{'rev'} && $config{'rev_must'} && !$revconf) { # Reverse zone must exist, but doesn't &error($text{'edit_erevmust'}); } &create_record($in{'file'}, $name, $ttl, "IN", $in{'type'}, $vals, $in{'comment'}); $r = { 'name' => $name, 'ttl' => $ttl, 'class' => 'IN', 'type' => $in{'type'}, 'values' => [ split(/\s+/, $vals) ], 'comment' => $in{'comment'} }; if ($in{'rev'} && $revconf && &can_edit_reverse($revconf) && $in{'value0'} !~ /\*/) { my $rname = &make_reverse_name($in{'value0'}, $in{'type'}, $revconf); if ($revrec && $in{'rev'} == 2) { # Update the existing reverse for the domain &lock_file(&make_chroot($revrec->{'file'})); &modify_record($revrec->{'file'}, $revrec, $rname, $revrec->{'ttl'}, "IN", "PTR", $fullname); my @rrecs = &read_zone_file($revfile, $revconf->{'name'}); &bump_soa_record($revfile, \@rrecs); &sign_dnssec_zone_if_key($revconf, \@rrecs); } elsif (!$revrec) { # Add a reverse record if we are the master for the # reverse domain, and if there is not already a # reverse record for the address. &lock_file(&make_chroot($revfile)); &create_record($revfile, $rname, $ttl, "IN", "PTR", $fullname); my @rrecs = &read_zone_file($revfile, $revconf->{'name'}); &bump_soa_record($revfile, \@rrecs); &sign_dnssec_zone_if_key($revconf, \@rrecs); } } my ($fwdconf, $fwdfile, $fwdrec) = &find_forward($vals, $vals =~ /\.$ipv6revzone/i); if ($in{'fwd'} && $fwdconf && !$fwdrec && &can_edit_zone($fwdconf)) { # Add a forward record if we are the master for the forward # domain, and if there is not already an A record # for the address my ($rtype); if (&check_ipaddress($in{'name'})) { $rtype = "A"; } elsif ($config{'support_aaaa'} && &check_ip6address($in{'name'})) { $rtype = "AAAA"; } if ($rtype) { &lock_file(&make_chroot($fwdfile)); &create_record($fwdfile, $vals, $ttl, "IN", $rtype, $in{'name'}); my @frecs = &read_zone_file($fwdfile, $fwdconf->{'name'}); &bump_soa_record($fwdfile, \@frecs); &sign_dnssec_zone_if_key($fwdconf, \@frecs); } } } else { # update an existing record $fulloldvalue0 = &convert_to_absolute($in{'oldvalue0'}, $in{'origin'}); $fulloldname = &convert_to_absolute($in{'oldname'}, $in{'origin'}); my ($orevconf, $orevfile, $orevrec) = &find_reverse($in{'oldvalue0'}, $in{'view'}); my ($revconf, $revfile, $revrec) = &find_reverse($in{'value0'}, $in{'view'}); if ($in{'rev'} && $config{'rev_must'} && !$revconf) { # Reverse zone must exist, but doesn't &error($text{'edit_erevmust'}); } &lock_file(&make_chroot($r->{'file'})); &modify_record($r->{'file'}, $r, $name, $ttl, "IN", $in{'type'}, $vals, $in{'comment'}); # Build names for the new and old reverse records my ($rname, $orname); if ($revconf) { $rname = &make_reverse_name($in{'value0'}, $in{'type'}, $revconf); } if ($orevconf) { $orname = &make_reverse_name($in{'oldvalue0'}, $in{'type'}, $orevconf); } if ($in{'rev'} && $orevrec && &can_edit_reverse($orevconf) && $fulloldname eq $orevrec->{'values'}->[0] && ($in{'type'} eq "A" || $in{'type'} eq "AAAA" && &expandall_ip6($in{'oldvalue0'}) eq &expandall_ip6(&ip6int_to_net($orevrec->{'name'})))) { # Updating the reverse record. Either the name, address # or both may have changed. Furthermore, the reverse record # may now be in a different file! &before_editing($orevconf); &before_editing($revconf); &lock_file(&make_chroot($orevfile)); &lock_file(&make_chroot($revfile)); my @orrecs = &read_zone_file($orevfile, $orevconf->{'name'}); my @rrecs = &read_zone_file($revfile, $revconf->{'name'}); if ($revconf eq $orevconf && &can_edit_reverse($revconf)) { # old and new in the same file &modify_record($orevrec->{'file'} , $orevrec, $rname, $orevrec->{'ttl'}, "IN", "PTR", $fullname, $in{'comment'}); &bump_soa_record($orevfile, \@orrecs); &sign_dnssec_zone_if_key($orevconf, \@orrecs); } elsif ($revconf && &can_edit_reverse($revconf)) { # old and new in different files &delete_record($orevrec->{'file'} , $orevrec); &create_record($revfile, $rname, $orevrec->{'ttl'}, "IN", "PTR", $fullname, $in{'comment'}); &bump_soa_record($orevfile, \@orrecs); &bump_soa_record($revfile, \@rrecs); &sign_dnssec_zone_if_key($orevconf, \@orrecs); &sign_dnssec_zone_if_key($revconf, \@rrecs); } else { # we don't handle the new reverse domain.. lose the # reverse record &delete_record($orevrec->{'file'}, $orevrec); &bump_soa_record($orevfile, \@orrecs); &sign_dnssec_zone_if_key($orevconf, \@orrecs); } &after_editing($revconf); &after_editing($orevconf); } elsif ($in{'rev'} && !$orevrec && $revconf && !$revrec && &can_edit_reverse($revconf)) { # we don't handle the old reverse domain but handle the new # one.. create a new reverse record &before_editing($revconf); &lock_file(&make_chroot($revfile)); my @rrecs = &read_zone_file($revfile, $revconf->{'name'}); &create_record($revfile, $rname, $ttl, "IN", "PTR", $fullname, $in{'comment'}); &bump_soa_record($revfile, \@rrecs); &sign_dnssec_zone_if_key($revconf, \@rrecs); &after_editing($revconf); } my $ipv6; ($ipv6 = ($in{'value0'} =~ /\.$ipv6revzone/i)); my ($ofwdconf, $ofwdfile, $ofwdrec) = &find_forward($fulloldvalue0, $ipv6); my ($fwdconf, $fwdfile, $fwdrec) = &find_forward($in{'value0'}, $ipv6); if ($in{'fwd'} && $ofwdrec && &can_edit_zone($ofwdconf) && &expandall_ip6(&ip6int_to_net(&arpa_to_ip($in{'oldname'}))) eq &expandall_ip6($ofwdrec->{'values'}->[0]) && $fulloldvalue0 eq $ofwdrec->{'name'}) { # Updating the forward record &before_editing($ofwdfile); &before_editing($fwdfile); &lock_file(&make_chroot($ofwdfile)); &lock_file(&make_chroot($fwdfile)); my @ofrecs = &read_zone_file($ofwdfile, $ofwdconf->{'name'}); my @frecs = &read_zone_file($fwdfile, $fwdconf->{'name'}); if ($fwdconf eq $ofwdconf && &can_edit_zone($fwdconf)) { # old and new are in the same file &modify_record($ofwdrec->{'file'} , $ofwdrec, $vals, $ofwdrec->{'ttl'}, "IN", $ipv6 ? "AAAA" : "A", $in{'name'}, $in{'comment'}); &bump_soa_record($ofwdfile, \@ofrecs); &sign_dnssec_zone_if_key($ofwdconf, \@ofrecs); } elsif ($fwdconf && &can_edit_zone($fwdconf)) { # old and new in different files &delete_record($ofwdrec->{'file'} , $ofwdrec); if (!$ipv6 || $config{'support_aaaa'}) { &create_record($fwdfile, $vals, $ofwdrec->{'ttl'}, "IN", $ipv6 ? "AAAA" : "A", $in{'name'}, $in{'comment'}); &bump_soa_record($fwdfile, \@frecs); &sign_dnssec_zone_if_key($fwdconf, \@frecs); } &bump_soa_record($ofwdfile, \@ofrecs); &sign_dnssec_zone_if_key($ofwdconf, \@ofrecs); } else { # lose the forward because it has been moved to # a zone not handled by this server &delete_record($ofwdrec->{'file'} , $ofwdrec); &bump_soa_record($ofwdfile, \@ofrecs); &sign_dnssec_zone_if_key($ofwdconf, \@ofrecs); } &after_editing($fwdfile); &after_editing($ofwdfile); } } &bump_soa_record($in{'file'}, \@recs); &sign_dnssec_zone_if_key($zone, \@recs); &after_editing($zone); &unlock_all_files(); $r->{'newvalues'} = $vals; &webmin_log($in{'new'} ? 'create' : 'modify', 'record', $in{'origin'}, $r); &redirect("edit_recs.cgi?zone=$in{'zone'}&view=$in{'view'}&". "type=$in{'redirtype'}&sort=$in{'sort'}"); # valname(name) sub valname { return valdnsname($_[0], 0, $in{'origin'}); } # valnamewild(name) sub valnamewild { return valdnsname($_[0], 1, $in{'origin'}); }
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
images | Folder | 0755 |
|
|
lang | Folder | 0755 |
|
|
CHANGELOG | File | 12.67 KB | 0644 |
|
acl_security.pl | File | 10.25 KB | 0755 |
|
backup_config.pl | File | 1.47 KB | 0755 |
|
bind8-lib.pl | File | 115.83 KB | 0755 |
|
cgi_args.pl | File | 1.92 KB | 0755 |
|
check_zone.cgi | File | 1.04 KB | 0755 |
|
close.cgi | File | 342 B | 0755 |
|
conf_acls.cgi | File | 989 B | 0755 |
|
conf_controls.cgi | File | 2.34 KB | 0755 |
|
conf_dnssec.cgi | File | 936 B | 0755 |
|
conf_dnssectools.cgi | File | 2.16 KB | 0755 |
|
conf_files.cgi | File | 1.19 KB | 0755 |
|
conf_forwarding.cgi | File | 1.54 KB | 0755 |
|
conf_keys.cgi | File | 1.07 KB | 0755 |
|
conf_logging.cgi | File | 4.85 KB | 0755 |
|
conf_manual.cgi | File | 1.21 KB | 0755 |
|
conf_misc.cgi | File | 1.95 KB | 0755 |
|
conf_ncheck.cgi | File | 807 B | 0755 |
|
conf_net.cgi | File | 3.49 KB | 0755 |
|
conf_rndc.cgi | File | 1.15 KB | 0755 |
|
conf_servers.cgi | File | 1.8 KB | 0755 |
|
conf_trusted.cgi | File | 2.84 KB | 0755 |
|
conf_zonedef.cgi | File | 4.9 KB | 0755 |
|
config-AlmaLinux-6.0-ALL | File | 989 B | 0644 |
|
config-CentOS-Linux-6.0-7.9 | File | 997 B | 0644 |
|
config-CentOS-Linux-8.0-ALL | File | 989 B | 0644 |
|
config-CentOS-Stream-Linux-8.0-ALL | File | 989 B | 0644 |
|
config-CloudLinux-8.0-ALL | File | 989 B | 0644 |
|
config-Oracle-Linux-8.0-ALL | File | 989 B | 0644 |
|
config-Redhat-Enterprise-Linux-6.0-7.9 | File | 976 B | 0644 |
|
config-Redhat-Enterprise-Linux-8.0-ALL | File | 989 B | 0644 |
|
config-Rocky-Linux-6.0-ALL | File | 989 B | 0644 |
|
config-Scientific-Linux-6.0-ALL | File | 935 B | 0644 |
|
config-aix | File | 717 B | 0644 |
|
config-cobalt-linux | File | 722 B | 0644 |
|
config-coherent-linux | File | 857 B | 0644 |
|
config-corel-linux | File | 722 B | 0644 |
|
config-debian-linux | File | 722 B | 0644 |
|
config-debian-linux-10.0-ALL | File | 991 B | 0644 |
|
config-debian-linux-2.2 | File | 727 B | 0644 |
|
config-debian-linux-3.0 | File | 842 B | 0644 |
|
config-debian-linux-3.1-9.0 | File | 934 B | 0644 |
|
config-freebsd-12.0-ALL | File | 790 B | 0644 |
|
config-freebsd-2.1-2.2 | File | 728 B | 0644 |
|
config-freebsd-3.0 | File | 729 B | 0644 |
|
config-freebsd-3.1-3.5 | File | 722 B | 0644 |
|
config-freebsd-4.0-11.0 | File | 757 B | 0644 |
|
config-generic-linux | File | 750 B | 0644 |
|
config-gentoo-linux | File | 827 B | 0644 |
|
config-hpux | File | 722 B | 0644 |
|
config-irix | File | 722 B | 0644 |
|
config-macos | File | 728 B | 0644 |
|
config-macos-1.3-ALL | File | 789 B | 0644 |
|
config-mandrake-linux | File | 814 B | 0644 |
|
config-mandrake-linux-10.2-ALL | File | 802 B | 0644 |
|
config-msc-linux | File | 788 B | 0644 |
|
config-netbsd | File | 729 B | 0644 |
|
config-open-linux | File | 798 B | 0644 |
|
config-openSUSE-Linux-15.0-ALL | File | 938 B | 0644 |
|
config-openbsd-2.5-3.1 | File | 722 B | 0644 |
|
config-openbsd-3.2-ALL | File | 740 B | 0644 |
|
config-openmamba-linux | File | 798 B | 0644 |
|
config-openserver | File | 722 B | 0644 |
|
config-osf1 | File | 722 B | 0644 |
|
config-pardus-linux | File | 875 B | 0644 |
|
config-redhat-linux-7.0-ALL | File | 989 B | 0644 |
|
config-redhat-linux-ALL-6.0 | File | 997 B | 0644 |
|
config-slackware-linux | File | 722 B | 0644 |
|
config-slackware-linux-8.0-ALL | File | 756 B | 0644 |
|
config-sol-linux | File | 850 B | 0644 |
|
config-solaris | File | 737 B | 0644 |
|
config-solaris-10-ALL | File | 835 B | 0644 |
|
config-solaris-7-9 | File | 725 B | 0644 |
|
config-suse-linux | File | 722 B | 0644 |
|
config-suse-linux-8.2 | File | 882 B | 0644 |
|
config-suse-linux-9.0-9.2 | File | 995 B | 0644 |
|
config-suse-linux-9.3-ALL | File | 1.03 KB | 0644 |
|
config-syno-linux | File | 683 B | 0644 |
|
config-trustix-linux | File | 927 B | 0644 |
|
config-trustix-linux-2.1 | File | 923 B | 0644 |
|
config-trustix-linux-2.2-ALL | File | 939 B | 0644 |
|
config-turbo-linux | File | 722 B | 0644 |
|
config-united-linux | File | 822 B | 0644 |
|
config-unixware | File | 763 B | 0644 |
|
config-windows | File | 1.17 KB | 0644 |
|
config.info | File | 4.02 KB | 0644 |
|
config.info.bg | File | 6.88 KB | 0644 |
|
config.info.ca | File | 4.5 KB | 0644 |
|
config.info.cs | File | 3.34 KB | 0644 |
|
config.info.de | File | 4.6 KB | 0644 |
|
config.info.es | File | 3.33 KB | 0644 |
|
config.info.fa | File | 4.7 KB | 0644 |
|
config.info.fr | File | 4.92 KB | 0644 |
|
config.info.hu | File | 0 B | 0644 |
|
config.info.ja | File | 4.03 KB | 0644 |
|
config.info.ms | File | 1.12 KB | 0644 |
|
config.info.nl | File | 4.1 KB | 0644 |
|
config.info.no | File | 4 KB | 0644 |
|
config.info.pl | File | 4.42 KB | 0644 |
|
config.info.pt_BR | File | 3.86 KB | 0644 |
|
config.info.ru | File | 3.02 KB | 0644 |
|
config.info.sv | File | 1.02 KB | 0644 |
|
config.info.tr | File | 646 B | 0644 |
|
config.info.uk | File | 3.14 KB | 0644 |
|
config.info.zh | File | 750 B | 0644 |
|
config.info.zh_TW | File | 364 B | 0644 |
|
convert_master.cgi | File | 1.02 KB | 0755 |
|
convert_slave.cgi | File | 1.44 KB | 0755 |
|
cpan_modules.pl | File | 143 B | 0644 |
|
create_delegation.cgi | File | 1.77 KB | 0755 |
|
create_forward.cgi | File | 2.09 KB | 0755 |
|
create_hint.cgi | File | 1.47 KB | 0755 |
|
create_master.cgi | File | 5.61 KB | 0755 |
|
create_slave.cgi | File | 4.1 KB | 0755 |
|
create_view.cgi | File | 1.5 KB | 0755 |
|
db.cache | File | 2.44 KB | 0644 |
|
defaultacl | File | 219 B | 0644 |
|
delegation_form.cgi | File | 1.3 KB | 0755 |
|
delete_recs.cgi | File | 2.66 KB | 0755 |
|
delete_view.cgi | File | 2.34 KB | 0755 |
|
delete_zone.cgi | File | 5.3 KB | 0755 |
|
disable_zonedt.cgi | File | 934 B | 0755 |
|
disable_zonekey.cgi | File | 928 B | 0755 |
|
dns_boot.cgi | File | 2.56 KB | 0755 |
|
edit_delegation.cgi | File | 1.11 KB | 0755 |
|
edit_forward.cgi | File | 1.82 KB | 0755 |
|
edit_hint.cgi | File | 1 KB | 0755 |
|
edit_master.cgi | File | 5.75 KB | 0755 |
|
edit_options.cgi | File | 1.62 KB | 0755 |
|
edit_record.cgi | File | 1.13 KB | 0755 |
|
edit_recs.cgi | File | 7.59 KB | 0755 |
|
edit_slave.cgi | File | 3.93 KB | 0755 |
|
edit_soa.cgi | File | 2.51 KB | 0755 |
|
edit_soptions.cgi | File | 2.27 KB | 0755 |
|
edit_stub.cgi | File | 3.93 KB | 0755 |
|
edit_text.cgi | File | 1.26 KB | 0755 |
|
edit_view.cgi | File | 2.12 KB | 0755 |
|
edit_zonedt.cgi | File | 6.52 KB | 0755 |
|
edit_zonekey.cgi | File | 4.13 KB | 0755 |
|
enable_zonedt.cgi | File | 1.12 KB | 0755 |
|
enable_zonekey.cgi | File | 1.42 KB | 0755 |
|
feedback_files.pl | File | 588 B | 0755 |
|
find_free.cgi | File | 5.59 KB | 0755 |
|
find_zones.cgi | File | 3.89 KB | 0755 |
|
fix_trusted.cgi | File | 1 KB | 0755 |
|
forward_form.cgi | File | 1.38 KB | 0755 |
|
free_chooser.cgi | File | 2 KB | 0755 |
|
freeze_zone.cgi | File | 992 B | 0755 |
|
hint_form.cgi | File | 1.79 KB | 0755 |
|
index.cgi | File | 17.51 KB | 0755 |
|
install_check.pl | File | 513 B | 0755 |
|
list_gen.cgi | File | 1.95 KB | 0755 |
|
list_slaves.cgi | File | 3.28 KB | 0755 |
|
log_parser.pl | File | 2.47 KB | 0755 |
|
mass_create.cgi | File | 7.33 KB | 0755 |
|
mass_delete.cgi | File | 3.42 KB | 0755 |
|
mass_form.cgi | File | 1.44 KB | 0755 |
|
mass_rcreate.cgi | File | 3.56 KB | 0755 |
|
mass_rcreate_form.cgi | File | 1.49 KB | 0755 |
|
mass_rdelete.cgi | File | 1.87 KB | 0755 |
|
mass_rdelete_form.cgi | File | 1.3 KB | 0755 |
|
mass_update.cgi | File | 3 KB | 0755 |
|
mass_update_form.cgi | File | 1.07 KB | 0755 |
|
master_form.cgi | File | 3.48 KB | 0755 |
|
module.info | File | 279 B | 0644 |
|
module.info.af | File | 0 B | 0644 |
|
module.info.af.auto | File | 116 B | 0644 |
|
module.info.ar | File | 0 B | 0644 |
|
module.info.ar.auto | File | 152 B | 0644 |
|
module.info.be | File | 0 B | 0644 |
|
module.info.be.auto | File | 173 B | 0644 |
|
module.info.bg | File | 30 B | 0644 |
|
module.info.bg.auto | File | 143 B | 0644 |
|
module.info.ca | File | 106 B | 0644 |
|
module.info.ca.auto | File | 16 B | 0644 |
|
module.info.cs | File | 24 B | 0644 |
|
module.info.cs.auto | File | 105 B | 0644 |
|
module.info.da | File | 0 B | 0644 |
|
module.info.da.auto | File | 122 B | 0644 |
|
module.info.de | File | 113 B | 0644 |
|
module.info.de.auto | File | 15 B | 0644 |
|
module.info.el | File | 0 B | 0644 |
|
module.info.el.auto | File | 199 B | 0644 |
|
module.info.es | File | 29 B | 0644 |
|
module.info.es.auto | File | 90 B | 0644 |
|
module.info.eu | File | 0 B | 0644 |
|
module.info.eu.auto | File | 129 B | 0644 |
|
module.info.fa | File | 0 B | 0644 |
|
module.info.fa.auto | File | 164 B | 0644 |
|
module.info.fi | File | 0 B | 0644 |
|
module.info.fi.auto | File | 129 B | 0644 |
|
module.info.fr | File | 41 B | 0644 |
|
module.info.fr.auto | File | 113 B | 0644 |
|
module.info.he | File | 0 B | 0644 |
|
module.info.he.auto | File | 147 B | 0644 |
|
module.info.hr | File | 0 B | 0644 |
|
module.info.hr.auto | File | 124 B | 0644 |
|
module.info.hu | File | 27 B | 0644 |
|
module.info.hu.auto | File | 125 B | 0644 |
|
module.info.it | File | 0 B | 0644 |
|
module.info.it.auto | File | 107 B | 0644 |
|
module.info.ja | File | 27 B | 0644 |
|
module.info.ja.auto | File | 134 B | 0644 |
|
module.info.ko | File | 25 B | 0644 |
|
module.info.ko.auto | File | 111 B | 0644 |
|
module.info.lt | File | 0 B | 0644 |
|
module.info.lt.auto | File | 128 B | 0644 |
|
module.info.lv | File | 0 B | 0644 |
|
module.info.lv.auto | File | 132 B | 0644 |
|
module.info.ms | File | 110 B | 0644 |
|
module.info.ms.auto | File | 13 B | 0644 |
|
module.info.mt | File | 0 B | 0644 |
|
module.info.mt.auto | File | 114 B | 0644 |
|
module.info.nl | File | 24 B | 0644 |
|
module.info.nl.auto | File | 87 B | 0644 |
|
module.info.no | File | 24 B | 0644 |
|
module.info.no.auto | File | 98 B | 0644 |
|
module.info.pl | File | 96 B | 0644 |
|
module.info.pl.auto | File | 17 B | 0644 |
|
module.info.pt | File | 29 B | 0644 |
|
module.info.pt.auto | File | 101 B | 0644 |
|
module.info.pt_BR | File | 32 B | 0644 |
|
module.info.pt_BR.auto | File | 107 B | 0644 |
|
module.info.ro | File | 0 B | 0644 |
|
module.info.ro.auto | File | 131 B | 0644 |
|
module.info.ru | File | 30 B | 0644 |
|
module.info.ru.auto | File | 167 B | 0644 |
|
module.info.sk | File | 0 B | 0644 |
|
module.info.sk.auto | File | 125 B | 0644 |
|
module.info.sl | File | 0 B | 0644 |
|
module.info.sl.auto | File | 128 B | 0644 |
|
module.info.sv | File | 24 B | 0644 |
|
module.info.sv.auto | File | 93 B | 0644 |
|
module.info.th | File | 0 B | 0644 |
|
module.info.th.auto | File | 218 B | 0644 |
|
module.info.tr | File | 26 B | 0644 |
|
module.info.tr.auto | File | 121 B | 0644 |
|
module.info.uk | File | 0 B | 0644 |
|
module.info.uk.auto | File | 197 B | 0644 |
|
module.info.ur | File | 0 B | 0644 |
|
module.info.ur.auto | File | 193 B | 0644 |
|
module.info.vi | File | 0 B | 0644 |
|
module.info.vi.auto | File | 151 B | 0644 |
|
module.info.zh | File | 27 B | 0644 |
|
module.info.zh.auto | File | 83 B | 0644 |
|
module.info.zh_TW | File | 30 B | 0644 |
|
module.info.zh_TW.auto | File | 89 B | 0644 |
|
move_zone.cgi | File | 1.27 KB | 0755 |
|
old_save_controls.cgi | File | 2.13 KB | 0755 |
|
open.cgi | File | 307 B | 0755 |
|
prefs.info | File | 61 B | 0644 |
|
records-lib.pl | File | 26.64 KB | 0755 |
|
refetch.cgi | File | 705 B | 0755 |
|
resign.pl | File | 2.11 KB | 0755 |
|
resign_zone.cgi | File | 708 B | 0755 |
|
restart.cgi | File | 819 B | 0755 |
|
restart_zone.cgi | File | 655 B | 0755 |
|
save_acls.cgi | File | 1.6 KB | 0755 |
|
save_controls.cgi | File | 2.3 KB | 0755 |
|
save_dnssec.cgi | File | 1.29 KB | 0755 |
|
save_dnssectools.cgi | File | 1.39 KB | 0755 |
|
save_files.cgi | File | 831 B | 0755 |
|
save_forward.cgi | File | 847 B | 0755 |
|
save_forwarding.cgi | File | 1.08 KB | 0755 |
|
save_gen.cgi | File | 3.79 KB | 0755 |
|
save_keys.cgi | File | 1.15 KB | 0755 |
|
save_logging.cgi | File | 2.97 KB | 0755 |
|
save_manual.cgi | File | 774 B | 0755 |
|
save_master.cgi | File | 1.06 KB | 0755 |
|
save_misc.cgi | File | 1.3 KB | 0755 |
|
save_net.cgi | File | 3.16 KB | 0755 |
|
save_record.cgi | File | 23.06 KB | 0755 |
|
save_rndc.cgi | File | 2.93 KB | 0755 |
|
save_servers.cgi | File | 1.73 KB | 0755 |
|
save_slave.cgi | File | 1.6 KB | 0755 |
|
save_soa.cgi | File | 2.58 KB | 0755 |
|
save_text.cgi | File | 1.12 KB | 0755 |
|
save_trusted.cgi | File | 2.76 KB | 0755 |
|
save_view.cgi | File | 1.36 KB | 0755 |
|
save_zonedef.cgi | File | 3.05 KB | 0755 |
|
sign_zone.cgi | File | 770 B | 0755 |
|
slave_add.cgi | File | 4.97 KB | 0755 |
|
slave_delete.cgi | File | 651 B | 0755 |
|
slave_form.cgi | File | 2.16 KB | 0755 |
|
start.cgi | File | 467 B | 0755 |
|
stop.cgi | File | 341 B | 0755 |
|
stub_form.cgi | File | 2.16 KB | 0755 |
|
syslog_logs.pl | File | 708 B | 0755 |
|
system_info.pl | File | 1.11 KB | 0644 |
|
unfreeze_zone.cgi | File | 990 B | 0755 |
|
view_form.cgi | File | 1.11 KB | 0755 |
|
view_text.cgi | File | 1.05 KB | 0755 |
|
whois.cgi | File | 1.14 KB | 0755 |
|
xfer.cgi | File | 1.66 KB | 0755 |
|
zone_dnssecmgt_dt.cgi | File | 1.37 KB | 0755 |
|
zone_dnssecmigrate_dt.cgi | File | 2.32 KB | 0755 |
|