#!/usr/bin/perl -wT

# Copyright 2002, 2003, 2004, 2005 Peter Palfrader <peter@palfrader.org>
# All rights reserved.

=pod

=head1 NAME

makezonefile - create config file for bind

=head1 SYNOPSIS

makezonefile

=head1 DESCRIPTION

makezonefile reads from STDIN a list of domains and
their assoziated nameservers; one domain per line, the primary, the nameservers
seperated by whitespace.

Example:

  sigint.net 82.94.251.194  asteria.debian.or.at. seppia.noreply.org.
  theremailer.net 195.244.237.84|213.239.201.102  asteria.debian.or.at.
  vanderheide.ca 64.26.156.90  asteria.debian.or.at.

First column is the domain in question, second is the primary or primaries
separated by a pipe symbol, the rest are the nameservers

For each domain it will then look whether this host's name (as configured in
the @THISNAMES variable) appears in the list of nameservers and if that is the
case add a slave entry to the file hardcoded in the script.

Afterwards a bind9 reload will be issued.


The script is typicalle called from ssh (using authorized keys with command=script).

=head1 OPTIONS

none

=head1 AUTHOR

Peter Palfrader E<lt>peter@palfrader.org<gt>

=head1 FILES

/var/cache/bind/weasel/ldapzones.conf.slave.pushed

=head1 REQUIREMENTS

none but perl

=head1 SEE ALSO

Ask author.

=cut
	

use strict;
use English;

$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

my $NAMEDCONF = '/etc/bind/named.conf.from-opium.ldapzones.slave.pushed';
my @RELOAD = qw{/etc/init.d/bind9 reload};
my @THISNAMES = qw{asteria.debian.or.at.};
#my @THISNAMES = qw{seppia.noreply.org. ns3.noreply.org.};
#my @THISNAMES = qw{redeemer.devspread.org.};

my $date = localtime();
open (CONF, ">$NAMEDCONF") or
	die ("Cannot open $NAMEDCONF: $!\n");
print CONF << "EOF";
// conf file for bind
// $date
// automatically created by $PROGRAM_NAME from stdin (probably called by ssh)
// vim:set syn=named:
EOF

my @lines = <>;
DOMAIN:
for my $line (@lines) {
	chomp ($line);
	my @part = split (/\s+/, $line);
	my $domain = shift @part;
	my @masters = split /\|/, shift @part;
	unless (defined $domain && ($domain =~ /^[a-z0-9.-]+$/)) {
		warn "Skipping $domain: bad name\n";
		next;
	};
	if (scalar @masters == 0) {
		warn "Skipping $domain: No masters\n";
		next;
	};
	for my $master (@masters) {
		unless (defined $master && ($master =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/)) {
			warn "Skipping $domain: bad master '$master'\n";
			next DOMAIN;
		};
	};
	my $this_ns = 0;
	for my $ns (@part) {
		for my $my_name (@THISNAMES) {
			$this_ns |= ($ns eq $my_name);
		};
	};
	next unless $this_ns;

	print CONF << "EOF";
	zone "$domain" {
		type slave;
		file "from-opium-slave-ldap-$domain";
		allow-transfer { "none"; };
		allow-query { any; };
		masters {
EOF
	for my $master (@masters) {
		print CONF "			$master;\n";
	};
	print CONF << "EOF";
		};
	};
EOF
};
close (CONF);

exec(@RELOAD);