Handle hostnames with upper-case letters
[webmin.git] / itsecur-firewall / restore.cgi
1 #!/usr/bin/perl
2 # Actually do a restore
3
4 require './itsecur-lib.pl';
5 &can_edit_error("restore");
6 &error_setup($text{'restore_err'});
7 &ReadParseMime();
8
9 # Validate inputs
10 if (!$in{'src_def'}) {
11         if (-d $in{'src'}) {
12                 $in{'src'} .= "/firewall.zip";
13                 }
14         -r $in{'src'} || &error_cleanup($text{'restore_esrc'});
15         $file = $in{'src'};
16         }
17 else {
18         $in{'file'} || &error_cleanup($text{'restore_efile'});
19         $file = &tempname();
20         open(FILE, ">$file");
21         print FILE $in{'file'};
22         close(FILE);
23         }
24 if (!$in{'pass_def'}) {
25         $in{'pass'} || &error_cleanup($text{'backup_epass'});
26         }
27 @what = split(/\0/, $in{'what'});
28 @what || &error_cleanup($text{'restore_ewhat'});
29 %what = map { $_, 1 } @what;
30
31 # Extract the zip file
32 $tempdir = &tempname();
33 mkdir($tempdir, 0700);
34 $pass = $in{'pass_def'} ? undef : "-P '$in{'pass'}'";
35 $out = &backquote_logged("(cd $tempdir && unzip $pass '$file') 2>&1 </dev/null");
36 &error_cleanup($text{'restore_epass2'}) if ($? && $out =~ /password/ &&
37                                             $in{'pass_def'});
38 &error_cleanup($text{'restore_epass'}) if ($? && $out =~ /password/);
39 &error_cleanup($text{'restore_etar'}) if ($?);
40
41 # Work out the new state
42 @rules = &list_rules(&if_exists("rules"));
43 @services = &list_services(&if_exists("services"));
44 @groups = &list_groups(&if_exists("groups"));
45 ($natiface, @nats) = &get_nat(&if_exists("nat"));
46 @pats = &get_pat(&if_exists("pat"));
47 ($spoofiface, @spoofs) = &get_spoof(&if_exists("spoof"));
48 ($flood, $spoof) = &get_syn(&if_exists("syn"));
49 @times = &list_times(&if_exists("times"));
50
51 # Ensure that the new state would be consistent
52 %groups = map { $_->{'name'}, $_ } @groups;
53 %services = map { $_->{'name'}, $_ } @services;
54 %times = map { $_->{'name'}, $_ } @times;
55 foreach $r (@rules) {
56         foreach $g (split(/\s+/, $r->{'source'}), split(/\s+/, $r->{'dest'})) {
57                 if ($g =~ /^\!?\@(.*)$/ && !$groups{$1}) {
58                         push(@cerrs, &text('restore_egroup', "$1",
59                                            $r->{'num'}));
60                         }
61                 }
62         foreach $s (split(/,/, $r->{'service'})) {
63                 if ($s ne "*" && !$services{$s}) {
64                         push(@cerrs, &text('restore_eservice', $s,
65                                            $r->{'num'}));
66                         }
67                 }
68         if ($r->{'time'} ne "*" && !$times{$r->{'time'}}) {
69                 push(@cerrs, &text('restore_etime', $r->{'time'},
70                                    $r->{'num'}));
71                 }
72         }
73 foreach $n (@nats) {
74         if (!ref($n) && $n =~ /^\!?(.*)$/ && !$groups{$1}) {
75                 push(@cerrs, &text('restore_enat', $1));
76                 }
77         }
78 foreach $p (@pats) {
79         if (!$services{$p->{'service'}}) {
80                 push(@cerrs, &text('restore_epat', $p->{'service'}));
81                 }
82         }
83 foreach $n (@nats) {
84         if (!ref($n) && $n =~ /^\!?(.*)$/ && !$groups{$1}) {
85                 push(@cerrs, &text('restore_enat', $1));
86                 }
87         }
88 if (@cerrs) {
89         # Tell the user
90         &header($text{'restore_title'}, "",
91                 undef, undef, undef, undef, &apply_button());
92         print "<hr>\n";
93
94         print "<p>$text{'restore_cerr'}<br>\n";
95         print "<ul>\n";
96         foreach $c (@cerrs) {
97                 print "<li>$c\n";
98                 }
99         print "</ul>\n";
100
101         print "<hr>\n";
102         &footer("", $text{'index_return'});
103         exit;
104         }
105
106 # Copy to the config directory
107 &automatic_backup();
108 &lock_itsecur_files();
109 foreach $w (@what) {
110         if ($w eq "ipsec") {
111                 # Copy ipsec config to proper location
112                 if (&has_ipsec() && -r "$tempdir/ipsec.conf") {
113                         &lock_file($ipsec::config{'file'});
114                         &lock_file($ipsec::config{'secrets'});
115                         system("cp $tempdir/ipsec.conf $ipsec::config{'file'}");
116                         system("cp $tempdir/ipsec.secrets $ipsec::config{'secrets'}");
117                         &unlock_file($ipsec::config{'file'});
118                         &unlock_file($ipsec::config{'secrets'});
119                         }
120                 }
121         elsif ($w eq "users") {
122                 # Copy Webmin user files
123                 &lock_file("$config_directory/miniserv.users");
124                 &lock_file("$config_directory/webmin.acl");
125                 system("cp $tempdir/miniserv.users $config_directory/miniserv.users");
126                 system("cp $tempdir/webmin.acl $config_directory/webmin.acl");
127                 foreach $a (glob("$tempdir/*.acl")) {
128                         local $fn = $a;
129                         $fn =~ s/^.*\///;
130                         if ($fn ne "webmin.acl") {
131                                 &lock_file("$module_config_directory/$fn");
132                                 system("cp $a $module_config_directory/$fn");
133                                 &unlock_file("$module_config_directory/$fn");
134                                 }
135                         }
136                 &unlock_file("$config_directory/miniserv.users");
137                 &unlock_file("$config_directory/webmin.acl");
138                 &restart_miniserv();
139                 }
140         elsif ($w eq "searches") {
141                 # Copy searches directory
142                 mkdir($searches_directory, 0755);
143                 system("cp $tempdir/searches/* $searches_directory >/dev/null 2>&1");
144                 }
145         elsif ($w eq "config") {
146                 # Update module config - except system type
147                 local %newconfig;
148                 &read_file("$tempdir/config", \%newconfig);
149                 $newconfig{'type'} = $config{'type'};
150                 &write_file("$module_config_directory/config", \%newconfig);
151                 }
152         else {
153                 if (-r "$tempdir/$w") {
154                         system("cp $tempdir/$w $module_config_directory");
155                         }
156                 }
157         }
158 &unlock_itsecur_files();
159
160 # Tell the user
161 &header($text{'restore_title'}, "",
162         undef, undef, undef, undef, &apply_button());
163 print "<hr>\n";
164
165 print "<p>",&text('restore_done'),"<p>\n";
166 &cleanup();
167
168 print "<hr>\n";
169 &footer("", $text{'index_return'});
170 &remote_webmin_log("restore", undef, $in{'src_def'} ? undef : $in{'src'});
171
172 sub error_cleanup
173 {
174 &cleanup();
175 &error(@_);
176 }
177
178 sub cleanup
179 {
180 unlink($file) if ($in{'src_def'});
181 system("rm -rf $tempdir") if ($tempdir);
182 }
183
184 sub if_exists
185 {
186 return -r "$tempdir/$_[0]" && $what{$_[0]} ? "$tempdir/$_[0]" : undef;
187 }
188