⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 save_record.cgi

📁 BIND 9 dynamic DNS webmin module. This module supports both static and dynamic zones, and IPv4 and I
💻 CGI
📖 第 1 页 / 共 3 页
字号:
#! /usr/bin/perl##    B9DDNS - BIND 9 dynamic DNS webmin module.#    Copyright (C) 2003 John Horne. <john.horne@plymouth.ac.uk>#    Copyright (C) 2004 John Horne. <john.horne@plymouth.ac.uk>##    This program is free software; you can redistribute it and/or modify#    it under the terms of the GNU General Public License as published by#    the Free Software Foundation; either version 2 of the License, or#    (at your option) any later version.##    This program is distributed in the hope that it will be useful,#    but WITHOUT ANY WARRANTY; without even the implied warranty of#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the#    GNU General Public License for more details.##    You should have received a copy of the GNU General Public License#    along with this program; if not, write to the Free Software#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.### Creates, deletes or updates a record of some type.#use strict;no strict 'vars';require './b9ddns-lib.pl';my $ipv4_zone = my $ipv4_rec = my $reverse = my $dynamic = my $ttl = 0;my $serial = my $new_serial = my $new = my $i = 0;my $old_rev_dynamic = my $new_rev_dynamic = 0;my $old_rev_serial = my $new_rev_serial = 0;my $only_ttl_changed = 0;my $conf = my $zone = my $view = my $rec = my $origin = '';my $oconf = my $ofile = my $orec = '';my $fwdconf = my $fwdfile = my $fwdrec = '';my $revconf = my $revfile = my $revrec = '';my $value = my $name = my $type = my $file = '';my $sfx = my $zn = my $z = my $v = '';my $rname = my $rtype = my $zone_ref = '';my $rec_name = my $oldname = my $oldvalue = '';my @zone_list = my @recs = my @orecs = ();&ReadParse();%access = &get_module_acl();if ($access{'ro'}) {	&terror('master_ero');}$conf = &get_config();if ($in{'view'}) {	$view = $conf->[$in{'view'}];	$conf = $view->{'members'};}@zone_list = &find('zone', $conf);$origin = lc($in{'origin'});$origin .= '.' unless ($origin =~ /\.$/o);($zone) = grep { $origin =~ /^$_->{'value'}\.?$/i } @zone_list;unless (&can_edit_zone(\%access, $zone, $view)) {	&terror('recs_ecannot');}$file = $in{'file'};$zone_ref = &get_zone_data($zone);$dynamic = $zone_ref->[1];if ($dynamic) {	if ($dynamic == 2) {		&terror('recs_eupdate');	}}else {	&lock_file($config{'chroot'} . &absolute_path($file));}%sd_zones = ();@recs = &get_zone($zone, $file, $origin, undef, $in{'ztype'});## Can we modify the serial number?#$new_serial = &check_serial_number($zone_ref, $zone, \@recs, undef);$new++ if ($in{'new'});$type = $in{'type'};$oldname = lc($in{'oldname'});$oldvalue = lc($in{'oldvalue'});if ($origin =~ /\.(in-addr|ip6)\.arpa\.$/o) {	$reverse++;	$ipv4_zone++ if ($1 eq 'in-addr');}&error_setup($text{'edit_err'});## Get the old record if necessary.#if (defined($in{'num'})) {	$rec = $recs[$in{'num'}];	$rec_name = $rec->{'fqdn'};}else {	$rec = $rec_name = undef;}## This is a bit messy but we must check whether we can update the *old*# reverse/forward zone's SOA serial number *before* we remove or change the# reverse/forward record.## Ultimately, and in the worst-case scenario, we shall have to check the serial# number for 3 zones - the old and new reverse zones and the new forward zone.# If any of these fail then the entire operation should be aborted.#if (($in{'rev'} || $in{'fwd'}) && ($oldname !~ /\*/o || $in{'delete'}) &&    ($in{'delete'} || ! $new)) {	if ($in{'rev'}) {		($oconf, $ofile, $orec) = &find_reverse($oldvalue, $oldname);	}	else {		($oconf, $ofile, $orec) = &find_forward($oldvalue, $oldname, $ipv4_zone);	}	($old_rev_serial, $old_rev_dynamic) = &check_rev_serial($oconf);}## For certain record types we must qualify the rdata domain name - for example,# a CNAME record may be stored using abbreviated names as in 'www in cname# fred'. We must do this now in the case of existing dynamic records since# they will require FQDN names being specified, and we may be about to delete# the record. For static zones the conversion, if required, is done later on.#if ($dynamic && ! $new) {	$i = &convert_value($type, undef);	if ($i >= 0) {		$oldvalue = $rec->{'values'}->[$i] = &convert_fqdn(1, $oldvalue, $origin, 1);	}}## Check for deleting a record.#if ($in{'delete'}) {	#	# First check if we are deleting a top-level name.	#	if ($reverse) {		if ($in{'fwd'}) {			unless (&check_tld($oldvalue, $oconf, \%access, 'master', $type)) {				&terror('edit_tld');			}		}	}	else {		unless (&check_tld($rec_name, $origin, \%access, $in{'ztype'}, $type)) {			&terror('edit_tld');		}		if ($type eq 'DNAME') {			unless (&check_sd($rec_name, $origin, \%access, $in{'ztype'}, $type)) {				&terror('edit_sd');			}		}	}	&fix_oldtxt_rec() if ($type eq 'TXT');	&delete_record($zone, $file, $rec);	&bump_soa_record($zone, \@recs, $new_serial);	&delete_rev_rec();	# Delete any reverse or forward record.	&unlock_all_files();	&webmin_log('delete', 'record', $origin, $rec);	&redirect("edit_recs.cgi?index=$in{'index'}&view=$in{'view'}&type=$in{'redirtype'}&sort=$in{'sort'}&file=${file}&ztype=$in{'ztype'}");	exit;}## Parse the inputs.### Are wildcards allowed in the name? Generally wildcards are accepted for most# record types. They are not allowed for NS and DNAME records. However, we also# restrict the use of wildcards to specific types since their use in other# records could either lead to problems or simply be confusing.#&trim($in{'name'});unless ($in{'name'}) {	&terror('edit_emissing');}elsif (! $config{'allow_wild'} && $in{'name'} =~ /\*/o) {	&terror('wild_no', $in{'name'});}else {	$i = ($type =~ /^(A|AAAA|PTR|MX|CNAME|TXT|RP|LOC|HINFO)$/o);	$name = &convert_fqdn(1, $in{'name'}, $origin, 1);	if ($reverse) {		if ($ipv4_zone) {		# IPv4 address.			$v = &compress_ip(&arpa_to_ip($name));			$name = &ip_to_arpa($v);		}		else {				# IPv6 address.			$v = &ip6arpa_to_net($name);			$v = &compress_ip6($v) unless ($type eq 'DNAME');			$name = &net_to_ip6arpa($v);		}		unless (&valipaddr($v, $origin, 1, $i, 1, $ipv4_zone)) {			&terror(($ipv4_zone) ? 'edit_eip' : 'edit_eip6', $in{'name'});		}	}	else {		unless (&valdnsname($name, $i, $origin)) {			&terror('edit_ename', $in{'name'});		}	}}if ($in{'ttl_def'}) {	$ttl = 0;}else {	&trim($in{'ttl'});	$ttl = &convert_time(0, $in{'ttl'} . $in{'ttlunit'}) if ($in{'ttl'});	unless ($ttl) {		unless ($in{'ttl'}) {			$in{'ttl'} = $text{'nothing'};			$in{'ttlunit'} = '';		}		&terror('edit_ettl', $in{'ttl'} . $in{'ttlunit'});	}}&trim($in{'comment'});			# Strip leading and trailing spaces.&trim($in{'value0'});$value = $in{'value0'};for ($i = 1; defined($in{"value$i"}); $i++) {	&trim($in{"value$i"});	$value .= ' ' . $in{"value$i"};}## Now carry out checks specific to the record type.#if ($type eq 'PTR') {	if ($value) {		$value .= '.' unless ($value =~ /\.$/o);		unless (&valdnsname($value, 0, $origin)) {			&terror('edit_ehost', $value);		}	}	else {		&terror('edit_emissing_value');	}	#	# Check to see if we are creating a record that already exists.	#	if ($new) {		($oconf, $ofile, $orec) = &find_reverse($name, $value);		if ($orec) {			&terror('edit_edupname', $value);		}		else {			# Reset these just in case.			$oconf = $ofile = $orec = '';		}	}	#	# Find the forward zone. Then check if we can update the SOA serial	# number, that the top-level name or sub-domain is okay, and that we	# can actually update the forward zone.	#	($fwdconf, $fwdfile, $fwdrec) = &find_forward($value, $name, $ipv4_zone);	if ($fwdconf) {		if ($access{'rev_updt_must'} && ! &can_edit_forward($fwdconf)) {			&terror('edit_no_updt_fwd');		}		if ($in{'fwd'} && $name !~ /\*/o) {			($new_rev_serial, $new_rev_dynamic) = &check_rev_serial($fwdconf);			#			# If we have asked to create the forward record, then			# check that we are allowed to create a top-level name			# if one has been specified.			#			if ($new) {				unless (&check_tld($value, $fwdconf, \%access, 'master', $type)) {					&terror('edit_tld');				}				unless (&check_sd($value, $fwdconf, \%access, 'master', $type)) {					&terror('edit_sd');				}			}			elsif (lc($value) ne $oldvalue || ! $fwdrec) {				if (! &check_tld($value, $fwdconf, \%access, 'master', $type) ||				    ($orec && ! &check_tld($oldvalue, $oconf, \%access, 'master', $type))) {					&terror('edit_tld');				}				if (! &check_sd($value, $fwdconf, \%access, 'master', $type) ||				    ($orec && ! &check_sd($oldvalue, $oconf, \%access, 'master', $type))) {					&terror('edit_sd');				}			}		}	}	elsif ($config{'fwd_must'} || $access{'rev_updt_must'}) {		&terror('edit_efwdmust');	}	#	# If necessary we must check if the IP address is already in use.	# We only do this for new records or ones where the address has been	# changed, and that the forward record is to be created or updated.	#	if ($ipv4_zone) {		$v = &compress_ip(&arpa_to_ip($name));	}	else {		$v = &compress_ip6(&ip6arpa_to_net($name));	}	#	# Check to see if the IP address is already in use.	#	if (($new || $oldname ne $name) && &ip_in_use($conf, $v, $value,		($ipv4_zone ? 'A' : 'AAAA'), $origin, $access{'no_multiple'})) {		&terror('edit_edupip', $v);	}}elsif ($type eq 'A' || $type eq 'AAAA') {	$ipv4_rec = ($type eq 'A');	if ($value) {		$value = ($ipv4_rec) ? &compress_ip($value)				     : &compress_ip6($value);		unless (&valipaddr($value, $origin, 0, 0, 0, $ipv4_rec)) {			&terror(($ipv4_rec) ? 'edit_eip' : 'edit_eip6', $value);		}	}	else {		&terror('edit_eipmissing_value');	}	#	# Check to see if we are creating a record that already exists.	#	if ($new) {		($oconf, $ofile, $orec) = &find_forward($name, $value, $ipv4_rec);		if ($orec) {			&terror('edit_edupip', $name);		}		else {			# Reset these just in case.			$oconf = $ofile = $orec = '';		}	}	#	# Check that the reverse zone exists if required, and that we can	# update the SOA serial number.	#	($revconf, $revfile, $revrec) = &find_reverse($value, $name);	if ($revconf) {		if ($access{'rev_updt_must'} && ! &can_edit_reverse($revconf)) {			&terror('edit_no_updt_rev');		}		if ($in{'rev'} && $name !~ /\*/o) {			($new_rev_serial, $new_rev_dynamic) = &check_rev_serial($revconf);		}	}	elsif ($config{'rev_must'} || $access{'rev_updt_must'}) {		&terror('edit_erevmust');	}	#	# Check to see if the IP address is already in use.	#	if (($new || $oldvalue ne $value) && &ip_in_use($conf, $value,			$rec_name, $type, undef, $access{'no_multiple'})) {		&terror('edit_edupip', $value);	}}elsif ($type eq 'NS') {	unless ($value) {		&terror('edit_emissing_value');	}	if ($value eq '@' || &valdnsname($value, 0, $origin)) {		$value = &convert_fqdn(1, $value, $origin, 1);	}	else {		&terror('edit_ens', $value);	}}elsif ($type eq 'CNAME') {	unless ($value) {		&terror('edit_emissing_value');	}	$value = &convert_fqdn(1, $value, $origin, 1);	if ($value =~ /(\.(in-addr|ip6)\.arpa\.)$/o) {		if ($2 eq 'in-addr') {			$v = &compress_ip(&arpa_to_ip($value));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -