Handle hostnames with upper-case letters
[webmin.git] / bind8 / create_slave.cgi
1 #!/usr/local/bin/perl
2 # create_slave.cgi
3 # Create a new slave zone
4 # Modified by Howard Wilkinson <howard@cohtech.co.uk> 7th NOvember 2001
5 #        Added a facility to create a slave zone with the master(s)
6 #        on a non-standard port
7
8 require './bind8-lib.pl';
9 &ReadParse();
10 &error_setup($in{'type'} ? $text{'screate_err1'} : $text{'screate_err2'});
11 $access{'slave'} || &error($in{'type'} ? $text{'screate_ecannot1'}
12                                        : $text{'screate_ecannot2'});
13 $access{'ro'} && &error($text{'master_ero'});
14 $conf = &get_config();
15 if ($in{'view'} ne '') {
16         $view = $conf->[$in{'view'}];
17         &can_edit_view($view) || &error($text{'master_eviewcannot'});
18         $vconf = $view->{'members'};
19         $viewname = $view->{'values'}->[0];
20         }
21 else {
22         $vconf = $conf;
23         $viewname = undef;
24         }
25
26 # validate inputs
27 if ($in{'rev'}) {
28         local($ipv4);
29         ($ipv4 = &check_net_ip($in{'zone'})) ||
30         $config{'support_aaaa'} &&
31         ($in{'zone'} =~ /^([\w:]+)(\/\d+)$/ || &check_ip6address($1)) ||
32                 &error(&text('create_enet', $in{'zone'}));
33         if ($ipv4) {
34                 $in{'zone'} = &ip_to_arpa($in{'zone'});
35                 }
36         else {
37                 $in{'zone'} = &net_to_ip6int($1, ($2 ? substr($2, 1) : "" ));
38                 }
39         }
40 else {
41         ($in{'zone'} =~ /^[\d\.]+$/ || $in{'zone'} =~ /^[\d\:]+(\/[\d]+)?$/) &&
42                 &error(&text('create_edom2', $in{'zone'}));
43         &valdnsname($in{'zone'}, 0, ".") ||
44                 &error(&text('create_edom', $in{'zone'}));
45         }
46 $in{'zone'} =~ s/\.$//;
47 foreach $z (&find("zone", $vconf)) {
48         if (lc($z->{'value'}) eq lc($in{'zone'})) {
49                 &error($text{'master_etaken'});
50                 }
51         }
52 $masterport = $in{'port_def'} ? undef : $in{'port'};
53 @masters = split(/\s+/, $in{'masters'});
54 foreach $m (@masters) {
55         &check_ipaddress($m) || &check_ip6address($m) ||
56                 &error(&text('create_emaster', $m));
57         }
58 if (!@masters) {
59         &error($text{'create_enone'});
60         }
61 $base = $access{'dir'} ne '/' ? $access{'dir'} :
62         $config{'slave_dir'} ? $config{'slave_dir'} :
63                                &base_directory($conf);
64 $base =~ s/\/+$// if ($base ne '/');
65 if ($base !~ /^([a-z]:)?\//) {
66         # Slave dir is relative .. make absolute
67         $base = &base_directory()."/".$base;
68         }
69 if ($in{'file_def'} == 0) {
70         # Use the entered filename
71         $in{'file'} =~ /^\S+$/ ||
72                 &error(&text('create_efile', $in{'file'}));
73         if ($in{'file'} !~ /^\//) {
74                 $file = $base."/".$in{'file'};
75                 }
76         else { $file = $in{'file'}; }
77         &allowed_zone_file(\%access, $file) ||
78                 &error(&text('create_efile2', $file));
79         }
80 elsif ($in{'file_def'} == 2) {
81         # Automatically choose a filename
82         $file = &automatic_filename($in{'zone'}, $in{'rev'}, $base,
83                                     $view ? $view->{'value'} : undef);
84         }
85 if ($file) {
86         &open_tempfile(ZONE, ">".&make_chroot($file), 1, 1) ||
87                 &error(&text('create_efile3', $file, $!));
88         &close_tempfile(ZONE);
89         &set_ownership(&make_chroot($file));
90         }
91
92 # Create the structure
93 @mdirs = map { { 'name' => $_ } } @masters;
94 $masters = { 'name' => 'masters',
95              'type' => 1,
96              'members' => \@mdirs };
97 if (defined($masterport)) {
98         $masters->{'values'} = [ 'port', $masterport ];
99         }
100 $dir = { 'name' => 'zone',
101          'values' => [ $in{'zone'} ],
102          'type' => 1,
103          'members' => [ { 'name' => 'type',
104                           'values' => [ $in{'type'} ? 'slave'
105                                                     : 'stub' ] },
106                         $masters
107                       ]
108         };
109 if ($file) {
110         push(@{$dir->{'members'}},
111                 { 'name' => 'file',
112                   'values' => [ $file ] });
113         }
114
115 # Create zone directive
116 &create_zone($dir, $conf, $in{'view'});
117 &webmin_log("create", $in{'type'} ? 'slave' : 'stub', $in{'zone'}, \%in);
118
119 # Get the new zone's index
120 $idx = &get_zone_index($in{'zone'}, $in{'view'});
121
122 &add_zone_access($in{'zone'});
123
124 # Create on slave servers
125 if ($in{'onslave'} && $access{'remote'}) {
126         @slaveerrs = &create_on_slaves($in{'zone'}, $masters[0],
127                         $in{'file_def'} == 1 ? "none" :
128                         $in{'file_def'} == 2 ? undef : $in{'sfile'},
129                         undef, $viewname);
130         if (@slaveerrs) {
131                 &error(&text('master_errslave',
132                      "<p>".join("<br>", map { "$_->[0]->{'host'} : $_->[1]" }
133                                             @slaveerrs)));
134                 }
135         }
136
137 &redirect(($in{'type'} ? "edit_slave.cgi" : "edit_stub.cgi").
138           "?index=$idx&view=$in{'view'}");
139