#!/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./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", <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"; } } } #########