0x1949 Team - FAZEMRX - MANAGER
Edit File: gather_update_logs_setupcrontab
#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - scripts/gather_update_logs_setupcrontab # Copyright(c) 2022 cPanel, L.L.C. # All rights Reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited # copying clamav_setupcrontab only because most recent solution is too new: # CPANEL-33654. So next cron added should use that instead, and this code should # be replaced with it after some time. package scripts::gather_update_logs_setupcrontab; =head1 NAME gather_update_logs_setupcrontab =head1 SYNOPSIS gather_update_logs_setupcrontab [ off --help ] =head1 DESCRIPTION This script adds a line to the system cron for the update gatherer script. The optional argument 'off' will remove the line. =cut use lib '/var/cpanel/perl'; use Cpanel::UpdateGatherer::Std; use parent 'Cpanel::HelpfulScript'; use constant _OPTIONS => (); use constant CRONTAB_FILE_PATH => '/etc/cron.d/cpanel-analytics'; use constant { CRONTAB_TYPE_USER => 0, CRONTAB_TYPE_FILE => 1, CRONTAB_TYPE_MAX => 1 }; use Try::Tiny; use Cpanel::ConfigFiles (); use Cpanel::SafeRun::Object (); use Cpanel::Autodie (); use Cpanel::Transaction::File::Raw (); __PACKAGE__->new()->run(@ARGV) if !caller; sub run ( $self, @args ) { my $match = 'gather_update_log_stats'; my $command = "$Cpanel::ConfigFiles::CPANEL_ROOT/scripts/gather_update_log_stats --logfile /var/cpanel/updatelogs/last --upload > /dev/null 2>&1"; my $enable = 1; if ( @args && $args[0] =~ m/^off$/i ) { $enable = 0; } # If there is an entry in root's crontab, mark it for deletion. my $has_match_root = 0; my @crontab_root = get_crontab_root(); foreach my $line (@crontab_root) { next if $line =~ m/^#/; if ( $line =~ m/$match/ ) { $has_match_root = 1; last; } } # Do the same for the file in /etc/cron.d. # FIXME: This is probaby too DRY, but it's also dead simple. my $has_match_file = 0; my @crontab_file = get_crontab_file(CRONTAB_FILE_PATH); foreach my $line (@crontab_file) { next if $line =~ m/^#/; if ( $line =~ m/$match/ ) { $has_match_file = 1; last; } } umask 077; # See SEC-408. my $ex; if ($enable) { if ( !$has_match_file ) { push @crontab_file, generate_crontab_entry( $command, CRONTAB_TYPE_FILE ); try { write_crontab_file(@crontab_file); } catch { $ex = $_; }; } } else { if ($has_match_file) { @crontab_file = remove_crontab_entry( $match, @crontab_file ); try { write_crontab_file(@crontab_file); } catch { $ex = $_; }; } } # Always clean the root crontab entry if things didn't go badly when writing the file. if ( $has_match_root && !defined $ex ) { @crontab_root = remove_crontab_entry( $match, @crontab_root ); try { write_crontab_root(@crontab_root); } catch { $ex = $_; }; } if ($ex) { return 0; } return 1; } sub generate_crontab_entry ( $command, $entry_type = CRONTAB_TYPE_USER ) { die "no command given" if !$command; die "unrecognized entry type" if ( $entry_type < 0 || $entry_type > CRONTAB_TYPE_MAX ); my $rt = int( rand(2.9999999) ); my $hour = int( rand(6) ); my $minute = int( rand(60) ); # With about 1/3rd probability, choose to run between 21:00 and 23:59 instead of 00:00 to 06:59. if ( $rt == 0 ) { $hour = ( 24 - int( rand(4) ) ); } if ( $hour == 24 ) { $hour = 0; } my $entry = "$minute $hour * * * "; # If this is for a crontab file, add the user name before the command. $entry .= "root " if $entry_type == CRONTAB_TYPE_FILE; $entry .= $command; return $entry; } sub remove_crontab_entry ( $match, @crontab ) { return grep( !/$match/, @crontab ) } sub get_crontab_root { my $crontab_sro = Cpanel::SafeRun::Object->new_or_die( 'program' => '/usr/bin/crontab', 'args' => ['-l'], ); my @crontab = split( /\n/, $crontab_sro->stdout() ); return @crontab; } sub get_crontab_file ($path) { my @crontab; local $/; try { Cpanel::Autodie::open( my $fh, '<', $path ); my $contents = <$fh>; @crontab = split( /\n/, $contents ) if defined $contents; close $fh; } catch { my $ex = $_; die $ex unless $ex->error_name() eq 'ENOENT'; }; return @crontab; } sub write_crontab_root (@crontab) { Cpanel::Autodie::open( my $cron_in, '>', '/scripts/.crontab' ); foreach my $line (@crontab) { Cpanel::Autodie::print( $cron_in, $line . "\n" ); } close $cron_in; system 'crontab', '/scripts/.crontab'; unlink '/scripts/.crontab'; return 1; } sub write_crontab_file (@crontab) { my $contents = join( "\n", @crontab ) . "\n"; my $txn = Cpanel::Transaction::File::Raw->new( 'path' => CRONTAB_FILE_PATH, 'ownership' => [ 0, 0 ], 'permissions' => 0600, ); $txn->set_data( \$contents ); $txn->save_and_close_or_die(); return 1; } 1;