Skip to content

Instantly share code, notes, and snippets.

@pironic
Created June 13, 2014 22:00
Show Gist options
  • Save pironic/eff2edfa961e6626297a to your computer and use it in GitHub Desktop.
Save pironic/eff2edfa961e6626297a to your computer and use it in GitHub Desktop.
WHM/WHMCS/CPanel Reseller remote backup script for all customers
<?php
include_once('config.php');
include_once('database.php');
try {
// pull a list of customers that are eligible for offsite backup
$db = new Database(
$cfg['db']['host'],
$cfg['db']['dbase'],
$cfg['db']['user'],
$cfg['db']['pass']
);
$query = "SELECT h.username
FROM `tblhostingaddons` as a
LEFT JOIN `tblhosting` as h ON a.hostingid = h.id
WHERE a.addonid = " . $cfg['whmcs']['addonid'] . " AND h.domainstatus = 'Active' AND a.status = 'Active';";
$clients = $db->select($query);
}
catch (Exception $e)
{
die ("no point in continuing, we got tripped up. \n<pre>".$e->getMessage());
}
// login to the reseller account and prepare an auth token
$auth = "user=".$cfg['whm']['user'] ."&pass=".$cfg['whm']['pass'] ;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $cfg['whm']['url'] . "/login");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $auth);
curl_setopt($ch, CURLOPT_HEADER, 1);
$resell_output = curl_exec($ch);
$resell_info = curl_getinfo($ch);
$resell_headers = substr($resell_output, 0, $resell_info['header_size']);
$resell_redirect = $resell_info['redirect_url'];
$forward = strtok($resell_redirect, '?')."xfercpanel/";
$cookie = "";
// save the cookies as directed by the server.
foreach(explode("\r\n", $resell_headers) as $header)
{
$head = explode(": ",$header);
$key = (isset($head[0]) ? $head[0] : null);
$value = (isset($head[1]) ? $head[1] : null);
if ($key == "Set-Cookie") {
$cookie .= $value."; ";
}
}
foreach ($clients as $client)
{
// fetch the TOTP url for the customer
$cust = $client['username'];
curl_setopt($ch, CURLOPT_URL, $forward.$cust);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: $cookie"));
$cust_output = curl_exec($ch);
$cust_info = curl_getinfo($ch);
//echo "TOPP url for $cust : ".$cust_info['redirect_url']."\n";
// use it to login and generate a valid session
curl_setopt($ch, CURLOPT_URL, $cust_info['redirect_url']);
curl_setopt($ch, CURLOPT_HEADER, 1);
$cust_output = curl_exec($ch);
$cust_info = curl_getinfo($ch);
$cust_headers = substr($cust_output, 0, $cust_info['header_size']);
// fresh baking is always better
$custCookie = "";//$cookie;
foreach(explode("\r\n", $cust_headers) as $header)
{
$head = explode(": ",$header);
$key = (isset($head[0]) ? $head[0] : null);
$value = (isset($head[1]) ? $head[1] : null);
if ($key == "Set-Cookie") {
$custCookie .= $value."; ";
}
}
// instruct the cpanel to back up to ftp
$params = "dest=" . $cfg['ftp']['mode']
. "&email_radio=1"
. "&email=" . $cfg['log']['contact']
. "&server=" . $cfg['ftp']['host']
. "&user=" . $cfg['ftp']['user']
. "&pass=" . $cfg['ftp']['pass']
. "&port=" . $cfg['ftp']['port']
. "&rdir=" . $cfg['ftp']['dir']
. "&submit=Generate Backup";
$url = strtolower(str_replace("frontend/" . $cfg['cpanel']['skin'] . "/index.html",
"frontend/" . $cfg['cpanel']['skin'] . "/backup/dofullbackup.html",
strtok($cust_info['redirect_url'], '?')));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: $custCookie\r\nReferer: $url"));
$cust_output = curl_exec($ch);
$cust_info = curl_getinfo($ch);
if ($cust_info['http_code'] < 400)
echo " + backup scheduled for $cust\n";
else
echo " - backup problem for $cust : " . $cust_info['http_code'] . "\n";
// // print_r($cust_output);
// print_r($cust_info);
//echo "forward: $forward\n";
}
curl_close($ch);
?>
<?php
// Super secret file. Only person who should have read to this is the user running the cronjob.
$cfg['log']['contact'] = ""; // /dev/null to disable.
$cfg['db']['host'] = "";
$cfg['db']['dbase'] = "";
$cfg['db']['user'] = "";
$cfg['db']['pass'] = "";
$cfg['whm']['user'] = ""; // Username used to login to WHM
$cfg['whm']['pass'] = ""; // Password used to login to WHM
$cfg['whm']['url'] = ""; // Domain name where WHM is run
$cfg['whmcs']['addonid'] = 4; // The id of the addon you defined to identify hosting accounts to backup.
$cfg['cpanel']['skin'] = "x3"; // Theme that is set for all customers... customer choice is bad!
$cfg['ftp']['host'] = "";
$cfg['ftp']['user'] = "";
$cfg['ftp']['pass'] = "";
$cfg['ftp']['port'] = 21;
$cfg['ftp']['dir'] = "";
$cfg['ftp']['mode'] = "ftp"; // FTP mode ("ftp" for active, "passiveftp" for passive)
<?php
class QueryParameters
{
private $parms = array();
public function addParameter($parameterName, $parameterValue)
{
$this->parms[$parameterName] = $parameterValue;
}
public function clear()
{
unset($this->parms);
}
public function getParameterValue($parameterName)
{
return $this->parms[$parameterName];
}
public function getParameterNames()
{
return array_keys($this->parms);
}
}
class Database
{
public $MaintenanceMode;
protected $dbConnection = null;
private function bindParameters($stmt, $parms)
{
if ($parms != null)
{
//print "doing parameter binding...\n";
foreach($parms->getParameterNames() as $parameterName)
{
$stmt->bindValue($parameterName, $parms->getParameterValue($parameterName));
//print "binding parameter $parameterName with " . $parms->getParameterValue($parameterName) . "\n";
}
}
}
public function execute($query, QueryParameters $parms = null)
{
if ($this->dbConnection == null)
throw new Exception("Cannot execute a query, no open connection.");
$stmt = $this->dbConnection->prepare($query);
$this->bindParameters($stmt, $parms);
if ($this->MaintenanceMode == false)
$stmt->execute();
return $stmt;
}
public function select($query, $parms = array())
{
if ($this->dbConnection == null)
throw new Exception("Cannot execute a query, no open connection.");
$stmt = $this->dbConnection->prepare($query);
$this->bindParameters($stmt, $parms);
if ($this->MaintenanceMode == false)
$stmt->execute();
$result = null;
while ($row = $stmt->fetch())
{
if ($result == null)
$result = array();
$result[] = $row;
}
return $result;
}
public function __construct(
$host,
$database,
$user,
$pass,
$maintMode = false
)
{
$this->initialize($host, $database, $user, $pass);
$this->maintenanceMode = $maintMode;
}
public function __destruct()
{
$this->dbConnection = null;
}
private function initialize($host, $database, $user, $pass)
{
if ($this->dbConnection != null)
{
throw new Exception("Database connection is already open.");
}
$cfg['host'] = $host;
$cfg['dbase'] = $database;
$cfg['user'] = $user;
$cfg['pass'] = $pass;
$conn = "mysql:host={$cfg['host']};dbname={$cfg['dbase']}";
$this->dbConnection = new PDO($conn, $cfg['user'], $cfg['pass']);
/*
catch (PDOException $e) {
header(':', true, 503);
printf("<div id=\"fail_connect\">\n <error details=\"%s\" />\n</div>\n", $e->getMessage());
}
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment