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

📄 delete_zone.cgi

📁 BIND 9 dynamic DNS webmin module. This module supports both static and dynamic zones, and IPv4 and I
💻 CGI
字号:
#! /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.### Delete a zone and all its records.#use strict;no strict 'vars';require './b9ddns-lib.pl';my $dynamic_zone = my $reverse = my $rev_zone_type = my $ipv4 = 0;my $count = my $no_named = 0;my $conf = my $zone_conf = my $view = my $type = my $server = '';my $file = my $real_file = my $record = my $oconf = my $ofile = my $orec = '';my $lref = my $user = my $zone = my $zone_hdr = my $origin = '';my $slave_parent = my $slave_conf = my $slave_zone_conf = '';my $slave_error = my $rev_zone_name = my $rev_file = '';my $dyn_rev_str = my $rev_zone_ref = my $rev_zone_rec_ref = my $err = '';my @servers = my @recs = my @orecs = ();my %wusers = my %uaccess = my %zone_type = my %rev_zone_recs = ();&ReadParse();$conf = &get_config();if ($in{'view'}) {	$view = $conf->[$in{'view'}];	$conf = $view->{'members'};}$zone_conf = $conf->[$in{'index'}];%access = &get_module_acl();unless (&can_edit_zone(\%access, $zone_conf, $view)) {	&terror('master_edelete');}if ($access{'ro'}) {	&terror('master_ero');}unless ($access{'delete'}) {	&terror('master_edeletecannot');}$origin = lc($zone_conf->{'value'});$origin .= '.' unless ($origin =~ /\.$/o);$dynamic_zone = &dynamic_zone($zone_conf, 1);$reverse++ if ($origin =~ /\.(in-addr|ip6)\.arpa\.$/o);$type = $in{'type'};$file = $in{'file'};$real_file = $config{'chroot'} . &absolute_path($file) if ($file);unless ($in{'confirm'}) {	#	# Ask the user if he/she is sure...	#	$zone_hdr = &zone_header($dynamic_zone, $origin, $text{ucfirst($type)});	&header($text{'delete_title'}, '', undef, 0, 0, 0, undef, undef, undef, $zone_hdr);	print '<hr>';	if ($type eq 'hint') {		print '<p>', $text{'hint_desc1'}, '<br><br>',		      $text{'hint_desc2'}, '<p>';		print '<center><p>', $text{'delete_mesg2'}, '<p>';	}	else {		if ($reverse) {			$orec = &ip6arpa_to_net(&arpa_to_ip($origin));		}		else {			$orec = $origin;			$orec =~ s/\.$//o unless ($origin eq '.');		}		print '<center><p>', &text('delete_mesg', "&nbsp;<b>$orec</b>");		print '&nbsp;&nbsp;', $text{'delete_mesg_file'} if ($file && -e $real_file);		print '<p>';	}	print "<form action=delete_zone.cgi>\n";	print '<input type=hidden name=index value=', $in{'index'}, '>';	print '<input type=hidden name=view value=', $in{'view'}, '>';	print '<input type=hidden name=file value=', $file, '>';	print '<input type=hidden name=type value=', $type, '>';	print '<input type=submit name=confirm value="', $text{'master_del'}, '">';	if ($type eq 'hint') {		print '&nbsp;' x 6, '<input type=checkbox name=del_hint value=1>', $text{'hint_del'};	}	elsif ($type eq 'master') {		print '<p>', $text{$reverse ? 'delete_fwd' : 'delete_rev'}, '&nbsp;&nbsp;';		print '<input type=radio name=rev value=1 checked> ', $text{'yes'};		print '<input type=radio name=rev value=0> ', $text{'no'}, '<br>';		&foreign_require('servers', 'servers-lib.pl');		@servers = grep { $_->{'user'} } &servers::list_servers();		if (@servers && $access{'remote'}) {			print $text{'delete_slave'}, ' <select name=slave>';			print '<option value="">&nbsp;';			foreach $server (@servers) {				printf "<option value=%s %s>%s\n",				    $server->{'host'},			    ($server->{'host'} eq $config{'default_slave'}) ?					'selected' : '',			    $server->{'desc'} ?					$server->{'desc'} : $server->{'host'};			}			print '</select><br>';		}	}	print '</form></center>';	print '<hr>';	&footer("edit_zone.cgi?index=$in{'index'}&view=$in{'view'}&type=$type", $text{'master_return'});	exit;}if ($in{'rev'} && $type eq 'master') {	#	# When deleting the forward/reverse records we do not want to increment	# the SOA serial number for each record deleted. The reason being that	# if a date format serial number is used then it could easily exceed	# the maximum of 100 changes per day. Since the reverse zone may be	# static or dynamic, we must find out the zone type first of all. Then,	# for static zones, we delete the record but increment the serial number	# after all the records have been deleted. For dynamic zones we have to	# store the record with the zone, and then at the end delete all the	# records for each reverse zone in one go. This way the serial number	# will only be incremented once.	#	# NOTE: There is no guarantee that a reverse record will be deleted -	# for example, the user may not have rights to edit that particular	# zone. As such it is the administrators responsibility to ensure that	# the zone is completely deleted.	#	$no_named = (&named_running() <= 0);	$ipv4 = ($origin =~ /\.in-addr\.arpa\.$/o);	if ($file) {				# This should always be true.		&lock_file($real_file);		@recs = &get_zone($zone_conf, $file, $origin, undef, 'master');	}	#	# We'll lock the named.conf file as well, just to be sure nobody else	# starts to move the zones around whilst we are deleting things.	#	&lock_file($config{'chroot'} . $zone_conf->{'file'});	#	# Find and delete the forward/reverse records.	#	foreach $record (@recs) {		if ($reverse) {			next if ($record->{'type'} ne 'PTR');			($oconf, $ofile, $orec) =					&find_forward($record->{'values'}->[0],						$record->{'fqdn'}, $ipv4);			next unless ($orec && &can_edit_zone(\%access, $oconf));		}		else {			next if ($record->{'type'} ne 'A' &&				 $record->{'type'} ne 'AAAA');			($oconf, $ofile, $orec) =				&find_reverse($record->{'values'}->[0],					      $record->{'fqdn'});			next unless ($orec && &can_edit_reverse($oconf));		}		$rev_zone_name = lc($oconf->{'value'});		$rev_zone_name .= '.' unless ($rev_zone_name =~ /\.$/o);		$rev_zone_ref = &get_zone_data($oconf);		if (defined($rev_zone_recs{$rev_zone_name})) {			#			# We must do this because non-updateable zones will			# have reset their zone type. Using this (reset) value			# will avoid us checking their SOA serial number every			# time.			#			$rev_zone_type = $rev_zone_recs{$rev_zone_name}->[0]->[0];		}		else {			$rev_zone_type = $rev_zone_ref->[1];		}		if ($rev_zone_type == 0) {		# A static zone.			#			# For static zones we can still delete the records,			# even if we cannot increment the serial number. The			# changes will then take place the next time named is			# restarted.			#			$rev_file = $config{'chroot'} . &absolute_path($ofile);			&lock_file($rev_file);			&delete_record($oconf, $ofile, $orec);			&unlock_file($rev_file);		}		elsif ($rev_zone_type == 1) {		# A dynamic zone.			#			# If named is not running then there is no way that we			# can delete dynamic zone records.			#			$rev_zone_type = 2 if ($no_named);		}		else {		# A dynamic zone which we cannot update or for			next;	# which we cannot update the serial number.		}		#		# We must now check the zones SOA serial number. If it is not		# updateable then we simply reset the zone type.		#		if ($config{'soa_date_style'} && $rev_zone_type != 2) {			$count = &check_soa_serial($rev_zone_ref, $oconf, undef, undef);			$rev_zone_type = 2 if ($count < 0);		}		push(@{ $rev_zone_recs{$rev_zone_name} },				[ $rev_zone_type, $oconf, $ofile, $orec ] );	}	#	# Get the first entry of the first record of each zone in order to	# determine the zone type. If it is a static zone then we have already	# deleted the record and just need to check the serial number and bump	# it up. For dynamic zones we first need to build up a string of the	# records to delete.	#	foreach $rev_zone_name (keys(%rev_zone_recs)) {		$rev_zone_type = $rev_zone_recs{$rev_zone_name}->[0]->[0];		if ($rev_zone_type == 0) {		# A static zone.			$rev_zone_rec_ref = $rev_zone_recs{$rev_zone_name}->[0];			$oconf = $rev_zone_rec_ref->[1];			$ofile = $rev_zone_rec_ref->[2];			$orec = $rev_zone_rec_ref->[3];		}		elsif ($rev_zone_type == 1) {		# A dynamic zone.			$count = 0;			$dyn_rev_str = 'local ' . $config{'ns_if_update'} . "\n";			$dyn_rev_str .= 'zone ' . $rev_zone_name . "\n";			foreach $rev_zone_rec_ref (@{ $rev_zone_recs{$rev_zone_name} }) {				$oconf = $rev_zone_rec_ref->[1];				$ofile = $rev_zone_rec_ref->[2];				$orec = $rev_zone_rec_ref->[3];				$count++;				$dyn_rev_str .= "update delete $orec->{'fqdn'} $orec->{'class'} $orec->{'type'} $orec->{'values'}->[0]\n";				#				# To ensure that the character string does not				# get excessively large, we update the zone				# after each 1000 records. This will, of course,				# result in the SOA serial number being				# increased for each thousand records. However,				# this should not be a problem unless the zone				# has a really large number of records.				#				if ($count >= 1000) {					$count = 0;					$dyn_rev_str .= "\n";					$err = `echo "$dyn_rev_str" | $config{'nsupdate_cmd'} >/dev/null 2>&1`;					$dyn_rev_str = 'local ' . $config{'ns_if_update'} . "\n";					$dyn_rev_str .= 'zone ' . $rev_zone_name . "\n";				}			}			if ($count) {				$dyn_rev_str .= "\n";				#				# We do not bother with errors because it is				# for the administrator to ensure that the zone				# records have been deleted.				#				$err = `echo "$dyn_rev_str" | $config{'nsupdate_cmd'} >/dev/null 2>&1`;			}		}		else {		# A non-updateable zone - ignore it.			next;		}		@recs = &get_zone($oconf, $ofile, $rev_zone_name, undef, 'master');		&bump_soa_record($oconf, \@recs, undef);	}}## Now delete the records file.#if ($file && ($type ne 'hint' || ($type eq 'hint' && $in{'del_hint'}))) {	&lock_file($real_file);	unlink $real_file, $real_file . '.jnl';	&unlock_file($real_file);}## Remove the zone directive.#&lock_file($config{'chroot'} . $zone_conf->{'file'});$lref = &read_file_lines($config{'chroot'} . $zone_conf->{'file'});splice(@$lref, $zone_conf->{'line'},			$zone_conf->{'eline'} - $zone_conf->{'line'} + 1);&flush_file_lines();&unlock_all_files();## Remove from acl files.#&read_acl(undef, \%wusers);$lref = $origin;$lref =~ s/\.$//o unless ($lref eq '.');foreach $user (keys(%wusers)) {	%uaccess = &get_module_acl($user);	if ($uaccess{'zones'} ne '*') {		$uaccess{'zones'} = join(' ', grep { $_ !~ /^$lref\.?$/i }					      split(/\s+/, $uaccess{'zones'}));		&save_module_acl(\%uaccess, $user);	}}## Also delete from slave servers.#if ($in{'slave'} && $access{'remote'}) {	&error_setup($text{'delete_err2'});	&remote_error_setup(\&slave_error_handler);	&remote_foreign_require($in{'slave'}, $module_name, 'b9ddns-lib.pl');	if ($slave_error) {		&error($slave_error);	}	$slave_parent = &remote_foreign_call($in{'slave'}, $module_name, 'get_config_parent');	$slave_conf = $slave_parent->{'members'};	foreach $zone (&find('zone', $slave_conf)) {		$slave_zone_conf = lc($zone->{'value'});		$slave_zone_conf .= '.' unless ($slave_zone_conf =~ /\.$/o);		if ($slave_zone_conf eq $origin) {			$slave_zone_conf = $zone;			last;		}	}	unless ($slave_zone_conf) {		&terror('slave_ezone');	}	&remote_foreign_call($in{'slave'}, $module_name, 'save_directive',			     $slave_parent, [ $slave_zone_conf ], [ ]);	&remote_foreign_call($in{'slave'}, $module_name, 'flush_file_lines');	&remote_foreign_call($in{'slave'}, $module_name, 'webmin_log',					'delete', 'slave', $origin, \%in);}&webmin_log('delete', $type, $origin, \%in);&redirect('');exit;## can_edit_reverse(&zone)#sub can_edit_reverse {	return $access{'reverse'} || &can_edit_zone(\%access, $_[0]);}sub slave_error_handler {	$slave_error = $_[0];	return;}

⌨️ 快捷键说明

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