#!/usr/bin/perl -wT # Copyright 2002, 2003, 2004, 2005 Peter Palfrader # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =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 Epeter@palfrader.org =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 $SOURCE_HOST = 'unknown'; if ($PROGRAM_NAME =~ m/-host-([a-z0-9]+)$/) { $SOURCE_HOST = $1; }; my $NAMEDCONF = "/etc/bind/named.conf.from-$SOURCE_HOST.ldapzones.slave.pushed"; my @RELOAD = qw{/etc/init.d/bind9 reload}; my @THISNAMES; my $CONFFILE = '/etc/noreply/make-bindconfig-from-ldap.conf'; if (-e $CONFFILE) { open(F, $CONFFILE) or die ("Cannot open $CONFFILE: $!\n"); for my $line () { chomp($line); push @THISNAMES, $line; }; } else { my $fqdn = `hostname -f`; chomp $fqdn; $fqdn .= '.'; push @THISNAMES, $fqdn; }; 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 for my $thishost (@THISNAMES) { print CONF "This system is known as $thishost\n"; }; 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-$SOURCE_HOST-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);