File: //proc/self/root/proc/self/root/scripts.20110531.215904.25158/suspendacct
#!/usr/bin/perl
# cpanel - suspendacct 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 Whostmgr::Quota ();
use Cpanel::AcctUtils ();
use Cpanel::AcctUtils::DomainOwner ();
use Cpanel::DomainTools ();
use Cpanel::AccessIds ();
use Cpanel::SafetyBits ();
use Cpanel::Config ();
use Cpanel::Config::CpUserGuard ();
use Cpanel::FileUtils ();
use Cpanel::Hostname ();
use Cpanel::iContact ();
use Cpanel::ApacheConf ();
use Cpanel::SafeFile ();
use Cpanel::Sys::Kill ();
use Cpanel::PwCache ();
use Cpanel::OSSys ();
use Cpanel::Usage ();
use AcctLock ();
usage() unless (@ARGV);
Cpanel::Usage::usage( \@ARGV, \&usage );
my $system = ( Cpanel::OSSys::uname() )[0];
my $user = $ARGV[0];
$user =~ s/\///g;
my $reason = $ARGV[1];
my $prevent_reseller_unsuspend = $ARGV[2];
usage() if ( !$user || $user eq 'root' );
# this one doesn't seem to exist
system '/scripts/presuspendacct', @ARGV if -x '/scripts/presuspendacct';
my $pass = (Cpanel::PwCache::getpwnam($user))[1];
if ( ! defined $pass ) {
$user = Cpanel::AcctUtils::DomainOwner::getdomainowner($user, { 'default' => '' } );
if (!$user ) {
die "Invalid user\n";
}
$pass = (Cpanel::PwCache::getpwnam($user))[1];
if ( !defined $pass ){
die "Invalid user\n";
}
}
if (!$user || $user eq 'root') { die "Invalid $user"; }
my $homedir = Cpanel::AcctUtils::gethomedir($user);
my $shell = Cpanel::AcctUtils::getshell($user);
my $host;
AcctLock::acctlock();
print "Changing Shell to /bin/false...";
system( "chsh", "-s", "/bin/false", "$user" );
print "Done\n";
print "Locking Password...";
if ( -e '/usr/sbin/pw' ) {
system( '/usr/sbin/pw', 'lock', $user );
}
else {
system( 'passwd', '-l', $user );
}
print "Done\n";
AcctLock::acctunlock();
my $owner = Cpanel::AcctUtils::getowner($user);
$owner =~ s/\n//g;
if ( $owner eq '' || $owner eq 'root' || $user eq $owner ) {
$host = Cpanel::Hostname::gethostname();
}
else {
$host = Cpanel::AcctUtils::getdomain($owner);
}
if ( !$host ) {
$host = Cpanel::Hostname::gethostname();
}
my $domain = Cpanel::AcctUtils::getdomain($user);
if ( !-e '/var/cpanel/suspended' ) {
mkdir( '/var/cpanel/suspended', 0755 );
}
open( USERS, ">", "/var/cpanel/suspended/${user}" );
print USERS $reason;
close(USERS);
if ( $prevent_reseller_unsuspend == 1 ) {
Cpanel::FileUtils::touchfile( '/var/cpanel/suspended/' . $user . '.lock' );
}
print Cpanel::Sys::Kill::kill_pids_owned_by( $user, '-9' );
my $cpuser_guard = Cpanel::Config::CpUserGuard->new($user);
my $cpuser_data = $cpuser_guard->{'data'};
my @DNS = ( $cpuser_data->{'DOMAIN'} );
if ( exists $cpuser_data->{'DOMAINS'} ) {
push @DNS, @{ $cpuser_data->{'DOMAINS'} };
}
mkdir( "/usr/local/cpanel/3rdparty/mailman/suspended.lists", 0755 );
if ( -e "$homedir/etc/webdav/shadow" ) {
print "Suspending webdav users\n";
suspendshadowfile("$homedir/etc/webdav/shadow");
}
foreach my $dns (@DNS) {
$dns = Cpanel::DomainTools::normalize($dns);
next if !Cpanel::DomainTools::is_valid($dns);
system("mv /usr/local/cpanel/3rdparty/mailman/lists/*_$dns /usr/local/cpanel/3rdparty/mailman/suspended.lists 2>/dev/null");
if ( -f "${homedir}/etc/${dns}/shadow"
&& !-l "${homedir}/etc/${dns}/shadow" ) {
print "Suspending email account logins for ${dns} .... ";
suspendshadowfile("${homedir}/etc/${dns}/shadow");
print "Done\n";
}
}
print "Suspending mysql users\n";
system( '/scripts/suspendmysqlusers', $user );
my $msg = <<"EOM";
+===================================+
| Account Info |
+===================================+
| Domain: $domain
| UserName: $user
+===================================+
Account suspended by $ENV{'REMOTE_USER'} ($ENV{'USER'})
EOM
if ($reason) {
$msg .= "\nReason:\n$reason\n";
}
Cpanel::iContact::icontact(
'application' => 'suspendacct',
'level' => 3,
'subject' => qq{Account Suspended on $host ($domain)},
'message' => $msg,
'msgtype' => ''
);
if ( $pass =~ /^\!/ || $pass =~ /^\*/) {
print "Account previously suspended (password was locked).\n";
}
if ( !-e '/var/cpanel/suspendinfo' ) {
mkdir( '/var/cpanel/suspendinfo', 0700 );
}
if ( !-e "/var/cpanel/suspendinfo/$user" || -z _ ) {
open( CPINFO, ">", "/var/cpanel/suspendinfo/$user" );
print CPINFO "shell=$shell\n";
close(CPINFO);
}
$cpuser_data->{'SUSPENDTIME'} = time();
$cpuser_data->{'SUSPENDED'} = 1;
$cpuser_guard->save();
if ( !-e "/var/spool/cron.suspended" ) {
mkdir( "/var/spool/cron.suspended", 0700 );
}
if ( -f "/var/spool/cron/${user}" ) {
link( "/var/spool/cron/${user}", "/var/spool/cron.suspended/${user}" );
unlink("/var/spool/cron/${user}");
}
Cpanel::SafetyBits::safe_chmod( 0000, $user, "${homedir}/public_ftp" );
my $quota = int( Whostmgr::Quota::getusersquota($user) );
my $quota_output;
( undef, undef, $quota_output ) = Whostmgr::Quota::setusersquota( $user, 0 );
print $quota_output;
if ( my $pid = fork() ) {
waitpid( $pid, 0 );
}
else {
my $docroot_ref = Cpanel::ApacheConf::getdocroots( \@DNS );
Cpanel::AccessIds::setuids($user);
foreach my $docroot ( keys %{$docroot_ref} ) {
if ( -e $docroot . '/.htaccess' ) {
if ( !Cpanel::FileUtils::has_txt_in_file( $docroot . '/.htaccess', '^RedirectMatch\s.+suspended.?page' ) ) {
rename $docroot . '/.htaccess', $docroot . '/.htaccess.suspend.' . time();
}
}
else {
Cpanel::FileUtils::touchfile( $docroot . '/.htaccess.suspend.' . time() );
}
if ( open my $htaccess_fh, '>', $docroot . '/.htaccess' ) {
my ( $uid, $gid ) = ( getpwnam($user) )[ 2, 3 ];
if ( $uid && $gid ) {
# cannot be safechown as we are allready setuid:
chown( $uid, $gid, $docroot . '/.htaccess' );
}
print {$htaccess_fh} "RedirectMatch .* /cgi-sys/suspendedpage.cgi\n";
close $htaccess_fh;
print "Suspended document root $docroot\n";
}
else {
warn "Failed to update htaccess file during suspension: $!";
print <<"EOM";
!!!!!! Failed to disable ${user}'s website !!!!!!!!
Their account will continue to be publically
accessible. To disable the website, create an
htaccess file with the following contents at
$docroot/.htaccess:
RedirectMatch .* /cgi-sys/suspendedpage.cgi
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
EOM
}
}
exit;
}
( undef, undef, $quota_output ) = Whostmgr::Quota::setusersquota( $user, $quota );
print $quota_output;
my $ftpfile = "/etc/proftpd/$user";
if ( -e $ftpfile && !-e $ftpfile . '.suspended' && -e "/var/cpanel/suspended/$user" ) {
print "Suspending FTP accounts...\n";
rename( $ftpfile, "$ftpfile.suspended" )
or warn "Could not rename $ftpfile to $ftpfile.suspended";
}
system( "/usr/local/cpanel/bin/ftpupdate", $user );
system '/usr/local/cpanel/bin/updateauthtab';
print ${user} . "'s account has been suspended\n";
system '/scripts/postsuspendacct', @ARGV if -x '/scripts/postsuspendacct';
sub suspendshadowfile {
my ($file) = @_;
my @shadow_file;
my $shadowlock = Cpanel::SafeFile::safeopen( \*SHF, '<', $file );
if ($shadowlock) {
@shadow_file = <SHF>;
Cpanel::SafeFile::safeclose( \*SHF, $shadowlock );
undef $shadowlock;
}
else {
if ( -e $file ) {
warn "Failed to read $file: $!";
return;
}
else {
return 1;
}
}
if (@shadow_file) {
$shadowlock = Cpanel::SafeFile::safeopen( \*SHF, '>', $file );
if ($shadowlock) {
foreach (@shadow_file) {
chomp;
my @DC = split( /:/, $_, 3 );
if ( $DC[1] !~ m/^\*LOCKED\*/ ) {
$DC[1] = "*LOCKED*" . $DC[1];
}
print SHF join( ':', @DC ) . "\n";
}
Cpanel::SafeFile::safeclose( \*SHF, $shadowlock );
}
else {
warn "Failed to update $file: $!";
return;
}
return 1;
}
else {
return 1;
}
}
sub usage {
my $p = $0;
$p =~ s@^.+/(.+)$@$1@;
print <<EOF;
Usage: $p user [reason] [disallow] [--usage | --help]
Suspend a user's account with possibly a more stringent
suspension as determined by disallow.
where
user -- is a valid user name (required)
reason -- is a quote bound description for the suspension
and is written into the /var/cpanel/suspended/<user> file
(optional)
disallow -- is for additionally generating a user.lock file
in /var/cpanel/suspended and to issue this the argument needs to
be 1 (optional)
Note that the order of user, reason and disallow must be maintained.
Now supports drving instructions via --help, --usage
EOF
exit;
}