#!/usr/bin/perl
BEGIN {
my $x = $0; $x =~ s/\/[^\/]+$//;
if ($x eq $0 || $x eq '') { $x = `pwd`;chomp $x; };
require "$x/config.pl";
};
use Net::DNS;
sub usage {
print "usage: transfer_zone ns zone ...\n"; exit 1;
}
my $ns1ip = $ENV{IP};
my @local_ns = ();
warn "IP not set; won't force creation of working nameserver records"
if (!defined($ns1ip) && $ARGV[1] ne '.'); # root zones...
if ($ns1ip && $ns1ip ne '') {
my $x = $ENV{LOCAL_NS};
if ($x && $x ne '') {
@local_ns = split /\s*,\s*/, $x;
}
if ($ns1ip =~ /,/) {
# tada
my @x = split /\s*\,\s*/, $ns1ip;
$ns1ip = \@x;
}
}
my $ns = shift @ARGV;
&usage if (!defined($ns));
my @zone = shift @ARGV;
&usage if (scalar(@zone) < 1);
if ($zone[0] eq '-') {
@zone = ();
while (<STDIN>) {
chomp;
push(@zone, $_);
}
}
my $ldap = &get_ldap_conn;
my $res = new Net::DNS::Resolver;
$res->nameservers($ns);
read_zone: foreach my $zonename (@zone) {
print $zonename . ' ' . ('=' x (79 - length($zonename))) . "\n\n";
my @records = $res->axfr($zonename);
while (!@records) {
if ($res->errorstring eq "couldn't connect") {
sleep(10);
@records = $res->axfr($zonename);
} else {
next read_zone;
}
}
foreach my $rr (@records) {
$rr->print;
if ($rr->type eq 'SOA') {
die "Invalid SOA(1) record for ", $rr->name, " "
unless ($rr->string =~ /^(\*?[0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)\s+([0-9a-zA-Z_.+-]+)\s+\((.*)\)/s);
die "Corrupt SOA record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type);
my $zn = $1;
my $soa = $7;
die "Invalid SOA fields for ", $zonename, " "
unless ($soa =~ /\s*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\s*/s);
my $soarecord = "$1 $2 $3 $4 $5";
set_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
sOARecord => $soarecord,
], { sOARecord => $soarecord });
} elsif ($rr->type eq "A") {
die "Invalid A record for ", $rr->name, " "
unless ($rr->string =~ /^(\*?[0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9.]+)/);
die "Corrupt A record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type && $5 eq $rr->address);
next if lc($1) eq lc("localhost.$zonename");
add_record($ldap, &fix_domain($zonename, $1), [
dc => &dc_domain($1),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
aRecord => $5,
], { aRecord => $5 });
} elsif ($rr->type eq "MX") {
die "Invalid MX record for ", $rr->name, " "
unless ($rr->string =~ /^(\*?[0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+(\d+)\s+([0-9a-zA-Z_.+-]+)/);
die "Corrupt MX record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type);
my $zn = $1;
my $pref = $5;
my $name = lc $6;
$name =~ s/\.$//; $name .= '.';
add_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
mXRecord => "$pref $name",
], { mXRecord => "$pref $name" });
} elsif ($rr->type eq "NS") {
die "Invalid NS record for ", $rr->name, " "
unless ($rr->string =~ /^(\*?[0-9a-zA-Z_.+-]*)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)/);
die "Corrupt NS record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type);
my $zn = $1;
$zn = '*' if ($zn eq '');
my $name = lc $5;
$name =~ s/\.$//; $name .= '.';
# nameserver records for PTR's?
next if ($zn =~ /\.in-addr\.arpa\.?$/ && $ns1ip && $ns1ip ne '');
if ($ns1ip && $ns1ip ne '') {
# we want $name to be fudged to be
# ns.$zn
$name = 'ns.' . $zn;
}
add_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
nSRecord => $name,
], { nSRecord => $name });
if ($ns1ip && $ns1ip ne '') {
set_record($ldap, &fix_domain($zonename, $name), [
dc => &dc_domain($name),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
aRecord => $ns1ip,
], { nSRecord => $name });
}
} elsif ($rr->type eq "CNAME") {
die "Invalid ", $rr->type, " record for ", $rr->name, " "
unless ($rr->string =~ /^(\*?[0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)/);
die "Corrupt ", $rr->type, " record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type);
my $zn = $1;
my $name = lc $5;
$name =~ s/\.$//; $name .= '.';
add_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
cNAMERecord => $name,
], { cNAMERecord => $name });
} elsif ($rr->type eq "TXT") {
die "Invalid ", $rr->type, " record for ", $rr->name, " "
unless ($rr->string =~ /^(\*?[0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+(.*)/);
die "Corrupt ", $rr->type, " record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type);
# displays as "doo" "doo" ""
my $arg = join('|', (split /\" \"/, substr($5, 1, -1)));
$arg =~ s/\|$//;
my $zn = $1;
add_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
description => $arg,
], { description => $arg });
} elsif ($rr->type eq "PTR") {
die "Invalid PTR record for ", $rr->name, " "
unless ($rr->string =~ /^([0-9.]+\.in-addr\.arpa)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)/i
|| $rr->string =~ /^([\w\/.+-]+\.$zonename)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([\w\/.+-]+)/i);
die "Corrupt PTR record for ", $rr->name, " "
unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type);
my $zn = $1;
my $name = lc $5;
$name =~ s/\.$//; $name .= '.';
if ($ns1ip && $ns1ip ne '') {
set_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
cNAMERecord => $name,
nSRecord => \@local_ns,
], { cNAMERecord => $name });
} else {
# let the "old" record keep it's NS...
set_record($ldap, &fix_domain($zonename, $zn), [
dc => &dc_domain($zn),
objectClass => 'dnsDomain',
objectClass => 'dcObject',
objectClass => 'domain',
cNAMERecord => $name,
], { cNAMERecord => $name });
}
}
}
}
sub fix_domain
{
my ($base, $zn)=(@_);
return $base if ($zn eq '');
return $zn;
}
syntax highlighted by Code2HTML, v. 0.9.1