File: //proc/self/root/scripts.20110531.215904.25158/RestartSrv.pm
#!/usr/bin/perl
# cpanel - RestartSrv.pm Copyright(c) 2010 cPanel, Inc.
# All rights Reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
BEGIN { unshift @INC, '/usr/local/cpanel'; }
use strict;
use IPC::Open2 ();
use Cpanel::CleanupStub ();
use Cpanel::Config::LoadCpConf ();
use Cpanel::AccessIds ();
use Cpanel::FileUtils::TouchFile ();
use Cpanel::Proc ();
use Cpanel::Services ();
eval {
local $SIG{'__DIE__'};
require Storable;
}; #for loadcpconf
$ENV{'RESTARTSRV'} = 1;
my $restartsrvlog = '/var/log/restartsrv_err.log';
sub loadcpconfig {
goto &Cpanel::Config::LoadCpConf::loadcpconf;
}
sub setuppath {
my @PDIRS = ( '/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin' );
my @EPDIRS;
foreach my $pdir (@PDIRS) {
next if !-e $pdir;
push @EPDIRS, $pdir;
}
$ENV{'PATH'} = join( ':', @EPDIRS );
}
sub parseargv {
my $restart = 1;
my $check = 0;
my $status = 0;
my $verbose = 0;
while ( $#ARGV != -1 ) {
$_ = $ARGV[0];
if (/^\-\-/) {
my $arg = shift(@ARGV);
$arg =~ s/^\-\-//g;
$arg =~ tr/[A-Z]/[a-z]/;
if ( $arg eq 'status' ) { $status = 1; $restart = 0; }
if ( $arg eq 'check' ) { $check = 1; $restart = 0; }
if ( $arg eq 'verbose' ) { $verbose = 1; }
if ( $arg eq 'stop' ) { $restart = -1; }
}
else {
last;
}
}
return ( $restart, $check, $status, $verbose );
}
sub getinitfile {
my ( $service, $system ) = @_;
my $strtscript;
my @initdirarray;
if ( $system =~ m/Linux/i ) {
push @initdirarray, '/etc/init.d';
if ( -d '/etc/rc.d/init.d' && !-l '/etc/rc.d/init.d' ) {
push @initdirarray, '/etc/rc.d/init.d';
}
}
else {
return if $service eq 'named'; # Kludge because we don't have a valid init script on FreeBSD
push @initdirarray, '/usr/local/etc/rc.d', '/etc/rc.d';
}
foreach my $initdir (@initdirarray) {
my @initfiles;
if ( opendir my $dh, $initdir ) {
@initfiles = readdir $dh;
closedir $dh;
}
my $partial_match;
my $numeric_match;
foreach my $strtscript (@initfiles) {
next if $strtscript =~ m/^\./;
next if $strtscript =~ m/\.rpm[a-z]+$/; # expanded match for .rpmorig, etc.
next if !-f $initdir . '/' . $strtscript;
if ( -x _ ) {
if ( lc $strtscript eq lc $service ) {
return "$initdir/$strtscript";
}
elsif ( !$partial_match && $strtscript =~ m/^\Q$service\E/i ) {
$partial_match = $strtscript;
}
elsif ( !$numeric_match && $strtscript =~ m/^[\d\.]+\Q$service\E/i ) {
$numeric_match = $strtscript;
}
}
}
if ($partial_match) {
return "$initdir/$partial_match";
}
if ($numeric_match) {
return "$initdir/$numeric_match";
}
}
return;
}
sub getmanualserviceinfo {
my ( $system, $service, $notrequired ) = @_;
my $servicebin = '';
my $serviceflags = '';
my $serviceenable = '';
if ( $system =~ /freebsd/i ) {
if ( $service eq 'pure-ftpd' ) { $service = 'pureftpd'; }
my (@CF) = ( "/etc/defaults/rc.conf", "/etc/rc.conf" );
foreach my $file (@CF) {
open( RCC, "<", $file );
while (<RCC>) {
if (/^[\s\t]*${service}_program=[\"\']([^\"\']+)/) {
$servicebin = $1;
}
if (/^[\s\t]*${service}_enable=[\"\']([^\"\']+)/) {
$serviceenable = $1;
}
if (/^[\s\t]*${service}_flags=[\"\']([^\"\']+)/) {
$serviceflags = $1;
}
}
close(RCC);
}
if ( $servicebin eq '' ) {
if ( $notrequired != 1 ) {
if ( $service =~ /inet/i ) {
open( RSTRTLG, '>>', $restartsrvlog );
print RSTRTLG "$service information could not be found. Starting inetd instead.";
close(RSTRTLG);
}
else {
die "Sorry, $service information could not be found.";
}
}
}
}
else {
if ( !$ENV{'RSINSTALL'}
&& !-e "/var/cpanel/restartsrv-install/$service" ) {
if ( !-e '/var/cpanel/restartsrv-install' ) {
mkdir( '/var/cpanel/restartsrv-install', 0700 );
}
open( SI, '>', "/var/cpanel/restartsrv-install/$service" );
close(SI);
print "Warning: service restart called for a service that may\n";
print "not be installed. Install is now being attempted!\n";
system( '/scripts/ensurerpm', $service );
$ENV{'RSINSTALL'} = 1;
if ( -e "/scripts/restartsrv_$service" ) {
exec "/scripts/restartsrv_$service";
exit;
}
else {
die "I don't know how to start $service";
}
}
else {
die "I don't know how to start $service";
}
}
return ( $servicebin, $serviceflags, $serviceenable );
}
sub find_pureftpd_service {
my ( $service, $servicebin, $processowner, $disabled ) = ( 'pure-ftpd', '', 'root', 0 );
my @ftpbinaries = qw( /usr/sbin/pure-ftpd /usr/local/sbin/pure-ftpd );
foreach my $ftpbin (@ftpbinaries) {
if ( -x $ftpbin ) {
if ( -e '/etc/' . $service . 'disable' ) { $disabled = 1; }
$servicebin = $ftpbin;
last;
}
}
return ( $service, $servicebin, $processowner, $disabled );
}
sub find_proftpd_service {
my ( $service, $servicebin, $processowner, $disabled ) = ( 'proftpd', '', 'nobody', 0 );
my @ftpbinaries = qw( /usr/sbin/proftpd /usr/local/sbin/proftpd /usr/local/libexec/proftpd );
foreach my $ftpbin (@ftpbinaries) {
if ( -x $ftpbin ) {
if ( -e '/etc/' . $service . 'disable' ) { $disabled = 1; }
$servicebin = $ftpbin;
}
}
return ( $service, $servicebin, $processowner, $disabled );
}
sub servicefixup {
my ( $system, $service ) = @_;
my $processowner = 'root';
my $iscript = '';
my $manualstart = 0;
my $servicebin = '';
my $serviceflags = '';
my $disabled = 0;
if ( -e '/var/cpanel/brokenfutex' ) {
$ENV{'LD_ASSUME_KERNEL'} = '2.4.1';
}
if ( $service eq 'ftpserver' || $service eq 'ftpd' ) {
if ( -e '/etc/ftpserverdisable'
|| -e '/etc/ftpddisable' ) {
$disabled = 1;
}
my $cpconf_ref = Cpanel::Config::LoadCpConf::loadcpconf();
my $selected_ftpserver = $cpconf_ref->{'ftpserver'} ? $cpconf_ref->{'ftpserver'} : ''; # localize setting to prevent warnings
if ( $selected_ftpserver eq 'disabled' ) {
$disabled = 1;
}
# Attempt ftpd server lookup based upon the selected server
if ( $selected_ftpserver eq 'pure-ftpd' ) {
my ( $ftpd_service, $ftpd_bin, $ftpd_owner, $ftpd_disabled ) = find_pureftpd_service();
if ($ftpd_bin) {
$service = $ftpd_service;
$servicebin = $ftpd_bin;
$processowner = $ftpd_owner;
if ( !$disabled ) {
$disabled = $ftpd_disabled;
}
}
}
elsif ( $selected_ftpserver eq 'proftpd' ) {
my ( $ftpd_service, $ftpd_bin, $ftpd_owner, $ftpd_disabled ) = find_proftpd_service();
if ($ftpd_bin) {
$service = $ftpd_service;
$servicebin = $ftpd_bin;
$processowner = $ftpd_owner;
if ( !$disabled ) {
$disabled = $ftpd_disabled;
}
}
}
# Handle the condition where the service may be disabled or the desired
# ftpd server is not installed
if ( !$servicebin ) {
if ( $selected_ftpserver ne 'pure-ftpd' ) {
my ( $ftpd_service, $ftpd_bin, $ftpd_owner, $ftpd_disabled ) = find_pureftpd_service();
if ($ftpd_bin) {
$service = $ftpd_service;
$servicebin = $ftpd_bin;
$processowner = $ftpd_owner;
if ( !$disabled ) {
$disabled = $ftpd_disabled;
}
}
}
if ( !$servicebin && $selected_ftpserver ne 'proftpd' ) {
my ( $ftpd_service, $ftpd_bin, $ftpd_owner, $ftpd_disabled ) = find_proftpd_service();
if ($ftpd_bin) {
$service = $ftpd_service;
$servicebin = $ftpd_bin;
$processowner = $ftpd_owner;
if ( !$disabled ) {
$disabled = $ftpd_disabled;
}
}
}
}
if ( $servicebin eq '' ) {
die "Ftp server is not installed. Exiting.";
}
$iscript = getinitfile( $service, $system );
if ( $iscript eq '' ) {
$manualstart = 1;
}
if ( $manualstart == 0 ) {
$manualstart = &needsmanualstart( $system, $service );
}
if ( $manualstart && $servicebin =~ m/pure/i && $system =~ m/freebsd/i ) {
$servicebin = '/usr/local/sbin/pure-config.pl';
$serviceflags = '/usr/local/etc/pure-ftpd.conf';
}
}
elsif ( $service eq 'syslog' ) {
if ( -e '/etc/syslogdisable' || -e '/etc/syslogddisable' ) {
$disabled = 1;
}
if ( $system =~ /freebsd/i ) {
$service = 'syslogd';
}
if ( -e '/etc/gentoo-release' ) {
$service = 'syslogd';
$processowner = 'root';
$iscript = getinitfile( 'sysklogd', $system );
}
if ( !$iscript ) {
$iscript = getinitfile( $service, $system );
}
if ( $iscript eq '' ) {
( $servicebin, $serviceflags ) = getmanualserviceinfo( $system, $service );
$manualstart = 1;
}
if ( $manualstart == 0 ) {
$manualstart = &needsmanualstart( $system, $service );
}
if ( -e '/etc/trustix-release' && getpwnam('syslog') ) {
$processowner = 'syslog';
}
}
elsif ( $service eq 'rsyslog' ) {
if ( -e '/etc/rsyslogdisable' || -e '/etc/rsyslogddisable' ) {
$disabled = 1;
}
if ( !$iscript ) {
$iscript = getinitfile( $service, $system );
}
if ( $iscript eq '' ) {
( $servicebin, $serviceflags ) = getmanualserviceinfo( $system, $service );
$manualstart = 1;
}
if ( $manualstart == 0 ) {
$manualstart = &needsmanualstart( $system, $service );
}
}
elsif ( $service eq 'inetd' ) {
if ( -e '/etc/inetddisable' || -e '/etc/xinetddisable' ) {
$disabled = 1;
}
if ( $system =~ /freebsd/i ) {
my $xinetdenable = 0;
my @CF = qw( /etc/defaults/rc.conf /etc/rc.conf );
foreach my $file (@CF) {
open( RCC, '<', $file );
while (<RCC>) {
if (/^[\s\t]*inetd_program=\"([^\"]+)\"/) {
$servicebin = $1;
if ( !-x $servicebin ) {
#If the bin in not executable use inetd
$manualstart = 1;
}
}
if (/^[\s\t]*xinetd_enable=\"(yes|true|1)\"/i) {
$xinetdenable = 1;
}
}
close(RCC);
}
if ( ( $servicebin =~ /xinetd$/i || $xinetdenable == 1 )
&& -e '/etc/xinetd.conf' ) {
$service = 'xinetd';
$iscript = getinitfile( $service, $system );
if ( $iscript ne '' && $xinetdenable == 0 ) {
$manualstart = 1;
}
else {
$servicebin = 'usexinetd';
}
}
else {
# Unless xinetd is properly configured, use inetd
$manualstart = 1;
}
if ( $servicebin eq '' || $manualstart == 1 ) {
$service = 'inetd';
$servicebin = '/usr/sbin/inetd';
$serviceflags = '-wW';
$manualstart = 1;
}
}
else {
$service = 'xinetd';
$iscript = getinitfile( $service, $system );
}
}
elsif ( $service eq 'postgresql' ) {
if ( -e '/etc/postgresqldisable'
|| -e '/etc/postgresdisable'
|| -e '/etc/postmasterdisable' ) {
$disabled = 1;
}
# Get init script while service is stil postgresql
$iscript = getinitfile( $service, $system );
if ( $system =~ /freebsd/i ) {
$service = 'postgres';
}
else {
$service = 'postmaster';
}
if ( -d '/var/lib/pgsql/data' ) {
if ( !-e "/var/lib/pgsql/data/PG_VERSION"
&& !-e "/var/lib/pgsql/data/base"
&& !-e "/var/lib/pgsql/data/global"
&& -e "/usr/bin/initdb" ) {
print 'Postgres database is not initialized...initializing it...';
open( PGA, '<', '/var/lib/pgsql/data/pg_hba.conf' );
my @PGA = <PGA>;
close(PGA);
unlink('/var/lib/pgsql/data/pg_hba.conf');
unlink('/var/lib/pgsql/data/pg_hbc.conf');
my $pg_user = 'pgsql';
if ( getpwnam('postgres') ) {
$pg_user = 'postgres';
}
system( 'su', '-l', $pg_user, '-c', '/usr/bin/initdb' );
open( PGA, '>', '/var/lib/pgsql/data/pg_hba.conf' );
foreach (@PGA) { print PGA; }
close(PGA);
print "Done\n";
}
}
if ( $system =~ /freebsd/i ) {
$processowner = 'pgsql';
}
else {
$processowner = 'postgres';
}
if ( $iscript eq '' ) {
$manualstart = 1;
}
}
elsif ( $service eq 'named' || $service eq 'nsd' ) {
if ( -e '/etc/nameddisable'
|| -e '/etc/binddisable'
|| -e '/etc/dnsdisable' ) {
$disabled = 1;
}
if ( $system =~ /freebsd/i ) {
$processowner = 'bind';
if ( $service eq 'named' ) {
( $servicebin, $serviceflags ) = getmanualserviceinfo( $system, $service );
$manualstart = &needsmanualstart( $system, $service );
}
}
else {
$processowner = 'named';
}
$iscript = getinitfile( $service, $system );
if ( $iscript eq '' ) {
$manualstart = 1;
}
}
return ( $processowner, $service, $iscript, $manualstart, $servicebin, $serviceflags, $disabled );
}
sub getspamdopts {
my $cpspamdconf = '/etc/cpspamd.conf';
my $spamdoptions = '';
my $socketpath = '';
my $allowedips = '--allowed-ips=127.0.0.1';
my $maxconnperchild = '';
my $maxchildren = '--max-children=5';
my $maxspare = '';
my $pidfile = '--pidfile=/var/run/spamd.pid';
my $localonly = '';
my $timeouttcp = '';
my $timeoutchild = '';
if ( -e $cpspamdconf ) {
open( SPAMD, "<", $cpspamdconf );
while (<SPAMD>) {
if ( !(/^[\s\t]*$/) && !(/^[\s\t]*\#.*$/) ) {
chomp();
my ( $option, $value ) = split( '=', $_ );
next if ( !defined $value || $value eq '' );
if ( $option eq 'allowedips' ) {
$allowedips = "--allowed-ips=${value}";
}
elsif ( $option eq 'socketpath' ) {
$socketpath = "--socketpath=${value}";
}
elsif ( $option eq 'maxconnperchild' ) {
$maxconnperchild = "--max-conn-per-child=${value}";
}
elsif ( $option eq 'maxspare' ) {
$maxspare = "--max-spare=${value}";
}
elsif ( $option eq 'maxchildren' ) {
$maxchildren = "--max-children=${value}";
}
elsif ( $option eq 'pidfile' ) {
$pidfile = "--pidfile=${value}";
}
elsif ( $option eq 'local' ) {
$localonly = '--local';
}
elsif ( $option eq 'timeouttcp' ) {
$timeouttcp = "--timeout-tcp=${value}";
}
elsif ( $option eq 'timeoutchild' ) {
$timeoutchild = "--timeout-child=${value}";
}
}
}
}
close(SPAMD);
$spamdoptions = $localonly . ' ' . $timeoutchild . ' ' . $timeouttcp . ' ' . ( $socketpath ? $socketpath : $allowedips ) . ' ' . $maxconnperchild . ' ' . $pidfile . ' ' . $maxchildren . ' ' . $maxspare;
return $spamdoptions;
}
sub spamdcheck {
my $spamdstat = 0;
my $raw_out;
my $opt = getspamdopts();
if ( !-x '/usr/bin/spamc' ) { return $spamdstat; }
local $SIG{'ALRM'} = sub { die 'timeout' };
_check_cpanel_spamassasin_dir();
eval {
my $pid;
# spamc aborts connection after 600 seconds by default
alarm(620);
if ( $opt =~ /--socketpath=(\S+)/ ) {
$pid = IPC::Open2::open2( \*RDRFH, \*WTRFH, '/usr/bin/spamc', '-u','cpanel','-U', $1 );
}
else {
$pid = IPC::Open2::open2( \*RDRFH, \*WTRFH, '/usr/bin/spamc','-u','cpanel' );
}
print WTRFH <<'EOM';
Subject: Test spam mail (GTUBE)
Message-ID: <GTUBE1.1010101@example.net>
Date: Wed, 23 Jul 2003 23:30:00 +0200
From: Sender <sender@example.net>
To: Recipient <recipient@example.net>
Precedence: junk
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
This is the GTUBE, the
Generic
Test for
Unsolicited
Bulk
Email
If your spam filter supports it, the GTUBE provides a test by which you
can verify that the filter is installed correctly and is detecting incoming
spam. You can send yourself a test mail containing the following string of
characters (in upper case and with no white spaces and line breaks):
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
You should send this test mail from an account outside of your network.
EOM
# Close the write file handle
close(WTRFH);
# Process command output
while (<RDRFH>) {
$raw_out .= $_;
if (/X-Spam-Status\: Yes/) {
$spamdstat = 1;
}
}
# Close the read file handle
close(RDRFH);
waitpid( $pid, 0 );
alarm(0);
};
if ($@) {
unless ( $@ =~ /timeout/ ) {
alarm(0);
die;
}
}
return($spamdstat,$raw_out) if wantarray;
return $spamdstat;
}
sub postgresqlfixup {
my ($system) = @_;
my $postmaster = '';
my $pgctl = '';
my $pgsqldir = '';
if ( -x '/usr/bin/pg_ctl' ) {
$pgctl = '/usr/bin/pg_ctl';
}
else {
$pgctl = '/usr/local/bin/pg_ctl';
}
if ( -e '/var/lib/pgsql/data' ) {
$pgsqldir = '/var/lib/pgsql/data';
}
else {
$pgsqldir = '/usr/local/pgsql/data';
}
return ( $pgctl, $pgsqldir );
}
sub setuids {
goto &Cpanel::AccessIds::setuids;
}
sub runasuser {
goto &Cpanel::AccessIds::runasuser;
}
sub doomedprocess {
goto &Cpanel::Proc::doom;
}
sub nooutputsystem {
my (@unsafecmd) = @_;
my (@cmd);
while ( $unsafecmd[$#unsafecmd] eq '' ) { pop(@unsafecmd); }
foreach (@unsafecmd) {
my @cmds = split( / /, $_ );
foreach (@cmds) { push( @cmd, $_ ); }
}
my $pid;
if ( $pid = fork() ) {
#master
}
else {
# Cheap way of doing setsid() without bringing in POSIX
setpgrp(0,0);
Cpanel::CleanupStub::closefds();
open( STDIN, '<', '/dev/null' );
open( STDOUT, '>', '/dev/null' );
open( STDERR, '>', '/dev/null' );
exec(@cmd);
exit;
}
waitpid( $pid, 0 );
}
sub check_service {
goto &Cpanel::Services::check_service;
}
sub needsmanualstart {
my ( $system, $service ) = @_;
my $manualstart = 0;
if ( $system =~ /freebsd/i ) {
my ( $servicebin, $serviceflags, $serviceenable ) = getmanualserviceinfo( $system, $service, 1 );
if ( $serviceenable =~ /no/i
|| $serviceenable =~ /false/i
|| $serviceenable =~ /0/
|| $serviceenable eq "" ) {
if ( $service eq 'pure-ftpd' ) { $service = 'pureftpd'; }
open( RSTRTLG, '>>', $restartsrvlog );
print RSTRTLG "Warning: Service Restart requested for a service that is disabled!\n";
print RSTRTLG "Please add the following line to /etc/rc.conf: \n";
print RSTRTLG "${service}_enable=\"YES\"\n";
print RSTRTLG "$service will be started manually!\n";
close(RSTRTLG);
$manualstart = 1;
}
}
return ($manualstart);
}
sub find_mysqladmin {
my ( @LOC, $loc );
@LOC = ( '/usr/bin/mysqladmin', '/usr/local/bin/mysqladmin' );
foreach $loc (@LOC) {
if ( -e $loc ) { return $loc; }
}
}
sub lock_file {
my $lock_file = shift;
if ( -e $lock_file ) {
my $mtime = ( stat($lock_file) )[9];
my $now = time;
my $diff = $now - $mtime;
if ( $diff < ( 60 * 3 ) ) {
exit;
}
}
Cpanel::FileUtils::TouchFile::touchfile($lock_file);
}
sub _check_cpanel_spamassasin_dir {
if (! -e '/usr/local/cpanel/.spamassassin') {
mkdir '/usr/local/cpanel/.spamassassin',0700;
}
require Cpanel::PwCache;
my @cpanel_pw = Cpanel::PwCache::getpwnam('cpanel');
if ($cpanel_pw[0]) {
chown $cpanel_pw[2],$cpanel_pw[3],'/usr/local/cpanel/.spamassassin';
}
}
1;