--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/master_watcher Mon Dec 23 09:18:06 2002 +0000
@@ -0,0 +1,160 @@
+#! /usr/bin/perl -w
+my $USAGE = <<'#';
+Usage: $ME [options]
+ -l --logfile=s Name of the logfile we've to read [$opt_logfile]
+ -d --dir=s Where the named.conf's are expected [$opt_zonesdir]
+ -u --[no]update Update the "masters"-entries [$opt_update]
+ -c --[no]create Add newly appeared domains [$opt_create]
+ -f --[no]follow Follow the end of the logfile [$opt_follow]
+ -h --help This text [$opt_help]
+#
+# Es wird ein Verzeichnis geben, in diesem Verzeichnis liegt für
+# *jede* Zone eine eigene Konfigurations-Datei.
+# Diese ganzen Konfigurationsdateien werden dann zusammengefaßt
+# und diese zusammengefaßte wird dem bind per "include" mitgeteilt.
+
+use strict;
+use File::Basename;
+use IO::Handle;
+use File::Path;
+use Getopt::Long;
+use Unix::Syslog qw/:macros :subs/;
+
+my $ME = basename $0;
+
+
+my %auth = (
+ "212.172.233.34" => "pu.schlittermann.de",
+ "212.80.235.130" => "pu2.schlittermann.de",
+ "145.253.160.50" => "bastion.actech.de",
+ "212.172.233.146" => "ns.flaemingnet.de",
+ "212.172.127.34" => "mango.compot.com",
+ "62.144.175.34" => "ns.add-on.de",
+ "195.145.19.34" => "ns.datom.de",
+);
+
+$SIG{__DIE__} = sub { syslog(LOG_ERR, $_[0]); exit -1; };
+$SIG{__WARN__} = sub { syslog(LOG_WARNING, $_[0]); };
+
+my %seen;
+
+my $opt_help = 0;
+my $opt_logfile = "./syslog";
+my $opt_zonesdir = "./zones";
+my $opt_follow = 0;
+my $opt_create = 1;
+my $opt_update = 1;
+
+my $naptime = 1;
+
+
+sub updateFile($@);
+
+
+MAIN: {
+
+
+ openlog($ME, LOG_PID | LOG_PERROR, LOG_DAEMON);
+ syslog(LOG_NOTICE, "starting");
+
+ GetOptions(
+ "help" => \$opt_help,
+ "logfile=s" => \$opt_logfile,
+ "follow!" => \$opt_follow,
+ "dir=s" => \$opt_zonesdir)
+ or die "$ME: Bad Usage\n";
+
+ if ($opt_help) {
+ print eval "\"$USAGE\"";
+ exit 0;
+ }
+
+ open (LOGFILE, $_ = "<$opt_logfile") or die "Can't open $_: $!\n";
+ for (;;) {
+ my (%masters, my %missing);
+ while (<LOGFILE>) {
+
+ my ($domain, $ip);
+
+ # NOTIFY-Zeilen
+ ($domain, $ip) = /NOTIFY.*?\((\S+?),.*?\[([\d.]+)\]/ and do {
+ if (not exists $auth{$ip}) {
+ warn "notify for $domain from unauthorized ip $ip\n";
+ next;
+ };
+ $masters{$domain}->{$ip} = 1;
+ next;
+ };
+
+ # NOTIFY for vergessene
+ /NOTIFY for "(\S+?)".*not one of our zones/ and do {
+ if (not exists $masters{$1}) {
+ warn "skipping $1 (not authorized)\n";
+ next;
+ }
+ $missing{$1} = 1;
+ };
+ }
+
+ # Jetzt sind wir erstmal durch und verarbeiten alles
+
+ #foreach my $domain (sort keys %missing) {
+ #updateFile($domain, keys %{$masters{$domain}});
+ #delete $masters{$domain};
+ #delete $missing{$domain};
+ #}
+
+ foreach my $domain (sort keys %masters) {
+ updateFile($domain, keys %{$masters{$domain}});
+ delete $masters{$domain};
+ delete $missing{$domain} if exists $missing{$domain};
+ }
+
+ last if !$opt_follow;
+ sleep $naptime;
+ # seek(LOGFILE, 0, 1);
+ LOGFILE->clearerr();
+ }
+}
+
+sub updateFile($@)
+{
+ local $_;
+ my $domain = shift;
+ my $masters = join "; ", @_;
+ my $file = "$opt_zonesdir/$domain";
+
+ syslog(LOG_NOTICE, "Updating/Creating $file ($masters)\n");
+ return;
+
+ if (-f $file) {
+ open (IN, $_ = "<$file") or die "Can't open $_: $!\n";
+ # ein etwas anderer Versuch - noch nicht fertig
+ $_ = join "", <IN>;
+ close(IN); open(OUT, ">&STDOUT"); # Wenn's geht, dann in's File
+ s/(masters\s*{)(.*?)(};)/$1$2; $masters; $3/;
+ print OUT;
+ }
+
+ else {
+ open(OUT, $_ = ">$file") or die "Can't open $_: $!\n";
+
+ print OUT <<_EOF_;
+// Autogenerated
+zone "$domain" {
+ type slave;
+ masters { $masters; };
+ file "/etc/bind/slave/$domain";
+ allow-query { any; };
+ allow-transfer { none; };
+ allow-update { none; };
+};
+_EOF_
+ close OUT;
+ }
+
+ return;
+}
+
+
+# vim:sts=4 sw=4 aw ai sm: