#!/usr/local/cpanel/3rdparty/bin/perl
#******************************************************************************
# Copyright 2009-2013, Way to the Web Limited
# URL: http://www.waytotheweb.com
# Email: sales@waytotheweb.com
#******************************************************************************
# Example cPanel Symlink Script for cxs watch --Wsymlink [script] option
#
# NOTE: If you intend to use this script, copy it to a different filename as
# this file will be overwritten when cxs upgrades. When you do this you also
# need to change the --Wsymlink [script] in /etc/cxs/cxswatch.sh and restart
# cxs watch

use strict;
use Sys::Hostname;
use POSIX qw(strftime);
use Fcntl qw(:DEFAULT :flock);

# Set to 1 to only send an email
# Set to 2 to send an email and disable the directory with chmod 000 and chattr +i
# Set to 3 to send an email and suspend the cPanel account if determined
my $action = 1;

# Assign arguments to variables
my $directory = $ARGV[0];
my $account = $ARGV[1];

# Setup hostname for emails
my $hostname = hostname;

# Setup timesone for emails
my $tz = strftime("\%z", localtime);

# Check if we've already sent an alert for this directory in the last hour to
# prevent flooding. Remember to remove the temporary file in
# /etc/cxs/symlinktmp/ if you want to detect hits again within the hour
if ($directory) {
        unless (-d "/etc/cxs/symlinktmp") {mkdir("/etc/cxs/symlinktmp")}
        my $cmpdir = $directory;
        $cmpdir =~ s/\W/_/g;
        if (-e "/etc/cxs/symlinktmp/$cmpdir") {
                open (FILE, "</etc/cxs/symlinktmp/$cmpdir");
                flock (FILE, LOCK_SH);
                my $time = <FILE>;
                close (FILE);
                chomp $time;
                if (time - $time < 3600) {
                        # We have sent an alert so exit
                        exit;
                } else {
                        unlink ("/etc/cxs/symlinktmp/$cmpdir");
                }
        } else {
                sysopen (FILE, "/etc/cxs/symlinktmp/$cmpdir", O_WRONLY | O_CREAT);
                flock (FILE, LOCK_EX);
                print FILE time;
                close (FILE);
        }
}

#Perform the configured action
if ($action >= 1) {
        # send an email to root from root
        if ($account eq "") {$account = "[unknown]"}
        open (FH, "|/usr/sbin/sendmail -t");
        print FH "From: root\n";
        print FH "To: root\n";
        print FH "Subject: Possible Symlink Attack detected in $directory on $hostname\n";
        print FH "\n";
        print FH "Time:      ".localtime(time)." $tz\n";
        print FH "Account:   $account\n";
        print FH "Directory: $directory\n";
        if ($action == 2) {print FH "Action:    Directory disabled with chmod 000 and chattr +1\n"}
        if ($action == 3 and $account ne "[unkown]") {print FH "Action:    Account suspended where possible\n"}
        close (FH);
}
if ($action == 2) {
        # check this is a directory
        if (-d $directory) {
                # disable $directory
                system ("chmod 000 '$directory'; chattr +i '$directory'");
        }
}
if ($action == 3 and $account ne "") {
        # if this is definitely a cPanel account
        if (-e "/var/cpanel/users/$account") {
                # If this account is not already suspended
                unless (-e "/var/cpanel/suspended/$account") {
                                # Suspend the account
                                system("/scripts/suspendacct","$account");
                }
        }
}

exit;
