#!/bin/sh
PATH=:/bin:/usr/bin:/usr/ucb:/usr/local/bin

# -----------------------------------------------------------------------
#  Copyright (c) 1991, 1994 Regents of the University of Michigan.
#  All rights reserved.
#
#  Redistribution and use is permitted provided that this notice 
#  is preserved and that due credit is given to the University of 
#  Michigan. The name of the University may not be used to endorse 
#  or promote products derived from this software without specific 
#  prior written permission. This software is provided "as is" 
#  without express or implied warranty.
#
#  Lame delegation notifier
#  Author:  Bryan Beecher
#  Last Modified:  8/1/94
#
#  To use this software, you will need to have built BIND 4.9.1 (or
#  a later version) with LAME_DELEGATION defined in options.h.  You
#  will also need to be sure that the 'dig' program resides in the
#  PATH set above.
# -----------------------------------------------------------------------

# -------------------------------------------------------------
#  tailor these to your system
# -------------------------------------------------------------

##
##  Where are lame delegations recorded?
##
LOGFILE=/var/log/named

##
##  Where is the "lame message" template?
##
MSGFILE=/usr/local/etc/lamer-message

##
##  Where should scratch files be kept?
##
TMP=/usr/tmp

##
##  Who should get the main "lame delegations" report?
##
HOSTMASTER="hostmaster"

##
##  Mailer to use
##
MAILER="/usr/lib/sendmail -t -fnobody"

##
##  Mail should show up as having come from this address
##
SENDER="hostmaster"

# -------------------------------------------------------------
#  you shouldn't need to change any of these
# -------------------------------------------------------------
LAMERS=$TMP/lamers$$
LAMEREPORT=$TMP/.lamereport$$
REPORT=$TMP/.report.$$

# -------------------------------------------------------------
#  handle arguments
# -------------------------------------------------------------
#	-f <logfile>
#	Change the LOGFILE.
#
#	-v
#	Be verbose.
#
#	-e
#	Echo messages that would have been sent as e-mail.
#
#	-t
#	Test mode.  Do not send mail to the lame delegation
#	hostmasters.  Do not empty the logfile.
#
#	-h <hostmaster>
#	Specify a different hostmaster.  Note that this
#	OVERRIDES the test mode option above, and a copy of
#	the final report is mailed to the specified hostmaster
#	even though individual hostmasters across the network
#	are NOT notified.
# -------------------------------------------------------------
VERBOSE=0
TESTMODE=0
MAILREPORT=1
while [ $# != 0 ] ; do
	case "$1" in

		-e)
		MAILER=/bin/cat
		;;

		-f)
		LOGFILE=$2
		shift
		;;

		-v)
		VERBOSE=1
		;;

		-t)
		TESTMODE=1
		MAILREPORT=0
		MAILER="/bin/cat > /dev/null"
		;;

		-h)
		HOSTMASTER=$2
		MAILREPORT=1
		shift
		;;
	esac
	shift
done

#--------------------------------------------------------------------------
#  Clean up and exit on a HUP, INT or QUIT
#--------------------------------------------------------------------------
trap "rm -f $LAMERS $LAMEREPORT  ; exit" 1 2 3

if [ $TESTMODE -eq 1 ] ; then
	echo
	echo "Operating in test mode.  Notification sent via $MAILER"
	if [ $MAILREPORT -eq 1 ] ; then
		echo "Final report will be mailed to $HOSTMASTER"
	else
		echo "Final report will be written to the tty"
	fi
	echo
fi

#--------------------------------------------------------------------------
#  See if there are any lamers
#--------------------------------------------------------------------------
grep "Lame" $LOGFILE | tr A-Z a-z | grep -v "*" | awk '{
    if (length($9) == 2)
	next
    print substr($9, 2, length($9) - 2), substr($11, 2, length($11) - 2) }' |
    sort | uniq | awk '{
		printf("%s %s\n", $1, $2)
}' > $LAMERS

if [ ! -s $LAMERS ] ; then
	exit 0
fi

if [ $VERBOSE -eq 1 ] ; then
	echo "Found" `awk 'END { print NR }' $LAMERS` "lame delegations"
fi

#--------------------------------------------------------------------------
#  There were lamers; send them mail
#--------------------------------------------------------------------------
touch $LAMEREPORT
NAME=""
while read DOMAIN IPADDR ; do
	#-----------------------------------------------------------
	# Echo args if verbose
	#-----------------------------------------------------------
	if [ $VERBOSE -eq 1 ] ; then
		echo ""
		echo "-> $IPADDR may be a lame delegation for $DOMAIN"
	fi
	#-----------------------------------------------------------
	# Lookup the SOA record form $DOMAIN.  A really broken name
	# server many have more than one SOA for a domain, so exit
	# after finding the first one.  Send it to the local hostmaster
	# if we cannot find the proper one.
	#-----------------------------------------------------------
	if [ $VERBOSE -eq 1 ] ; then
		echo "   Looking up the hostmaster for $DOMAIN"
	fi
	HOSTMASTER=`dig $DOMAIN SOA 2> /dev/null | 
	    awk '$3 == "SOA" { print substr($5, 1, length($5) - 1) ; exit }' |
	    sed -e 's/\./@/'`
	NAME=`dig -x $IPADDR 2> /dev/null |
	    awk '$3 == "PTR" { print substr($4, 1, length($4) - 1) ; exit }'`
	if [ -z "$HOSTMASTER" ] ; then
	    if [ ! -z ""$NAME ] ; then
		HOSTMASTER="No SOA record found for $DOMAIN <postmaster@$NAME>"
	    else
		HOSTMASTER=""
	    fi
	fi
	if [ $VERBOSE -eq 1 -a -z "$HOSTMASTER" ] ; then
		echo "   Could not locate an appropriate e-mail address"
	elif [ $VERBOSE -eq 1 ] ; then
		echo "   "Hostmaster is "$HOSTMASTER"
	fi
	#-----------------------------------------------------------
	# Find the name associated with IP address $IPADDR.  Query
	# the nameserver at that address:  If it responds listing
	# itself as a domain namserver, then it is lame; if it isn't
	# in the list, then perhaps the lame delegation alert was
	# spurious.
	#-----------------------------------------------------------
	if [ $VERBOSE -eq 1 ] ; then
		echo -n "   Is $IPADDR listed as a NS for $DOMAIN?  "
	fi
	dig @$IPADDR $DOMAIN NS 2>&1 | grep "A	$IPADDR" > /dev/null
	if [ $? -eq 1 ] ; then
		if [ $VERBOSE -eq 1 ] ; then
			echo "No, skipping."
		fi
		continue
	else
		if [ $VERBOSE -eq 1 ] ; then
			echo "Yes."
		fi
	fi
	#-----------------------------------------------------------
	# If the delegation is no longer lame, don't send mail.
	# We do the query twice; the first answer could be authori-
	# tative even if the nameserver is not performing service
	# for the domain.  If this is the case, then the second
	# query will come from cached data, and will be exposed
	# on the second query.  If the resolver returns trash, the
	# entire set of flags will be set.  In this case, don't
	# count the answer as authoritative.
	#-----------------------------------------------------------
	if [ $VERBOSE -eq 1 ] ; then
		echo -n "   Data returned from $IPADDR is from the "
	fi
	dig @$IPADDR $DOMAIN > /dev/null
	dig @$IPADDR $DOMAIN | grep flags | grep aa | grep -v tc > /dev/null
	if [ $? -eq 0 ] ; then
		if [ $VERBOSE -eq 1 ] ; then
			echo "hash table (authoritative)."
		fi
		continue
	fi
	if [ $VERBOSE -eq 1 ] ; then
		echo "cache (non-authoritative)."
	fi
	#-----------------------------------------------------------
	# Notify the owner of the lame delegation, and also notify
	# the local hostmaster.
	#-----------------------------------------------------------
	if [ -z "$HOSTMASTER" ] ; then
		continue
	fi
	if [ $VERBOSE -eq 1 ] ; then
		echo "  "
	fi
	if [ -z ""$NAME ] ; then
		NAME=" "
	fi
	sed -e "s|%DOMAIN%|$DOMAIN|" -e "s|%SERVER%|$NAME|" -e "s|%IPADDR%|$IPADDR|" -e "s|%HOSTMASTER%|$HOSTMASTER|" -e "s|%SENDER%|$SENDER|" $MSGFILE | eval $MAILER
	if [ $VERBOSE -eq 1 ] ; then
		echo "  "
	fi
	echo $IPADDR $DOMAIN >> $LAMEREPORT
done < $LAMERS
#--------------------------------------------------------------------------
# No news is good news
#--------------------------------------------------------------------------
if [ -s $LAMEREPORT ] ; then
	rm -f $REPORT
	echo "The following lame delegations were detected by the UMich nameservers" >> $REPORT
	echo "during the past week of operation." >> $REPORT
	echo " " >> $REPORT
	echo "This nameserver  was found to be a lame delegation for this domain" >> $REPORT
	echo "---------------  -------------------------------------------------" >> $REPORT
	sort -t. -n +0 -1 +1 -2 +2 -3 +3 -4 $LAMEREPORT | 
			awk '{ printf("%-15s  %s\n", $1, $2) }' >> $REPORT
	if [ $MAILREPORT -eq 1 ] ; then
		Mail -s "U-M lame delegation report" $HOSTMASTER < $REPORT
	else
		cat $REPORT
	fi
fi

#--------------------------------------------------------------------------
# Tidy up
#--------------------------------------------------------------------------
rm -f $LAMERS $LAMEREPORT $REPORT
if [ $TESTMODE -eq 0 ] ; then
	cp $LOGFILE $LOGFILE.0
	cp /dev/null $LOGFILE
fi
