#!/bin/sh

# Should we run the cronjob
# DEFAULT: "false"
RUN_DEPLOY="false"

# How the LDAP server can be accessed
# DEFAULT: ""
# Example: "ldap://localhost"
LDAP_URI=""

# Where the bind config is stored
# DEFAULT: "/etc/bind"
BIND_DIR="/etc/bind"

# Where the zonefiles are located
# DEFAULT: "/var/cache/bind"
BIND_DATA="/var/cache/bind"

# Time to live value for a and ptr records
# DEFAULT: 500 Seconds
TTL="500"

# Prefix for zone definition files
# DEFAULT: "db."
# The zone definition file for 0.168.192.in-addr.arpa is stored as 'db.0.168.192.in-addr.arpa'
PREFIX="db."

[ -r /etc/default/ldap2zone ] && . /etc/default/ldap2zone

# if shell is non-interactive (e.g. like when called via CRON) and RUN_DEPLOY is false, exit silently.
if [ ! -t 1 ] && [ "$RUN_DEPLOY" = "false" ]; then
        exit 0
fi

case "$LDAP_URI" in 
ldap://*|ldaps://*|ldapi://*) ;;
'')
    # No LDAP server set, no need trying to generate a zone file.
    exit 0
    ;;
 *) LDAP_URI="ldap://${LDAP_URI}" ;; 
 esac

LDAPSEARCH=`which ldapsearch`

if [ -z "${LDAPSEARCH}" ]; then
        echo "ldapsearch program not in $PATH. Exiting..."
        exit 1
fi

LDAP_URI_PARAM=${LDAP_URI:+"-H $LDAP_URI"}

if [ "$ALLOW_NOTIFY" ]; then
        ALLOW_NOTIFY="$ALLOW_NOTIFY";
else ALLOW_NOTIFY=;
fi

if [ "$ALLOW_UPDATE" ]; then
	ALLOW_UPDATE_PARAM="allow-update {$ALLOW_UPDATE};";
else ALLOW_UPDATE_PARAM=;
fi

if [ "$ALLOW_TRANSFER" ]; then
	ALLOW_TRANSFER_PARAM="allow-transfer {$ALLOW_TRANSFER};";
else ALLOW_TRANSFER_PARAM=;
fi

ZONES=`ldapsearch -LLL $LDAP_URI_PARAM -x "(objectClass=dNSZone)" zoneName | grep zoneName: | sort | uniq | awk '{print $2}'`
ldap2zone=`which ldap2zone`
rndc=`which rndc`

if [ -z "${ZONES}" ]; then
	echo "No domains configured. Exiting..."
	exit 0
fi

if [ -z "${rndc}" ]; then
	echo "rndc program not in $PATH. Exiting..."
	exit 1
fi

if [ -z "${ldap2zone}" ]; then
	echo "ldap2zone program not in $PATH. Exiting..."
	exit 1
fi

if [ ! -d $BIND_DIR ]; then
	echo "The directory specified as $BIND_DIR does not exist. Exiting..."
	exit 1
fi

if [ ! -d $BIND_DATA ]; then
        echo "The directory specified as $BIND_DATA does not exist. Exiting..."
        exit 1
fi


if [ -w $BIND_DIR/named.conf.ldap2zone ]; then
	>${BIND_DIR}/named.conf.ldap2zone
	for domain in $ZONES; do
		cat << EOF >> ${BIND_DIR}/named.conf.ldap2zone
zone "${domain}" {
	type master;
	$ALLOW_NOTIFY
	file "${BIND_DATA}/${PREFIX}${domain}";
	$ALLOW_UPDATE_PARAM
	$ALLOW_TRANSFER_PARAM
};
EOF
	done
	$rndc reconfig
fi

for domain in $ZONES; do
	TMPFILE=$(mktemp)
	CURRENT=$BIND_DATA/${PREFIX}${domain}
	OLD=$BIND_DATA/${PREFIX}${domain}.old-$$
	if $ldap2zone $domain $LDAP_URI $TTL > $TMPFILE; then
		lines=$(cat $TMPFILE | wc -l)
		if [ $lines -gt 1 ] ; then
		    result=$(named-checkzone $domain $TMPFILE 2>&1)
		    if [ $? -ne 0 ]; then
			logger -t ldap2bind "Checking the zone '$domain' failed: $result. Not deploying.\n"
			rm $TMPFILE
			continue
		    else
			mv $CURRENT $OLD
			mv $TMPFILE $CURRENT
		    fi
		fi
	fi

	result=$($rndc reload $domain 2>&1)
	if [ $? -ne 0 ]; then
		logger -t ldap2bind "Reloading the zone '$domain' failed: $result. Reverting.\n"
		mv $CURRENT $CURRENT.broken
		mv $OLD $CURRENT
	else
		rm $OLD
		logger -t ldap2bind "Reloading the zone '$domain' was successful\n"
	fi
done
