* The script needs to run with root permissions in order to do the ipset operations. So remove code to drop the permissions on startup.
* Adjust execute calls to use the proper functions from general functions.
* Add some code to set the correct ownership (nobody:nobody) for changed files during script runtime.
Fixes #13072.
Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org --- config/cfgroot/ipblocklist-functions.pl | 27 ++++++++++++++++++++++++ src/scripts/update-ipblocklists | 28 +++++++++++-------------- 2 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/config/cfgroot/ipblocklist-functions.pl b/config/cfgroot/ipblocklist-functions.pl index ecabf42e8..bd026a01d 100644 --- a/config/cfgroot/ipblocklist-functions.pl +++ b/config/cfgroot/ipblocklist-functions.pl @@ -383,4 +383,31 @@ sub get_holdoff_rate($) { return $value; }
+# +## sub set_ownership(file) +## +## Function to set the correct ownership (nobody:nobody) to a given file. +## +# +sub set_ownership($) { + my ($file) = @_; + + # User and group of the WUI. + my $uname = "nobody"; + my $grname = "nobody"; + + # The chown function implemented in perl requies the user and group as nummeric id's. + my $uid = getpwnam($uname); + my $gid = getgrnam($grname); + + # Check if the given file exists. + unless ($file) { + # Stop the script and print error message. + die "The given $file does not exist. Cannot change the ownership!\n"; + } + + # Change ownership of the file. + chown($uid, $gid, "$file"); +} + 1; diff --git a/src/scripts/update-ipblocklists b/src/scripts/update-ipblocklists index 9918cac41..a17b47999 100644 --- a/src/scripts/update-ipblocklists +++ b/src/scripts/update-ipblocklists @@ -32,19 +32,6 @@ require "${General::swroot}/lang.pl"; # Hash to store the settings. my %settings = ();
-# The user and group name as which this script should be run. -my $run_as = 'nobody'; - -# Get user and group id of the user. -my ( $uid, $gid ) = ( getpwnam $run_as )[ 2, 3 ]; - -# Check if the script currently runs as root. -if ( $> == 0 ) { - # Drop privileges and switch to the specified user and group. - POSIX::setgid( $gid ); - POSIX::setuid( $uid ); -} - # Establish the connection to the syslog service. openlog('ipblocklist', 'cons', 'user');
@@ -122,6 +109,12 @@ foreach my $blocklist (@blocklists) { &_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Unexpected error!"); } } else { + # Get the filename of the blocklist. + my $ipset_db_file = &IPblocklist::get_ipset_db_file($blocklist); + + # Set the correct ownership. + &IPblocklist::set_ownership($ipset_db_file); + # Log successfull update. &_log_to_syslog("<INFO> Successfully updated $blocklist blocklist.");
@@ -132,22 +125,25 @@ foreach my $blocklist (@blocklists) {
# Check if a blocklist has been updated and therefore needs to be reloaded. if (@updated_blocklists) { + # Set correct ownership to the modified file. + &IPblocklist::set_ownership($IPblocklist::modified_file); + # Loop through the array. foreach my $updated_blocklist (@updated_blocklists) { # Get the blocklist file. my $ipset_db_file = &IPblocklist::get_ipset_db_file($updated_blocklist);
# Call safe system function to reload/update the blocklist. - &General::system("ipset", "restore", "-f", "$ipset_db_file"); + &General::safe_system("ipset", "restore", "-f", "$ipset_db_file");
# The set name contains a "v4" as suffix. my $set_name = "$updated_blocklist" . "v4";
# Swap the sets to use the new one. - &General::system("ipset", "swap", "$set_name", "$updated_blocklist"); + &General::safe_system("ipset", "swap", "$set_name", "$updated_blocklist");
# Destroy the old blocklist. - &General::system("ipset", "destroy", "$set_name"); + &General::safe_system("ipset", "destroy", "$set_name"); } }