Handle hostnames with upper-case letters
[webmin.git] / bind8 / delete_zone.cgi
1 #!/usr/local/bin/perl
2 # delete_zone.cgi
3 # Delete an existing master, slave or secondary zone, and it's records file
4
5 require './bind8-lib.pl';
6 &ReadParse();
7 $conf = &get_config();
8 $parent = &get_config_parent();
9 if ($in{'view'} ne '') {
10         $view = $conf->[$in{'view'}];
11         $conf = $view->{'members'};
12         $viewname = $view->{'values'}->[0];
13         $parent = $view;
14         }
15 else {
16         $viewname = undef;
17         }
18 $zconf = $conf->[$in{'index'}];
19 &can_edit_zone($zconf, $view) ||
20         &error($text{'master_edelete'});
21 $access{'ro'} && &error($text{'master_ero'});
22 $access{'delete'} || &error($text{'master_edeletecannot'});
23
24 $rev = ($zconf->{'value'} =~ /in-addr\.arpa/i || $zconf->{'value'} =~ /\.$ipv6revzone/i);
25 $type = &find("type", $zconf->{'members'})->{'value'};
26 if (!$in{'confirm'} && $config{'confirm_zone'}) {
27         # Ask the user if he is sure ..
28         &ui_print_header(undef, $text{'delete_title'}, "",
29                          undef, undef, undef, undef, &restart_links());
30
31         # Check if deleted on slaves too
32         @servers = &list_slave_servers();
33         if ($type eq 'slave' || $type eq 'stub') {
34                 @servers = grep { $_->{'sec'} } @servers;
35                 }
36         elsif ($type ne 'master') {
37                 @servers = ( );
38                 }
39
40         $zdesc = "<tt>".&ip6int_to_net(&arpa_to_ip($zconf->{'value'}))."</tt>";
41         print &ui_confirmation_form("delete_zone.cgi",
42                 $type eq 'hint' ? $text{'delete_mesg2'} :
43                 $type eq 'master' ? &text('delete_mesg', $zdesc) :
44                                     &text('delete_mesg3', $zdesc),
45                 [ [ 'index', $in{'index'} ],
46                   [ 'view', $in{'view'} ] ],
47                 [ [ 'confirm', $text{'master_del'} ] ],
48                 ($type eq 'master' ?
49                         $text{$rev ? 'delete_fwd' : 'delete_rev'}." ".
50                         &ui_yesno_radio("rev", 1)."<br>" : "").
51                 (@servers && $access{'remote'} ?
52                         $text{'delete_onslave'}." ".
53                         &ui_yesno_radio("onslave", 1)."<br>" : "")
54                 );
55
56         &ui_print_footer("", $text{'index_return'});
57         exit;
58         }
59
60 if (!$rev && $in{'rev'} && $type eq 'master') {
61         # find and delete reverse records
62         local $file = &find("file", $zconf->{'members'})->{'value'};
63         &lock_file(&make_chroot($file));
64         @recs = &read_zone_file($file, $zconf->{'value'});
65         foreach $r (@recs) {
66                 next if ($r->{'type'} ne "A" && $r->{'type'} ne "AAAA");
67                 ($orevconf, $orevfile, $orevrec) =
68                         &find_reverse($r->{'values'}->[0], $in{'view'});
69                 if ($orevrec && &can_edit_reverse($orevconf) &&
70                     $r->{'name'} eq $orevrec->{'values'}->[0] &&
71                     ($r->{'type'} eq "A" &&
72                      $r->{'values'}->[0] eq &arpa_to_ip($orevrec->{'name'})
73                      || $r->{'type'} eq "AAAA" &&
74                      &expandall_ip6($r->{'values'}->[0]) eq &expandall_ip6(&ip6int_to_net($orevrec->{'name'})))) {
75                         &lock_file(&make_chroot($orevrec->{'file'}));
76                         &delete_record($orevrec->{'file'} , $orevrec);
77                         &lock_file(&make_chroot($orevfile));
78                         @orrecs = &read_zone_file($orevfile,
79                                                   $orevconf->{'name'});
80                         &bump_soa_record($orevfile, \@orrecs);
81                         &sign_dnssec_zone_if_key($orevconf, \@orrecs);
82                         }
83                 }
84         }
85 elsif ($rev && $in{'rev'} && $type eq 'master') {
86         # find and delete forward records
87         local $file = &find("file", $zconf->{'members'})->{'value'};
88         &lock_file(&make_chroot($file));
89         @recs = &read_zone_file($file, $zconf->{'value'});
90         foreach $r (@recs) {
91                 next if ($r->{'type'} ne "PTR");
92                 ($ofwdconf, $ofwdfile, $ofwdrec) =
93                         &find_forward($r->{'values'}->[0]);
94                 if ($ofwdrec && &can_edit_zone($ofwdconf) &&
95                     ($ofwdrec->{'type'} eq "A" &&
96                      &arpa_to_ip($r->{'name'}) eq $ofwdrec->{'values'}->[0] 
97                      || $ofwdrec->{'type'} eq "AAAA" &&
98                      &expandall_ip6(&ip6int_to_net($r->{'name'})) eq &expandall_ip6($ofwdrec->{'values'}->[0])) &&
99                     $r->{'values'}->[0] eq $ofwdrec->{'name'}) {
100                         &lock_file(&make_chroot($ofwdrec->{'file'}));
101                         &delete_record($ofwdrec->{'file'} , $ofwdrec);
102                         &lock_file(&make_chroot($ofwdfile));
103                         @ofrecs = &read_zone_file($ofwdfile,
104                                                   $ofwdconf->{'name'});
105                         &bump_soa_record($ofwdfile, \@ofrecs);
106                         &sign_dnssec_zone_if_key($ofwdconf, \@ofrecs);
107                         }
108                 }
109         }
110
111 # delete the records file
112 $f = &find("file", $zconf->{'members'});
113 if ($f && $type ne 'hint') {
114         &delete_records_file($f->{'value'});
115         }
116
117 # delete any keys
118 &delete_dnssec_key($zconf);
119
120 # remove the zone directive
121 &lock_file(&make_chroot($zconf->{'file'}));
122 &save_directive($parent, [ $zconf ], [ ]);
123 &flush_file_lines();
124 &unlock_all_files();
125 &webmin_log("delete", &find("type", $zconf->{'members'})->{'value'},
126             $zconf->{'value'}, \%in);
127
128 # remove from acl files
129 &read_acl(undef, \%wusers);
130 foreach $u (keys %wusers) {
131         %uaccess = &get_module_acl($u);
132         if ($uaccess{'zones'} ne '*') {
133                 $uaccess{'zones'} = join(' ', grep { $_ ne $zconf->{'value'} }
134                                               split(/\s+/, $uaccess{'zones'}));
135                 &save_module_acl(\%uaccess, $u);
136                 }
137         }
138
139 # Also delete from slave servers
140 delete($ENV{'HTTP_REFERER'});
141 if ($in{'onslave'} && $access{'remote'}) {
142         @slaveerrs = &delete_on_slaves($zconf->{'value'}, undef, $viewname);
143         if (@slaveerrs) {
144                 &error(&text('delete_errslave',
145                      "<p>".join("<br>", map { "$_->[0]->{'host'} : $_->[1]" }
146                                       @slaveerrs)));
147                 }
148         }
149
150 &redirect("");
151
152 sub slave_error_handler
153 {
154 $slave_error = $_[0];
155 }
156