#!/usr/bin/perl # # This script uses the named D-BUS support, which must be enabled in # the running named with the named '-D' option, to get and print the # list of forwarding zones in the running server. # # It accepts an optional first argument which is the DNS name # of the zone whose forwarders (if any) will be retrieved. # # If no zone argument is specified, all forwarding zones will be listed. # # Usage: GetForwarders [-n -r] [ ] # -n : output forward zone statements for named.conf # -r : output in resolv.conf format # : no -r or -n: just list the forwarders # # Copyright(C) Jason Vas Dias Red Hat Inc. 2005 # # 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 at # http://www.fsf.org/licensing/licenses/gpl.txt # and included in this software distribution as the "LICENSE" file. # # 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. # use Getopt::Std; %opts=(); getopts("rn",\%opts); $zone = ''; if ( $#ARGV >= 0 ) { $zone = "string:'". join("' string:'",@ARGV)."'"; }; @dn=(); open(DNS, '/usr/bin/dbus-send --system --type=method_call --print-reply --reply-timeout=20000 ' .'--dest=com.redhat.named /com/redhat/named com.redhat.named.text.GetForwarders ' .$zone .'|' ) || die("dbus-send failed: $?: $!"); while() { $_=~s/[\s\r\n]+$//; if ( /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ ) { # nameserver address push @{${$dn[-1]}{'s'}}, { 'a' => "$1.$2.$3.$4" }; }elsif ( /\"(\d+)\"$/ ) { # port if ( $1 != 53 ) { ${@{${$dn[-1]}{'s'}}[-1]}{'p'} = $1; }; }elsif ( /string\s+\"([^\"]+)\"$/ ) { if ( ($1 eq 'first') || ($1 eq 'only') ) { # policy if( $1 eq 'only' ) { # not default ${$dn[-1]}{'o'} = 1; } }else { # new DN - "zone" push @dn, {'n'=>$1,'s'=>[]}; }; }; }; close(DNS); if( exists($opts{'r'}) ) { # resolv.conf style: my %svrs=(); print 'search ', join( ' ', grep { !( $_ =~ /\.in-addr\.arpa$/) } map { ${$_}{'n'} } @dn ),"\n", 'nameserver ', join( "\nnameserver ", grep { exists ( $svrs{ $_ } ) ? undef : { $svrs{$_}=$_ } } map { ${$_}{'a'} } map { @{${$_}{'s'}} } @dn ),"\n"; }elsif( exists($opts{'n'}) ) { # named.conf style: foreach $d (@dn) { print 'zone "',${$d}{'n'},'." IN { type forward; forwarders { ', join("; ", map { exists( ${$_}{'p'} ) ? ${$_}{'a'} . ' port ' . ${$_}{'p'} : ${$_}{'a'} } @{${$d}{'s'}} ), '; }; ', exists(${$d}{'o'}) ? ' forward only; ' : '', "};\n"; }; }else { # just list: foreach $d (@dn) { print ${$d}{'n'}, "\n\t", (exists(${$d}{'o'}) ? "forward only\n\t" : ''), join( "\n\t", map { exists( ${$_}{'p'} ) ? ${$_}{'a'} . ':' . ${$_}{'p'} : ${$_}{'a'} } @{${$d}{'s'}} ),"\n"; }; };