From 57a7cffcc8686df0f67e22df5f49962bd261e1ff Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sun, 14 Jan 2018 16:31:46 -0800 Subject: [PATCH] Lock all files when updating configs --- fail2ban/delete_actions.cgi | 4 ++-- fail2ban/delete_filters.cgi | 4 ++-- fail2ban/delete_jails.cgi | 4 ++-- fail2ban/fail2ban-lib.pl | 16 ++++++++++++++++ fail2ban/save_action.cgi | 8 ++++---- fail2ban/save_config.cgi | 4 ++-- fail2ban/save_filter.cgi | 8 ++++---- fail2ban/save_jail.cgi | 8 ++++---- fail2ban/save_jaildef.cgi | 4 ++-- 9 files changed, 38 insertions(+), 22 deletions(-) diff --git a/fail2ban/delete_actions.cgi b/fail2ban/delete_actions.cgi index 3028a8b0a..06a7f0e9e 100755 --- a/fail2ban/delete_actions.cgi +++ b/fail2ban/delete_actions.cgi @@ -12,6 +12,7 @@ our (%in, %text, %config); my @d = split(/\0/, $in{'d'}); @d || &error($text{'actions_enone'}); my @actions = &list_actions(); +&lock_all_files(); foreach my $file (@d) { my ($action) = grep { $_->[0]->{'file'} eq $file } @actions; next if (!$action); @@ -21,10 +22,9 @@ foreach my $file (@d) { @users && &error(&text('actions_einuse', &filename_to_name($file), join(" ", map { $_->{'name'} } @users))); - &lock_file($file); &delete_section($file, $def); - &unlock_file($file); } +&unlock_all_files(); &webmin_log("delete", "actions", scalar(@d)); &redirect("list_actions.cgi"); diff --git a/fail2ban/delete_filters.cgi b/fail2ban/delete_filters.cgi index 97ce7a8f7..a64222681 100755 --- a/fail2ban/delete_filters.cgi +++ b/fail2ban/delete_filters.cgi @@ -12,6 +12,7 @@ our (%in, %text, %config); my @d = split(/\0/, $in{'d'}); @d || &error($text{'filters_enone'}); my @filters = &list_filters(); +&lock_all_files(); foreach my $file (@d) { my ($filter) = grep { $_->[0]->{'file'} eq $file } @filters; next if (!$filter); @@ -21,10 +22,9 @@ foreach my $file (@d) { @users && &error(&text('filters_einuse', &filename_to_name($file), join(" ", map { $_->{'name'} } @users))); - &lock_file($file); &delete_section($file, $def); - &unlock_file($file); } +&unlock_all_files(); &webmin_log("delete", "filters", scalar(@d)); &redirect("list_filters.cgi"); diff --git a/fail2ban/delete_jails.cgi b/fail2ban/delete_jails.cgi index cc9bebeed..074cdd2f4 100755 --- a/fail2ban/delete_jails.cgi +++ b/fail2ban/delete_jails.cgi @@ -12,13 +12,13 @@ our (%in, %text, %config); my @d = split(/\0/, $in{'d'}); @d || &error($text{'jails_enone'}); my @jails = &list_jails(); +&lock_all_files(); foreach my $name (@d) { my ($jail) = grep { $_->{'name'} eq $name } @jails; next if (!$jail); - &lock_file($jail->{'file'}); &delete_section($jail->{'file'}, $jail); - &unlock_file($jail->{'file'}); } +&unlock_all_files(); &webmin_log("delete", "jails", scalar(@d)); &redirect("list_jails.cgi"); diff --git a/fail2ban/fail2ban-lib.pl b/fail2ban/fail2ban-lib.pl index 1ba0db2c2..420a43e50 100644 --- a/fail2ban/fail2ban-lib.pl +++ b/fail2ban/fail2ban-lib.pl @@ -490,6 +490,22 @@ push(@rv, "$config{'config_dir'}/jail.local"); return grep { -r $_ } @rv; } +sub lock_all_files +{ +@all_files_for_lock = &list_all_config_files(); +foreach my $f (@all_files_for_lock) { + &lock_file($f); + } +} + +sub unlock_all_files +{ +foreach my $f (reverse(@all_files_for_lock)) { + &unlock_file($f); + } +@all_files_for_lock = (); +} + # get_fail2ban_version() # Returns the version number, or undef if it cannot be found sub get_fail2ban_version diff --git a/fail2ban/save_action.cgi b/fail2ban/save_action.cgi index 5f08a5030..2136d1aee 100755 --- a/fail2ban/save_action.cgi +++ b/fail2ban/save_action.cgi @@ -29,9 +29,9 @@ if ($in{'delete'}) { my @users = &find_jail_by_action($action); @users && &error(&text('action_einuse', join(" ", map { $_->{'name'} } @users))); - &lock_file($file); + &lock_all_files(); &delete_section($file, $def); - &unlock_file($file); + &unlock_all_files(); } else { # Validate inputs @@ -44,7 +44,7 @@ else { } # Create new section if needed - &lock_file($file); + &lock_all_files(); if ($in{'new'}) { &create_section($file, $def); } @@ -61,7 +61,7 @@ else { $in{'unban'} =~ s/\r//g; &save_directive("actionunban", $in{'unban'}, $def); - &unlock_file($file); + &unlock_all_files(); } # Log and redirect diff --git a/fail2ban/save_config.cgi b/fail2ban/save_config.cgi index a9f9465df..e897a9431 100755 --- a/fail2ban/save_config.cgi +++ b/fail2ban/save_config.cgi @@ -21,7 +21,7 @@ if (!$in{'socket_def'}) { } # Update config file -&lock_file($def->{'file'}); +&lock_all_files(); &save_directive("loglevel", $in{'loglevel'}, $def); &save_directive("logtarget", @@ -30,6 +30,6 @@ if (!$in{'socket_def'}) { $in{'logtarget_def'}, $def); &save_directive("socket", $in{'socket_def'} ? undef : $in{'socket'}, $def); -&unlock_file($def->{'file'}); +&unlock_all_files(); &webmin_log("config"); &redirect(""); diff --git a/fail2ban/save_filter.cgi b/fail2ban/save_filter.cgi index 8a83bd890..a5277a392 100755 --- a/fail2ban/save_filter.cgi +++ b/fail2ban/save_filter.cgi @@ -29,9 +29,9 @@ if ($in{'delete'}) { my @users = &find_jail_by_filter($filter); @users && &error(&text('filter_einuse', join(" ", map { $_->{'name'} } @users))); - &lock_file($file); + &lock_all_files(); &delete_section($file, $def); - &unlock_file($file); + &unlock_all_files(); } else { # Validate inputs @@ -45,7 +45,7 @@ else { $in{'fail'} =~ /\S/ || &error($text{'filter_efail'}); # Create new section if needed - &lock_file($file); + &lock_all_files(); if ($in{'new'}) { &create_section($file, $def); } @@ -56,7 +56,7 @@ else { $in{'ignore'} =~ s/\r//g; &save_directive("ignoreregex", $in{'ignore'}, $def); - &unlock_file($file); + &unlock_all_files(); } # Log and redirect diff --git a/fail2ban/save_jail.cgi b/fail2ban/save_jail.cgi index e559f4c5d..b6c9efbaa 100755 --- a/fail2ban/save_jail.cgi +++ b/fail2ban/save_jail.cgi @@ -26,10 +26,10 @@ else { if ($in{'delete'}) { # Just delete the jail - &lock_file($jail->{'file'}); + &lock_all_files(); &delete_section($jail->{'file'}, $jail, $jail->{'file'} =~ /jail.local$/ ? 1 : 0); - &unlock_file($jail->{'file'}); + &unlock_all_files(); } else { # Validate inputs @@ -102,7 +102,7 @@ else { } # Create new section or rename existing if needed - &lock_file($jail->{'file'}); + &lock_all_files(); if ($in{'new'}) { &create_section($jail->{'file'}, $jail); } @@ -122,7 +122,7 @@ else { &save_directive("ignoreip", @ignoreips ? join(" ", @ignoreips) : undef, $jail); - &unlock_file($jail->{'file'}); + &unlock_all_files(); } # Log and redirect diff --git a/fail2ban/save_jaildef.cgi b/fail2ban/save_jaildef.cgi index 635984852..e42a06214 100755 --- a/fail2ban/save_jaildef.cgi +++ b/fail2ban/save_jaildef.cgi @@ -30,7 +30,7 @@ foreach my $ip (@ignoreips) { # Update the jail -&lock_file($jail->{'file'}); +&lock_all_files(); foreach my $f ("maxretry", "findtime", "bantime") { &save_directive($f, $in{$f."_def"} ? undef : $in{$f}, $jail); } @@ -40,7 +40,7 @@ foreach my $f ("maxretry", "findtime", "bantime") { $jail); &save_directive("banaction", $in{'banaction'} || undef, $jail); &save_directive("protocol", $in{'protocol'} || undef, $jail); -&unlock_file($jail->{'file'}); +&unlock_all_files(); &webmin_log("jaildef"); &redirect("list_jails.cgi");