Files
webmin/nftables/save_chain.cgi
2026-05-03 00:44:55 +02:00

102 lines
3.1 KiB
Perl

#!/usr/bin/perl
# save_chain.cgi
# Save a new or existing chain
require './nftables-lib.pl'; ## no critic
use strict;
use warnings;
our (%in, %text);
ReadParse();
error_setup($text{'chain_err'});
my @tables = get_nftables_save();
my $table = $tables[$in{'table'}];
$table || error($text{'chain_notable'});
my $is_new = $in{'new'} ? 1 : 0;
my $is_rename = $in{'rename'} ? 1 : 0;
my $name = $in{'chain_name'};
$name =~ s/^\s+// if (defined($name));
$name =~ s/\s+$// if (defined($name));
$name =~ /^\w[\w-]*$/ || error($text{'chain_ename'});
my $old = $is_rename ? $in{'chain_old'} : $name;
$old =~ s/^\s+// if (defined($old));
$old =~ s/\s+$// if (defined($old));
if ($is_new) {
$table->{'chains'}->{$name} && error($text{'chain_edup'});
} elsif ($is_rename) {
$table->{'chains'}->{$old} || error($text{'chain_nochain'});
if ($name ne $old && $table->{'chains'}->{$name}) {
error($text{'chain_edup'});
}
} else {
$table->{'chains'}->{$name} || error($text{'chain_nochain'});
}
if ($is_rename) {
if ($name eq $old) {
redirect("index.cgi?table=$in{'table'}");
return;
}
if ($name ne $old) {
$table->{'chains'}->{$name} = $table->{'chains'}->{$old};
delete($table->{'chains'}->{$old});
foreach my $r (@{$table->{'rules'}}) {
$r->{'chain'} = $name if ($r->{'chain'} && $r->{'chain'} eq $old);
my $changed = 0;
if ($r->{'jump'} && $r->{'jump'} eq $old) {
$r->{'jump'} = $name;
$changed = 1;
}
if ($r->{'goto'} && $r->{'goto'} eq $old) {
$r->{'goto'} = $name;
$changed = 1;
}
$r->{'text'} = format_rule_text($r) if ($changed);
}
}
my $err = save_table_configuration($table, @tables);
error(text('rename_chain_failed', $err)) if ($err);
webmin_log("rename", "chain", $old,
{ 'new' => $name,
'table' => $table->{'name'},
'family' => $table->{'family'} });
redirect("index.cgi?table=$in{'table'}");
return;
}
my $type = $in{'chain_type'};
my $hook = $in{'chain_hook'};
my $priority = $in{'chain_priority'};
my $policy = $in{'chain_policy'};
for my $v (\$type, \$hook, \$priority, \$policy) {
$$v =~ s/^\s+// if (defined($$v));
$$v =~ s/\s+$// if (defined($$v));
}
$type = undef if (!defined($type) || $type eq '');
$hook = undef if (!defined($hook) || $hook eq '');
$priority = undef if (!defined($priority) || $priority eq '');
$policy = undef if (!defined($policy) || $policy eq '');
validate_chain_base($type, $hook, $priority, $policy) ||
error($text{'chain_ebase'});
my $chain = $table->{'chains'}->{$name} || { };
$chain->{'type'} = $type;
$chain->{'hook'} = $hook;
$chain->{'priority'} = $priority;
$chain->{'policy'} = $policy;
$table->{'chains'}->{$name} = $chain;
my $err = save_table_configuration($table, @tables);
error(text('chain_failed', $err)) if ($err);
webmin_log($is_new ? "create" : "modify", "chain", $name,
{ 'table' => $table->{'name'}, 'family' => $table->{'family'} });
redirect("index.cgi?table=$in{'table'}");