1#!/bin/sh
2# Copyright 2007 Roy Marples <roy@marples.name>
3# All rights reserved
4
5# named updater for resolvconf
6
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10#     * Redistributions of source code must retain the above copyright
11#       notice, this list of conditions and the following disclaimer.
12#     * Redistributions in binary form must reproduce the above
13#       copyright notice, this list of conditions and the following
14#       disclaimer in the documentation and/or other materials provided
15#       with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29# This is very important!
30# We assume that we are a local dns cache - after all, why would a server
31# use resolvconf?
32# Now that we have assumed this, we also assume that generic DHCP clients
33# will enter their domains and search domains ONLY in the "search" field
34# in their resolv.confs and VPN clients will put the domain they are for
35# into the domain field only.
36# This allows bind to forward domains for a specific VPN domain to the
37# VPN nameserver and everything else to the standard name servers.
38
39# The bind config needs to be setup to include our file
40#options {
41#   include "resolvconf-options.conf";
42#};
43#include "resolvconf-zones.conf";
44
45# The last step is to configure dns configuration for /etc/resolv.conf
46#echo "nameserver 127.0.0.1" > /etc/resolvconf/resolv.conf.d/base
47# On some platforms, like FreeBSD, resolvconf is in /usr/local so it becomes
48#echo "nameserver 127.0.0.1" > /usr/local/etc/resolvconf/resolv.conf.d/base
49
50# Load our variables from resolvconf
51VARS="$(resolvconf -v)"
52eval "${VARS}"
53
54# If our dir doesn't exist then don't do anything
55NAMEDB=/etc/namedb
56[ -d "${NAMEDB}" ] || NAMEDB="/etc/bind"
57[ -d "${NAMEDB}" ] || exit 0
58
59NAMEDOPTIONS="${NAMEDB}/resolvconf-options.conf"
60NAMEDZONES="${NAMEDB}/resolvconf-zones.conf"
61
62# If we only have domain information then put it in search too
63[ -z "${NEWSEARCH}" -a -z "${NEWNS}" ] && NEWSEARCH="${NEWDOMAIN}"
64
65NEWOPTIONS="# Generated by resolvconf\n"
66NEWZONES="${NEWOPTIONS}"
67FORWARD=
68for N in ${NEWSEARCH}; do
69	case "${FORWARD}" in
70		*"\n\t${N#*,};"*);;
71		*) FORWARD="${FORWARD}\n\t${N#*,};";;
72	esac
73done
74for N in ${NEWNS}; do
75	case "${FORWARD}" in
76		*"\n\t${N};"*);;
77		*) FORWARD="${FORWARD}\n\t${N};";;
78	esac
79done
80if [ -n "${FORWARD}" ]; then
81	NEWOPTIONS="${NEWOPTIONS}\nforward first;\nforwarders {${FORWARD}\n};\n"
82fi
83
84LASTDN=
85ZONES=
86for DN in $(printf "%s\n" ${NEWDOMAIN} | sort -u); do
87	case "${LASTDN}" in
88		"${DN%,*}");;
89		*)
90		[ -n "${ZONES}" ] && ZONES="${NEWZONES}\n\t};\n};\n"
91		ZONES="${ZONES}\nzone \"${DN%,*}\" {\n"
92		ZONES="${ZONES}\ttype forward;\n"
93		ZONES="${ZONES}\tforward first;\n"
94		ZONES="${ZONES}\tforwarders {"
95		;;
96	esac
97	ZONES="${ZONES}\n\t\t${DN#*,};"
98done
99[ -n "${ZONES}" ] && NEWZONES="${NEWZONES}${ZONES}\n\t};\n};\n"
100
101# No point in changing files or reloading bind if the end result has not
102# changed
103RELOAD="no"
104if [ -e "${NAMEDOPTIONS}" ]; then
105	if [ "$(cat "${NAMEDOPTIONS}")" != "$(printf "${NEWOPTIONS}")" ]; then
106		printf "${NEWOPTIONS}" > "${NAMEDOPTIONS}"
107		RELOAD="yes"
108	fi
109else
110	printf "${NEWOPTIONS}" > "${NAMEDOPTIONS}"
111	RELOAD="yes"
112fi
113if [ -e "${NAMEDZONES}" ]; then
114	if [ "$(cat "${NAMEDZONES}")" != "$(printf "${NEWZONES}")" ]; then
115		printf "${NEWZONES}" > "${NAMEDZONES}"
116		RELOAD="yes"
117	fi
118else
119	printf "${NEWZONES}" > "${NAMEDZONES}"
120	RELOAD="yes"
121fi
122
123[ "${RELOAD}" = "yes" ] && resolvconf -s named restart
124
125exit 0
126