File: //scripts.20110531.215904.25158/setupfp5
#!/usr/bin/perl
# cpanel - setupfp5 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'; }
require 5.006;
use strict;
use warnings;
use Cpanel::AcctUtils::DomainOwner ();
use Cpanel::StringFunc::Match ();
use Cpanel::SafeFile ();
use Cpanel::SafeFind ();
use Cpanel::DomainIp ();
use Cpanel::SafeRun::Simple ();
use Cpanel::ConfigFiles ();
use Cpanel::PwCache ();
use Cpanel::AccessIds ();
use Cpanel::Errors ();
use Cpanel::FileUtils::Copy ();
use Cpanel::Config::Httpd ();
use Cpanel::Config::LoadCpUserFile ();
use Cpanel::Config::userdata::Load ();
use Cpanel::Config::userdata::Cache ();
use Cpanel::FrontpageAdmin ();
use Cpanel::CleanupStub ();
use Cpanel::Logger ();
my $logger = Cpanel::Logger->new();
$| = 1;
my $cleanuppid;
my @DOMAINS;
my ( $domain, $subweb );
my $siteconfonly = 0;
my $owsadm_bin = '/usr/local/frontpage/version5.0/bin/owsadm.exe';
if ( !-e $owsadm_bin ) {
die "Frontpage extensions are not installed on this system!";
}
my $main_port = Cpanel::Config::Httpd::get_main_httpd_port(1);
my $ssl_port = Cpanel::Config::Httpd::get_ssl_httpd_port(1);
if (@ARGV) {
if ( $ARGV[0] =~ m/siteconfonly/i ) {
shift(@ARGV);
$siteconfonly = 1;
}
$domain = shift(@ARGV);
if ($domain) {
$domain =~ s/\n//g;
}
$subweb = shift(@ARGV) || '';
if ($subweb) {
$subweb =~ s/\.\.//g;
$subweb =~ s/\///g;
$subweb =~ /([\w\.\-]+)/;
$subweb = $1;
}
@DOMAINS = @ARGV;
$0 = "setupfp - $domain";
}
if ( !$domain ) {
if ( -t STDIN ) {
print 'What is the servername you want to setup? ';
chomp( $domain = <STDIN> );
}
else {
Cpanel::Errors::deaderror('No domain was provided');
}
}
$domain =~ s/^www\.//g;
if ( Cpanel::FrontpageAdmin::check_fpfakeout($owsadm_bin) == -1 ) {
# Warnings are already printed in check_fpfakeout()
exit 1;
}
my $hassuexec = ( -x '/usr/local/apache/bin/suexec' || ( -e '/var/cpanel/apache2' && -x '/usr/local/apache2/bin/suexec' ) ) ? 1 : 0;
my $httpconf = Cpanel::ConfigFiles::find_httpconf();
my @HTDIR = split( /\//, $httpconf );
pop @HTDIR;
my $htdir = join '/', @HTDIR;
pop @HTDIR;
my $htbasedir = join '/', @HTDIR;
my $ud_cache = Cpanel::Config::userdata::Cache::load_cache();
if ( !$ud_cache->{$domain} ) {
Cpanel::Errors::deaderror('No Server found');
}
elsif ( $ud_cache->{$domain}->[2] =~ /parked|addon/ ) {
if ( !grep( /^\Q$domain\E$/, @DOMAINS ) ) {
push @DOMAINS, $domain;
}
$domain = $ud_cache->{$domain}->[3];
}
my $docroot = $ud_cache->{$domain}->[4];
my @homedirparts = split( /\//, $docroot );
my $user = $ud_cache->{$domain}->[0];
if ( !$user || $user eq 'root' ) {
print "Frontpage could not be installed on $domain because the domain owner could not be determined.\n";
exit 1;
}
my ( $cryptpass, $useruid, $usergid ) = ( Cpanel::PwCache::getpwnam($user) )[ 1, 2, 3 ];
if ( !$cryptpass ) {
$cryptpass = ( getpwnam($user) )[1];
}
my $httpgid = ( getgrnam('nobody') )[2];
my @DLIST = getdlist($domain);
my $fphttpconf = "${htdir}/sites/${domain}.conf";
buildsiteconf( $domain, $domain );
foreach my $target (@DLIST) {
foreach my $port ( $main_port, $ssl_port ) {
if ( -e "/usr/local/frontpage/${target}:${port}.cnf" ) {
my $fplock = Cpanel::SafeFile::safeopen( \*FPC, "+<", "/usr/local/frontpage/${target}:${port}.cnf" );
if ( !$fplock ) {
$logger->warn("Could not edit /usr/local/frontpage/${target}:${port}.cnf");
next;
}
my @FPC = <FPC>;
@FPC = grep( !/^(sendmailcommand|frontpageroot|serverconfig):/i, @FPC );
#drop sendmailcommand (fp4)
push @FPC, "serverconfig:$fphttpconf\n";
push @FPC, "SendmailCommand:/usr/sbin/sendmail\n";
push @FPC, "frontpageroot:/usr/local/frontpage/version5.0\n";
seek FPC, 0, 0;
print FPC join( '', @FPC );
truncate FPC, tell FPC;
Cpanel::SafeFile::safeclose( \*FPC, $fplock );
}
}
}
my $cpuser = Cpanel::Config::LoadCpUserFile::loadcpuserfile($user);
my %ALLDOMAINS = map { $_ => 1 } @{ $cpuser->{'DOMAINS'} };
$ALLDOMAINS{$domain} = 1;
if ( !grep( /^\Q$domain\E$/, @DOMAINS ) ) {
push @DOMAINS, $domain;
}
if ($siteconfonly) {
fixupsubwebcnfs();
checksslconf();
checkwecnf();
exit 0;
}
my $fsubweb = '';
my $pass = 'x';
if ( $subweb && $subweb ne '' ) {
$fsubweb = '/' . $subweb;
}
my $group = getgrgid($usergid); #group is always the user even with fileprotect
if ( !-d "${docroot}${fsubweb}" ) {
Cpanel::Errors::deaderror("${docroot}${fsubweb} does not exist or is not a directory!");
}
my $is_upgrade = -e "${docroot}${fsubweb}/_vti_pvt" ? 1 : 0;
my $fp_install_time = time();
if ( -d $docroot ) {
if ( my $pid = fork() ) {
waitpid( $pid, 0 );
}
else {
Cpanel::AccessIds::setuids($user);
Cpanel::SafeFind::find(
{
'wanted' => sub {
if ( Cpanel::StringFunc::Match::endmatch( $File::Find::name, '/.htaccess' ) ) {
return if ( $File::Find::name =~ /\/_vti_/ );
my $safefile = $File::Find::name;
$safefile =~ /(.*)/;
print "Saving .htaccess file: $1\n";
if ( $File::Find::name eq "${docroot}${fsubweb}/.htaccess"
&& -e "${docroot}${fsubweb}/_vti_pvt" ) {
print "Using Upgrade Mode\n";
Cpanel::FileUtils::Copy::safecopy( $1, "$1.fpinstall.$fp_install_time" );
}
else {
rename( $1, "$1.fpinstall.$fp_install_time" ) || do {
warn "Could not rename $1 to $1.fpinstall.$fp_install_time: frontpage install will probably fail.";
my $dir = $1;
my @DIR = split( /\//, $dir );
pop(@DIR);
my $path = join( '/', @DIR );
if ( !-w $path ) {
warn "Could not write to $path! Does it need to be chowned to the user $user?";
warn Cpanel::SafeRun::Simple::saferun( 'ls', '-ld', $path );
}
};
}
}
},
'no_chdir' => 1
},
"${docroot}${fsubweb}"
);
exit;
}
}
activatecleanup();
if ($subweb) {
Cpanel::FrontpageAdmin::fpcmd( $user, $domain, $main_port, $owsadm_bin, '-o', 'install', '-nochowncontent', 'yes', '-t', 'apache-fp', '-m', $domain, '-w', $subweb, '-p', $main_port, '-xuser', $user, '-xgroup', $group, '-u', $user, '-pw', $pass, '-servconf', $fphttpconf );
Cpanel::AccessIds::do_as_user(
$user,
sub {
chmod 0755, "${docroot}${fsubweb}", "${docroot}${fsubweb}/_vti_pvt";
}
);
}
else {
Cpanel::FrontpageAdmin::fpcmd( $user, $domain, $main_port, $owsadm_bin, '-o', 'install', '-nochowncontent', 'yes', '-t', 'apache-fp', '-m', $domain, '-p', $main_port, '-xuser', $user, '-xgroup', $group, '-u', $user, '-pw', $pass, '-servconf', $fphttpconf );
Cpanel::AccessIds::do_as_user(
$user,
sub {
chmod 0755, $docroot, "$docroot/_vti_pvt";
}
);
}
if ( my $pid = fork() ) {
waitpid( $pid, 0 ); #wait for cleanup to finish
}
else {
Cpanel::AccessIds::setuids($user);
Cpanel::SafeFind::find(
{
wanted => sub {
if ( Cpanel::StringFunc::Match::endmatch( $File::Find::name, '/.htaccess.fpinstall.' . $fp_install_time ) ) {
my $safefile = $File::Find::name;
$safefile =~ /(.*)/;
my $rawhtaccess = $1;
my $tmphtaccess = $1;
$rawhtaccess =~ s/\.fpinstall\.${fp_install_time}//go;
print "Merging .htaccess file: $rawhtaccess\n";
open( my $fp_install_fh, '<', $tmphtaccess );
my $hl;
if ( $rawhtaccess eq "${docroot}${fsubweb}/.htaccess" && $is_upgrade ) {
$hl = Cpanel::SafeFile::safeopen( \*HTA, '>', $rawhtaccess );
}
else {
$hl = Cpanel::SafeFile::safeopen( \*HTA, '>>', $rawhtaccess );
}
if ( !$hl ) {
$logger->warn("Could not write to $rawhtaccess");
}
else {
while ( readline($fp_install_fh) ) {
print HTA;
}
truncate( HTA, tell(HTA) );
Cpanel::SafeFile::safeclose( \*HTA, $hl );
close($fp_install_fh);
unlink($tmphtaccess);
if ( !( $rawhtaccess eq "${docroot}${fsubweb}/.htaccess" && $is_upgrade ) ) {
Cpanel::FrontpageAdmin::remove_fphtaccess_dupes($rawhtaccess);
}
}
}
},
no_chdir => 1
},
"${docroot}${fsubweb}"
);
exit(0);
}
if ( $? != 0 && $? != 1 ) {
deactivatecleanup();
Cpanel::Errors::deaderror($!);
}
# site conf file shoule be owned by root:user on Apache 2+ and root:nobody on Apache 1
my $forced_ownership = -e '/usr/local/apache/modules/mod_auth_passthrough.so';
buildsiteconf( $domain, $domain, $forced_ownership );
fixupsubwebcnfs();
checksslconf();
checkwecnf();
deactivatecleanup();
if ( -e '/var/cpanel/fileprotect' ) {
my $change_perms = sub {
if ($fsubweb) {
chown $useruid, $httpgid, "${docroot}${fsubweb}", "${docroot}${fsubweb}/_vti_pvt";
chmod 0750, "${docroot}${fsubweb}", "${docroot}${fsubweb}/_vti_pvt";
}
chown $useruid, $httpgid, $docroot, "$docroot/_vti_pvt";
chmod 0750, $useruid, $docroot, "$docroot/_vti_pvt";
};
Cpanel::AccessIds::do_as_user_group( $useruid, $httpgid, $change_perms );
}
Cpanel::SafeRun::Simple::saferun( '/scripts/addfpmail', '--domain', $domain );
print "Setting Password\n";
my $webpass;
if ( $subweb && -e '/etc/proftpd/' . $user ) {
if ( open my $proftp_fh, '<', '/etc/proftpd/' . $user ) {
while (<$proftp_fh>) {
if (m/^${subweb}:/) {
( undef, $webpass, undef ) = split( /:/, $_ );
last;
}
}
close $proftp_fh;
}
if ($webpass) {
if ( $ENV{'CPANEL'} ) { print "<b>"; }
print "Adding the user $subweb with their ftp password!\n";
if ( $ENV{'CPANEL'} ) { print "</b>"; }
print "\n";
my $rand = int( rand(10000000) );
Cpanel::FrontpageAdmin::fpcmd( $user, $domain, $main_port, $owsadm_bin, '-o', 'users', '-c', 'add', '-u', $subweb, '-t', 'apache-fp', '-m', $domain, '-w', $subweb, '-p', $main_port, '-pw', $rand, '-servconf', $fphttpconf );
if ( $? != 0 && $? != 1 ) {
Cpanel::Errors::undeaderror($!);
}
Cpanel::FrontpageAdmin::fpcmd( $user, $domain, $main_port, $owsadm_bin, '-o', 'userroles', '-c', 'add', '-u', $subweb, '-n', 'admin', '-t', 'apache-fp', '-m', $domain, '-w', $subweb, '-p', $main_port, '-servconf', $fphttpconf );
if ( $? != 0 && $? != 1 ) { Cpanel::Errors::undeaderror("$!\n"); }
print "\n";
}
}
my $passwd_mod = sub {
my $service_pass = $docroot . $fsubweb . '/_vti_pvt/service.pwd';
if ( open my $spw_fh, '+<', "${docroot}${fsubweb}/_vti_pvt/service.pwd" ) {
my @SPW = <$spw_fh>;
seek( $spw_fh, 0, 0 );
foreach my $line (@SPW) {
next if ( $subweb && $line =~ m/ \A $subweb :/xms );
if ( $line =~ /^\Q${user}\E:/ ) {
print {$spw_fh} $user . ':' . $cryptpass . "\n";
}
else {
print {$spw_fh} $line;
}
}
if ( $subweb && $webpass ) {
print {$spw_fh} $subweb . ':' . $webpass . "\n";
}
truncate( $spw_fh, tell($spw_fh) );
close $spw_fh;
chmod 0755, "${docroot}${fsubweb}/_private";
return 1;
}
else {
warn "Unable to update password file $service_pass: $!";
return;
}
};
Cpanel::AccessIds::do_as_user( $user, $passwd_mod );
if ( -e '/usr/local/apache/libexec/mod_auth_passthrough.so' || -e '/usr/local/apache/modules/mod_auth_passthrough.so' ) {
print "Frontpage passthough auth enabled in $docroot$fsubweb!\n";
my $auth_pass_mod = sub {
my $want = 'Passthrough';
my $have = 'Basic';
chmod( 0600, $docroot . $fsubweb . '/_vti_pvt/service.pwd' );
Cpanel::FrontpageAdmin::change_auth_type( $docroot . $fsubweb . '/_vti_bin', { 'want' => $want, 'have' => $have } );
Cpanel::FrontpageAdmin::change_auth_type( $docroot . $fsubweb . '/_vti_bin/_vti_aut', { 'want' => $want, 'have' => $have } );
Cpanel::FrontpageAdmin::change_auth_type( $docroot . $fsubweb . '/_vti_bin/_vti_adm', { 'want' => $want, 'have' => $have } );
};
Cpanel::AccessIds::do_as_user( $user, $auth_pass_mod );
}
if (@DOMAINS) {
print "Frontpage was installed on the following domains: " . join( ' ', @DOMAINS ) . "\n";
}
else {
print "Frontpage was installed on the domain: " . $domain . "\n";
}
sub activatecleanup {
return if !-e '/var/cpanel/fileprotect';
unless ( $cleanuppid = fork ) {
Cpanel::CleanupStub::daemonclosefds();
Cpanel::AccessIds::setuids( $useruid, $httpgid );
$0 = 'setupfp5 - fileprotect check';
my $t = 0;
while ( $t < 200 ) {
$t++;
if ($fsubweb) {
chown $useruid, $httpgid, "${docroot}${fsubweb}", "${docroot}${fsubweb}/_vti_pvt";
chmod 0750, "${docroot}${fsubweb}", "${docroot}${fsubweb}/_vti_pvt";
}
chown $useruid, $httpgid, $docroot, "$docroot/_vti_pvt";
chmod 0750, $docroot, "$docroot/_vti_pvt";
sleep 5;
}
exit 0;
}
}
sub deactivatecleanup {
return if !-e '/var/cpanel/fileprotect';
if ( $cleanuppid && $cleanuppid > 0 ) {
kill 'TERM', $cleanuppid;
}
}
sub buildsiteconf {
my ( $dns_name, $vhost_name, $forcedperm ) = @_;
my $userdata = Cpanel::Config::userdata::Load::load_userdata($ud_cache->{$vhost_name}->[0], $vhost_name);
my $user = $userdata->{'user'};
chmod( 0711, '/usr/local/frontpage' );
if ( !-e "${htdir}/sites" ) {
mkdir( "${htdir}/sites", 0711 );
}
else {
chmod( 0711, "${htdir}/sites" );
}
open( HTTPSITE, ">", "${htdir}/sites/${dns_name}.conf" );
if ( $hassuexec || $forcedperm ) {
chmod( 0640, "${htdir}/sites/${dns_name}.conf" );
my $usergid = ( getgrnam($user) )[2];
chown( 0, $usergid, "${htdir}/sites/${dns_name}.conf" ); #safe we own the parent
}
else {
chmod( 0644, "${htdir}/sites/${dns_name}.conf" );
# we should never get here since we are die()ing above.
chown( 0, $httpgid, "${htdir}/sites/${dns_name}.conf" ); #safe we own the parent
}
print HTTPSITE "DocumentRoot " . $userdata->{'documentroot'} . "\n";
print HTTPSITE "Port $main_port\n";
print HTTPSITE "DirectoryIndex index.htm index.html\n";
print HTTPSITE "ServerRoot ${htbasedir}\n\n";
print HTTPSITE "<VirtualHost " . $userdata->{'ip'} . ':' . $userdata->{'port'} . ">\n";
print HTTPSITE "DocumentRoot $userdata->{'documentroot'}\n";
print HTTPSITE "ServerAdmin $userdata->{'serveradmin'}\n";
print HTTPSITE "ServerName $userdata->{'servername'}\n";
if ( exists $userdata->{'serveralias'} && $userdata->{'serveralias'} ) {
print HTTPSITE "ServerAlias " . $userdata->{'serveralias'} . "\n";
}
if ( exists $userdata->{'user'} && $userdata->{'user'} ) {
print HTTPSITE "User " . $userdata->{'user'} . "\n";
print HTTPSITE "Group " . $userdata->{'user'} . "\n";
}
print HTTPSITE "</VirtualHost>\n";
close(HTTPSITE);
}
sub fixupsubwebcnfs {
foreach my $ddomain (@DOMAINS) {
my $origdomain = $ddomain;
next if !$ALLDOMAINS{$ddomain};
my @DLIST = getdlist($ddomain);
foreach my $dns_name (@DLIST) {
next if $dns_name eq $domain;
(my $vhost_name = $dns_name) =~ s/^www\.//;
if ( !$ud_cache->{$vhost_name} ) {
next;
}
elsif ( $ud_cache->{$vhost_name}->[2] =~ /parked|addon/ ) {
$vhost_name = $ud_cache->{$vhost_name}->[3];
}
buildsiteconf( $dns_name, $vhost_name );
foreach my $port ( $main_port, $ssl_port ) {
if ( -l "/usr/local/frontpage/${dns_name}:${port}.cnf" ) {
unlink "/usr/local/frontpage/${dns_name}:${port}.cnf";
}
}
}
my $servername_config = '/usr/local/frontpage/' . $domain . ':' . $main_port . '.cnf';
if ( open my $template_fh, '<', $servername_config ) {
foreach my $target (@DLIST) {
foreach my $port ( $main_port, $ssl_port ) {
seek( $template_fh, 0, 0 );
my $new_conf = '/usr/local/frontpage/' . $target . ':' . $port . '.cnf';
if ( $target ne $domain || $port ne $main_port ) {
if ( open my $new_conf_fh, '>', $new_conf ) {
while ( my $line = readline $template_fh ) {
if ( $line =~ m/^MailSender:/i ) {
print {$new_conf_fh} "MailSender:webmaster\@${origdomain}\n";
}
elsif ( $line =~ m/^(serverconfig:)/i ) {
print {$new_conf_fh} $1 . $htdir . '/sites/' . $target . '.conf' . "\n";
}
else {
print {$new_conf_fh} $line;
}
}
close $new_conf_fh;
}
else {
warn "Unable to update $new_conf: $!";
next;
}
}
chmod( 0644, $new_conf );
chown( 0, $usergid, $new_conf ); #should they own this file?
}
}
close $template_fh;
}
else {
warn "Could not open $servername_config: $!";
}
}
}
sub checksslconf {
my @DLIST = getdlist($domain);
foreach my $target (@DLIST) {
if ( -e "/usr/local/frontpage/${target}:${main_port}.cnf"
&& !-e "/usr/local/frontpage/${target}:${ssl_port}.cnf" ) {
system 'cp', '-pf', "/usr/local/frontpage/${target}:${main_port}.cnf", "/usr/local/frontpage/${target}:${ssl_port}.cnf";
}
}
}
sub getdlist {
my $sr = shift;
$sr =~ s/^www\.//g;
return ( $sr, 'www.' . $sr );
}
sub checkwecnf {
if ( !-e "/usr/local/frontpage/we${main_port}.cnf" && -e '/usr/local/frontpage/we80.cnf' ) {
Cpanel::FileUtils::Copy::safecopy( "/usr/local/frontpage/we80.cnf", "/usr/local/frontpage/we${main_port}.cnf" );
}
}