mirror of
https://github.com/webmin/webmin.git
synced 2025-08-16 14:51:18 +00:00
118 lines
3.0 KiB
Perl
Executable File
118 lines
3.0 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# save_service.cgi
|
|
# Create, update or delete a service
|
|
|
|
require './itsecur-lib.pl';
|
|
&can_edit_error("services");
|
|
&ReadParse();
|
|
&lock_itsecur_files();
|
|
@servs = &list_services();
|
|
if (!$in{'new'}) {
|
|
$serv = $servs[$in{'idx'}];
|
|
}
|
|
|
|
if ($in{'delete'}) {
|
|
# Check if in use by a rule or other service
|
|
&error_setup($text{'service_err2'});
|
|
@rules = &list_rules();
|
|
foreach $r (@rules) {
|
|
@rservs = split(/,/, $r->{'service'});
|
|
&error($text{'service_einuse'})
|
|
if (&indexof($serv->{'name'}, @rservs) >= 0);
|
|
}
|
|
foreach $s (@servs) {
|
|
&error($text{'service_einuse2'})
|
|
if (&indexof($serv->{'name'}, @{$s->{'others'}}) >= 0);
|
|
}
|
|
|
|
# Just delete this service
|
|
splice(@servs, $in{'idx'}, 1);
|
|
&automatic_backup();
|
|
}
|
|
else {
|
|
# Validate inputs
|
|
&error_setup($text{'service_err'});
|
|
$in{'name'} =~ /\S/ || &error($text{'service_ename'});
|
|
@others = split(/\0/, $in{'others'});
|
|
for($i=0; defined($in{"proto_$i"}); $i++) {
|
|
next if (!$in{"proto_$i"});
|
|
if ($in{"proto_$i"} eq 'icmp') {
|
|
$in{"port_$i"} =~ /^\d+$/ ||
|
|
$in{"port_$i"} eq '*' ||
|
|
&error(&text('service_eicmp', $i+1));
|
|
}
|
|
elsif ($in{"proto_$i"} eq 'ip') {
|
|
$in{"port_$i"} =~ /^\d+$/ ||
|
|
&error(&text('service_eip', $i+1));
|
|
}
|
|
else {
|
|
$in{"port_$i"} =~ /^\d+$/ ||
|
|
$in{"port_$i"} =~ /^\d+\-\d+$/ ||
|
|
$in{"port_$i"} =~ /^\d+(\s+\d+)*$/ ||
|
|
&error(&text('service_eport', $i+1));
|
|
}
|
|
push(@protos, $in{"proto_$i"});
|
|
push(@ports, $in{"port_$i"});
|
|
}
|
|
@protos || @others || &error($text{'service_enone'});
|
|
#&unique(@protos) == 1 || &error($text{'service_eprotos'});
|
|
if ($in{'new'} || lc($in{'name'}) ne lc($serv->{'name'})) {
|
|
# Check for clash
|
|
($clash) = grep { lc($_->{'name'}) eq lc($in{'name'}) } @servs;
|
|
$clash && &error($text{'service_eclash'});
|
|
}
|
|
$oldname = $serv->{'name'};
|
|
$serv->{'name'} = $in{'name'};
|
|
$serv->{'protos'} = \@protos;
|
|
$serv->{'ports'} = \@ports;
|
|
$serv->{'others'} = \@others;
|
|
|
|
if ($in{'new'}) {
|
|
push(@servs, $serv);
|
|
}
|
|
|
|
&automatic_backup();
|
|
if (!$in{'new'} && $oldname ne $serv->{'name'}) {
|
|
# Has been re-named .. update all rules!
|
|
@rules = &list_rules();
|
|
foreach $r (@rules) {
|
|
$r->{'service'} = &replace_service_name(
|
|
$r->{'service'}, $oldname, $serv->{'name'});
|
|
}
|
|
&save_rules(@rules);
|
|
|
|
# Also update PAT services
|
|
@forwards = &get_pat();
|
|
foreach $f (@forwards) {
|
|
$f->{'service'} = &replace_service_name(
|
|
$f->{'service'}, $oldname, $serv->{'name'});
|
|
}
|
|
&save_pat(@forwards);
|
|
|
|
# Also update other services
|
|
foreach $s (@servs) {
|
|
$idx = &indexof($oldname, @{$s->{'others'}});
|
|
if ($idx >= 0) {
|
|
$s->{'others'}->[$idx] = $serv->{'name'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
&save_services(@servs);
|
|
&unlock_itsecur_files();
|
|
&remote_webmin_log($in{'delete'} ? "delete" : $in{'new'} ? "create" : "update",
|
|
"service", $serv->{'name'}, $serv);
|
|
&redirect("list_services.cgi");
|
|
|
|
# replace_service_name(comma-list, old, new)
|
|
sub replace_service_name
|
|
{
|
|
local @servs = split(/,/, $_[0]);
|
|
foreach $s (@servs) {
|
|
$s = $_[2] if ($s eq $_[1]);
|
|
}
|
|
return join(",", @servs);
|
|
}
|
|
|