summaryrefslogtreecommitdiffstats
path: root/dns_wizard/Bind.pm
diff options
context:
space:
mode:
Diffstat (limited to 'dns_wizard/Bind.pm')
-rw-r--r--dns_wizard/Bind.pm930
1 files changed, 930 insertions, 0 deletions
diff --git a/dns_wizard/Bind.pm b/dns_wizard/Bind.pm
new file mode 100644
index 00000000..29e2d766
--- /dev/null
+++ b/dns_wizard/Bind.pm
@@ -0,0 +1,930 @@
+#!/usr/bin/perl -w
+#
+# version 0.4
+# Copyright (C) 2004 Mandrakesoft
+# Author: Antoine Ginies <aginies _ateuh _ mandrakesoft.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+package MDK::Wizard::Bind;
+use lib qw(/usr/lib/libDrakX);
+
+use strict;
+use services;
+use common;
+use MDK::Wizard::Varspaceval;
+use MDK::Wizard::Wizcommon;
+use network::network;
+
+my $wiz = new MDK::Wizard::Wizcommon;
+my $in = interactive->vnew;
+my $SERIAL = chomp_(`date +20%y%m%d`);
+my $HOSTNAME = $wiz->{net}->network_get("HOSTNAME");
+my $BIND_CHROOT = "/var/lib/named";
+
+my $IPSERVER = $wiz->{net}->itf_get("IPADDR");
+my $sys_wizard_dns = "/etc/sysconfig/drak_dns_wiz";
+if (-f $sys_wizard_dns) {
+ our ($interface) = cat_($sys_wizard_dns) =~ /INTERFACE=(.*)/;
+ ($IPSERVER) = `/sbin/ip addr show dev $interface` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m;
+} else {
+ our $interface = "eth0";
+ ($IPSERVER) = `/sbin/ip addr show dev $interface` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m;
+}
+
+my $DOMAINNAME = chomp_(`dnsdomainname`);
+my $CLIENTIP = get_spe_ip("ipnor", $IPSERVER) . ".";
+my $WDIR = "/tmp/dnstest";
+my $NAMED_DIR = $BIND_CHROOT . "/var/named";
+my $DNSKEY = "";
+my $SHORTHOSTNAME = chomp_(`hostname -s`);
+my $TEXTINFO = "dns Wizard";
+my $REP_SAVE = "/tmp/bck";
+my $ZONE_DIR = $NAMED_DIR . "/zone";
+my $DATE = `date +%d-%m-20%y`;
+
+my $o = {
+ name => 'DNS Configuration Wizard',
+ var => {
+ IPOFFORWARDER => '',
+ ADDSEARCH => '',
+ DOMAINNAME => $DOMAINNAME,
+ SHORTHOSTNAME => $SHORTHOSTNAME,
+ IPMASTER => '',
+ CLIENTNAME => '',
+ CLIENTIP => $CLIENTIP,
+ },
+ init => sub {
+ my ($err, $msg) = test_host_domain($SHORTHOSTNAME, $DOMAINNAME);
+ if (!$err) {
+ $in->ask_warn(N('Error'), $msg);
+ die 'wizcancel';
+ }
+ ($err, $msg)
+ },
+ needed_rpm => [ 'bind' ],
+ defaultimage => "/usr/share/mcc/themes/default/dns_server-mdk.png",
+ };
+
+my %level = (
+ 1 => N("Master DNS server"),
+ 2 => N("Slave DNS server"),
+ 3 => N("Add host in DNS"),
+ 4 => N("Remove host in DNS"),
+ );
+
+my @list_hosts;
+
+sub list_hosts {
+ my $iprev = get_spe_ip('iprev', $IPSERVER);
+ my $db = "$ZONE_DIR/db.$iprev.hosts";
+ #my $ipnor = get_spe_ip('iprev', $IPSERVER);
+# push @list_hosts, "";
+ foreach (cat_($db)) {
+ my ($h) = /\d{1,3}\tIN\tPTR\t(.*)/;
+ !$h or push @list_hosts,$h;
+ }
+ @list_hosts;
+}
+
+$o->{pages} = {
+ welcome => {
+ name => N("DNS Master configuration wizard") . "\n\n" . N("DNS (Domain Name Server) is the service that maps an IP address of a machine with an internet host name.") . "\n\n" . N("This wizard will help you configuring the DNS services of your server. This configuration will provide a local DNS service for local computers names, with non-local requests forwarded to an outside DNS."),
+ no_back => 1,
+ pre => sub {
+ $o->{var}{wiz_level} ||= 1;
+ },
+ post => sub {
+ if ($o->{var}{wiz_level} == 2) {
+ return 'slave' }
+ elsif ($o->{var}{wiz_level} == 1) {
+ return 'interface' }
+ elsif ($o->{var}{wiz_level} == 3) {
+ if (-f $sys_wizard_dns) { return 'addhost' } else { return 'error_notmaster' } }
+ elsif ($o->{var}{wiz_level} == 4) {
+ if (-f $sys_wizard_dns) { return 'removehost' } else { return 'error_notmaster' } }
+ },
+ data => [
+ { label => '', val => \$o->{var}{wiz_level}, type => 'list', list => [ sort keys %level ], format => sub { $level{$_[0]} } },
+ ],
+ next => 'interface',
+ },
+ interface => {
+ name => N("DNS server Interface"),
+ data => [
+ { list => [ keys %{$wiz->{net}{itf}} ], val => \$o->{var}{interface} },
+ ],
+ no_back => 1,
+ next => 'ipforward'
+ },
+ addhost => {
+ name => N("Client identification:") . "\n\n" . N("Your client on the network will be identified by name, as in clientname.company.net. Every machine on the network must have a (unique) IP address, in the usual dotted syntax.") . "\n\n" . N("(You don't need to add the domain after the name)") . "\n\n" . N("Note that the given IP address and client name should be unique in the network."),
+ data => [
+ { label => N("Server:"), val_ref => \$o->{var}{SHORTHOSTNAME} },
+ { label => N("DNS Domainname:"), val_ref => \$o->{var}{DOMAINNAME} },
+ { label => N("Name of the machine:"), val => \$o->{var}{CLIENTNAME} },
+ { label => N("IP address of the machine:"), val => \$o->{var}{CLIENTIP} },
+ ],
+ complete => sub {
+ if ($o->{var}{CLIENTIP}) {
+ if (!is_ip($o->{var}{CLIENTIP})) {
+ #$in->ask_warn(N('Error'), N('This is not a valid IP address.'));
+ return 1;
+ } else { return 0; }
+ }
+ },
+ no_back => 1,
+ next => 'summaryadd', no_back => 1,
+ },
+ removehost => {
+ name => N("Remove host:") . "\n\n" . N("Remove a host in existing DNS configuration.") . "\n\n" . N("Choose the host you want to remove in the following list."),
+ data => [
+ { label => N("Computer Name:"), val => \$o->{var}{CLIENTNAME}, list_ref => \@list_hosts },
+ ],
+ post => \&list_hosts,
+ next => 'summaryremove', no_back => 1,
+ },
+ slave => {
+ name => N("Slave DNS server") . "\n\n" . N("A slave name server will take some of the burden away from your primary name server, and will also function as a backup server, in case your master server is unreachable."),
+ data => [
+ { label => N("IP Address of the master DNS server:"), val => \$o->{var}{IPMASTER} },
+ ],
+ complete => sub {
+ if ($o->{var}{IPMASTER}) {
+ if (!is_ip($o->{var}{IPMASTER})) {
+ #$in->ask_warn(N('Error'), N('This is not a valid IP address.'));
+ return 1;
+ } else { return 0; }
+ }
+ },
+ no_back => 1,
+ next => 'summaryslave',
+ },
+
+ ipforward => {
+ name => N("IP of your forwarder") . "\n\n" . N("Forwarding occurs on only those queries for which the server is not authoritative and does not have the answer in its cache.") . "\n\n" . N("If you need it and know your IP forwarder enter IP address of it, if you dont know leave it blank"),
+ pre => sub {
+ ($IPSERVER) = `/sbin/ip addr show dev $o->{var}{interface}` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m;
+ output($sys_wizard_dns, "INTERFACE=$o->{var}{interface}\n");
+ },
+ data => [
+ { label => N("External DNS:"), val => \$o->{var}{IPOFFORWARDER} },
+ ],
+ complete => sub {
+ if ($o->{var}{IPOFFORWARDER}) {
+ if (!is_ip($o->{var}{IPOFFORWARDER})) {
+ #$in->ask_warn(N('Error'), N('This is not a valid IP address for your forwarder.'));
+ return 1;
+ } else { return 0; }
+ }
+ },
+ no_back => 1,
+ next => 'addsearch',
+ },
+ addsearch => {
+ name => N("Add search domain") . "\n\n" . N("Search list for host-name lookup. The search list is normally determined from the local domain name; by default, it contains only the local domain name. This may be changed by listing the desired domain search path following the search keyword") . "\n\n" . N("Domainname of this server is automatically added, and you dont need to add it here."),
+
+ data => [
+ { label => N("Default domain name to search:"), val => \$o->{var}{ADDSEARCH} },
+ ],
+ next => 'summary',
+ },
+ error_ipf => {
+ name => N("This is not a valid IP address for your forwarder... press next to continue"),
+ ignore => 1,
+ next => 'ipforward',
+ },
+ error_ipm => {
+ name => N("This is not a valid Master DNS IP address... press next to continue"),
+ ignore => 1,
+ next => 'slave',
+ },
+ error_iph => {
+ name => N("This is not a valid IP address... press next to continue"),
+ ignore => 1,
+ next => 'addhost',
+ },
+ dhcp_warning => {
+ name => N("Warning") . "\n\n" . N("You are in dhcp, server may not work with your configuration."),
+ ignore => 1,
+ next => 'client_id'
+ },
+ error_add => {
+ name => N("Error.") . "\n\n" . N("It seems that host is already in your DNS configuration... press next to continue"),
+ ignore => 1,
+ next => 'addhost',
+ },
+ error_remove => {
+ name => N("Error:") . "\n\n" . N("It seems that this is not present in your DNS configuration... press next to continue"),
+ ignore => 1,
+ next => 'removehost',
+ },
+ error_nosrv => {
+ name => N("It seems that no DNS server has been set through wizard. Please run DNS wizard: Master DNS server."),
+ end => 1,
+ },
+ error_notmaster => {
+ name => N("It seems that you are not a master DNS server, so I can't add/remove host."),
+ end => 1,
+ },
+ summaryslave => {
+ name => N("Wizard will Now build your DNS slave configuration") . "\n\n" . N("with this configuration:"),
+ data => [
+ { label => N("IP Address of the master DNS server:"), val_ref => \$o->{var}{IPMASTER} },
+ ],
+ post => \&do_it_slave,
+ next => 'end',
+ },
+ summaryadd => {
+ name => N("Client with this identification will be added to your DNS"),
+ data => [
+ { label => N("Server:"), val_ref => \$o->{var}{SHORTHOSTNAME} },
+ { label => N("DNS Domainname:"), val_ref => \$o->{var}{DOMAINNAME} },
+ { label => N("Computer name:"), val_ref => \$o->{var}{CLIENTNAME} },
+ { label => N("Computer IP address:"), val_ref => \$o->{var}{CLIENTIP} },
+ ],
+ post => \&do_it_add,
+ },
+ summaryremove => {
+ name => N("Client with this identification will be removed from your DNS"),
+ data => [
+ { label => N("Computer name:"), val => \$o->{var}{CLIENTNAME}, list_ref => \@list_hosts },
+ ],
+ post => \&do_it_remove,
+ next => 'endremove',
+ },
+ summary => {
+ name => N("The DNS server is about to be configured with the following configuration"),
+ data => [
+ { label => N("Server Hostname:"), val_ref => \$o->{var}{SHORTHOSTNAME} },
+ { label => N("Domainname:"), val_ref => \$o->{var}{DOMAINNAME} },
+ { label => N("External DNS:"), val_ref => \$o->{var}{IPOFFORWARDER} },
+ { label => N("Default domain name to search:"), val_ref => \$o->{var}{ADDSEARCH} },
+ ],
+ post => \&do_it_master,
+ next => 'end',
+ },
+ endadd => {
+ name => N("Congratulations"),
+ data => [ { label => N("The wizard successfully added the host in your DNS.") } ],
+ no_back => 1,
+ end => 1,
+ },
+ endremove => {
+ name => N("Congratulations"),
+ data => [ { label => N("The wizard successfully removed the host from your DNS.") } ],
+ no_back => 1,
+ end => 1,
+ },
+ end => {
+ name => N("Congratulations"),
+ data => [ { label => N("The wizard successfully configured the DNS service of your server.") } ],
+ no_back => 1,
+ end => 1,
+ },
+ error_end => {
+ name => N("Failed"),
+ data => [ { label => N("Please Relaunch drakwizard, and try to change some parameters.") } ],
+ no_back => 1,
+ end => 1,
+ },
+ };
+
+sub test_srv {
+ my $dir = $BIND_CHROOT . "/var/named/zone";
+ -d $dir or return 'error_nosrv';
+}
+
+sub interface_to_ip {
+ my ($interface) = @_;
+ my ($ip) = `/sbin/ip addr show dev $interface` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m;
+ $ip;
+}
+
+sub crea_wdir {
+ if (-e $WDIR) { system("rm -rf $WDIR") }
+ mkdir_p($WDIR);
+}
+
+sub resolv_ip {
+ my ($ip) = @_;
+ gethostbyaddr(Socket::inet_aton($ip), Socket::AF_INET());
+}
+
+sub resolv_name {
+ my ($name) = @_;
+ join(".", unpack "C4", (gethostbyname $name)[4]);
+}
+
+
+sub get_spe_ip {
+ # waiting iprev, ipnorm or ipend
+ my ($att, $ip) = @_;
+ my @o = split(/\./, $ip);
+ if ($att =~ /iprev/) {
+ my $iprev = $o[2] . "." . $o[1] . "." . $o[0];
+ return $iprev;
+ } elsif ($att =~ /ipnor/) {
+ my $ipnor = $o[0] . "." . $o[1] . "." . $o[2];
+ return $ipnor;
+ } elsif ($att =~ /ipend/) {
+ my $ipend = $o[3];
+ return $ipend;
+ }
+}
+
+sub increment_serial {
+ my ($iprev) = @_;
+ my ($SERIAL) = cat_("$ZONE_DIR/db.$DOMAINNAME.hosts") =~ m/\s+(.*?)\s+;\s+Serial/;
+ $SERIAL = chomp_($SERIAL+1);
+ substInFile {
+ s/\s+\d+\s+;\s+Serial/ $SERIAL ; Serial/;
+ } "$ZONE_DIR/db.$DOMAINNAME.hosts";
+
+ substInFile {
+ s/\s+\d+\s+;\s+Serial/ $SERIAL ; Serial/;
+ } "$ZONE_DIR/db.$iprev.hosts";
+}
+
+
+sub crea_db_local {
+ output($WDIR . "/db.localhost", <<EOF);
+\$TTL 3D
+\@ IN SOA $HOSTNAME. root.$HOSTNAME. (
+ $SERIAL ; Serial
+ 8H ; Refresh
+ 2H ; Retry
+ 4W ; Expire
+ 1D) ; Minimum TTL
+ NS $HOSTNAME.
+1 IN PTR localhost.
+EOF
+}
+# end of db.local
+
+
+# create named.conf file
+sub crea_named_common {
+ output($WDIR . "/named.conf", <<EOF);
+// (oe) Loosely based on the document below and from production server configurations.
+// http://www.cymru.com/Documents/secure-bind-template.html
+
+// secret must be the same as in /etc/rndc.conf
+include "/etc/rndc.key";
+
+controls {
+ inet 127.0.0.1 port 953
+ allow { 127.0.0.1; } keys { mykey; };
+};
+
+options {
+ version "";
+ directory "/var/named";
+ dump-file "/var/tmp/named_dump.db";
+ pid-file "/var/run/named.pid";
+ statistics-file "/var/tmp/named.stats";
+ zone-statistics yes;
+// datasize 256M;
+ coresize 100M;
+// fetch-glue no;
+// recursion no;
+// recursive-clients 10000;
+ auth-nxdomain yes;
+ query-source address * port *;
+ listen-on port 53 { any; };
+ cleaning-interval 120;
+ transfers-in 20;
+ transfers-per-ns 2;
+ lame-ttl 0;
+ max-ncache-ttl 10800;
+
+// forwarders { first_public_nameserver_ip; second_public_nameserver_ip; };
+EOF
+ !$o->{var}{IPOFFORWARDER} or append_to_file($WDIR . "/named.conf", "\tforwarders { $o->{var}{IPOFFORWARDER}; };\n");
+ append_to_file($WDIR . "/named.conf", <<EOF);
+
+// allow-update { none; };
+// allow-transfer { any; };
+// Prevent DoS attacks by generating bogus zone transfer
+// requests. This will result in slower updates to the
+// slave servers (e.g. they will await the poll interval
+// before checking for updates).
+ notify no;
+// notify explicit;
+// also-notify { secondary_name_server };
+
+// Generate more efficient zone transfers. This will place
+// multiple DNS records in a DNS message, instead of one per
+// DNS message.
+ transfer-format many-answers;
+
+// Set the maximum zone transfer time to something more
+// reasonable. In this case, we state that any zone transfer
+// that takes longer than 60 minutes is unlikely to ever
+// complete. WARNING: If you have very large zone files,
+// adjust this to fit your requirements.
+ max-transfer-time-in 60;
+
+// We have no dynamic interfaces, so BIND shouldn't need to
+// poll for interface state {UP|DOWN}.
+ interface-interval 0;
+
+// Uncoment these to enable IPv6 connections support
+// IPv4 will still work
+// listen-on { none; };
+// listen-on-v6 { any; };
+
+ allow-query { any; };
+ allow-recursion { any; };
+
+// Deny anything from the bogon networks as
+// detailed in the "bogon" ACL.
+// blackhole { bogon; };
+};
+
+// workaround stupid stuff... (OE: Wed 17 Sep 2003)
+zone "ac" { type delegation-only; };
+zone "cc" { type delegation-only; };
+zone "com" { type delegation-only; };
+zone "cx" { type delegation-only; };
+zone "lv" { type delegation-only; };
+zone "museum" { type delegation-only; };
+zone "net" { type delegation-only; };
+zone "nu" { type delegation-only; };
+zone "ph" { type delegation-only; };
+zone "sh" { type delegation-only; };
+zone "tm" { type delegation-only; };
+zone "ws" { type delegation-only; };
+
+zone "." IN {
+ type hint;
+ file "named.ca";
+};
+
+zone "localdomain" IN {
+ type master;
+ file "master/localdomain.zone";
+ allow-update { none; };
+};
+
+zone "localhost" IN {
+ type master;
+ file "master/localhost.zone";
+ allow-update { none; };
+};
+
+zone "0.0.127.in-addr.arpa" IN {
+ type master;
+ file "reverse/named.local";
+ allow-update { none; };
+};
+
+zone "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" IN {
+ type master;
+ file "reverse/named.ip6.local";
+ allow-update { none; };
+};
+
+zone "255.in-addr.arpa" IN {
+ type master;
+ file "reverse/named.broadcast";
+ allow-update { none; };
+};
+
+zone "0.in-addr.arpa" IN {
+ type master;
+ file "reverse/named.zero";
+ allow-update { none; };
+};
+
+EOF
+}
+# end named.conf
+
+sub crea_named_master {
+ my ($ip, $d) = @_;
+ my $iprev = get_spe_ip('iprev', $ip);
+ append_to_file($WDIR . "/named.conf", <<EOF);
+zone "$iprev.in-addr.arpa" {
+ type master;
+ file "zone/db.$iprev.hosts";
+ forwarders { };
+};
+
+zone "$d" {
+ type master;
+ file "zone/db.$d.hosts";
+ forwarders { };
+};
+EOF
+}
+
+sub crea_named_slave {
+ my ($ip, $d, $IPM) = @_;
+ my $iprev = get_spe_ip('iprev', $ip);
+ append_to_file($WDIR . "/named.conf", <<EOF);
+zone "$iprev.in-addr.arpa" {
+ type slave;
+ masters { $IPM; };
+ file "bak.db.$iprev.hosts";
+};
+
+zone "$d" {
+ type slave;
+ masters { $IPM; };
+ file "bak.db.$d.hosts";
+};
+EOF
+}
+
+# create hints
+sub crea_hints {
+ output($WDIR . "/root.hints", <<EOF);
+; <<>> DiG 8.1 <<>> \@A.ROOT-SERVERS.NET.
+; (1 server found)
+;; res options: init recurs defnam dnsrch
+;; got answer:
+;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10
+;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13
+;; QUERY SECTION:
+;; ., type = NS, class = IN
+
+;; ANSWER SECTION:
+. 6D IN NS G.ROOT-SERVERS.NET.
+. 6D IN NS J.ROOT-SERVERS.NET.
+. 6D IN NS K.ROOT-SERVERS.NET.
+. 6D IN NS L.ROOT-SERVERS.NET.
+. 6D IN NS M.ROOT-SERVERS.NET.
+. 6D IN NS A.ROOT-SERVERS.NET.
+. 6D IN NS H.ROOT-SERVERS.NET.
+. 6D IN NS B.ROOT-SERVERS.NET.
+. 6D IN NS C.ROOT-SERVERS.NET.
+. 6D IN NS D.ROOT-SERVERS.NET.
+. 6D IN NS E.ROOT-SERVERS.NET.
+. 6D IN NS I.ROOT-SERVERS.NET.
+. 6D IN NS F.ROOT-SERVERS.NET.
+
+;; ADDITIONAL SECTION:
+G.ROOT-SERVERS.NET. 5w6d16h IN A 192.112.36.4
+J.ROOT-SERVERS.NET. 5w6d16h IN A 198.41.0.10
+K.ROOT-SERVERS.NET. 5w6d16h IN A 193.0.14.129
+L.ROOT-SERVERS.NET. 5w6d16h IN A 198.32.64.12
+M.ROOT-SERVERS.NET. 5w6d16h IN A 202.12.27.33
+A.ROOT-SERVERS.NET. 5w6d16h IN A 198.41.0.4
+H.ROOT-SERVERS.NET. 5w6d16h IN A 128.63.2.53
+B.ROOT-SERVERS.NET. 5w6d16h IN A 128.9.0.107
+C.ROOT-SERVERS.NET. 5w6d16h IN A 192.33.4.12
+D.ROOT-SERVERS.NET. 5w6d16h IN A 128.8.10.90
+E.ROOT-SERVERS.NET. 5w6d16h IN A 192.203.230.10
+I.ROOT-SERVERS.NET. 5w6d16h IN A 192.36.148.17
+F.ROOT-SERVERS.NET. 5w6d16h IN A 192.5.5.241
+;; Total query time: 215 msec
+;; FROM: roke.uio.no to SERVER: A.ROOT-SERVERS.NET. 198.41.0.4
+;; WHEN: Sun Feb 15 01:22:51 1998
+;; MSG SIZE sent: 17 rcvd: 436
+EOF
+}
+# end roots.hints
+
+# create ipreverse
+sub crea_iprev {
+ my ($ip, $d) = @_;
+ my $iprev = get_spe_ip('iprev', $ip);
+ my $ipend = get_spe_ip('ipend', $ip);
+ output($WDIR . "/db." . $iprev . ".hosts", <<EOF);
+\$TTL 3D
+@ IN SOA $SHORTHOSTNAME.$d. $SHORTHOSTNAME.$d. (
+ $SERIAL ; Serial
+ 10800 ; Refresh
+ 3600 ; Retry
+ 604800 ; Expire
+ 86400) ; Minimum TTL
+ NS $SHORTHOSTNAME.$d.
+$ipend IN PTR $SHORTHOSTNAME.$d.
+; use tab to retrieve data in drakwizard bind
+; 34 IN PTR xp2400.guibland.com.
+EOF
+
+}
+# end create iprev
+
+# create ipnormal
+sub crea_ipnorm {
+ my ($ip, $d) = @_;
+ output($WDIR . "/db.$d.hosts", <<EOF);
+\$TTL 3D
+@ IN SOA $SHORTHOSTNAME.$d. root.$SHORTHOSTNAME.$d. (
+ $SERIAL ; Serial
+ 8H ; Refresh
+ 2H ; Retry
+ 4W ; Expire
+ 1D) ; Minimum TTL
+ TXT $TEXTINFO
+ IN NS $SHORTHOSTNAME.$d.
+localhost A 127.0.0.1
+dnsmaster IN CNAME $SHORTHOSTNAME.$d.
+$SHORTHOSTNAME.$d. IN A $ip
+; use tab to retrieve data in drakwizard bind
+; xp2400.guibland.com. IN A 10.0.1.34
+EOF
+}
+# end of ipnorm
+
+
+# create 127.0.
+sub crea_127 {
+ my $d = $DOMAINNAME;
+ output($WDIR . "/db.127.0.0.1", <<EOF);
+\$TTL 3D
+\@ IN SOA $d. root.$d. (
+ $SERIAL ; Serial
+ 28800 ; Refresh
+ 7200 ; Retry
+ 604800 ; Expire
+ 86400) ; Minimum TTL
+ NS $HOSTNAME.
+localhost IN A 127.0.0.1
+EOF
+}
+# end create 127
+
+# create rndc.conf
+sub crea_rndc {
+ output($WDIR . "/rndc.conf", <<EOF);
+/*
+* Copyright (C) 2000, 2001 Internet Software Consortium.
+*
+* Permission to use, copy, modify, and distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+/* Id: dns_cluster.pm,v 1.18 2003/04/10 16:01:47 aginies Exp */
+/*
+* Sample rndc configuration file.
+*/
+
+options {
+ default-server localhost;
+ default-key "mykey";
+};
+
+server localhost {
+ key "mykey";
+};
+
+key "mykey" {
+ algorithm hmac-md5;
+ secret "$DNSKEY";
+};
+EOF
+}
+# end of create rndc
+
+# save old config files
+
+sub save_old_config {
+ if (-d $ZONE_DIR) {
+ print " - Backup of current configuration in " . $REP_SAVE . "\n";
+ }
+ if (-d "$REP_SAVE/dns") { rm_rf("$REP_SAVE/dns") }
+ mkdir_p($REP_SAVE . '/dns');
+ system("cp -avf $ZONE_DIR/* $REP_SAVE/dns/");
+# cp_af($_, "$REP_SAVE/dns/$_" . '-' . $DATE . '.sauv') foreach glob_($ZONE_DIR . "/*");
+ if (-e "$BIND_CHROOT/etc/named.conf") {
+ cp_af("$BIND_CHROOT/etc/named.conf", "$REP_SAVE/dns/named.conf-$DATE");
+ }
+}
+# end save old config
+
+sub generate_rndc {
+ mkdir_p($WDIR);
+ system("rndc-confgen -a -c $WDIR/rndc.key");
+ my ($key) = cat_("$WDIR/rndc.key") =~ /secret "(\S*)";/;
+ $key;
+}
+
+
+# reinit resolv.conf
+sub set_resolv {
+ output($WDIR . "/resolv.conf", <<EOF);
+domain $DOMAINNAME
+search $DOMAINNAME
+nameserver $IPSERVER
+EOF
+
+ !$o->{var}{IPMASTER} or return append_to_file($WDIR . "/resolv.conf", "nameserver $o->{var}{IPMASTER}\n");
+ !$o->{var}{ADDSEARCH} or return append_to_file($WDIR . "/resolv.conf", "search $o->{var}{ADDSEARCH}\n");
+ !$o->{var}{IPOFFORWARDER} or return append_to_file($WDIR . "/resolv.conf", "nameserver $o->{var}{IPOFFORWARDER}\n");
+}
+# end set resolv.conf
+
+# set /etc/hosts
+sub set_hosts {
+ my ($ip, $h) = @_;
+ if (!any { /$ip\s* $h/ } cat_($WDIR . "/hosts")) {
+ append_to_file($WDIR . "/hosts", <<EOF);
+$ip $h
+EOF
+ }
+}
+# end set hosts
+
+# check config of dns
+sub check_config {
+ system('named-checkconf', $WDIR . '/named.conf');
+}
+# end check config
+
+# copy file correct place
+sub copy_good {
+ mkdir_p($ZONE_DIR);
+ mkdir_p("$BIND_CHROOT/etc");
+ cp_af($WDIR . '/named.conf', "$BIND_CHROOT/etc/named.conf");
+ cp_af($WDIR . '/rndc.conf', "$BIND_CHROOT/etc/rndc.conf");
+ cp_af($WDIR . '/hosts', '/etc/hosts');
+ cp_af($WDIR . '/resolv.conf', '/etc/resolv.conf');
+ cp_af($WDIR . '/root.hints', $ZONE_DIR . '/');
+ cp_af(glob($WDIR . '/db*'), $ZONE_DIR . '/');
+}
+# end copy goodplace
+
+my $ip_regexp = qr/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
+sub check_ipm {
+ my $ip = $o->{var}{IPMASTER};
+ $ip or return 'slave';
+ my @fields = $ip =~ $ip_regexp or return 'error_ipm';
+ every { 0 <= $_ && $_ <= 255 } @fields or return 'error_ipm';
+}
+
+sub check_ipf {
+ my $ip = $o->{var}{IPOFFORWARDER};
+ $ip or return 'addsearch';
+ my @fields = $ip =~ $ip_regexp or return 'error_ipf';
+ every { 0 <= $_ && $_ <= 255 } @fields or return 'error_ipf';
+}
+
+
+sub check_iph {
+ my $ip = $o->{var}{CLIENTIP};
+ my @fields = $ip =~ $ip_regexp or return 'error_iph';
+ every { 0 <= $_ && $_ <= 255 } @fields or return 'error_iph';
+}
+
+sub do_it {
+ $::testing and return;
+ #my ($st) = @_;
+ crea_wdir($WDIR);
+ # create files
+ crea_db_local();
+ crea_127();
+ crea_named_common();
+ # set host configuration
+ if (-f $WDIR . '/hosts') { rm_rf($WDIR . '/hosts') }
+ set_hosts('127.0.0.1', 'localhost.localdomain localhost');
+ set_hosts($IPSERVER, $HOSTNAME);
+}
+
+sub end_it {
+ crea_hints();
+ crea_rndc();
+ # set configuration files on server
+ set_resolv();
+ # check generated config file are good
+ check_config();
+ # create backup
+ save_old_config();
+ # copy in correct place
+ copy_good();
+ # start or restart the service
+ if (services::is_service_running('named')) {
+ services::restart('named')
+ } else {
+ services::start('named')
+ }
+}
+
+sub do_it_master {
+ return if $::testing;
+ my $in = 'interactive'->vnew('su', 'dns');
+ check_starts_on_boot($in, 'named');
+ my $w = $in->wait_message(N("Master DNS server"), N("Configuring your system as Master DNS server ..."));
+ output($sys_wizard_dns, "INTERFACE=$o->{var}{interface}\n");
+ do_it();
+ crea_iprev($IPSERVER, $DOMAINNAME);
+ crea_ipnorm($IPSERVER, $DOMAINNAME);
+ crea_named_master($IPSERVER, $DOMAINNAME);
+ end_it();
+ undef $w;
+ check_started('named');
+}
+
+sub do_it_slave {
+ return if $::testing;
+ my $in = 'interactive'->vnew('su', 'dns');
+ check_starts_on_boot($in, 'named');
+ my $w = $in->wait_message(N("Slave DNS server"), N("Configuring your system as Slave DNS server ..."));
+ if (-f $sys_wizard_dns) { unlink $sys_wizard_dns }
+ do_it();
+ rm_rf(glob("$NAMED_DIR/bak*"));
+ crea_named_slave($IPSERVER, $DOMAINNAME, $o->{var}{IPMASTER});
+ end_it();
+ undef $w;
+ check_started('named');
+}
+
+sub get_shortname {
+# sure someone can find a better method to do that
+ my ($name) = @_;
+ my @DT = split(/\./, $DOMAINNAME);
+ my $NB = $#DT;
+ if (any { /$DOMAINNAME$/x } $name) {
+ my @shortname = split(/\./, $name);
+ splice(@shortname, -$NB);
+ my $shortn;
+ foreach (@shortname) {
+ $shortn or return $shortn = $_;
+ !$shortn or return $shortn . "." . $_;
+ }
+ } else { return $name }
+}
+
+sub do_it_add {
+ return if $::testing;
+ test_srv();
+ my $iprev = get_spe_ip('iprev', $IPSERVER);
+ my $ipend = get_spe_ip('ipend', $o->{var}{CLIENTIP});
+ my $SNAME = get_shortname($o->{var}{CLIENTNAME});
+ if (any { /$ipend\tIN/ } cat_("$ZONE_DIR/db.$iprev.hosts")) {
+ return 'error_add';
+ } elsif (any { /$SNAME.$DOMAINNAME.$/ } cat_("$ZONE_DIR/db.$iprev.hosts")) {
+ return 'error_add';
+ } else {
+ append_to_file("$ZONE_DIR/db.$DOMAINNAME.hosts",
+ "$SNAME.$DOMAINNAME.\tIN\tA\t$o->{var}{CLIENTIP}\n");
+ append_to_file("$ZONE_DIR/db.$iprev.hosts",
+ "$ipend\tIN\tPTR\t$SNAME.$DOMAINNAME.\n");
+ }
+ increment_serial($iprev);
+ system("service named reload");
+ return 'endadd'
+}
+
+sub do_it_remove {
+ return if $::testing;
+ test_srv();
+ my $iprev = get_spe_ip('iprev', $IPSERVER);
+ my $NAME = $o->{var}{CLIENTNAME};
+ substInFile {
+ s/^\b$NAME.\b.*//;
+ s/^\s*$//;
+ } "$ZONE_DIR/db.$DOMAINNAME.hosts";
+ substInFile {
+ s/^\d+\tIN\tPTR\t$NAME.*//;
+ s/^\s*$//;
+ } "$ZONE_DIR/db.$iprev.hosts";
+ increment_serial($iprev);
+ system("service named reload");
+}
+
+
+#34 IN PTR xp2400.guibland.com.
+sub do_it_list {
+ return if $::testing;
+ my $iprev = get_spe_ip('iprev', $IPSERVER);
+ my $db = "$ZONE_DIR/db.$iprev.hosts";
+ #my $ipnor = get_spe_ip('ipnor', $IPSERVER);
+ my @hosts; my @ip;
+ foreach (cat_($db)) {
+ my ($ipend, $h) = /(\d{1,3})\tIN\tPTR\t(.*)/;
+ if (!$h) { push @hosts, $h; push @ip, $ipend }
+ }
+}
+
+
+sub new {
+ my ($class) = @_;
+ bless $o, $class;
+}
+
+1;