| #!/bin/sh |
| # |
| # 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 <zone> 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: namedGetForwarders [-n -r] [ <zone> ] |
| # -n : output forward zone statements for named.conf |
| # -r : output in resolv.conf format |
| # : no -r or -n: just list the forwarders |
| # |
| # This script is based on perl script of Jason Vas Dias <jvdias@redhat.com>. |
| # |
| # Copyright(C) Baris Cicek <baris@nerd.com.tr> Nerd Software. 2007 |
| # |
| # 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. |
| |
| declare -a zones; |
| declare -a servers; |
| declare -a ports; |
| declare -a only; |
| |
| output_format='plain'; |
| zonecnt=0; |
| |
| function push () { |
| local array |
| array=( `echo $1` ); |
| array[${#array[*]}]=$2; |
| echo ${array[@]}; |
| } |
| |
| function concat () { |
| local string |
| while [ $# -gt 0 ]; do |
| string=${string}$1; |
| shift; |
| done |
| echo $string; |
| } |
| |
| if [ $# -ge 0 ]; then |
| if [ "$1" == "-r" ]; then |
| output_format='resolv'; |
| shift; |
| elif [ "$1" == "-n" ]; then |
| output_format='named'; |
| shift; |
| fi |
| zone=""; |
| for arg in $*; do |
| zone=$(push "$zone" " string:'$arg'"); |
| done |
| fi |
| |
| DNS=`/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`; |
| |
| if [ $? -ne 0 ]; then |
| echo -e "dbus-send failed: $? $!"; |
| exit 1; |
| fi |
| |
| IFS=$'\n' |
| |
| |
| for line in $DNS; do |
| match_ip=$( echo "$line" | awk --re-interval '{ match ($0, /([[:digit:]]{1,3})\.([[:digit:]]{1,3})\.([[:digit:]]{1,3})\.([[:digit:]]{1,3})/, a); printf "%s.%s.%s.%s", substr($0, a[1, "start"], a[1, "length"]), substr($0, a[2, "start"], a[2, "length"]), substr($0, a[3, "start"], a[3, "length"]), substr($0, a[4, "start"], a[4, "length"]);}' ); |
| match_port=$( echo "$line" | awk '{ match ($0, /\"([[:digit:]]+)\"$/, a); printf "%s", substr($0, a[1, "start"], a[1,"length"]);}' ); |
| match_string=$( echo "$line" | awk '{ match ($0, /string.+\"([^\"]+)\"$/, a); printf "%s", substr($0, a[1, "start"], a[1,"length"]);}' ); |
| |
| if [ "$match_ip" != "" ] && [ "$match_ip" != "..." ]; then |
| servers[$zonecnt]=$(push "${servers[$zonecnt]}" "$match_ip"); |
| elif [ "$match_port" != "" ]; then |
| ports[$zonecnt]=$(push "${ports[$zonecnt]}" "$match_port"); |
| elif [ "$match_string" == "only" ]; then |
| only[$zonecnt]="1"; |
| elif [ "$match_string" != "" ] && [ "$match_string" != "first" ]; then |
| zonecnt=$((zonecnt + 1)); |
| zones[$zonecnt]="$match_string"; |
| fi |
| |
| done |
| |
| if [ "$output_format" == "resolv" ]; then |
| # resolv.conf style: |
| search_line='search'; |
| nameserver_lines=''; |
| for index in $(seq 1 $zonecnt); do |
| if [ "` echo ${zones[$index]} | awk ' /\.in-addr\.arpa$/ { print $0 }'`" == '' ]; then |
| search_line=$(push "$search_line" "${zones[$index]}"); |
| fi |
| IFS=$' '; |
| for ns in ${servers[$index]}; do |
| nameserver_lines=$(concat "$nameserver_lines" "\nnameserver " "$ns"); |
| done |
| done |
| echo -n $search_line; |
| echo -e $nameserver_lines; |
| elif [ "$output_format" == "named" ]; then |
| # named.conf style: |
| zone_lines=''; |
| for index in $(seq 1 $zonecnt); do |
| zone_line=$(concat 'zone "' "${zones[$index]}" '." IN { type forward; forwarders { '); |
| srvcnt=1; |
| IFS=$' '; |
| for ns in ${servers[$index]}; do |
| srvport=$(eval "echo ${ports[$index]} | awk '{ print \$${srvcnt} }'"); |
| if [ "$srvport" != "53" ]; then |
| zone_line=$(concat "$zone_line" " $ns port $srvport;"); |
| else |
| zone_line=$(concat "$zone_line" " $ns;"); |
| fi |
| srvcnt=$((srvcnt+1)); |
| done |
| zone_line=$(concat "$zone_line" " };"); |
| if [ "${only[$index]}" == '1' ]; then |
| zone_line=$(concat "$zone_line" " forward only;"); |
| fi |
| zone_line=$(concat "$zone_line" " };"); |
| zone_lines=$(concat "$zone_lines" "$zone_line\n"); |
| done |
| echo -e ${zone_lines%\\n}; |
| elif [ "$output_format" == "plain" ]; then |
| # just list: |
| output=''; |
| for index in $(seq 1 $zonecnt); do |
| output=$(concat "$output" "${zones[$index]}" "\n"); |
| if [ "${only[$index]}" == "1" ]; then |
| output=$(concat "$output" "\t" "forward only" "\n"); |
| fi |
| srvcnt=1; |
| IFS=$' '; |
| for ns in ${servers[$index]}; do |
| srvport=$(eval "echo ${ports[$index]} | awk '{ print \$${srvcnt} }'"); |
| if [ "$srvport" != "53" ]; then |
| output=$(concat "$output" "\t" "$ns:$srvport" "\n"); |
| else |
| output=$(concat "$output" "\t" "$ns" "\n"); |
| fi |
| srvcnt=$((srvcnt+1)); |
| done |
| done |
| echo -e ${output%\\n}; |
| fi |