From 389ecff3dd90602b691d77c0b49205eb07285d2b Mon Sep 17 00:00:00 2001 From: sjing Date: Thu, 12 May 2011 04:05:14 +0000 Subject: [PATCH] support ddns as the default dnshandler. git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9574 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/xcat/plugins/bind.pm | 1595 -------------------------- 1 file changed, 1595 deletions(-) delete mode 100755 xCAT-server/lib/xcat/plugins/bind.pm diff --git a/xCAT-server/lib/xcat/plugins/bind.pm b/xCAT-server/lib/xcat/plugins/bind.pm deleted file mode 100755 index c19164f53..000000000 --- a/xCAT-server/lib/xcat/plugins/bind.pm +++ /dev/null @@ -1,1595 +0,0 @@ -#!/usr/bin/perl -# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html -#This is ported forward from xCAT 1.3 -#TODO: A lot of stuff was handled by the script portion of makedns, notably: -# db.cache -# forwarders -# chroot -# dnsallowq -# mucking with sysconfig -package xCAT_plugin::bind; -use strict; -no strict "refs"; #This code is as yet still very broken... - -#use warnings; -use Sys::Hostname; -use Cwd; -use Getopt::Long; -use xCAT::Table; -use xCAT::MsgUtils; -use Data::Dumper; - -sub handled_commands -{ - return {"makedns" => "bind"}; -} - -#NAME -# -# h2n - Translate host table to name server file format -# $Date: 1999/08/08 17:17:56 $ $Revision: 8.2 $ -# -#SYNOPSIS -# -# h2n -d DOMAIN -n NET [options] - -# Various defaults -my $Host; -my $doaliases = 1; -my $domx = 1; -my $dowks = 0; -my $dotxt = 0; -my $dontdodomains = 0; -my $Bootfile = "/etc/named.conf"; -my $DBDir = "/var/named/"; -my $Domain = ""; -my $Hostfile = "/etc/hosts"; -my $Commentfile = ""; -my $Commentfileread = 0; -my $User = "root"; -my $RespHost = ""; -my $RespUser = ""; -my $DefSerial = 1; -my $DefRefresh = 10800; -my $DefRetry = 3600; -my $DefExpire = 604800; -my $DefTtl = 86400; -my $UseDefSOAValues = 0; -my $DefMxWeight = 10; -my $Defsubnetmask = ""; -my $ForceSerial = -1; -my $UseDateInSerial = 1; -my $DateSerial = 0; -my $Version = 8; -my $request; -my $callback; -my @forwarders; - -#Declarations to alleviate use strict, since the code doesn't seem to be structured well enough to avoid it for these cases -my $Bootsecsaveaddr; -my $Bootsecaddr; -my @Networks; -my @bootmsgs_v4; -my @bootmsgs_v8; -my @elimpats; -my @cpats; -my @makesoa; -my $Domainfile; -my %cpatrel; -my @Servers; -my $Serial; -my $Refresh; -my @Mx; -my $Expire; -my %Hosts; -my %Comments; -my $Domainpattern; -my @Netpatterns; -my $Ttl; -my $Retry; -my %Cnames; -my %CommentRRs; -my $soa_warned; -my %Aliases; -my %Netfiles; - -sub process_request -{ - $request = shift; - $callback = shift; - %Netfiles = (); - %Aliases = (); - $soa_warned = 0; - my $canonical; - my $aliases; - %Comments = (); - %CommentRRs = (); - %Cnames = (); - %Hosts = (); - @Netpatterns = (); - $DBDir = "/var/named/"; - - unless (-d $DBDir) - { - $DBDir = "/var/lib/named/"; - } - - # if both do not exist, make /var/named - unless (-d $DBDir) - { - $DBDir = "/var/named/"; - my $cmd = "/bin/mkdir $DBDir"; - my $outref = xCAT::Utils->runcmd("$cmd", 0); - if ($::RUNCMD_RC != 0) - { - my $rsp = {}; - $rsp->{data}->[0] = "Could not create $DBDir.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - return 1; - } - } - - $Host = hostname; - $Host =~ s/\..*//; - my $sitetab = xCAT::Table->new('site'); - unless ($sitetab) - { - my $rsp = {}; - $rsp->{data}->[0] = "No site table found.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - return; - } - my @args = (); - if ($request->{arg}) - { - @args = @{$request->{arg}}; - @ARGV = @{$request->{arg}}; - } - &checkusageandversion($callback); - - (my $fent) = $sitetab->getAttribs({key => 'forwarders'}, 'value'); - if ($fent and defined $fent->{value}) - { - @forwarders = split /[,:;]/, $fent->{value}; - } - unless (grep /^-d$/, @args) - { - (my $dent) = $sitetab->getAttribs({key => 'domain'}, 'value'); - if ($dent and $dent->{value}) - { - push @args, "-d"; - $dent->{value} =~ s/\.$//; - push @args, $dent->{value}; - } - } - unless (grep /^-s$/, @args) - { - push @args, "-s"; - push @args, $Host; - } - unless (grep /^-n$/, @args) - { - my $nettab = xCAT::Table->new('networks'); - unless ($nettab) - { - my $rsp = {}; - $rsp->{data}->[0] = - "Unable to open networks table, has makenetworks been run?.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - return; - } - foreach (@{$nettab->getAllEntries()}) - { - if ($_->{net} =~ /:/) { - my $rsp = {}; - $rsp->{data}->[0] = "Ignoring IPv6 network, not supported in bind.pm (site.dnshandler=ddns if you want to do IPv6 DNS records"; - xCAT::MsgUtils->message("W",$rsp,$callback,1); - next; - } - push @args, "-n"; - push @args, $_->{net} . ":" . $_->{mask}; - } - } - - push(@bootmsgs_v4, "primary\t0.0.127.IN-ADDR.ARPA db.127.0.0\n"); - push(@bootmsgs_v8, - qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;\n\tfile "db.127.0.0";\n\tnotify no;\n};\n\n| - ); - - &PARSEARGS($callback, @args); - &FIXUP($callback); - unless (open(HOSTS, $Hostfile)) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open $Hostfile\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - my $data; - my $comment; - my $addr; - my $names; - LINE: while () - { - next if /^[ \t]*#/; # skip comment lines - next if /^$/; # skip empty lines - chop; # remove the trailing newline - tr/A-Z/a-z/; # translate to lower case - - ($data, $comment) = split('#', $_, 2); - ($addr, $names) = split(/[ ]+/, $data, 2); - if ($names =~ /^[ \t]*$/) - { - - #$callback->({data=>["Bad line in hosts file ignored '$_'"]}); - next LINE; - } - $addr =~ s/^[ ]*//; - $addr =~ s/[ ]*$//; - if ($addr !~ /^\d+\.\d+\.\d+\.\d+$/) - { - my $rsp = {}; - $rsp->{data}->[0] = "Ignoring $addr (not a valid IPv4 address).\n"; - xCAT::MsgUtils->message("I", $rsp, $callback); - next LINE; - } - - # Match -e args - my $netpat; - foreach $netpat (@elimpats) - { - next LINE if (/[.\s]$netpat/); - } - - # Process -c args - foreach $netpat (@cpats) - { - if (/\.$netpat/) - { - ($canonical, $aliases) = split(' ', $names, 2); - $canonical =~ s/\.$netpat//; - #If we feed in names with, say, underscores, bind complains usually due to default check-names behavior. Later, we may should support putting check-names to ignore, but for now let them know it won't work and skip it - unless ($canonical =~ /^[a-z0-9-]+$/i) { - xCAT::MsgUtils->message("E", {errorcode=>[1],error=>["$canonical contains invalid characters, skipping entry"]}, $callback, 1); - next LINE; - } - if ($Cnames{$canonical} != 1) - { - printf DOMAIN "%-20s IN CNAME %s.%s.\n", $canonical, - $canonical, $cpatrel{$netpat}; - $Cnames{$canonical} = 1; - } - next LINE; - } - } - - # Check that the address is in the address list. - my $match = 'none'; - foreach $netpat (@Netpatterns) - { - $match = $netpat, last - if ($addr =~ /^$netpat\./ or $addr =~ /^$netpat$/); - } - next if ($match eq 'none'); - - ($canonical, $aliases) = split(' ', $names, 2); # separate out aliases - next if ($dontdodomains && $canonical =~ /\./); # skip domain names - $canonical =~ s/$Domainpattern//; # strip off domain if there is one - unless ($canonical =~ /^[a-z0-9-]+$/i) { - xCAT::MsgUtils->message("E", {errorcode=>[1],error=>["$canonical contains invalid characters, skipping entry"]}, $callback, 1); - next; - } - $Hosts{$canonical} .= $addr . " "; # index addresses by canonical name - $Aliases{$addr} .= $aliases . " "; # index aliases by address - $Comments{"$canonical-$addr"} = $comment; - - # Print PTR records - my $file = $Netfiles{$match}; - printf $file "%-30s\tIN PTR %s.%s.\n", &REVERSE($addr), $canonical, - $Domain; - } - - # - # Go through the list of canonical names. - # If there is more than 1 address associated with the - # name, it is a multi-homed host. For each address - # look up the aliases since the aliases are associated - # with the address, not the canonical name. - # - foreach $canonical (keys %Hosts) - { - my @addrs = split(' ', $Hosts{$canonical}); - my $numaddrs = $#addrs + 1; - foreach my $addr (@addrs) - { - - # - # Print address record for canonical name. - # - if ($Cnames{$canonical} != 1) - { - printf DOMAIN "%-20s IN A %s\n", $canonical, $addr; - } - else - { - my $rsp = {}; - $rsp->{data}->[0] = - "$canonical - cannot create A record because CNAME exists for name.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - } - - # - # Print cname or address records for each alias. - # If this is a multi-homed host, print an address - # record for each alias. If this is a single address - # host, print a cname record. - # - my $alias; - if ($doaliases) - { - my @aliases = split(' ', $Aliases{$addr}); - foreach $alias (@aliases) - { - - # - # Skip over the alias if the alias and canonical - # name only differ in that one of them has the - # domain appended to it. - # - next - if ($dontdodomains && $alias =~ /\./); # skip domain names - $alias =~ s/$Domainpattern//; - if ($alias eq $canonical) - { - next; - } - unless ($alias =~ /^[a-z0-9-]+$/i) { - xCAT::MsgUtils->message("E", {errorcode=>[1],error=>["$canonical alias $alias contains invalid characters, skipping entry"]}, $callback, 1); - next; - } - - my $aliasforallnames = 0; - if ($numaddrs > 1) - { - - # - # If alias exists for *all* addresses of this host, we - # can use a CNAME instead of an address record. - # - my $aliasforallnames = 1; - my $xalias = $alias . " "; # every alias ends with blank - my @xaddrs = split(' ', $Hosts{$canonical}); - foreach my $xaddr (@xaddrs) - { - if (!($Aliases{$xaddr} =~ /\b$xalias/)) - { - $aliasforallnames = 0; - } - } - } - - if (($numaddrs > 1) && !$aliasforallnames) - { - printf DOMAIN "%-20s IN A %s\n", $alias, $addr; - } - else - { - - # - # Flag aliases that have already been used - # in CNAME records or have A records. - # - if (($Cnames{$alias} != 1) && (!$Hosts{$alias})) - { - printf DOMAIN "%-20s IN CNAME %s.%s.\n", $alias, - $canonical, $Domain; - $Cnames{$alias} = 1; - } - else - { - my $rsp = {}; - $rsp->{data}->[0] = - "$alias - CNAME or A exists already. alias ignored.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - } - } - - if ($aliasforallnames) - { - - # - # Since a CNAME record was created, remove this - # name from the alias list so we don't encounter - # it again for the next address of this host. - # - my $xalias = $alias . " "; # every alias ends with blank - my @xaddrs = split(' ', $Hosts{$canonical}); - my $xaddr; - foreach $xaddr (@xaddrs) - { - $Aliases{$xaddr} =~ s/\b$xalias//; - } - } - } - } - } - if ($domx) - { - &MX($callback, $canonical, @addrs); - } - if ($dotxt) - { - &TXT($canonical, @addrs); - } - if ($Commentfile ne "") - { - &DO_COMMENTS($callback, $canonical, @addrs); - } - } - - # Deal with spcl's - if (-r "spcl.$Domainfile") - { - print DOMAIN "\$INCLUDE spcl.$Domainfile\n"; - } - my $file; - my $n; - foreach $n (@Networks) - { - if (-r "spcl.$n") - { - $file = "DB.$n"; - print $file "\$INCLUDE spcl.$n\n"; - } - } - - # generate boot.* files - &GEN_BOOT($callback); - my $rsp = {}; - $rsp->{data}->[0] = "Setup of DNS complete."; - xCAT::MsgUtils->message("I", $rsp, $callback); - return 0; -} - -# -# Generate resource record data for -# strings from the commment field that -# are found in the comment file (-C). -# -sub DO_COMMENTS -{ - my ($callback, $canonical, @addrs) = @_; - my (@c, $c, $a, $comments); - - if (!$Commentfileread) - { - unless (open(F, $Commentfile)) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open file $Commentfile: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - $Commentfileread++; - while () - { - chop; - my ($key, $c) = split(':', $_, 2); - $CommentRRs{$key} = $c; - } - close(F); - } - - my $key; - foreach $a (@addrs) - { - $key = "$canonical-$a"; - $comments .= " $Comments{$key}"; - } - - @c = split(' ', $comments); - foreach $c (@c) - { - if ($CommentRRs{$c}) - { - printf DOMAIN "%-20s %s\n", $canonical, $CommentRRs{$c}; - } - } -} - -# -# Generate MX record data -# -sub MX -{ - my ($callback, $canonical, @addrs) = @_; - my ($first, $a, $key, $comments); - - if ($Cnames{$canonical}) - { - my $rsp = {}; - $rsp->{data}->[0] = - "$canonical - cannot create MX record because CNAME exists for name.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - return; - } - $first = 1; - - foreach $a (@addrs) - { - $key = "$canonical-$a"; - $comments .= " $Comments{$key}"; - } - - if ($comments !~ /\[no smtp\]/) - { - - # Add WKS if requested - if ($dowks) - { - foreach $a (@addrs) - { - printf DOMAIN "%-20s IN WKS %s TCP SMTP\n", $canonical, $a; - } - } - printf DOMAIN "%-20s IN MX %s %s.%s.\n", $canonical, $DefMxWeight, - $canonical, $Domain; - $first = 0; - } - if ($#Mx >= 0) - { - foreach $a (@Mx) - { - if ($first) - { - printf DOMAIN "%-20s IN MX %s\n", $canonical, $a; - $first = 0; - } - else - { - printf DOMAIN "%-20s IN MX %s\n", "", $a; - } - } - } - -} - -# -# Generate TXT record data -# -sub TXT -{ - my ($canonical, @addrs) = @_; - my ($a, $key, $comments); - - foreach $a (@addrs) - { - $key = "$canonical-$a"; - $comments .= " $Comments{$key}"; - } - $comments =~ s/\[no smtp\]//g; - $comments =~ s/^\s*//; - $comments =~ s/\s*$//; - - if ($comments ne "") - { - printf DOMAIN "%s IN TXT \"%s\"\n", $canonical, $comments; - } -} - -# -# Create the SOA record at the beginning of the file -# -sub MAKE_SOA -{ - my ($callback, $fname, $file) = @_; - my ($s); - - if (-s $fname) - { - - unless (open($file, "$fname")) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open $fname: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - $_ = <$file>; - chop; - if (/\($/) - { - my $junk; - if (!$soa_warned) - { - my $rsp = {}; - $rsp->{data}->[0] = "Converting SOA format to new style.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - $soa_warned++; - } - if ($ForceSerial > 0) - { - $Serial = $ForceSerial; - } - else - { - ($Serial, $junk) = split(' ', <$file>, 2); - $Serial++; - if ($UseDateInSerial && ($DateSerial > $Serial)) - { - $Serial = $DateSerial; - } - } - ($Refresh, $junk) = split(' ', <$file>, 2); - ($Retry, $junk) = split(' ', <$file>, 2); - ($Expire, $junk) = split(' ', <$file>, 2); - ($Ttl, $junk) = split(' ', <$file>, 2); - } - else - { - if (/TTL/) - { - $_ = <$file>; - } - split(' '); - if ($#_ == 11) - { - if ($ForceSerial > 0) - { - $Serial = $ForceSerial; - } - else - { - $Serial = ++$_[6]; - if ($UseDateInSerial && ($DateSerial > $Serial)) - { - $Serial = $DateSerial; - } - } - $Refresh = $_[7]; - $Retry = $_[8]; - $Expire = $_[9]; - $Ttl = $_[10]; - } - else - { - my $rsp = {}; - $rsp->{data}->[0] = "Improper format SOA in $fname.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - } - if ($UseDefSOAValues) - { - $Refresh = $DefRefresh; - $Retry = $DefRetry; - $Expire = $DefExpire; - $Ttl = $DefTtl; - } - close($file); - } - else - { - if ($ForceSerial > 0) - { - $Serial = $ForceSerial; - } - else - { - $Serial = $DefSerial; - if ($UseDateInSerial && ($DateSerial > $Serial)) - { - $Serial = $DateSerial; - } - } - $Refresh = $DefRefresh; - $Retry = $DefRetry; - $Expire = $DefExpire; - $Ttl = $DefTtl; - close($file); - } - - unless (open($file, "> $fname")) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open $fname: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - print $file '$TTL 86400' . "\n"; - print $file "\@ IN SOA $RespHost $RespUser "; - print $file "( $Serial $Refresh $Retry $Expire $Ttl )\n"; - foreach $s (@Servers) - { - print $file " IN NS $s\n"; - } - print $file "\n"; -} - -# -# Reverse the octets of an IP address and append -# in-addr.arpa. -# -sub REVERSE -{ - join('.', reverse(split('\.', $_[0]))) . '.IN-ADDR.ARPA.'; -} - -# -# Establish what we will be using for SOA records -# -sub FIXUP -{ - my $callback = shift; - my ($s); - - if ($Host =~ /\./) - { - $RespHost = "$Host."; - } - else - { - $RespHost = "$Host.$Domain."; - } - $RespHost =~ s/\.\././g; - - if ($User =~ /@/) - { # -u user@... - if ($User =~ /\./) - { - $RespUser = "$User."; # -u user@terminator.movie.edu - } - else - { - $RespUser = "$User.$Domain."; # -u user@terminator - } - $RespUser =~ s/@/./; - } - elsif ($User =~ /\./) - { - $RespUser = "$User."; # -u user.terminator.movie.edu - } - else - { - $RespUser = "$User.$RespHost"; # -u user - } - $RespUser =~ s/\.\././g; # Strip any ".."'s to "." - - # Clean up nameservers - if (!@Servers) - { - my $rsp = {}; - $rsp->{data}->[0] = - "No -s option specified. Assuming \"-s $Host.$Domain\".\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - push(@Servers, "$Host.$Domain."); - } - else - { - foreach $s (@Servers) - { - if ($s !~ /\./) - { - $s .= ".$Domain"; - } - if ($s !~ /\.$/) - { - $s .= "."; - } - } - } - - # Clean up MX hosts - foreach $s (@Mx) - { - $s =~ s/:/ /; - if ($s !~ /\./) - { - $s .= ".$Domain"; - } - if ($s !~ /\.$/) - { - $s .= "."; - } - } - - # Now open boot file (named.conf) and print saved data - unless (open(BOOT, "> $Bootfile")) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open $Bootfile.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - - # - # Write either the version 4 boot file directives or the - # version 8 boot file directives. - # - - if ($Version == 4) - { - print BOOT "\ndirectory $DBDir\n"; - foreach my $line (@bootmsgs_v4) - { - print BOOT $line; - } - print BOOT "cache\t. db.cache\n"; - if (-r "spcl.boot") - { - print BOOT "include\tspcl.boot\n"; - } - } - else - { - print BOOT qq|\noptions {\n\tdirectory "$DBDir";\n|; - if (@forwarders) - { - print BOOT qq|\tforwarders {\n|; - foreach (@forwarders) - { - print BOOT qq|\t\t$_;\n|; - } - print BOOT qq|\t};\n|; - } - if (-r "spcl.options") - { - print BOOT "\t# These options came from the file spcl.options\n"; - - # - # Copy the options in since "include" cannot be used - # within a statement. - # - unless (open(OPTIONS, "{data}->[0] = "Unable to open spcl.options.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - while () - { - print BOOT; - } - close(OPTIONS); - } - print BOOT qq|};\n\n|; - foreach my $line (@bootmsgs_v8) - { - print BOOT $line; - } - - # hint zone is also needed for DNS forwarders on AIX - if (xCAT::Utils->isAIX()) - { - print BOOT - qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|; - } - else - { - unless (@forwarders) - { - print BOOT - qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|; - } - } - - if (-r "spcl.boot") - { - print BOOT qq|include "spcl.boot";\n\n|; - } - } - - close(BOOT); - - # Go ahead and start creating files and making SOA's - my $x1; - my $x2; - foreach my $i (@makesoa) - { - ($x1, $x2) = split(' ', $i); - &MAKE_SOA($callback, $x1, $x2); - } - printf DOMAIN "%-20s IN A 127.0.0.1\n", "localhost"; - - my $file = "DB.127.0.0.1"; - &MAKE_SOA($callback, $DBDir . "db.127.0.0", $file); - if (xCAT::Utils->isAIX()) - { - # if forwarders is set, we need to create the hint file for root name servers. - if (@forwarders) - { - my $tmpfile = $DBDir . "db.cache"; - my $cmd = qq~dig @"$forwarders[0]" . ns >> $tmpfile~; - my $outref = xCAT::Utils->runcmd("$cmd", 0); - if ($::RUNCMD_RC != 0) - { - my $rsp = {}; - $rsp->{data}->[0] = "Could not run command: $cmd.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - } - else - { - my $nothing; - open($nothing, ">>", $DBDir . "db.cache"); - close($nothing); - - } - } - else - { - my $nothing; - open($nothing, ">>", $DBDir . "db.cache"); - close($nothing); - - } - printf $file "%-30s\tIN PTR localhost.\n", &REVERSE("127.0.0.1"); - close($file); -} - -sub PARSEARGS -{ - my ($callback, @args) = @_; - my ($i, $net, $subnetmask, $option, $tmp1); - my ($file, @newargs, @targs); - my ($sec, $min, $hour, $mday, $mon, $year, $rest); - ($sec, $min, $hour, $mday, $mon, $year, $rest) = localtime(time); - $DateSerial = - ($mday * 100) + (($mon + 1) * 10000) + (($year + 1900) * 1000000); - - $i = 0; - while ($i <= $#args) - { - $option = $args[$i]; - if ($option eq "-d") - { - if ($Domain ne "") - { - my $rsp = {}; - $rsp->{data}->[0] = "Only one -d option allowed.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - $Domain = $args[++$i]; - $Domainpattern = "." . $Domain; - $Domainpattern =~ s/\./\\./g; # for stripping off domain - - # Add entry to the boot file. - $Domainfile = $Domain; - $Domainfile =~ s/\..*//; - push(@makesoa, $DBDir . "db.$Domainfile DOMAIN"); - push(@bootmsgs_v4, "primary\t$Domain db.$Domainfile\n"); - push(@bootmsgs_v8, - qq|zone "$Domain" in {\n\ttype master;\n\tfile "db.$Domainfile";\n};\n\n| - ); - - } - elsif ($option eq "-f") - { - $file = $args[++$i]; - unless (open(F, $file)) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open args file $file: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - while () - { - next if (/^#/); - next if (/^$/); - chop; - @targs = split(' '); - push(@newargs, @targs); - } - close(F); - &PARSEARGS($callback, @newargs); - - } - elsif ($option eq "-z") - { - $Bootsecsaveaddr = $args[++$i]; - if (!defined($Bootsecaddr)) - { - $Bootsecaddr = $Bootsecsaveaddr; - } - - } - elsif ($option eq "-Z") - { - $Bootsecaddr = $args[++$i]; - if (!defined($Bootsecsaveaddr)) - { - $Bootsecsaveaddr = $Bootsecaddr; - } - - } - elsif ($option eq "-b") - { - $Bootfile = $args[++$i]; - - } - elsif ($option eq "-A") - { - $doaliases = 0; - - } - elsif ($option eq "-M") - { - $domx = 0; - - } - elsif ($option eq "-w") - { - $dowks = 1; - - } - elsif ($option eq "-D") - { - $dontdodomains = 1; - - } - elsif ($option eq "-t") - { - $dotxt = 1; - - } - elsif ($option eq "-u") - { - $User = $args[++$i]; - - } - elsif ($option eq "-s") - { - while ($args[++$i] !~ /^-/ && $i <= $#args) - { - push(@Servers, $args[$i]); - } - $i--; - - } - elsif ($option eq "-m") - { - if ($args[++$i] !~ /:/) - { - my $rsp = {}; - $rsp->{data}->[0] = - "Improper format for -m option ignored ($args[$i]).\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - } - push(@Mx, $args[$i]); - - } - elsif ($option eq "-c") - { - my $tmp1 = $args[++$i]; - if ($tmp1 !~ /\./) - { - $tmp1 .= ".$Domain"; - } - if ($Domain eq $tmp1) - { - my $rsp = {}; - $rsp->{data}->[0] = - "Domain for -c option must not match domain for -d option.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - my $tmp2 = $tmp1; - $tmp2 =~ s/\./\\./g; - $cpatrel{$tmp2} = $tmp1; - push(@cpats, $tmp2); - - } - elsif ($option eq "-e") - { - $tmp1 = $args[++$i]; - if ($tmp1 !~ /\./) - { - $tmp1 .= ".$Domain"; - } - $tmp1 =~ s/\./\\./g; - push(@elimpats, $tmp1); - - } - elsif ($option eq "-h") - { - $Host = $args[++$i]; - - } - elsif ($option eq "-o") - { - if ($args[++$i] !~ /^[:\d]*$/ - || split(':', $args[$i]) != 4) - { - my $rsp = {}; - $rsp->{data}->[0] = "Improper format for -o ($args[$i]).\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - ($DefRefresh, $DefRetry, $DefExpire, $DefTtl) = - split(':', $args[$i]); - $UseDefSOAValues = 1; - - } - elsif ($option eq "-i") - { - $ForceSerial = $args[++$i]; - - } - elsif ($option eq "-H") - { - $Hostfile = $args[++$i]; - if (!-r $Hostfile || -z $Hostfile) - { - my $rsp = {}; - $rsp->{data}->[0] = - "Invalid file specified for -H ($Hostfile).\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - - } - elsif ($option eq "-C") - { - $Commentfile = $args[++$i]; - if (!-r $Commentfile || -z $Commentfile) - { - my $rsp = {}; - $rsp->{data}->[0] = - "Invalid file specified for -C ($Commentfile).\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - - } - elsif ($option eq "-N") - { - $Defsubnetmask = $args[++$i]; - if ($Defsubnetmask !~ /^[.\d]*$/ - || split('\.', $Defsubnetmask) != 4) - { - my $rsp = {}; - $rsp->{data}->[0] = "Improper subnet mask ($Defsubnetmask).\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - if ($#Networks >= 0) - { - my $rsp = {}; - $rsp->{data}->[0] = - "-N option should be specified before any -n options.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - } - - } - elsif ($option eq "-n") - { - (my $tnet, $subnetmask) = split(':', $args[++$i]); - $net = ""; - my @netm = split(/\./, $subnetmask); - my @tnets = split(/\./, $tnet); - foreach (0 .. 3) - { - my $res = ($tnets[$_] + 0) & ($netm[$_] + 0); - if ($netm[$_]) - { - $net .= $res . '.'; - } - } - $net =~ s/\.$//; - - if (not $net) - { - my $rsp = {}; - $rsp->{data}->[0] = - "Empty network found in networks table (i.e. ,,),This is almost certainly going to cause a problem....\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - } - if ($subnetmask eq "") - { - my $rsp = {}; - $rsp->{data}->[0] = - "$net has no defined netmask in the networks table, the result will probably be wrong.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - foreach $tmp1 (&SUBNETS($net, $Defsubnetmask)) - { - &BUILDNET($tmp1); - } - } - else - { - if ($subnetmask !~ /^[.\d]*$/ - || split('\.', $subnetmask) != 4) - { - my $rsp = {}; - $rsp->{data}->[0] = "Improper subnet mask ($subnetmask).\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } - foreach $tmp1 (&SUBNETS($net, $subnetmask)) - { - &BUILDNET($tmp1); - } - } - - } - else - { - if ($option =~ /^-.*/) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unknown option: $option ... ignored.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - } - } - $i++; - } - - if (!@Networks || $Domain eq "") - { - my $rsp = {}; - $rsp->{data}->[0] = "Must specify one -d and at least one -n.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit(1); - } -} - -sub BUILDNET -{ - my ($net) = @_; - - push(@Networks, $net); - - # - # Create pattern to match against. - # The dots must be changed to \. so they - # aren't used as wildcards. - # - my $netpat = $net; - $netpat =~ s/\./\\./g; - push(@Netpatterns, $netpat); - - # - # Create db files for PTR records. - # Save the file names in an array for future use. - # - my $netfile = "DB.$net"; - $Netfiles{$netpat} = $netfile; - push(@makesoa, $DBDir . "db.$net $netfile"); - - # Add entry to the boot file. - my $revaddr = &REVERSE($net); - chop($revaddr); # remove trailing dot - push(@bootmsgs_v4, "primary $revaddr db.$net\n"); - push(@bootmsgs_v8, - qq|zone "$revaddr" in {\n\ttype master;\n\tfile "db.$net";\n};\n\n|); -} - -# -# Calculate all the subnets from a network number and mask. -# This was originally written for awk, not perl. -# -sub SUBNETS -{ - my ($network, $mask) = @_; - my (@ans, @net, @mask, $buf, $number, $i, $j, $howmany); - - @net = split(/\./, $network); - @mask = split(/\./, $mask); - $number = ''; - - # - # Only expand bytes 1, 2, or 3 - # for DNS purposes - # - for ($i = 0 ; $i < 4 ; $i++) - { - if ($mask[$i] == 255) - { - $number = $number . $net[$i] . '.'; - } - elsif (($mask[$i] == 0) || $mask[$i] eq '') - { - push(@ans, $network); - last; - } - else - { - - # - # This should be done as a bit-wise or - # but awk does not have an or symbol - # - $howmany = 255 - $mask[$i]; - for ($j = 0 ; $j <= $howmany ; $j++) - { - if ($net[$i] + $j <= 255) - { - $buf = sprintf("%s%d", $number, $net[$i] + $j); - push(@ans, $buf); - } - } - last; - } - } - - if ($#ans == -1) - { - push(@ans, $network); - } - - @ans; -} - -sub GEN_BOOT -{ - $callback = shift; - my ($revaddr, $n); - - if (0) - { #! -e "boot.cacheonly") { DISABLE THIS PART - # - # Create a boot file for a cache-only server - # - unless (open(F, ">boot.cacheonly")) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open boot.cacheonly: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - if ($Version == 4) - { - print F "directory\t$DBDir\n"; - print F "primary\t\t0.0.127.IN-ADDR.ARPA db.127.0.0\n"; - print F "cache\t\t. db.cache\n"; - if (-r "spcl.cacheonly") - { - printf F "include\t\tspcl.cacheonly\n"; - } - close(F); - } - else - { - print F qq|\noptions {\n\tdirectory "$DBDir";\n|; - if (@forwarders) - { - print F qq|\tforwarders {\n|; - foreach (@forwarders) - { - print F qq|\t\t$_;\n|; - } - print F qq|\t};\n|; - } - if (-r "spcl.options") - { - print F "\t# These options came from the file spcl.options\n"; - - # - # Copy the options in since "include" cannot be used - # within a statement. - # - - unless (open(OPTIONS, "{data}->[0] = "Unable to open boot.cacheonly: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - - while () - { - print F; - } - close(OPTIONS); - } - print F qq|};\n\n|; - print F qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;|; - print F qq|\n\tfile "db.127.0.0";|; - print F qq|\n\tnotify no;\n};\n\n|; - - #print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|; - if (-r "spcl.cacheonly") - { - print F qq|include "spcl.cacheonly";\n\n|; - } - } - } - - # - # Create a 2 boot files for a secondary (slave) servers. - # One boot file doesn't save the zone data in a file. The - # other boot file does save the zone data in a file. - # - if (defined($Bootsecaddr)) - { - unless (open(F, ">boot.sec")) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open boot.sec: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - - if ($Version == 4) - { - print F "directory\t$DBDir\n"; - print F "primary\t\t0.0.127.IN-ADDR.ARPA db.127.0.0\n"; - printf F "secondary\t%-23s $Bootsecaddr\n", $Domain; - foreach $n (@Networks) - { - $revaddr = &REVERSE($n); - chop($revaddr); - printf F "secondary\t%-23s $Bootsecaddr\n", $revaddr; - } - print F "cache\t\t. db.cache\n"; - if (-r "spcl.boot") - { - printf F "include\t\tspcl.boot\n"; - } - } - else - { - print F qq|\noptions {\n\tdirectory "$DBDir";\n|; - if (-r "spcl.options") - { - print F "\t# These options came from the file spcl.options\n"; - - # - # Copy the options in since "include" cannot be used - # within a statement. - # - unless (open(OPTIONS, "{data}->[0] = "Unable to open spcl.options.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - - while () - { - print F; - } - close(OPTIONS); - } - print F qq|};\n\n|; - print F qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;|; - print F qq|\n\tfile "db.127.0.0";|; - print F qq|\n\tnotify no;\n};\n\n|; - print F qq|zone "$Domain" in {\n\ttype slave;\n\tmasters {|; - print F qq| $Bootsecaddr; };\n};\n\n|; - - foreach $n (@Networks) - { - $revaddr = &REVERSE($n); - chop($revaddr); - print F qq|zone "$revaddr" in {\n\ttype slave;\n\tmasters {|; - print F qq| $Bootsecaddr; };\n};\n\n|; - } - - #print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|; - if (-r "spcl.boot") - { - print F qq|include "spcl.boot";\n\n|; - } - } - close(F); - - unless (open(F, ">boot.sec.save")) - { - my $rsp = {}; - $rsp->{data}->[0] = "Unable to open boot.sec.save: $!.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - - if ($Version == 4) - { - print F "directory\t$DBDir\n"; - print F "primary\t\t0.0.127.IN-ADDR.ARPA db.127.0.0\n"; - printf F "secondary\t%-23s $Bootsecsaveaddr db.%s\n", $Domain, - $Domainfile; - foreach $n (@Networks) - { - $revaddr = &REVERSE($n); - chop($revaddr); - printf F "secondary\t%-23s $Bootsecsaveaddr db.%s\n", $revaddr, - $n; - } - print F "cache\t\t. db.cache\n"; - if (-r "spcl.boot") - { - printf F "include\t\tspcl.boot\n"; - } - } - else - { - print F qq|\noptions {\n\tdirectory "$DBDir";\n|; - if (-r "spcl.options") - { - print F "\t# These options came from the file spcl.options\n"; - - # - # Copy the options in since "include" cannot be used - # within a statement. - # - unless (open(OPTIONS, "{data}->[0] = "Can't open spcl.options.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback, 1); - exit 1; - } - while () - { - print F; - } - close(OPTIONS); - } - print F qq|};\n\n|; - print F qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;|; - print F qq|\n\tfile "db.127.0.0";|; - print F qq|\n\tnotify no;\n};\n\n|; - - print F - qq|zone "$Domain" in {\n\ttype slave;\n\tfile "db.$Domainfile";|; - print F qq|\n\tmasters { $Bootsecsaveaddr; };\n};\n\n|; - - foreach $n (@Networks) - { - $revaddr = &REVERSE($n); - chop($revaddr); - print F - qq|zone "$revaddr" in {\n\ttype slave;\n\tfile "db.$n";\n\tmasters {|; - print F qq| $Bootsecsaveaddr; };\n};\n\n|; - } - - #print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|; - if (-r "spcl.boot") - { - print F qq|include "spcl.boot";\n\n|; - } - } - close(F); - } -} - -# subroutine to display the usage -sub checkusageandversion -{ - my $callback = shift; - - # parse the options - if ( - GetOptions('h|help' => \$::HELP, - 'v|version' => \$::VERSION) - ) - { - if ($::HELP) - { - my $rsp = {}; - $rsp->{data}->[0] = "Usage:"; - $rsp->{data}->[1] = " makedns "; - $rsp->{data}->[2] = " makedns [-h|--help|-v|--version]"; - $rsp->{data}->[3] = " See man makedns"; - xCAT::MsgUtils->message("I", $rsp, $callback); - exit 0; - } - if ($::VERSION) - { - my $version = xCAT::Utils->Version(); - my $rsp = {}; - $rsp->{data}->[0] = "$version"; - xCAT::MsgUtils->message("I", $rsp, $callback); - exit 0; - } - } - return; -} - -1;