diff options
Diffstat (limited to 'bin/bind.import')
-rwxr-xr-x | bin/bind.import | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/bin/bind.import b/bin/bind.import new file mode 100755 index 000000000..41313fba6 --- /dev/null +++ b/bin/bind.import @@ -0,0 +1,214 @@ +#!/usr/bin/perl -w +# +# -s: import slave zones as master. useful if you need to recreate your +# primary nameserver from a secondary +# -c chroot_dir: import data from chrooted bind (corrects the path for +# downloading zone files +# +# need to manually put header in +# /usr/local/etc/freeside/export.<datasrc./bind/<machine>/named.conf.HEADER + +use strict; +use vars qw( %d_part_svc ); +use Getopt::Std; +use Term::Query qw(query); +#use BIND::Conf_Parser; +#use DNS::ZoneParse 0.81; + +#use Net::SCP qw(iscp); +use Net::SCP qw(scp); +use FS::UID qw(adminsuidsetup datasrc); +use FS::Record qw(qsearch); #qsearchs); +#use FS::svc_acct_sm; +use FS::svc_domain; +use FS::domain_record; +#use FS::svc_acct; +#use FS::part_svc; + +use vars qw($opt_s $opt_c); +getopts("sc:"); + +my $user = shift or die &usage; +adminsuidsetup $user; + +$FS::svc_Common::noexport_hack = 1; +$FS::domain_record::noserial_hack = 1; + +use vars qw($spooldir); +$spooldir = "/usr/local/etc/freeside/export.". datasrc. "/bind"; +mkdir $spooldir unless -d $spooldir; + +%d_part_svc = + map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'}); + +print "\n\n", + ( join "\n", map "$_: ".$d_part_svc{$_}->svc, sort keys %d_part_svc ), + "\n\n"; +use vars qw($domain_svcpart); +$^W=0; #Term::Query isn't -w-safe +$domain_svcpart = + query "Enter part number for domains: ", 'irk', [ keys %d_part_svc ]; +$^W=1; + +print "\n\n", <<END; +Enter the location and name of your primary named.conf file, for example +"ns.isp.com:/var/named/named.conf" +END +my($named_conf)=&getvalue(":"); + +use vars qw($named_machine $prefix); +$named_machine = (split(/:/, $named_conf))[0]; +$prefix = "$spooldir/$named_machine"; +mkdir $prefix unless -d $prefix; + +#iscp("root\@$named_conf","$prefix/named.conf.import"); +scp("root\@$named_conf","$prefix/named.conf.import"); + + +sub getvalue { + my $prompt = shift; + $^W=0; # Term::Query isn't -w-safe + my $return = query $prompt, ''; + $^W=1; + $return; +} + +print "\n\n"; + +## + +$FS::svc_domain::whois_hack=1; + +my $p = Parser->new; +$p->parse_file("$prefix/named.conf.import"); + +print "\nBIND import completed.\n"; + +## + +sub usage { + die "Usage:\n\n bind.import user\n"; +} + +######## +BEGIN { + + package Parser; + use BIND::Conf_Parser; + use vars qw(@ISA $named_dir); + @ISA = qw(BIND::Conf_Parser); + + sub handle_option { + my($self, $option, $argument) = @_; + return unless $option eq "directory"; + $named_dir = $argument; + } + + sub handle_zone { + my($self, $name, $class, $type, $options) = @_; + return unless $class eq 'in'; + return if grep { $name eq $_ } (qw( + . localhost 127.in-addr.arpa 0.in-addr.arpa 255.in-addr.arpa + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int + )); + + use FS::Record qw(qsearchs); + use FS::svc_domain; + + my $domain = + qsearchs('svc_domain', { 'domain' => $name } ) + || new FS::svc_domain( { + svcpart => $main::domain_svcpart, + domain => $name, + action => 'N', + } ); + unless ( $domain->svcnum ) { + my $error = $domain->insert; + die $error if $error; + } + + if ( $type eq 'slave' && !$main::opt_s ) { + + #use Data::Dumper; + #print Dumper($options); + #exit; + + foreach my $master ( @{ $options->{masters} } ) { + my $domain_record = new FS::domain_record( { + 'svcnum' => $domain->svcnum, + 'reczone' => '@', + 'recaf' => 'IN', + 'rectype' => '_mstr', + 'recdata' => $master, + } ); + my $error = $domain_record->insert; + die $error if $error; + } + + } elsif ( $type eq 'master' || ( $type eq 'slave' && $main::opt_s ) ) { + + my $file = $options->{file}; + + use File::Basename; + my $basefile = basename($file); + my $sourcefile = $file; + $sourcefile = "$named_dir/$sourcefile" unless $file =~ /^\//; + $sourcefile = "$main::opt_c/$sourcefile" if $main::opt_c; + + use Net::SCP qw(iscp scp); + scp("root\@$main::named_machine:$sourcefile", + "$main::prefix/$basefile.import"); + + use DNS::ZoneParse 0.84; + my $zone = DNS::ZoneParse->new("$main::prefix/$basefile.import"); + + my $dump = $zone->dump; + + #use Data::Dumper; + #print "$name: ". Dumper($dump); + #exit; + + foreach my $rectype ( keys %$dump ) { + if ( $rectype =~ /^SOA$/i ) { + my $rec = $dump->{$rectype}; + my $domain_record = new FS::domain_record( { + 'svcnum' => $domain->svcnum, + 'reczone' => $rec->{origin}, + 'recaf' => 'IN', + 'rectype' => $rectype, + 'recdata' => + $rec->{primary}. ' '. $rec->{email}. ' ( '. + join(' ', map $rec->{$_}, + qw( serial refresh retry expire minimumTTL ) ). + ' )', + } ); + my $error = $domain_record->insert; + die $error if $error; + } else { + #die $dump->{$rectype}; + foreach my $rec ( @{ $dump->{$rectype} } ) { + my $domain_record = new FS::domain_record( { + 'svcnum' => $domain->svcnum, + 'reczone' => $rec->{name}, + 'recaf' => $rec->{class}, + 'rectype' => $rectype, + 'recdata' => ( $rectype =~ /^MX$/i + ? $rec->{priority}. ' '. $rec->{host} + : $rec->{host} ), + } ); + my $error = $domain_record->insert; + die $error if $error; + } + } + } + + #} else { + # die "unrecognized type $type\n"; + } + + } + +} +######### + |