File: //proc/self/root/scripts.20110531.215904.25158/eximup
#!/usr/bin/perl
# cpanel - eximup 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', '/scripts'; }
use strict;
use Cpanel::Exim ();
use Cpanel::NSCD ();
use Cpanel::RpmStor;
use Cpanel::SafeRun;
use Cpanel::RpmUtils;
use Cpanel::Hostname ();
use Cpanel::Config ();
use Cpanel::HttpRequest;
use Cpanel::Update ();
use Cpanel::SysPkgs ();
use Cpanel::Sys::OS ();
use Cpanel::OSSys ();
use Fcntl ();
use cPpkgversions;
use IPC::Open3;
use Cpanel::OSSys ();
Cpanel::Update::safe_update_environment('exim');
Cpanel::Update::init_UP_update('exim');
my $httpClient = Cpanel::HttpRequest->new( 'hideOutput' => 0 );
my ( $system, $release, $machine ) = ( Cpanel::OSSys::uname() )[ 0, 2, 4 ];
my $cpargs = '-af';
if ( $system =~ /freebsd/i ) {
$cpargs = '-Rpf';
}
my %CPCONF = Cpanel::Config::loadcpconf();
my $now = time();
my $hostname = Cpanel::Hostname::gethostname();
my $add;
if ( $CPCONF{'maildir'} ) {
$add = '(maildir) ';
}
print "Exim ${add}Setup Script Version 20.0\n";
my $latest = 0;
my $src = 0;
my $force = ( -x '/usr/sbin/sendmail' && -e '/etc/exim.pl' ) ? 0 : 1;
my $exim_bin = _find_exim_bin();
if ($exim_bin) {
my $ldd_results = `ldd $exim_bin`;
if ( $ldd_results =~ m/not\s+found/im ) {
$force = 1;
}
}
else {
$force = 1;
}
if ( grep( /force/, @ARGV ) ) { $force = 1; }
if ( grep( /source/, @ARGV ) ) { $src = 1; }
if ( grep( /latest/, @ARGV ) ) { $latest = 1; }
my $basedir = 'exim';
my $xdir = '';
if ( -e '/etc/valiases/' . $hostname ) {
unlink '/etc/valiases/' . $hostname;
}
if ( -e '/etc/gentoo-release' ) {
my $syspkgobj = Cpanel::SysPkgs->new();
if ( !$syspkgobj ) { die print "Could not create SysPkgs object\n"; }
my @pkgs = ('exim');
$syspkgobj->install( 'pkglist' => \@pkgs );
system( '/scripts/installcpbsdpkg', 'exim' );
system( '/scripts/restartsrv', 'exim' );
exit();
}
if ( $system =~ /freebsd/i ) {
system("/scripts/checkmakeconf");
if ($force) {
unlink("/var/cpanel/lastportsup");
}
system("/scripts/portsup");
my $pkg = 'exim';
if ( -x "/scripts/preeximup" ) {
system("/scripts/preeximup");
}
my $result;
my (@GS) = ( '/scripts/ensurepkg', '--keepnew', $pkg );
if ($force) {
@GS = ( '/scripts/ensurepkg', '--force', $pkg );
}
open( RNULL, "<", "/dev/null" );
open3( "<&RNULL", \*INS, \*INS, @GS );
while (<INS>) {
print;
$result .= $_;
}
close(INS);
close(RNULL);
my $needres = 0;
if ( $result !~ /(^|(?<!Checking if)\s)\s*\S*${pkg}.*\salready\s+installed/m
&& $result !~ /${pkg}.*\sis\s+installed/m
&& $result !~ /${pkg}.*\sis\s+newer/m ) {
$needres = 1;
}
if ($needres) {
system( '/scripts/restartsrv', 'exim' );
}
if ( $CPCONF{'maildir'} eq '1' ) {
system( '/scripts/installcpbsdpkg', 'exim-maildir' );
}
else {
system( '/scripts/installcpbsdpkg', 'exim' );
}
if ( -x "/scripts/posteximup" ) {
system("/scripts/posteximup");
}
exit;
}
my %VINFO = cPpkgversions::getpkgversioninfo('exim');
my $pkgname = 'exim4';
if ( $CPCONF{'maildir'} eq '1' ) {
$pkgname .= '-maildir';
}
my $ises;
my $buildnum = $VINFO{$pkgname}{'release'};
my $eximver = $VINFO{$pkgname}{'version'};
my $bsv = $VINFO{$pkgname}{'flags'};
my $arch = 'i386';
my $distro;
my $version;
if ( -e "/etc/trustix-release" ) {
$distro = 'trustix';
($version) = Cpanel::Sys::OS::getversionfromfile('/etc/trustix-release');
$arch = 'i586';
}
elsif ( -e "/etc/caos-release" ) {
$distro = 'caos';
($version) = Cpanel::Sys::OS::getversionfromfile('/etc/caos-release');
}
elsif ( -e "/etc/SuSE-release" ) {
$distro = 'suse';
($version) = Cpanel::Sys::OS::getversionfromfile('/etc/SuSE-release');
if ( $version >= 9 ) { $arch = 'i586'; }
}
elsif ( -e "/etc/fedora-release" ) {
$distro = 'fedora';
($version) = Cpanel::Sys::OS::getversionfromfile('/etc/fedora-release');
}
elsif ( -e "/etc/mandrake-release" ) {
$distro = 'mandrake';
($version) = Cpanel::Sys::OS::getversionfromfile('/etc/mandrake-release');
$arch = 'i586';
}
elsif ( -e "/etc/whitebox-release" ) {
$distro = 'whitebox';
($version) = Cpanel::Sys::OS::getversionfromfile('/etc/whitebox-release');
}
elsif ( -e "/etc/redhat-release" ) {
$distro = 'redhat';
( $version, $ises ) = Cpanel::Sys::OS::getversionfromfile('/etc/redhat-release');
}
if ( $ises == 1 ) {
$version = "AS-${version}";
}
if ( $ises == 2 ) {
$distro = "centos";
}
if ( $ises == 3 ) {
$distro = "whitebox";
}
if ( $machine =~ /64/ ) {
$arch = 'x86_64';
$xdir .= "/64";
}
my $cver = Cpanel::SafeRun::saferunnoerror( "rpm", "-q", "exim" );
chomp($cver);
print "This is the exim $eximver installer release number ${buildnum} for platform ${distro} ${version}\n";
if ( $cver eq "exim-${eximver}-${buildnum}_${bsv}" && !$force && -e "/etc/exim.pl" ) {
if ( !-e '/usr/sbin/sendmail' ) {
$force = 1;
}
else {
print "exim is up to date. Use eximup --force to force a reinstall\n";
exit();
}
}
if ( -x "/scripts/preeximup" ) {
system("/scripts/preeximup");
}
mkdir '/home/exim4-install', 0700;
chdir '/home/exim4-install';
my $syspkgobj = Cpanel::SysPkgs->new();
if ( !$syspkgobj ) { die print "Could not create SysPkgs object\n"; }
my @pkgs = ( 'libdb3.3-devel', 'db4-devel', 'pam-devel', 'openssl', 'openssl-devel', 'gcc', 'glibc-devel', 'compat-db', 'zlib-devel', 'rpm-build' );
$syspkgobj->install( 'pkglist' => \@pkgs );
system '/scripts/checklibssl';
print "Resetting Exim to cPanel Defaults and Installing the Latest Version\n";
system '/scripts/mseclocal';
my @STRIPCHATTR = ( '/etc/rc.d/init.d/exim', '/etc/exim.conf', '/etc/exim.pl', '/usr/sbin/sendmail', '/usr/lib/sendmail' );
foreach my $file (@STRIPCHATTR) {
Cpanel::SafeRun::saferunnoerror( "chattr", "-i", $file );
}
system '/scripts/killspamkeys';
system '/scripts/installspam';
my (@RESETFILES) = ( '/etc/localdomains', '/etc/aliases', '/etc/secondarymx' );
foreach my $file (@RESETFILES) {
system 'cp', $cpargs, $file, $file . '.eximreset.' . $now;
}
my $url = "http://diff.cpanel.net/${basedir}/${eximver}-${buildnum}${xdir}/${distro}/${version}/exim-${eximver}-${buildnum}_${bsv}.${arch}.rpm";
my @SLA = split( /\//, $url );
my $file = $SLA[$#SLA];
die "File $file is not valid" if ( $file eq "" );
if ( !$src ) {
$httpClient->download( $url, $file );
if ( ( stat($file) )[7] <= 0 ) {
print "Failed to download $url .. using source instead\n";
$latest = 1;
$src = 1;
}
}
if ($src) {
# $buildnum = '80';
# $eximver = '4.42';
$file = buildrpm();
if ( $file eq '' ) {
die "Rpm failed to build!";
}
}
if ( ( stat($file) )[7] <= 0 ) {
die "Failed to download or build rpm from $url ($file)";
}
if ( !Cpanel::RpmUtils::checkrpm($file) ) {
die "$file is not a valid rpm file";
}
$ENV{'RPMINSTALL'} = 1;
Cpanel::RpmUtils::rpmpreinstall($file);
# Prepare for rpm installation
rename '/etc/exim.pl', '/etc/exim.pl.rpmpreinstall';
unlink '/usr/share/amavis/amavis-filter';
unlink '/etc/antivirus.exim';
# Preserve Certificate files, but keep valid files in place.
unlink '/etc/exim.crt.preinstall';
rename '/etc/exim.crt', '/etc/exim.crt.preinstall';
system 'cp', $cpargs, '/etc/exim.crt.preinstall', '/etc/exim.crt';
unlink '/etc/exim.key.preinstall';
rename '/etc/exim.key', '/etc/exim.key.preinstall';
system 'cp', $cpargs, '/etc/exim.key.preinstall', '/etc/exim.key';
# Install rpm
# Instruct RPM that we will run /scripts/mailperm in eximup
$ENV{'DONT_RUN_MAILPERM'} = 1;
system( 'rpm', '-Uvh', '--nodeps', '--force', $file );
$ENV{'DONT_RUN_MAILPERM'} = 0;
# When RPM db is corrupt, exim.pl is not reinstalled.
if ( !-e '/etc/exim.pl' ) {
if ( -e '/etc/exim.pl.rpmpreinstall' ) {
rename '/etc/exim.pl.rpmpreinstall', '/etc/exim.pl';
}
}
else {
unlink '/etc/exim.pl.rpmpreinstall';
}
# Install latest antirelayd
if ( -e '/usr/local/cpanel/src/antirelayd' ) {
print 'Installing latest version of antirelayd ... ';
system 'cp', '-f', '/usr/local/cpanel/src/antirelayd', '/usr/sbin/antirelayd';
system 'chmod', '755', '/usr/sbin/antirelayd';
print "Done\n";
}
# Restore original certificate files
if ( -e '/etc/exim.crt.preinstall' ) {
unlink '/etc/exim.crt';
rename '/etc/exim.crt.preinstall', '/etc/exim.crt';
}
if ( -e '/etc/exim.key.preinstall' ) {
unlink '/etc/exim.key';
rename '/etc/exim.key.preinstall', '/etc/exim.key';
}
$ENV{'RPMINSTALL'} = 0;
chdir '/';
if ( -e '/home/exim4-install' ) {
system 'rm', '-rf', '/home/exim4-install';
}
buildeximcrt();
foreach my $file (@RESETFILES) {
next if ( !-e "${file}.eximreset.${now}" );
system( 'cp', $cpargs, "${file}.eximreset.${now}", $file );
unlink("${file}.eximreset.${now}");
}
system( 'chown', '-R', 'mailnull:mail', '/var/spool/exim' );
system( 'chown', 'mailnull:mail', '/etc/exim.crt' );
system( 'chown', 'mailnull:mail', '/etc/exim.key' );
if ( -e '/var/log/exim_mainlog' ) {
system('chmod 640 /var/log/exim_*');
system('chown mailnull:mail /var/log/exim_*');
}
if ( !-e '/etc/exim.conf' ) {
print 'Building exim.conf ... ';
system('/scripts/buildeximconf');
print "Done\n";
}
system( 'killall', '-TERM', 'exim' );
sleep(2);
system( 'killall', '-TERM', 'exim' );
system( '/scripts/restartsrv', 'exim' );
system('rm -f /var/spool/exim/db/*.lock* 2>/dev/null');
my (@EXIMDBS) = ( 'retry', 'wait-remote_smtp', 'misc', 'callout' );
foreach my $db (@EXIMDBS) {
Cpanel::SafeRun::saferunnoerror( '/usr/sbin/exim_dbmbuild', '/dev/null', "/var/spool/exim/db/${db}" );
}
if ( -e "/var/spool/exim_incoming" ) {
system("rm -f /var/spool/exim_incoming/db/*.lock* 2>/dev/null");
foreach my $db (@EXIMDBS) {
Cpanel::SafeRun::saferunnoerror( "/usr/sbin/exim_dbmbuild", "/dev/null", "/var/spool/exim_incoming/db/${db}" );
}
system("chmod 640 /var/spool/exim_incoming/db/* 2>/dev/null");
system( "chown", "-R", "mailnull:mail", "/var/spool/exim_incoming" );
}
system("chmod 640 /var/spool/exim/db/* 2>/dev/null");
system( "chown", "-R", "mailnull:mail", "/var/spool/exim" );
my $pid = fork();
if ( defined $pid && $pid == 0 ) {
for ( my $n = 0; $n < 1024; $n++ ) { Cpanel::OSSys::close($n); }
Cpanel::OSSys::setsid();
open( STDIN, "</dev/null" );
open( STDOUT, ">/dev/null" );
open( STDERR, ">/dev/null" );
exec('/scripts/mailperm');
exit;
}
if ( -x "/scripts/posteximup" ) {
system("/scripts/posteximup");
}
if ( -x "/scripts/postexim4install" ) {
system("/scripts/postexim4install");
}
print "Install Complete\n";
sub buildrpm {
if ( getgrnam("mailnull")
&& !getpwnam("mailnull")
&& -e "/usr/sbin/groupdel" ) {
system( "/usr/sbin/groupdel", "mailnull" );
Cpanel::NSCD::clear_cache('group');
}
if ( !getpwnam("mailnull") && -e "/usr/sbin/useradd" ) {
system( "/usr/sbin/useradd", "-c", "Exim", "-u", "47", "-s", "/bin/false", "-r", "-d", "/var/spool/mqueue", "mailnull" );
Cpanel::NSCD::clear_cache();
}
if ( !getgrnam("mailnull") && -e "/usr/sbin/groupadd" ) {
system( "/usr/sbin/groupadd", "mailnull" );
Cpanel::NSCD::clear_cache('group');
}
if ( !getgrnam("mailtrap") && -e "/usr/sbin/groupadd" ) {
system( "/usr/sbin/groupadd", "mailtrap" );
Cpanel::NSCD::clear_cache('group');
}
my $syspkgobj = Cpanel::SysPkgs->new();
if ( !$syspkgobj ) { die print "Could not create SysPkgs object\n"; }
my @pkgs = ( "rpm", "rpm-build", "db-devel", "gdbm-devel", "db1-devel", "db4-devel", "compat-db", "ndbm-devel", "pam-devel", "openssl-devel", "gcc", "glibc-devel" );
$syspkgobj->install( 'pkglist' => \@pkgs );
if ( $distro eq 'fedora' && ( $version eq '9' || $version eq '10' ) ) {
my $syspkgobj = Cpanel::SysPkgs->new();
if ( !$syspkgobj ) { die print "Could not create SysPkgs object\n"; }
my @pkgs = ('perl-ExtUtils-Embed');
$syspkgobj->install( 'pkglist' => \@pkgs );
}
my $rpm = 'rpm';
if ( -e "/usr/bin/rpmbuild" ) { $rpm = '/usr/bin/rpmbuild'; }
$url = "http://diff.cpanel.net/${basedir}/${eximver}-${buildnum}/src/exim-${eximver}-${buildnum}_${bsv}.src.rpm";
$httpClient->download( $url, "exim.src.rpm" );
open( RNULL, "<", "/dev/null" );
print "Building RPM...";
open( RPM, ">", "rpmbuildlog" );
my $pid = open3( "<&RNULL", ">&RPM", ">&RPM", "$rpm", "--rebuild", "exim.src.rpm" );
while ( waitpid( $pid, 1 ) <= 0 ) {
print ".";
sleep(1);
}
close(RPM);
close(RNULL);
print "Done\n";
open( RPM, "<", "rpmbuildlog" );
while (<RPM>) {
if (/^Wrote: (\S+)/) {
$file = $1;
if ( $file =~ /.(64|86)\.rpm/ ) {
Cpanel::RpmStor::rpmstor($file);
return ($file);
}
}
}
close(RPM);
open( RPM, "<", "rpmbuildlog" );
seek( RPM, -2048, &Fcntl::SEEK_END );
while (<RPM>) {
print "\t" . $_;
}
close(RPM);
die "Failed to build rpm";
}
sub buildeximcrt {
if ( -l "/etc/exim.crt"
&& -e "/etc/exim.crt"
&& -l "/etc/exim.key"
&& -e "/etc/exim.key" ) {
return ();
}
my (@CRTD) = ( '/etc/exim.key', '/etc/exim.crt' );
buildselfsignedcert(@CRTD);
my ( $mailnulluid, $mailnullgid ) = ( getpwnam('mailnull') )[ 2, 3 ];
chown $mailnulluid, $mailnullgid, @CRTD;
chmod 0600, @CRTD;
}
sub buildselfsignedcert {
my ( $key, $crt ) = @_;
open3( \*WRTFH, \*RDRFH, ">&STDERR", "openssl", "req", "-x509", "-newkey", "rsa:1024", "-keyout", $key, "-out", $crt, "-days", "9999", "-nodes" );
print WRTFH "US\n";
print WRTFH "Unknown\n";
print WRTFH "Unknown\n";
print WRTFH "Unknown\n";
print WRTFH "Unknown\n";
print WRTFH "${hostname}\n";
print WRTFH "ssl\@cpanel.net\n";
close(WRTFH);
while (<RDRFH>) {
print;
}
close(RDRFH);
}
sub _find_exim_bin {
goto &Cpanel::Exim::find_exim;
}