make cronjobs also classes and began to refactor the whole cronjob stuff
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -1,256 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class DnsBase
|
||||
*
|
||||
* Base class for all DNS server configs
|
||||
*/
|
||||
abstract class DnsBase
|
||||
{
|
||||
|
||||
protected $_logger = false;
|
||||
|
||||
protected $_ns = array();
|
||||
|
||||
protected $_mx = array();
|
||||
|
||||
protected $_axfr = array();
|
||||
|
||||
abstract public function writeConfigs();
|
||||
|
||||
public function __construct($logger)
|
||||
{
|
||||
$this->_logger = $logger;
|
||||
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = gethostbynamel6($nameserver);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
// act like gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
}
|
||||
$this->_ns[] = array(
|
||||
'hostname' => $nameserver,
|
||||
'ips' => $nameserver_ips
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings::Get('system.mxservers') != '') {
|
||||
$mxservers = explode(',', Settings::Get('system.mxservers'));
|
||||
foreach ($mxservers as $mxserver) {
|
||||
if (substr($mxserver, - 1, 1) != '.') {
|
||||
$mxserver .= '.';
|
||||
}
|
||||
$this->_mx[] = $mxserver;
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server #100
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
$this->_axfr[] = trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDomainList()
|
||||
{
|
||||
$result_domains_stmt = Database::query("
|
||||
SELECT
|
||||
`d`.`id`,
|
||||
`d`.`domain`,
|
||||
`d`.`isemaildomain`,
|
||||
`d`.`iswildcarddomain`,
|
||||
`d`.`wwwserveralias`,
|
||||
`d`.`customerid`,
|
||||
`d`.`zonefile`,
|
||||
`d`.`bindserial`,
|
||||
`d`.`dkim`,
|
||||
`d`.`dkim_id`,
|
||||
`d`.`dkim_pubkey`,
|
||||
`d`.`ismainbutsubto`,
|
||||
`c`.`loginname`,
|
||||
`c`.`guid`
|
||||
FROM
|
||||
`" . TABLE_PANEL_DOMAINS . "` `d`
|
||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)
|
||||
WHERE
|
||||
`d`.`isbinddomain` = '1'
|
||||
ORDER BY
|
||||
`d`.`domain` ASC
|
||||
");
|
||||
|
||||
$domains = array();
|
||||
// don't use fetchall() to be able to set the first column to the domain id and use it later on to set the rows'
|
||||
// array of direct children without having to search the outer array
|
||||
while ($domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$domains[$domain["id"]] = $domain;
|
||||
}
|
||||
|
||||
// frolxor-hostname (#1090)
|
||||
if (Settings::get('system.dns_createhostnameentry') == 1) {
|
||||
$hostname_arr = array(
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'isbinddomain' => '1',
|
||||
'isemaildomain' => Settings::Get('system.dns_createmailentry'),
|
||||
'customerid' => 'none',
|
||||
'loginname' => 'froxlor.panel',
|
||||
'bindserial' => date('Ymd') . '00',
|
||||
'dkim' => '0',
|
||||
'iswildcarddomain' => '1',
|
||||
'ismainbutsubto' => '0',
|
||||
'zonefile' => '',
|
||||
'froxlorhost' => '1'
|
||||
);
|
||||
$domains['none'] = $hostname_arr;
|
||||
}
|
||||
|
||||
if (empty($domains)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// collect domain IDs of direct child domains as arrays in ['children'] column
|
||||
foreach (array_keys($domains) as $key) {
|
||||
if (! isset($domains[$key]['children'])) {
|
||||
$domains[$key]['children'] = array();
|
||||
}
|
||||
if ($domains[$key]['ismainbutsubto'] > 0) {
|
||||
if (isset($domains[$domains[$key]['ismainbutsubto']])) {
|
||||
$domains[$domains[$key]['ismainbutsubto']]['children'][] = $domains[$key]['id'];
|
||||
} else {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_ERR, 'Database inconsistency: domain ' . $domain['domain'] . ' (ID #' . $key . ') is set to to be subdomain to non-existent domain ID #' . $domains[$key]['ismainbutsubto'] . '. No DNS record(s) will be created for this domain.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_DEBUG, str_pad('domId', 9, ' ') . str_pad('domain', 40, ' ') . 'ismainbutsubto ' . str_pad('parent domain', 40, ' ') . "list of child domain ids");
|
||||
foreach ($domains as $domain) {
|
||||
$logLine = str_pad($domain['id'], 9, ' ') . str_pad($domain['domain'], 40, ' ') . str_pad($domain['ismainbutsubto'], 15, ' ') . str_pad(((isset($domains[$domain['ismainbutsubto']])) ? $domains[$domain['ismainbutsubto']]['domain'] : '-'), 40, ' ') . join(', ', $domain['children']);
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_DEBUG, $logLine);
|
||||
}
|
||||
|
||||
return $domains;
|
||||
}
|
||||
|
||||
public function reloadDaemon()
|
||||
{
|
||||
// reload DNS daemon
|
||||
$cmd = Settings::Get('system.bindreload_command');
|
||||
$cmdStatus = 1;
|
||||
safe_exec(escapeshellcmd($cmd), $cmdStatus);
|
||||
if ($cmdStatus === 0) {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, Settings::Get('system.dns_server') . ' daemon reloaded');
|
||||
} else {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_ERR, 'Error while running `' . $cmd . '`: exit code (' . $cmdStatus . ') - please check your system logs');
|
||||
}
|
||||
}
|
||||
|
||||
public function writeDKIMconfigs()
|
||||
{
|
||||
if (Settings::Get('dkim.use_dkim') == '1') {
|
||||
if (! file_exists(makeCorrectDir(Settings::Get('dkim.dkim_prefix')))) {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_NOTICE, 'mkdir -p ' . escapeshellarg(makeCorrectDir(Settings::Get('dkim.dkim_prefix'))));
|
||||
safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir(Settings::Get('dkim.dkim_prefix'))));
|
||||
}
|
||||
|
||||
$dkimdomains = '';
|
||||
$dkimkeys = '';
|
||||
$result_domains_stmt = Database::query("
|
||||
SELECT `id`, `domain`, `dkim`, `dkim_id`, `dkim_pubkey`, `dkim_privkey`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `dkim` = '1' ORDER BY `id` ASC
|
||||
");
|
||||
|
||||
while ($domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$privkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']);
|
||||
$pubkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public');
|
||||
|
||||
if ($domain['dkim_privkey'] == '' || $domain['dkim_pubkey'] == '') {
|
||||
$max_dkim_id_stmt = Database::query("SELECT MAX(`dkim_id`) as `max_dkim_id` FROM `" . TABLE_PANEL_DOMAINS . "`");
|
||||
$max_dkim_id = $max_dkim_id_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$domain['dkim_id'] = (int) $max_dkim_id['max_dkim_id'] + 1;
|
||||
$privkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']);
|
||||
safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
|
||||
$domain['dkim_privkey'] = file_get_contents($privkey_filename);
|
||||
safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));
|
||||
$pubkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public');
|
||||
safe_exec('openssl rsa -in ' . escapeshellarg($privkey_filename) . ' -pubout -outform pem -out ' . escapeshellarg($pubkey_filename));
|
||||
$domain['dkim_pubkey'] = file_get_contents($pubkey_filename);
|
||||
safe_exec("chmod 0664 " . escapeshellarg($pubkey_filename));
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`dkim_id` = :dkimid,
|
||||
`dkim_privkey` = :privkey,
|
||||
`dkim_pubkey` = :pubkey
|
||||
WHERE `id` = :id
|
||||
");
|
||||
$upd_data = array(
|
||||
'dkimid' => $domain['dkim_id'],
|
||||
'privkey' => $domain['dkim_privkey'],
|
||||
'pubkey' => $domain['dkim_pubkey'],
|
||||
'id' => $domain['id']
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
|
||||
if (! file_exists($privkey_filename) && $domain['dkim_privkey'] != '') {
|
||||
$privkey_file_handler = fopen($privkey_filename, "w");
|
||||
fwrite($privkey_file_handler, $domain['dkim_privkey']);
|
||||
fclose($privkey_file_handler);
|
||||
safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));
|
||||
}
|
||||
|
||||
if (! file_exists($pubkey_filename) && $domain['dkim_pubkey'] != '') {
|
||||
$pubkey_file_handler = fopen($pubkey_filename, "w");
|
||||
fwrite($pubkey_file_handler, $domain['dkim_pubkey']);
|
||||
fclose($pubkey_file_handler);
|
||||
safe_exec("chmod 0644 " . escapeshellarg($pubkey_filename));
|
||||
}
|
||||
|
||||
$dkimdomains .= $domain['domain'] . "\n";
|
||||
$dkimkeys .= "*@" . $domain['domain'] . ":" . $domain['domain'] . ":" . $privkey_filename . "\n";
|
||||
}
|
||||
|
||||
$dkimdomains_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/' . Settings::Get('dkim.dkim_domains'));
|
||||
$dkimdomains_file_handler = fopen($dkimdomains_filename, "w");
|
||||
fwrite($dkimdomains_file_handler, $dkimdomains);
|
||||
fclose($dkimdomains_file_handler);
|
||||
$dkimkeys_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/' . Settings::Get('dkim.dkim_dkimkeys'));
|
||||
$dkimkeys_file_handler = fopen($dkimkeys_filename, "w");
|
||||
fwrite($dkimkeys_file_handler, $dkimkeys);
|
||||
fclose($dkimkeys_file_handler);
|
||||
|
||||
safe_exec(escapeshellcmd(Settings::Get('dkim.dkimrestart_command')));
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Dkim-milter reloaded');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2017 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2017-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class Extrausers
|
||||
{
|
||||
|
||||
public static function generateFiles(&$cronlog)
|
||||
{
|
||||
// passwd
|
||||
$passwd = '/var/lib/extrausers/passwd';
|
||||
$sql = "SELECT username,'x' as password,uid,gid,'Froxlor User' as comment,homedir,shell, login_enabled FROM ftp_users ORDER BY uid ASC";
|
||||
self::_generateFile($passwd, $sql, $cronlog);
|
||||
|
||||
// group
|
||||
$group = '/var/lib/extrausers/group';
|
||||
$sql = "SELECT groupname,'x' as password,gid,members FROM ftp_groups ORDER BY gid ASC";
|
||||
self::_generateFile($group, $sql, $cronlog);
|
||||
|
||||
// shadow
|
||||
$shadow = '/var/lib/extrausers/shadow';
|
||||
$sql = "SELECT username,password FROM ftp_users ORDER BY gid ASC";
|
||||
self::_generateFile($shadow, $sql, $cronlog);
|
||||
|
||||
// set correct permissions
|
||||
@chmod('/var/lib/extrausers/', 0755);
|
||||
@chmod('/var/lib/extrausers/passwd', 0644);
|
||||
@chmod('/var/lib/extrausers/group', 0644);
|
||||
@chmod('/var/lib/extrausers/shadow', 0640);
|
||||
}
|
||||
|
||||
private static function _generateFile($file, $query, &$cronlog)
|
||||
{
|
||||
$type = basename($file);
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Creating ' . $type . ' file');
|
||||
|
||||
if (! file_exists($file)) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, $type . ' file does not yet exist');
|
||||
@mkdir(dirname($file), 0750, true);
|
||||
touch($file);
|
||||
}
|
||||
|
||||
$data_sel_stmt = Database::query($query);
|
||||
$data_content = "";
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Writing ' . $data_sel_stmt->rowCount() . ' entries to ' . $type . ' file');
|
||||
while ($u = $data_sel_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
switch ($type) {
|
||||
case 'passwd':
|
||||
if ($u['login_enabled'] != 'Y') {
|
||||
$u['password'] = '*';
|
||||
$u['shell'] = '/bin/false';
|
||||
$u['comment'] = 'Locked Froxlor User';
|
||||
}
|
||||
$line = $u['username'] . ':' . $u['password'] . ':' . $u['uid'] . ':' . $u['gid'] . ':' . $u['comment'] . ':' . $u['homedir'] . ':' . $u['shell'] . PHP_EOL;
|
||||
break;
|
||||
case 'group':
|
||||
$line = $u['groupname'] . ':' . $u['password'] . ':' . $u['gid'] . ':' . $u['members'] . PHP_EOL;
|
||||
break;
|
||||
case 'shadow':
|
||||
$line = $u['username'] . ':' . $u['password'] . ':' . floor(time() / 86400 - 1) . ':0:99999:7:::' . PHP_EOL;
|
||||
break;
|
||||
}
|
||||
$data_content .= $line;
|
||||
}
|
||||
if (file_put_contents($file, $data_content) !== false) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Succesfully wrote ' . $type . ' file');
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Error when writing ' . $type . ' file entries');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class HttpConfigBase
|
||||
*
|
||||
* Base class for all HTTP server configs
|
||||
*
|
||||
*/
|
||||
class HttpConfigBase
|
||||
{
|
||||
|
||||
/**
|
||||
* process special config as template, by substituting {VARIABLE} with the
|
||||
* respective value.
|
||||
*
|
||||
* The following variables are known at the moment:
|
||||
*
|
||||
* {DOMAIN} - domain name
|
||||
* {IP} - IP for this domain
|
||||
* {PORT} - Port for this domain
|
||||
* {CUSTOMER} - customer name
|
||||
* {IS_SSL} - evaluates to 'ssl' if domain/ip is ssl, otherwise it is an empty string
|
||||
* {DOCROOT} - document root for this domain
|
||||
*
|
||||
* @param
|
||||
* $template
|
||||
* @return string
|
||||
*/
|
||||
protected function processSpecialConfigTemplate($template, $domain, $ip, $port, $is_ssl_vhost)
|
||||
{
|
||||
$templateVars = array(
|
||||
'DOMAIN' => $domain['domain'],
|
||||
'CUSTOMER' => $domain['loginname'],
|
||||
'IP' => $ip,
|
||||
'PORT' => $port,
|
||||
'SCHEME' => ($is_ssl_vhost) ? 'https' : 'http',
|
||||
'DOCROOT' => $domain['documentroot']
|
||||
);
|
||||
return replace_variables($template, $templateVars);
|
||||
}
|
||||
|
||||
protected function getMyPath($ip_port = null)
|
||||
{
|
||||
if (! empty($ip_port) && $ip_port['docroot'] == '') {
|
||||
if (Settings::Get('system.froxlordirectlyviahostname')) {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__))));
|
||||
} else {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(dirname(__FILE__)))));
|
||||
}
|
||||
} else {
|
||||
// user-defined docroot, #417
|
||||
$mypath = makeCorrectDir($ip_port['docroot']);
|
||||
}
|
||||
return $mypath;
|
||||
}
|
||||
|
||||
protected function checkAlternativeSslPort()
|
||||
{
|
||||
// We must not check if our port differs from port 443,
|
||||
// but if there is a destination-port != 443
|
||||
$_sslport = '';
|
||||
// This returns the first port that is != 443 with ssl enabled,
|
||||
// ordered by ssl-certificate (if any) so that the ip/port combo
|
||||
// with certificate is used
|
||||
$ssldestport_stmt = Database::prepare("
|
||||
SELECT `ip`.`port` FROM " . TABLE_PANEL_IPSANDPORTS . " `ip`
|
||||
WHERE `ip`.`ssl` = '1' AND `ip`.`port` != 443
|
||||
ORDER BY `ip`.`ssl_cert_file` DESC, `ip`.`port` LIMIT 1;
|
||||
");
|
||||
$ssldestport = Database::pexecute_first($ssldestport_stmt);
|
||||
|
||||
if ($ssldestport['port'] != '') {
|
||||
$_sslport = ":" . $ssldestport['port'];
|
||||
}
|
||||
|
||||
return $_sslport;
|
||||
}
|
||||
|
||||
protected function froxlorVhostHasLetsEncryptCert()
|
||||
{
|
||||
// check whether we have an entry with valid certificates which just does not need
|
||||
// updating yet, so we need to skip this here
|
||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
if ($froxlor_ssl && ! empty($froxlor_ssl['ssl_cert_file'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function froxlorVhostLetsEncryptNeedsRenew()
|
||||
{
|
||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
WHERE `domainid` = '0' AND
|
||||
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
if ($froxlor_ssl && ! empty($froxlor_ssl['ssl_cert_file'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ for ($x = 1; $x < count($argv); $x++) {
|
||||
|
||||
$cronlog->setCronDebugFlag(defined('CRON_DEBUG_FLAG'));
|
||||
|
||||
$tasks_cnt_stmt = Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt_stmt = \Froxlor\Database\Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// do we have anything to include?
|
||||
@@ -88,14 +88,13 @@ if (count($jobs_to_run) > 0) {
|
||||
|
||||
if ($tasks_cnt['jobcnt'] > 0)
|
||||
{
|
||||
if (Settings::Get('system.nssextrausers') == 1)
|
||||
if (\Froxlor\Settings::Get('system.nssextrausers') == 1)
|
||||
{
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR.'/scripts/classes/class.Extrausers.php');
|
||||
Extrausers::generateFiles($cronlog);
|
||||
\Froxlor\Cron\System\Extrausers::generateFiles($cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (\Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int)\Froxlor\Settings::Get('phpfpm.enabled') == 1) {
|
||||
$false_val = false;
|
||||
safe_exec('nscd -i passwd 1> /dev/null', $false_val, array('>'));
|
||||
safe_exec('nscd -i group 1> /dev/null', $false_val, array('>'));
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.35.1
|
||||
*
|
||||
*/
|
||||
|
||||
// Check Traffic-Lock
|
||||
if (function_exists('pcntl_fork')) {
|
||||
$BackupLock = makeCorrectFile(dirname($lockfile)."/froxlor_cron_backup.lock");
|
||||
if (file_exists($BackupLock)
|
||||
&& is_numeric($BackupPid=file_get_contents($BackupLock))
|
||||
) {
|
||||
if (function_exists('posix_kill')) {
|
||||
$BackupPidStatus = @posix_kill($BackupPid,0);
|
||||
} else {
|
||||
system("kill -CHLD " . $BackupPid . " 1> /dev/null 2> /dev/null", $BackupPidStatus);
|
||||
$BackupPidStatus = $BackupPidStatus ? false : true;
|
||||
}
|
||||
if ($BackupPidStatus) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Backup run already in progress');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Create Backup Log and Fork
|
||||
// We close the database - connection before we fork, so we don't share resources with the child
|
||||
Database::needRoot(false); // this forces the connection to be set to null
|
||||
$BackupPid = pcntl_fork();
|
||||
// Parent
|
||||
if ($BackupPid) {
|
||||
file_put_contents($BackupLock, $BackupPid);
|
||||
// unnecessary to recreate database connection here
|
||||
return 0;
|
||||
|
||||
}
|
||||
//Child
|
||||
elseif ($BackupPid == 0) {
|
||||
posix_setsid();
|
||||
fclose($debugHandler);
|
||||
// re-create db
|
||||
Database::needRoot(false);
|
||||
}
|
||||
//Fork failed
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (extension_loaded('pcntl')) {
|
||||
$msg = "PHP compiled with pcntl but pcntl_fork function is not available.";
|
||||
} else {
|
||||
$msg = "PHP compiled without pcntl.";
|
||||
}
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, $msg." Not forking backup-cron, this may take a long time!");
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_backup: started - creating customer backup');
|
||||
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20' ORDER BY `id` ASC
|
||||
");
|
||||
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `id` = :id");
|
||||
|
||||
$all_jobs = $result_tasks_stmt->fetchAll();
|
||||
foreach ($all_jobs as $row) {
|
||||
|
||||
if ($row['data'] != '') {
|
||||
$row['data'] = json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['customerid'])
|
||||
&& isset($row['data']['loginname'])
|
||||
&& isset($row['data']['destdir'])
|
||||
) {
|
||||
$row['data']['destdir'] = makeCorrectDir($row['data']['destdir']);
|
||||
$customerdocroot = makeCorrectDir(Settings::Get('system.documentroot_prefix').'/'.$row['data']['loginname'].'/');
|
||||
|
||||
// create folder if not exists
|
||||
if (!file_exists($row['data']['destdir'])
|
||||
&& $row['data']['destdir'] != '/'
|
||||
&& $row['data']['destdir'] != Settings::Get('system.documentroot_prefix')
|
||||
&& $row['data']['destdir'] != $customerdocroot
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Creating backup-destination path for customer: ' . escapeshellarg($row['data']['destdir']));
|
||||
safe_exec('mkdir -p '.escapeshellarg($row['data']['destdir']));
|
||||
}
|
||||
|
||||
createCustomerBackup($row['data'], $customerdocroot, $cronlog);
|
||||
}
|
||||
}
|
||||
|
||||
// remove entry
|
||||
Database::pexecute($del_stmt, array('id' => $row['id']));
|
||||
}
|
||||
|
||||
if (function_exists('pcntl_fork')) {
|
||||
@unlink($BackupLock);
|
||||
die();
|
||||
}
|
||||
@@ -1,294 +0,0 @@
|
||||
<?php
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <kontakt-froxlor@neteraser.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.35
|
||||
*
|
||||
*/
|
||||
|
||||
if (Settings::Get('system.leapiversion') == '2') {
|
||||
// use ACME v2 is specified
|
||||
require_once __DIR__ . '/cron_letsencrypt_v2.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updating Let's Encrypt certificates");
|
||||
|
||||
if (! extension_loaded('curl')) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Let's Encrypt requires the php cURL extension to be installed.");
|
||||
exit();
|
||||
}
|
||||
|
||||
$certificates_stmt = Database::query("
|
||||
SELECT
|
||||
domssl.`id`,
|
||||
domssl.`domainid`,
|
||||
domssl.expirationdate,
|
||||
domssl.`ssl_cert_file`,
|
||||
domssl.`ssl_key_file`,
|
||||
domssl.`ssl_ca_file`,
|
||||
domssl.`ssl_csr_file`,
|
||||
dom.`domain`,
|
||||
dom.`wwwserveralias`,
|
||||
dom.`documentroot`,
|
||||
dom.`id` AS 'domainid',
|
||||
dom.`ssl_redirect`,
|
||||
cust.`leprivatekey`,
|
||||
cust.`lepublickey`,
|
||||
cust.`leregistered`,
|
||||
cust.`customerid`,
|
||||
cust.`loginname`
|
||||
FROM
|
||||
`" . TABLE_PANEL_CUSTOMERS . "` AS cust,
|
||||
`" . TABLE_PANEL_DOMAINS . "` AS dom
|
||||
LEFT JOIN
|
||||
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` AS domssl ON
|
||||
dom.`id` = domssl.`domainid`
|
||||
WHERE
|
||||
dom.`customerid` = cust.`customerid`
|
||||
AND cust.deactivated = 0
|
||||
AND dom.`letsencrypt` = 1
|
||||
AND dom.`aliasdomain` IS NULL
|
||||
AND dom.`iswildcarddomain` = 0
|
||||
AND (
|
||||
domssl.`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY)
|
||||
OR domssl.`expirationdate` IS NULL
|
||||
)
|
||||
");
|
||||
|
||||
$aliasdomains_stmt = Database::prepare("
|
||||
SELECT
|
||||
dom.`id` as domainid,
|
||||
dom.`domain`,
|
||||
dom.`wwwserveralias`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` AS dom
|
||||
WHERE
|
||||
dom.`aliasdomain` = :id
|
||||
AND dom.`letsencrypt` = 1
|
||||
AND dom.`iswildcarddomain` = 0
|
||||
");
|
||||
|
||||
$updcert_stmt = Database::prepare("
|
||||
REPLACE INTO
|
||||
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
SET
|
||||
`id` = :id,
|
||||
`domainid` = :domainid,
|
||||
`ssl_cert_file` = :crt,
|
||||
`ssl_key_file` = :key,
|
||||
`ssl_ca_file` = :ca,
|
||||
`ssl_cert_chainfile` = :chain,
|
||||
`ssl_csr_file` = :csr,
|
||||
`ssl_fullchain_file` = :fullchain,
|
||||
`expirationdate` = :expirationdate
|
||||
");
|
||||
|
||||
$upddom_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid");
|
||||
|
||||
// flag for re-generation of vhost files
|
||||
$changedetected = 0;
|
||||
|
||||
// first - generate LE for system-vhost if enabled
|
||||
if (Settings::Get('system.le_froxlor_enabled') == '1') {
|
||||
|
||||
$certrow = array(
|
||||
'loginname' => 'froxlor.panel',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'domainid' => 0,
|
||||
'documentroot' => FROXLOR_INSTALL_DIR,
|
||||
'leprivatekey' => Settings::Get('system.leprivatekey'),
|
||||
'lepublickey' => Settings::Get('system.lepublickey'),
|
||||
'leregistered' => Settings::Get('system.leregistered'),
|
||||
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
|
||||
'expirationdate' => null,
|
||||
'ssl_cert_file' => null,
|
||||
'ssl_key_file' => null,
|
||||
'ssl_ca_file' => null,
|
||||
'ssl_csr_file' => null,
|
||||
'id' => null
|
||||
);
|
||||
|
||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
WHERE `domainid` = '0' AND
|
||||
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
|
||||
$insert_or_update_required = true;
|
||||
if ($froxlor_ssl) {
|
||||
$certrow['id'] = $froxlor_ssl['id'];
|
||||
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
|
||||
$certrow['ssl_cert_file'] = $froxlor_ssl['ssl_cert_file'];
|
||||
$certrow['ssl_key_file'] = $froxlor_ssl['ssl_key_file'];
|
||||
$certrow['ssl_ca_file'] = $froxlor_ssl['ssl_ca_file'];
|
||||
$certrow['ssl_csr_file'] = $froxlor_ssl['ssl_csr_file'];
|
||||
} else {
|
||||
// check whether we have an entry with valid certificates which just does not need
|
||||
// updating yet, so we need to skip this here
|
||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
if ($froxlor_ssl && ! empty($froxlor_ssl['ssl_cert_file'])) {
|
||||
$insert_or_update_required = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($insert_or_update_required) {
|
||||
$domains = array(
|
||||
$certrow['domain']
|
||||
);
|
||||
|
||||
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
|
||||
// - this temp. deactivation of the ssl-redirect is handled by the webserver-cronjob
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updating " . $certrow['domain']);
|
||||
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => $certrow['loginname']
|
||||
));
|
||||
|
||||
try {
|
||||
// Initialize Lescript with documentroot
|
||||
$le = new lescript($cronlog, $version);
|
||||
|
||||
// Initialize Lescript
|
||||
$le->initAccount($certrow, true);
|
||||
|
||||
// Request the new certificate (old key may be used)
|
||||
$return = $le->signDomains($domains, $certrow['ssl_key_file']);
|
||||
|
||||
// We are interessted in the expirationdate
|
||||
$newcert = openssl_x509_parse($return['crt']);
|
||||
|
||||
// Store the new data
|
||||
Database::pexecute($updcert_stmt, array(
|
||||
'id' => $certrow['id'],
|
||||
'domainid' => $certrow['domainid'],
|
||||
'crt' => $return['crt'],
|
||||
'key' => $return['key'],
|
||||
'ca' => $return['chain'],
|
||||
'chain' => $return['chain'],
|
||||
'csr' => $return['csr'],
|
||||
'fullchain' => $return['fullchain'],
|
||||
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
|
||||
));
|
||||
|
||||
if ($certrow['ssl_redirect'] == 3) {
|
||||
Settings::Set('system.le_froxlor_redirect', '1');
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
|
||||
|
||||
$changedetected = 1;
|
||||
} catch (Exception $e) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// customer domains
|
||||
$certrows = $certificates_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($certrows as $certrow) {
|
||||
|
||||
// set logger to corresponding loginname for the log to appear in the users system-log
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => $certrow['loginname']
|
||||
));
|
||||
|
||||
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
|
||||
if ($certrow['ssl_redirect'] != 2) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updating " . $certrow['domain']);
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']);
|
||||
$domains = array(
|
||||
$certrow['domain']
|
||||
);
|
||||
// add www.<domain> to SAN list
|
||||
if ($certrow['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
|
||||
$domains[] = 'www.' . $certrow['domain'];
|
||||
}
|
||||
|
||||
// add alias domains (and possibly www.<aliasdomain>) to SAN list
|
||||
Database::pexecute($aliasdomains_stmt, array(
|
||||
'id' => $certrow['domainid']
|
||||
));
|
||||
$aliasdomains = $aliasdomains_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($aliasdomains as $aliasdomain) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
|
||||
$domains[] = $aliasdomain['domain'];
|
||||
if ($aliasdomain['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
|
||||
$domains[] = 'www.' . $aliasdomain['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Initialize Lescript with documentroot
|
||||
$le = new lescript($cronlog, $version);
|
||||
|
||||
// Initialize Lescript
|
||||
$le->initAccount($certrow);
|
||||
|
||||
// Request the new certificate (old key may be used)
|
||||
$return = $le->signDomains($domains, $certrow['ssl_key_file']);
|
||||
|
||||
// We are interessted in the expirationdate
|
||||
$newcert = openssl_x509_parse($return['crt']);
|
||||
|
||||
// Store the new data
|
||||
Database::pexecute($updcert_stmt, array(
|
||||
'id' => $certrow['id'],
|
||||
'domainid' => $certrow['domainid'],
|
||||
'crt' => $return['crt'],
|
||||
'key' => $return['key'],
|
||||
'ca' => $return['chain'],
|
||||
'chain' => $return['chain'],
|
||||
'csr' => $return['csr'],
|
||||
'fullchain' => $return['fullchain'],
|
||||
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
|
||||
));
|
||||
|
||||
if ($certrow['ssl_redirect'] == 3) {
|
||||
Database::pexecute($upddom_stmt, array(
|
||||
'domainid' => $certrow['domainid']
|
||||
));
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
|
||||
|
||||
$changedetected = 1;
|
||||
} catch (Exception $e) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a change in a certificate, we need to update the webserver - configs
|
||||
// This is easiest done by just creating a new task ;)
|
||||
if ($changedetected) {
|
||||
inserttask(1);
|
||||
}
|
||||
|
||||
// reset logger
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'cronjob'
|
||||
));
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
|
||||
@@ -1,300 +0,0 @@
|
||||
<?php
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <kontakt-froxlor@neteraser.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.35
|
||||
*
|
||||
*/
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updating Let's Encrypt certificates");
|
||||
|
||||
if (! extension_loaded('curl')) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Let's Encrypt requires the php cURL extension to be installed.");
|
||||
exit();
|
||||
}
|
||||
|
||||
$certificates_stmt = Database::query("
|
||||
SELECT
|
||||
domssl.`id`,
|
||||
domssl.`domainid`,
|
||||
domssl.expirationdate,
|
||||
domssl.`ssl_cert_file`,
|
||||
domssl.`ssl_key_file`,
|
||||
domssl.`ssl_ca_file`,
|
||||
domssl.`ssl_csr_file`,
|
||||
dom.`domain`,
|
||||
dom.`wwwserveralias`,
|
||||
dom.`iswildcarddomain`,
|
||||
dom.`documentroot`,
|
||||
dom.`id` AS 'domainid',
|
||||
dom.`ssl_redirect`,
|
||||
cust.`leprivatekey`,
|
||||
cust.`lepublickey`,
|
||||
cust.`leregistered`,
|
||||
cust.`leaccount`,
|
||||
cust.`customerid`,
|
||||
cust.`loginname`
|
||||
FROM
|
||||
`" . TABLE_PANEL_CUSTOMERS . "` AS cust,
|
||||
`" . TABLE_PANEL_DOMAINS . "` AS dom
|
||||
LEFT JOIN
|
||||
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` AS domssl ON
|
||||
dom.`id` = domssl.`domainid`
|
||||
WHERE
|
||||
dom.`customerid` = cust.`customerid`
|
||||
AND cust.deactivated = 0
|
||||
AND dom.`letsencrypt` = 1
|
||||
AND dom.`aliasdomain` IS NULL
|
||||
AND dom.`iswildcarddomain` = 0
|
||||
AND (
|
||||
domssl.`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY)
|
||||
OR domssl.`expirationdate` IS NULL
|
||||
)
|
||||
");
|
||||
|
||||
$aliasdomains_stmt = Database::prepare("
|
||||
SELECT
|
||||
dom.`id` as domainid,
|
||||
dom.`domain`,
|
||||
dom.`wwwserveralias`,
|
||||
dom.`iswildcarddomain`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` AS dom
|
||||
WHERE
|
||||
dom.`aliasdomain` = :id
|
||||
AND dom.`letsencrypt` = 1
|
||||
AND dom.`iswildcarddomain` = 0
|
||||
");
|
||||
|
||||
$updcert_stmt = Database::prepare("
|
||||
REPLACE INTO
|
||||
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
SET
|
||||
`id` = :id,
|
||||
`domainid` = :domainid,
|
||||
`ssl_cert_file` = :crt,
|
||||
`ssl_key_file` = :key,
|
||||
`ssl_ca_file` = :ca,
|
||||
`ssl_cert_chainfile` = :chain,
|
||||
`ssl_csr_file` = :csr,
|
||||
`ssl_fullchain_file` = :fullchain,
|
||||
`expirationdate` = :expirationdate
|
||||
");
|
||||
|
||||
$upddom_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid");
|
||||
|
||||
// flag for re-generation of vhost files
|
||||
$changedetected = 0;
|
||||
|
||||
// first - generate LE for system-vhost if enabled
|
||||
if (Settings::Get('system.le_froxlor_enabled') == '1') {
|
||||
|
||||
$certrow = array(
|
||||
'loginname' => 'froxlor.panel',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'domainid' => 0,
|
||||
'documentroot' => FROXLOR_INSTALL_DIR,
|
||||
'leprivatekey' => Settings::Get('system.leprivatekey'),
|
||||
'lepublickey' => Settings::Get('system.lepublickey'),
|
||||
'leregistered' => Settings::Get('system.leregistered'),
|
||||
'leaccount' => Settings::Get('system.leaccount'),
|
||||
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
|
||||
'expirationdate' => null,
|
||||
'ssl_cert_file' => null,
|
||||
'ssl_key_file' => null,
|
||||
'ssl_ca_file' => null,
|
||||
'ssl_csr_file' => null,
|
||||
'id' => null
|
||||
);
|
||||
|
||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
WHERE `domainid` = '0' AND
|
||||
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
|
||||
$insert_or_update_required = true;
|
||||
if ($froxlor_ssl) {
|
||||
$certrow['id'] = $froxlor_ssl['id'];
|
||||
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
|
||||
$certrow['ssl_cert_file'] = $froxlor_ssl['ssl_cert_file'];
|
||||
$certrow['ssl_key_file'] = $froxlor_ssl['ssl_key_file'];
|
||||
$certrow['ssl_ca_file'] = $froxlor_ssl['ssl_ca_file'];
|
||||
$certrow['ssl_csr_file'] = $froxlor_ssl['ssl_csr_file'];
|
||||
} else {
|
||||
// check whether we have an entry with valid certificates which just does not need
|
||||
// updating yet, so we need to skip this here
|
||||
$froxlor_ssl_settings_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
if ($froxlor_ssl && ! empty($froxlor_ssl['ssl_cert_file'])) {
|
||||
$insert_or_update_required = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($insert_or_update_required) {
|
||||
$domains = array(
|
||||
$certrow['domain']
|
||||
);
|
||||
|
||||
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
|
||||
// - this temp. deactivation of the ssl-redirect is handled by the webserver-cronjob
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updating " . $certrow['domain']);
|
||||
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => $certrow['loginname']
|
||||
));
|
||||
|
||||
try {
|
||||
// Initialize Lescript with documentroot
|
||||
$le = new lescript_v2($cronlog, $version);
|
||||
|
||||
// Initialize Lescript
|
||||
$le->initAccount($certrow, true);
|
||||
|
||||
// Request the new certificate (old key may be used)
|
||||
$return = $le->signDomains($domains, $certrow['ssl_key_file']);
|
||||
|
||||
// We are interessted in the expirationdate
|
||||
$newcert = openssl_x509_parse($return['crt']);
|
||||
|
||||
// Store the new data
|
||||
Database::pexecute($updcert_stmt, array(
|
||||
'id' => $certrow['id'],
|
||||
'domainid' => $certrow['domainid'],
|
||||
'crt' => $return['crt'],
|
||||
'key' => $return['key'],
|
||||
'ca' => $return['chain'],
|
||||
'chain' => $return['chain'],
|
||||
'csr' => $return['csr'],
|
||||
'fullchain' => $return['fullchain'],
|
||||
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
|
||||
));
|
||||
|
||||
if ($certrow['ssl_redirect'] == 3) {
|
||||
Settings::Set('system.le_froxlor_redirect', '1');
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
|
||||
|
||||
$changedetected = 1;
|
||||
} catch (Exception $e) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// customer domains
|
||||
$certrows = $certificates_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($certrows as $certrow) {
|
||||
|
||||
// set logger to corresponding loginname for the log to appear in the users system-log
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => $certrow['loginname']
|
||||
));
|
||||
|
||||
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
|
||||
if ($certrow['ssl_redirect'] != 2) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updating " . $certrow['domain']);
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']);
|
||||
$domains = array(
|
||||
$certrow['domain']
|
||||
);
|
||||
if ($certrow['iswildcarddomain'] == 1) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: *." . $certrow['domain']);
|
||||
$domains[] = '*.' . $certrow['domain'];
|
||||
}
|
||||
elseif ($certrow['wwwserveralias'] == 1) {
|
||||
// add www.<domain> to SAN list
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
|
||||
$domains[] = 'www.' . $certrow['domain'];
|
||||
}
|
||||
|
||||
// add alias domains (and possibly www.<aliasdomain>) to SAN list
|
||||
Database::pexecute($aliasdomains_stmt, array(
|
||||
'id' => $certrow['domainid']
|
||||
));
|
||||
$aliasdomains = $aliasdomains_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($aliasdomains as $aliasdomain) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
|
||||
$domains[] = $aliasdomain['domain'];
|
||||
if ($aliasdomain['iswildcarddomain'] == 1) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: *." . $aliasdomain['domain']);
|
||||
$domains[] = '*.' . $aliasdomain['domain'];
|
||||
}
|
||||
elseif ($aliasdomain['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
|
||||
$domains[] = 'www.' . $aliasdomain['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Initialize Lescript with documentroot
|
||||
$le = new lescript_v2($cronlog, $version);
|
||||
|
||||
// Initialize Lescript
|
||||
$le->initAccount($certrow);
|
||||
|
||||
// Request the new certificate (old key may be used)
|
||||
$return = $le->signDomains($domains, $certrow['ssl_key_file']);
|
||||
|
||||
// We are interessted in the expirationdate
|
||||
$newcert = openssl_x509_parse($return['crt']);
|
||||
|
||||
// Store the new data
|
||||
Database::pexecute($updcert_stmt, array(
|
||||
'id' => $certrow['id'],
|
||||
'domainid' => $certrow['domainid'],
|
||||
'crt' => $return['crt'],
|
||||
'key' => $return['key'],
|
||||
'ca' => $return['chain'],
|
||||
'chain' => $return['chain'],
|
||||
'csr' => $return['csr'],
|
||||
'fullchain' => $return['fullchain'],
|
||||
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
|
||||
));
|
||||
|
||||
if ($certrow['ssl_redirect'] == 3) {
|
||||
Database::pexecute($upddom_stmt, array(
|
||||
'domainid' => $certrow['domainid']
|
||||
));
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
|
||||
|
||||
$changedetected = 1;
|
||||
} catch (Exception $e) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a change in a certificate, we need to update the webserver - configs
|
||||
// This is easiest done by just creating a new task ;)
|
||||
if ($changedetected) {
|
||||
inserttask(1);
|
||||
}
|
||||
|
||||
// reset logger
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'cronjob'
|
||||
));
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.29.1
|
||||
*
|
||||
*/
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'calculating mailspace usage');
|
||||
|
||||
$maildirs_stmt = Database::query("
|
||||
SELECT `id`, CONCAT(`homedir`, `maildir`) AS `maildirpath` FROM `".TABLE_MAIL_USERS."` ORDER BY `id`
|
||||
");
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `".TABLE_MAIL_USERS."` SET `mboxsize` = :size WHERE `id` = :id
|
||||
");
|
||||
|
||||
while ($maildir = $maildirs_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$_maildir = makeCorrectDir($maildir['maildirpath']);
|
||||
|
||||
if (file_exists($_maildir)
|
||||
&& is_dir($_maildir)
|
||||
) {
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($_maildir), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
foreach ($back as $backrow) {
|
||||
$emailusage = explode(' ', $backrow);
|
||||
}
|
||||
$emailusage = floatval($emailusage['0']);
|
||||
|
||||
// as freebsd does not have the -b flag for 'du' which gives
|
||||
// the size in bytes, we use "-sk" for all and calculate from KiB
|
||||
$emailusage *= 1024;
|
||||
|
||||
unset($back);
|
||||
Database::pexecute($upd_stmt, array('size' => $emailusage, 'id' => $maildir['id']));
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'maildir ' . $_maildir . ' does not exist');
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
<?php
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class bind extends DnsBase
|
||||
{
|
||||
|
||||
private $_bindconf_file = "";
|
||||
|
||||
public function writeConfigs()
|
||||
{
|
||||
// tell the world what we are doing
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Task4 started - Rebuilding froxlor_bind.conf');
|
||||
|
||||
// clean up
|
||||
$this->_cleanZonefiles();
|
||||
|
||||
// check for subfolder in bind-config-directory
|
||||
if (! file_exists(makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/'))) {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_NOTICE, 'mkdir ' . escapeshellarg(makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
}
|
||||
|
||||
$domains = $this->getDomainList();
|
||||
|
||||
if (empty($domains)) {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
$bindconf_file = '# ' . Settings::Get('system.bindconf_directory') . 'froxlor_bind.conf' . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n";
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
if ($domain['ismainbutsubto'] > 0) {
|
||||
// domains with ismainbutsubto>0 are handled by recursion within walkDomainList()
|
||||
continue;
|
||||
}
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
|
||||
$bindconf_file_handler = fopen(makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
|
||||
fwrite($bindconf_file_handler, $this->_bindconf_file);
|
||||
fclose($bindconf_file_handler);
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'froxlor_bind.conf written');
|
||||
$this->reloadDaemon();
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
}
|
||||
|
||||
|
||||
private function walkDomainList($domain, $domains)
|
||||
{
|
||||
$zoneContent = '';
|
||||
$subzones = '';
|
||||
|
||||
foreach ($domain['children'] as $child_domain_id) {
|
||||
$subzones .= $this->walkDomainList($domains[$child_domain_id], $domains);
|
||||
}
|
||||
|
||||
if ($domain['zonefile'] == '') {
|
||||
// check for system-hostname
|
||||
$isFroxlorHostname = false;
|
||||
if (isset($domain['froxlorhost']) && $domain['froxlorhost'] == 1) {
|
||||
$isFroxlorHostname = true;
|
||||
}
|
||||
|
||||
if ($domain['ismainbutsubto'] == 0) {
|
||||
$zoneContent = (string) createDomainZone(($domain['id'] == 'none') ?
|
||||
$domain :
|
||||
$domain['id'],
|
||||
$isFroxlorHostname);
|
||||
$domain['zonefile'] = 'domains/' . $domain['domain'] . '.zone';
|
||||
$zonefile_name = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' .
|
||||
$domain['zonefile']);
|
||||
$zonefile_handler = fopen($zonefile_name, 'w');
|
||||
fwrite($zonefile_handler, $zoneContent . $subzones);
|
||||
fclose($zonefile_handler);
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, '`' . $zonefile_name . '` written');
|
||||
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
|
||||
} else {
|
||||
return (string) createDomainZone(($domain['id'] == 'none') ?
|
||||
$domain :
|
||||
$domain['id'],
|
||||
$isFroxlorHostname,
|
||||
true);
|
||||
}
|
||||
} else {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO,
|
||||
'Added zonefile ' . $domain['zonefile'] . ' for domain ' . $domain['domain'] .
|
||||
' - Note that you will also have to handle ALL records for ALL subdomains.');
|
||||
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
|
||||
}
|
||||
}
|
||||
|
||||
private function _generateDomainConfig($domain = array())
|
||||
{
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_DEBUG, 'Generating dns config for ' . $domain['domain']);
|
||||
|
||||
$bindconf_file = '# Domain ID: ' . $domain['id'] . ' - CustomerID: ' . $domain['customerid'] . ' - CustomerLogin: ' . $domain['loginname'] . "\n";
|
||||
$bindconf_file .= 'zone "' . $domain['domain'] . '" in {' . "\n";
|
||||
$bindconf_file .= ' type master;' . "\n";
|
||||
$bindconf_file .= ' file "' . makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']) . '";' . "\n";
|
||||
$bindconf_file .= ' allow-query { any; };' . "\n";
|
||||
|
||||
if (count($this->_ns) > 0 || count($this->_axfr) > 0) {
|
||||
// open allow-transfer
|
||||
$bindconf_file .= ' allow-transfer {' . "\n";
|
||||
// put nameservers in allow-transfer
|
||||
if (count($this->_ns) > 0) {
|
||||
foreach ($this->_ns as $ns) {
|
||||
foreach ($ns["ips"] as $ip) {
|
||||
$bindconf_file .= ' ' . $ip . ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// AXFR server #100
|
||||
if (count($this->_axfr) > 0) {
|
||||
foreach ($this->_axfr as $axfrserver) {
|
||||
$bindconf_file .= ' ' . $axfrserver . ';' . "\n";
|
||||
}
|
||||
}
|
||||
// close allow-transfer
|
||||
$bindconf_file .= ' };' . "\n";
|
||||
}
|
||||
|
||||
$bindconf_file .= '};' . "\n";
|
||||
$bindconf_file .= "\n";
|
||||
|
||||
return $bindconf_file;
|
||||
}
|
||||
|
||||
private function _cleanZonefiles()
|
||||
{
|
||||
$config_dir = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/domains/');
|
||||
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Cleaning dns zone files from ' . $config_dir);
|
||||
|
||||
// check directory
|
||||
if (@is_dir($config_dir)) {
|
||||
|
||||
// create directory iterator
|
||||
$its = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($config_dir));
|
||||
|
||||
// iterate through all subdirs, look for zone files and delete them
|
||||
foreach ($its as $it) {
|
||||
if ($it->isFile()) {
|
||||
// remove file
|
||||
safe_exec('rm -f ' . escapeshellarg(makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
<?php
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class pdns extends DnsBase
|
||||
{
|
||||
|
||||
public function writeConfigs()
|
||||
{
|
||||
// tell the world what we are doing
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Task4 started - Refreshing DNS database');
|
||||
|
||||
$domains = $this->getDomainList();
|
||||
|
||||
// clean up
|
||||
$this->_clearZoneTables($domains);
|
||||
|
||||
if (empty($domains)) {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
if ($domain['ismainbutsubto'] > 0) {
|
||||
// domains with ismainbutsubto>0 are handled by recursion within walkDomainList()
|
||||
continue;
|
||||
}
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'PowerDNS database updated');
|
||||
$this->reloadDaemon();
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
}
|
||||
|
||||
private function walkDomainList($domain, $domains)
|
||||
{
|
||||
$zoneContent = '';
|
||||
$subzones = array();
|
||||
|
||||
foreach ($domain['children'] as $child_domain_id) {
|
||||
$subzones[] = $this->walkDomainList($domains[$child_domain_id], $domains);
|
||||
}
|
||||
|
||||
if ($domain['zonefile'] == '') {
|
||||
// check for system-hostname
|
||||
$isFroxlorHostname = false;
|
||||
if (isset($domain['froxlorhost']) && $domain['froxlorhost'] == 1) {
|
||||
$isFroxlorHostname = true;
|
||||
}
|
||||
|
||||
if ($domain['ismainbutsubto'] == 0) {
|
||||
$zoneContent = createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
|
||||
if (count($subzones)) {
|
||||
foreach ($subzones as $subzone) {
|
||||
$zoneContent->records[] = $subzone;
|
||||
}
|
||||
}
|
||||
$pdnsDomId = $this->_insertZone($zoneContent->origin, $zoneContent->serial);
|
||||
$this->_insertRecords($pdnsDomId, $zoneContent->records, $zoneContent->origin);
|
||||
$this->_insertAllowedTransfers($pdnsDomId);
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'DB entries stored for zone `' . $domain['domain'] . '`');
|
||||
} else {
|
||||
return createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname, true);
|
||||
}
|
||||
} else {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_ERROR, 'Custom zonefiles are NOT supported when PowerDNS is selected as DNS daemon (triggered by: ' . $domain['domain'] . ')');
|
||||
}
|
||||
}
|
||||
|
||||
private function _clearZoneTables($domains = null)
|
||||
{
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Cleaning dns zone entries from database');
|
||||
|
||||
$pdns_domains_stmt = PowerDNS::getDB()->prepare("SELECT `id`, `name` FROM `domains` WHERE `name` = :domain");
|
||||
|
||||
$del_rec_stmt = PowerDNS::getDB()->prepare("DELETE FROM `records` WHERE `domain_id` = :did");
|
||||
$del_meta_stmt = PowerDNS::getDB()->prepare("DELETE FROM `domainmetadata` WHERE `domain_id` = :did");
|
||||
$del_dom_stmt = PowerDNS::getDB()->prepare("DELETE FROM `domains` WHERE `id` = :did");
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$pdns_domains_stmt->execute(array(
|
||||
'domain' => $domain['domain']
|
||||
));
|
||||
$pdns_domain = $pdns_domains_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
$del_rec_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
$del_meta_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
$del_dom_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function _insertZone($domainname, $serial = 0)
|
||||
{
|
||||
$ins_stmt = PowerDNS::getDB()->prepare("
|
||||
INSERT INTO domains set `name` = :domainname, `notified_serial` = :serial, `type` = 'NATIVE'
|
||||
");
|
||||
$ins_stmt->execute(array(
|
||||
'domainname' => $domainname,
|
||||
'serial' => $serial
|
||||
));
|
||||
$lastid = PowerDNS::getDB()->lastInsertId();
|
||||
return $lastid;
|
||||
}
|
||||
|
||||
private function _insertRecords($domainid = 0, $records, $origin)
|
||||
{
|
||||
$changedate = date('Ymds', time());
|
||||
|
||||
$ins_stmt = PowerDNS::getDB()->prepare("
|
||||
INSERT INTO records set
|
||||
`domain_id` = :did,
|
||||
`name` = :rec,
|
||||
`type` = :type,
|
||||
`content` = :content,
|
||||
`ttl` = :ttl,
|
||||
`prio` = :prio,
|
||||
`disabled` = '0',
|
||||
`change_date` = :changedate
|
||||
");
|
||||
|
||||
foreach ($records as $record) {
|
||||
if ($record instanceof DnsZone) {
|
||||
$this->_insertRecords($domainid, $record->records, $record->origin);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($record->record == '@') {
|
||||
$_record = $origin;
|
||||
} else {
|
||||
$_record = $record->record . "." . $origin;
|
||||
}
|
||||
|
||||
$ins_data = array(
|
||||
'did' => $domainid,
|
||||
'rec' => $_record,
|
||||
'type' => $record->type,
|
||||
'content' => $record->content,
|
||||
'ttl' => $record->ttl,
|
||||
'prio' => $record->priority,
|
||||
'changedate' => $changedate
|
||||
);
|
||||
$ins_stmt->execute($ins_data);
|
||||
}
|
||||
}
|
||||
|
||||
private function _insertAllowedTransfers($domainid)
|
||||
{
|
||||
$ins_stmt = PowerDNS::getDB()->prepare("
|
||||
INSERT INTO domainmetadata set `domain_id` = :did, `kind` = 'ALLOW-AXFR-FROM', `content` = :value
|
||||
");
|
||||
|
||||
$ins_data = array(
|
||||
'did' => $domainid
|
||||
);
|
||||
|
||||
if (count($this->_ns) > 0 || count($this->_axfr) > 0) {
|
||||
// put nameservers in allow-transfer
|
||||
if (count($this->_ns) > 0) {
|
||||
foreach ($this->_ns as $ns) {
|
||||
foreach ($ns["ips"] as $ip) {
|
||||
$ins_data['value'] = $ip;
|
||||
$ins_stmt->execute($ins_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
// AXFR server #100
|
||||
if (count($this->_axfr) > 0) {
|
||||
foreach ($this->_axfr as $axfrserver) {
|
||||
$ins_data['value'] = $axfrserver;
|
||||
$ins_stmt->execute($ins_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,237 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
class apache_fcgid extends apache
|
||||
{
|
||||
protected function composePhpOptions($domain, $ssl_vhost = false)
|
||||
{
|
||||
$php_options_text = '';
|
||||
|
||||
if($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1')
|
||||
{
|
||||
$php = new phpinterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
if((int)Settings::Get('phpfpm.enabled') == 1)
|
||||
{
|
||||
$srvName = 'fpm.external';
|
||||
if ($domain['ssl'] == 1 && $ssl_vhost) {
|
||||
$srvName = 'ssl-fpm.external';
|
||||
}
|
||||
// #1317 - perl is executed via apache and therefore, when using fpm, does not know the user
|
||||
// which perl is supposed to run as, hence the need for Suexec need
|
||||
if (customerHasPerlEnabled($domain['customerid'])) {
|
||||
$php_options_text.= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
|
||||
}
|
||||
|
||||
// mod_proxy stuff for apache-2.4
|
||||
if (Settings::Get('system.apache24') == '1'
|
||||
&& Settings::Get('phpfpm.use_mod_proxy') == '1'
|
||||
) {
|
||||
$filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
|
||||
$extensions = explode(" ", $filesmatch);
|
||||
$filesmatch = "";
|
||||
foreach ($extensions as $ext) {
|
||||
$filesmatch .= substr($ext, 1).'|';
|
||||
}
|
||||
// start block, cut off last pipe and close block
|
||||
$filesmatch = '('.str_replace(".", "\.", substr($filesmatch, 0, -1)).')';
|
||||
$php_options_text.= ' <FilesMatch \.'.$filesmatch.'$>'. "\n";
|
||||
$php_options_text.= ' SetHandler proxy:unix:' . $php->getInterface()->getSocketFile() . '|fcgi://localhost'. "\n";
|
||||
$php_options_text.= ' </FilesMatch>' . "\n";
|
||||
|
||||
$mypath_dir = new frxDirectory($domain['documentroot']);
|
||||
|
||||
// only create the require all granted if there is not active directory-protection
|
||||
// for this path, as this would be the first require and therefore grant all access
|
||||
if ($mypath_dir->isUserProtected() == false) {
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
if ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
$php_options_text.= ' CGIPassAuth On' . "\n";
|
||||
}
|
||||
$php_options_text.= ' Require all granted' . "\n";
|
||||
$php_options_text.= ' AllowOverride All' . "\n";
|
||||
$php_options_text.= ' </Directory>' . "\n";
|
||||
} elseif ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
// allow Pass of Authorization header
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text.= ' CGIPassAuth On' . "\n";
|
||||
$php_options_text.= ' </Directory>' . "\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
$addheader = "";
|
||||
if ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
$addheader = " -pass-header Authorization";
|
||||
}
|
||||
$php_options_text.= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $php->getInterface()->getSocketFile() . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n";
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
|
||||
$extensions = explode(" ", $filesmatch);
|
||||
$filesmatch = "";
|
||||
foreach ($extensions as $ext) {
|
||||
$filesmatch .= substr($ext, 1).'|';
|
||||
}
|
||||
// start block, cut off last pipe and close block
|
||||
$filesmatch = '('.str_replace(".", "\.", substr($filesmatch, 0, -1)).')';
|
||||
$php_options_text.= ' <FilesMatch \.'.$filesmatch.'$>'. "\n";
|
||||
$php_options_text.= ' SetHandler php-fastcgi'. "\n";
|
||||
$php_options_text.= ' Action php-fastcgi /fastcgiphp' . "\n";
|
||||
$php_options_text.= ' Options +ExecCGI' . "\n";
|
||||
$php_options_text.= ' </FilesMatch>' . "\n";
|
||||
// >=apache-2.4 enabled?
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$mypath_dir = new frxDirectory($domain['documentroot']);
|
||||
// only create the require all granted if there is not active directory-protection
|
||||
// for this path, as this would be the first require and therefore grant all access
|
||||
if ($mypath_dir->isUserProtected() == false) {
|
||||
$php_options_text.= ' Require all granted' . "\n";
|
||||
$php_options_text.= ' AllowOverride All' . "\n";
|
||||
}
|
||||
} else {
|
||||
$php_options_text.= ' Order allow,deny' . "\n";
|
||||
$php_options_text.= ' allow from all' . "\n";
|
||||
}
|
||||
$php_options_text.= ' </Directory>' . "\n";
|
||||
$php_options_text.= ' Alias /fastcgiphp ' . $php->getInterface()->getAliasConfigDir() . $srvName . "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= ' FcgidIdleTimeout ' . Settings::Get('system.mod_fcgid_idle_timeout') . "\n";
|
||||
if((int)Settings::Get('system.mod_fcgid_wrapper') == 0)
|
||||
{
|
||||
$php_options_text.= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
|
||||
$php_options_text.= ' ScriptAlias /php/ ' . $php->getInterface()->getConfigDir() . "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$file_extensions = explode(' ', $phpconfig['file_extensions']);
|
||||
$php_options_text.= ' <FilesMatch "\.(' . implode('|', $file_extensions) . ')$">' . "\n";
|
||||
$php_options_text.= ' SetHandler fcgid-script' . "\n";
|
||||
foreach($file_extensions as $file_extension)
|
||||
{
|
||||
$php_options_text.= ' FcgidWrapper ' . $php->getInterface()->getStarterFile() . ' .' . $file_extension . "\n";
|
||||
}
|
||||
$php_options_text.= ' Options +ExecCGI' . "\n";
|
||||
$php_options_text.= ' </FilesMatch>' . "\n";
|
||||
// >=apache-2.4 enabled?
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$mypath_dir = new frxDirectory($domain['documentroot']);
|
||||
// only create the require all granted if there is not active directory-protection
|
||||
// for this path, as this would be the first require and therefore grant all access
|
||||
if ($mypath_dir->isUserProtected() == false) {
|
||||
$php_options_text.= ' Require all granted' . "\n";
|
||||
$php_options_text.= ' AllowOverride All' . "\n";
|
||||
}
|
||||
} else {
|
||||
$php_options_text.= ' Order allow,deny' . "\n";
|
||||
$php_options_text.= ' allow from all' . "\n";
|
||||
}
|
||||
$php_options_text.= ' </Directory>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= ' # PHP is disabled for this vHost' . "\n";
|
||||
}
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('system.mod_fcgid_ownvhost') == '1'
|
||||
|| (Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1')
|
||||
) {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
|
||||
if (Settings::Get('system.mod_fcgid_ownvhost') == '1')
|
||||
{
|
||||
$user = Settings::Get('system.mod_fcgid_httpuser');
|
||||
$group = Settings::Get('system.mod_fcgid_httpgroup');
|
||||
}
|
||||
elseif(Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1'
|
||||
) {
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
|
||||
// get fpm config
|
||||
$fpm_sel_stmt = Database::prepare("
|
||||
SELECT f.id FROM `" . TABLE_PANEL_FPMDAEMONS . "` f
|
||||
LEFT JOIN `" . TABLE_PANEL_PHPCONFIGS . "` p ON p.fpmsettingid = f.id
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, array(
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
));
|
||||
}
|
||||
|
||||
$domain = array(
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'adminid' => 1, /* first admin-user (superadmin) */
|
||||
'mod_fcgid_starter' => -1,
|
||||
'mod_fcgid_maxrequests' => -1,
|
||||
'guid' => $user,
|
||||
'openbasedir' => 0,
|
||||
'email' => Settings::Get('panel.adminmail'),
|
||||
'loginname' => 'froxlor.panel',
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath,
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new phpinterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
// fpm
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('phpfpm.vhost_defaultini'));
|
||||
} else {
|
||||
// fcgid
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('system.mod_fcgid_defaultini_ownvhost'));
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,168 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
class lighttpd_fcgid extends lighttpd
|
||||
{
|
||||
protected function composePhpOptions($domain)
|
||||
{
|
||||
$php_options_text = '';
|
||||
|
||||
if($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1')
|
||||
{
|
||||
$php = new phpinterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
// vhost data for php-fpm
|
||||
if((int)Settings::Get('phpfpm.enabled') == 1)
|
||||
{
|
||||
$php_options_text = ' fastcgi.server = ( '."\n";
|
||||
$php_options_text.= "\t".'".php" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"localhost" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"socket" => "'.$php->getInterface()->getSocketFile().'",'."\n";
|
||||
$php_options_text.= "\t\t".'"check-local" => "enable",'."\n";
|
||||
$php_options_text.= "\t\t".'"disable-time" => 1'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
$php_options_text.= ' )'."\n";
|
||||
}
|
||||
// vhost data for fcgid
|
||||
elseif((int)Settings::Get('system.mod_fcgid') == 1)
|
||||
{
|
||||
$php_options_text = ' fastcgi.server = ( '."\n";
|
||||
$file_extensions = explode(' ', $phpconfig['file_extensions']);
|
||||
foreach($file_extensions as $f_extension)
|
||||
{
|
||||
$php_options_text.= "\t".'".'.$f_extension.'" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"localhost" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"socket" => "/var/run/lighttpd/'.$domain['loginname'].'-'.$domain['domain'].'-php.socket",'."\n";
|
||||
$php_options_text.= "\t\t".'"bin-path" => "'.$phpconfig['binary'].' -c '.$php->getInterface()->getIniFile().'",'."\n";
|
||||
$php_options_text.= "\t\t".'"bin-environment" => ('."\n";
|
||||
if((int)$domain['mod_fcgid_starter'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_CHILDREN" => "' . (int)$domain['mod_fcgid_starter'] . '",'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if((int)$phpconfig['mod_fcgid_starter'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_CHILDREN" => "' . (int)$phpconfig['mod_fcgid_starter'] . '",'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_CHILDREN" => "' . (int)Settings::Get('system.mod_fcgid_starter') . '",'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if((int)$domain['mod_fcgid_maxrequests'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_MAX_REQUESTS" => "' . (int)$domain['mod_fcgid_maxrequests'] . '"'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if((int)$phpconfig['mod_fcgid_maxrequests'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_MAX_REQUESTS" => "' . (int)$phpconfig['mod_fcgid_maxrequests'] . '"'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_MAX_REQUESTS" => "' . (int)Settings::Get('system.mod_fcgid_maxrequests') . '"'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$php_options_text.= "\t\t".')'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
|
||||
} // foreach extension
|
||||
$php_options_text.= ' )'."\n";
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= ' # PHP is disabled for this vHost' . "\n";
|
||||
}
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1'
|
||||
) {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
|
||||
// get fpm config
|
||||
$fpm_sel_stmt = Database::prepare("
|
||||
SELECT f.id FROM `" . TABLE_PANEL_FPMDAEMONS . "` f
|
||||
LEFT JOIN `" . TABLE_PANEL_PHPCONFIGS . "` p ON p.fpmsettingid = f.id
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, array(
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
));
|
||||
|
||||
$domain = array(
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'adminid' => 1, /* first admin-user (superadmin) */
|
||||
'mod_fcgid_starter' => -1,
|
||||
'mod_fcgid_maxrequests' => -1,
|
||||
'guid' => $user,
|
||||
'openbasedir' => 0,
|
||||
'email' => Settings::Get('panel.adminmail'),
|
||||
'loginname' => 'froxlor.panel',
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath,
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new phpinterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
// fpm
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('phpfpm.vhost_defaultini'));
|
||||
} else {
|
||||
// fcgid
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('system.mod_fcgid_defaultini_ownvhost'));
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,119 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
class nginx_phpfpm extends nginx
|
||||
{
|
||||
protected function composePhpOptions($domain, $ssl_vhost = false) {
|
||||
$php_options_text = '';
|
||||
|
||||
if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
|
||||
$php = new phpinterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
$php_options_text = "\t" . 'location ~ ^(.+?\.php)(/.*)?$ {' . "\n";
|
||||
$php_options_text .= "\t\t" . 'try_files ' . $domain['nonexistinguri'] . ' @php;' . "\n";
|
||||
$php_options_text .= "\t" . '}' . "\n\n";
|
||||
|
||||
$php_options_text .= "\t" . 'location @php {' . "\n";
|
||||
$php_options_text .= "\t\t" . 'try_files $1 = 404;' . "\n\n";
|
||||
$php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n";
|
||||
$php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+\.php)(/.+)\$;' . "\n";
|
||||
$php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $document_root$1;' . "\n";
|
||||
$php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n";
|
||||
if ($domain['ssl'] == '1' && $ssl_vhost) {
|
||||
$php_options_text .= "\t\t" . 'fastcgi_param HTTPS on;' . "\n";
|
||||
}
|
||||
$php_options_text .= "\t\t" . 'fastcgi_pass unix:' . $php->getInterface()->getSocketFile() . ";\n";
|
||||
$php_options_text .= "\t\t" . 'fastcgi_index index.php;' . "\n";
|
||||
$php_options_text .= "\t}\n\n";
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
else {
|
||||
$php_options_text.= ' # PHP is disabled for this vHost' . "\n";
|
||||
}
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
|
||||
public function createOwnVhostStarter() {
|
||||
if (Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1'
|
||||
) {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
|
||||
// get fpm config
|
||||
$fpm_sel_stmt = Database::prepare("
|
||||
SELECT f.id FROM `" . TABLE_PANEL_FPMDAEMONS . "` f
|
||||
LEFT JOIN `" . TABLE_PANEL_PHPCONFIGS . "` p ON p.fpmsettingid = f.id
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, array(
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
));
|
||||
|
||||
$domain = array(
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'adminid' => 1, /* first admin-user (superadmin) */
|
||||
'mod_fcgid_starter' => -1,
|
||||
'mod_fcgid_maxrequests' => -1,
|
||||
'guid' => $user,
|
||||
'openbasedir' => 0,
|
||||
'email' => Settings::Get('panel.adminmail'),
|
||||
'loginname' => 'froxlor.panel',
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath,
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new phpinterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
// fpm
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('phpfpm.vhost_defaultini'));
|
||||
} else {
|
||||
// fcgid
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('system.mod_fcgid_defaultini_ownvhost'));
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
// necessary includes
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.dns.10.bind.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.dns.20.pdns.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.10.apache.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.15.apache_fcgid.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.20.lighttpd.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.25.lighttpd_fcgid.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.30.nginx.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.35.nginx_phpfpm.php');
|
||||
|
||||
/**
|
||||
* LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "cron_tasks: Searching for tasks to do");
|
||||
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `id` ASC
|
||||
");
|
||||
$num_results = Database::num_rows();
|
||||
$resultIDs = array();
|
||||
|
||||
while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$resultIDs[] = $row['id'];
|
||||
|
||||
if ($row['data'] != '') {
|
||||
$row['data'] = json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF
|
||||
*/
|
||||
if ($row['type'] == '1') {
|
||||
|
||||
// get configuration-I/O object
|
||||
$configio = new ConfigIO();
|
||||
// clean up old configs
|
||||
$configio->cleanUp();
|
||||
|
||||
if (!isset($webserver)) {
|
||||
if (Settings::Get('system.webserver') == "apache2") {
|
||||
$websrv = 'apache';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= '_fcgid';
|
||||
}
|
||||
} elseif (Settings::Get('system.webserver') == "lighttpd") {
|
||||
$websrv = 'lighttpd';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= '_fcgid';
|
||||
}
|
||||
} elseif (Settings::Get('system.webserver') == "nginx") {
|
||||
$websrv = 'nginx';
|
||||
if (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= '_phpfpm';
|
||||
}
|
||||
}
|
||||
|
||||
$webserver = new $websrv($cronlog, $idna_convert);
|
||||
}
|
||||
|
||||
if (isset($webserver)) {
|
||||
$webserver->createIpPort();
|
||||
$webserver->createVirtualHosts();
|
||||
$webserver->createFileDirOptions();
|
||||
$webserver->writeConfigs();
|
||||
$webserver->createOwnVhostStarter();
|
||||
$webserver->reload();
|
||||
} else {
|
||||
echo "Please check you Webserver settings\n";
|
||||
}
|
||||
|
||||
// if we use php-fpm and have a local user for froxlor, we need to
|
||||
// add the webserver-user to the local-group in order to allow the webserver
|
||||
// to access the fpm-socket
|
||||
if (Settings::Get('phpfpm.enabled') == 1 && function_exists("posix_getgrnam")) {
|
||||
// get group info about the local-user's group (e.g. froxlorlocal)
|
||||
$groupinfo = posix_getgrnam(Settings::Get('phpfpm.vhost_httpgroup'));
|
||||
// check group members
|
||||
if (isset($groupinfo['members'])
|
||||
&& !in_array(Settings::Get('system.httpuser'), $groupinfo['members'])
|
||||
) {
|
||||
// webserver has no access, add it
|
||||
if (isFreeBSD()) {
|
||||
safe_exec('pw usermod '.escapeshellarg(Settings::Get('system.httpuser')).' -G '.escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')));
|
||||
} else {
|
||||
safe_exec('usermod -a -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')).' '.escapeshellarg(Settings::Get('system.httpuser')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the Let's Encrypt cron it's okay to generate the certificate and enable the redirect afterwards
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '3' WHERE `ssl_redirect` = '2'");
|
||||
Database::pexecute($upd_stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN
|
||||
*/
|
||||
elseif ($row['type'] == '2') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task2 started - create new home');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
// define paths
|
||||
$userhomedir = makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$usermaildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
// stats directory
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
// in case we changed from the other stats -> remove old
|
||||
// (yes i know, the stats are lost - that's why you should not change all the time!)
|
||||
if (file_exists($userhomedir . 'webalizer')) {
|
||||
safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
}
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
// in case we changed from the other stats -> remove old
|
||||
// (yes i know, the stats are lost - that's why you should not change all the time!)
|
||||
if (file_exists($userhomedir . 'awstats')) {
|
||||
safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
}
|
||||
}
|
||||
|
||||
// maildir
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($usermaildir));
|
||||
|
||||
//check if admin of customer has added template for new customer directories
|
||||
if ((int)$row['data']['store_defaultindex'] == 1) {
|
||||
storeDefaultIndex($row['data']['loginname'], $userhomedir, $cronlog, true);
|
||||
}
|
||||
|
||||
// strip of last slash of paths to have correct chown results
|
||||
$userhomedir = (substr($userhomedir, 0, -1) == '/') ? substr($userhomedir, 0, -1) : $userhomedir;
|
||||
$usermaildir = (substr($usermaildir, 0, -1) == '/') ? substr($usermaildir, 0, -1) : $usermaildir;
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
safe_exec('chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
// don't allow others to access the directory (webserver will be the group via libnss-mysql)
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
// fcgid or fpm
|
||||
safe_exec('chmod 0750 ' . escapeshellarg($userhomedir));
|
||||
} else {
|
||||
// mod_php -> no libnss-mysql -> no webserver-user in group
|
||||
safe_exec('chmod 0755 ' . escapeshellarg($userhomedir));
|
||||
}
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)Settings::Get('system.vmail_uid') . ':' . (int)Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
safe_exec('chown -R ' . (int)Settings::Get('system.vmail_uid') . ':' . (int)Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
|
||||
if (Settings::Get('system.nssextrausers') == 1)
|
||||
{
|
||||
// explicitly create files after user has been created to avoid unknown user issues for apache/php-fpm when task#1 runs after this
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR.'/scripts/classes/class.Extrausers.php');
|
||||
Extrausers::generateFiles($cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$false_val = false;
|
||||
safe_exec('nscd -i passwd 1> /dev/null', $false_val, array('>'));
|
||||
safe_exec('nscd -i group 1> /dev/null', $false_val, array('>'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=4 MEANS THAT SOMETHING IN THE BIND CONFIG HAS CHANGED. REBUILD froxlor_bind.conf IF BIND IS ENABLED
|
||||
*/
|
||||
elseif ($row['type'] == '4' && (int)Settings::Get('system.bind_enable') != 0) {
|
||||
|
||||
$dnssrv = Settings::Get('system.dns_server');
|
||||
|
||||
if (!isset($nameserver)) {
|
||||
$nameserver = new $dnssrv($cronlog);
|
||||
}
|
||||
|
||||
if (Settings::Get('dkim.use_dkim') == '1') {
|
||||
$nameserver->writeDKIMconfigs();
|
||||
}
|
||||
|
||||
$nameserver->writeConfigs();
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=5 MEANS THAT A NEW FTP-ACCOUNT HAS BEEN CREATED, CREATE THE DIRECTORY
|
||||
*/
|
||||
elseif ($row['type'] == '5') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating new FTP-home');
|
||||
$result_directories_stmt = Database::query("
|
||||
SELECT `f`.`homedir`, `f`.`uid`, `f`.`gid`, `c`.`documentroot` AS `customerroot`
|
||||
FROM `" . TABLE_FTP_USERS . "` `f` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING (`customerid`)
|
||||
");
|
||||
|
||||
while ($directory = $result_directories_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
mkDirWithCorrectOwnership($directory['customerroot'], $directory['homedir'], $directory['uid'], $directory['gid']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=6 MEANS THAT A CUSTOMER HAS BEEN DELETED AND THAT WE HAVE TO REMOVE ITS FILES
|
||||
*/
|
||||
elseif ($row['type'] == '6') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task6 started - deleting customer data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
if (isset($row['data']['loginname'])) {
|
||||
// remove homedir
|
||||
$homedir = makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($homedir)
|
||||
&& $homedir != '/'
|
||||
&& $homedir != Settings::Get('system.documentroot_prefix')
|
||||
&& substr($homedir, 0, strlen(Settings::Get('system.documentroot_prefix'))) == Settings::Get('system.documentroot_prefix')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($homedir));
|
||||
safe_exec('rm -rf '.escapeshellarg($homedir));
|
||||
}
|
||||
|
||||
// remove maildir
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($maildir)
|
||||
&& $maildir != '/'
|
||||
&& $maildir != Settings::Get('system.vmail_homedir')
|
||||
&& substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir')
|
||||
&& is_dir($maildir)
|
||||
&& fileowner($maildir) == Settings::Get('system.vmail_uid')
|
||||
&& filegroup($maildir) == Settings::Get('system.vmail_gid')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
safe_exec('rm -rf '.escapeshellarg($maildir), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
}
|
||||
|
||||
// remove tmpdir if it exists
|
||||
$tmpdir = makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
if (file_exists($tmpdir)
|
||||
&& is_dir($tmpdir)
|
||||
&& $tmpdir != "/"
|
||||
&& $tmpdir != Settings::Get('system.mod_fcgid_tmpdir')
|
||||
&& substr($tmpdir, 0, strlen(Settings::Get('system.mod_fcgid_tmpdir'))) == Settings::Get('system.mod_fcgid_tmpdir')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($tmpdir));
|
||||
safe_exec('rm -rf '.escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
// webserver logs
|
||||
$logsdir = makeCorrectFile(Settings::Get('system.logfiles_directory').'/'.$row['data']['loginname']);
|
||||
|
||||
if (file_exists($logsdir)
|
||||
&& $logsdir != '/'
|
||||
&& $logsdir != makeCorrectDir(Settings::Get('system.logfiles_directory'))
|
||||
&& substr($logsdir, 0, strlen(Settings::Get('system.logfiles_directory'))) == Settings::Get('system.logfiles_directory')
|
||||
) {
|
||||
// build up wildcard for webX-{access,error}.log{*}
|
||||
$logfiles .= '-*';
|
||||
safe_exec('rm -f '.escapeshellarg($logfiles));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=7 Customer deleted an email account and wants the data to be deleted on the filesystem
|
||||
*/
|
||||
elseif ($row['type'] == '7') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task7 started - deleting customer e-mail data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname'])
|
||||
&& isset($row['data']['email'])
|
||||
) {
|
||||
// remove specific maildir
|
||||
$email_full = $row['data']['email'];
|
||||
if (empty($email_full)) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERROR, 'FATAL: Task7 asks to delete a email account but email field is empty!');
|
||||
}
|
||||
$email_user = substr($email_full,0,strrpos($email_full,"@"));
|
||||
$email_domain = substr($email_full,strrpos($email_full,"@")+1);
|
||||
$maildirname = trim(Settings::Get('system.vmail_maildirname'));
|
||||
// Add trailing slash to Maildir if needed
|
||||
$maildirpath = $maildirname;
|
||||
if (!empty($maildirname) and substr($maildirname,-1) != "/") {
|
||||
$maildirpath .= "/";
|
||||
}
|
||||
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') .'/'. $row['data']['loginname'] .'/'. $email_domain .'/'. $email_user);
|
||||
|
||||
if ($maildir != '/'
|
||||
&& !empty($maildir)
|
||||
&& !empty($email_full)
|
||||
&& $maildir != Settings::Get('system.vmail_homedir')
|
||||
&& substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir')
|
||||
&& is_dir($maildir)
|
||||
&& is_dir(makeCorrectDir($maildir.'/'.$maildirpath))
|
||||
&& fileowner($maildir) == Settings::Get('system.vmail_uid')
|
||||
&& filegroup($maildir) == Settings::Get('system.vmail_gid')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
safe_exec('rm -rf '.escapeshellarg($maildir), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
|
||||
} else {
|
||||
// backward-compatibility for old folder-structure
|
||||
$maildir_old = makeCorrectDir(Settings::Get('system.vmail_homedir') .'/'. $row['data']['loginname'] .'/'. $row['data']['email']);
|
||||
|
||||
if ($maildir_old != '/'
|
||||
&& !empty($maildir_old)
|
||||
&& $maildir_old != Settings::Get('system.vmail_homedir')
|
||||
&& substr($maildir_old, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir')
|
||||
&& is_dir($maildir_old)
|
||||
&& fileowner($maildir_old) == Settings::Get('system.vmail_uid')
|
||||
&& filegroup($maildir_old) == Settings::Get('system.vmail_gid')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir_old));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
safe_exec('rm -rf '.escapeshellarg($maildir_old), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=8 Customer deleted a ftp account and wants the homedir to be deleted on the filesystem
|
||||
* refs #293
|
||||
*/
|
||||
elseif ($row['type'] == '8') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task8 started - deleting customer ftp homedir');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname'])
|
||||
&& isset($row['data']['homedir'])
|
||||
) {
|
||||
// remove specific homedir
|
||||
$ftphomedir = makeCorrectDir($row['data']['homedir']);
|
||||
$customerdocroot = makeCorrectDir(Settings::Get('system.documentroot_prefix').'/'.$row['data']['loginname'].'/');
|
||||
|
||||
if (file_exists($ftphomedir)
|
||||
&& $ftphomedir != '/'
|
||||
&& $ftphomedir != Settings::Get('system.documentroot_prefix')
|
||||
&& $ftphomedir != $customerdocroot
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($ftphomedir));
|
||||
safe_exec('rm -rf '.escapeshellarg($ftphomedir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=10 Set the filesystem - quota
|
||||
*/
|
||||
elseif ($row['type'] == '10' && (int)Settings::Get('system.diskquota_enabled') != 0) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task10 started - setting filesystem quota');
|
||||
|
||||
$usedquota = getFilesystemQuota();
|
||||
|
||||
// Check whether we really have entries to check
|
||||
if (is_array($usedquota) && count($usedquota) > 0) {
|
||||
// Select all customers Froxlor knows about
|
||||
$result_stmt = Database::query("SELECT `guid`, `loginname`, `diskspace` FROM `" . TABLE_PANEL_CUSTOMERS . "`;");
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// We do not want to set a quota for root by accident
|
||||
if ($row['guid'] != 0) {
|
||||
// The user has no quota in Froxlor, but on the filesystem
|
||||
if (($row['diskspace'] == 0 || $row['diskspace'] == -1024)
|
||||
&& $usedquota[$row['guid']]['block']['hard'] != 0
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
|
||||
if (isFreeBSD()) {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']);
|
||||
} else {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
}
|
||||
// The user quota in Froxlor is different than on the filesystem
|
||||
elseif ($row['diskspace'] != $usedquota[$row['guid']]['block']['hard']
|
||||
&& $row['diskspace'] != -1024
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $usedquota[$row['guid']]['block']['hard'] . " to " . $row['diskspace']);
|
||||
if (isFreeBSD()) {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']);
|
||||
} else {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=11 domain has been deleted, remove from pdns database if used
|
||||
*/
|
||||
if ($row['type'] == '11' && Settings::Get('system.dns_server') == 'pdns')
|
||||
{
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
|
||||
PowerDNS::cleanDomainZone($row['data']['domain']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($num_results != 0) {
|
||||
$where = array();
|
||||
$where_data = array();
|
||||
foreach ($resultIDs as $id) {
|
||||
$where[] = "`id` = :id_" . (int)$id;
|
||||
$where_data['id_'.$id] = $id;
|
||||
}
|
||||
$where = implode($where, ' OR ');
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE " . $where);
|
||||
Database::pexecute($del_stmt, $where_data);
|
||||
unset($resultIDs);
|
||||
unset($where);
|
||||
}
|
||||
|
||||
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_tasks_run';");
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ARCHIVING CLOSED TICKETS
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Ticket-archiving run started...');
|
||||
$result_tickets_stmt = Database::query("
|
||||
SELECT `id`, `lastchange`, `subject` FROM `" . TABLE_PANEL_TICKETS . "`
|
||||
WHERE `status` = '3' AND `answerto` = '0';"
|
||||
);
|
||||
$archiving_count = 0;
|
||||
|
||||
while ($row_ticket = $result_tickets_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$lastchange = $row_ticket['lastchange'];
|
||||
$now = time();
|
||||
$days = (int)(($now - $lastchange) / 86400);
|
||||
|
||||
if ($days >= Settings::Get('ticket.archiving_days')) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'archiving ticket "' . $row_ticket['subject'] . '" (ID #' . $row_ticket['id'] . ')');
|
||||
$mainticket = ticket::getInstanceOf(null, (int)$row_ticket['id']);
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '1', true, true);
|
||||
$mainticket->Set('status', '3', true, true);
|
||||
$mainticket->Update();
|
||||
$mainticket->Archive();
|
||||
$archiving_count++;
|
||||
}
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Archived ' . $archiving_count . ' tickets');
|
||||
Database::query("
|
||||
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP()
|
||||
WHERE `settinggroup` = 'system' AND `varname` = 'last_archive_run'"
|
||||
);
|
||||
@@ -1,358 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
function awstatsDoSingleDomain($domain, $outputdir) {
|
||||
|
||||
global $cronlog, $theme;
|
||||
$returnval = 0;
|
||||
|
||||
$domainconfig = makeCorrectFile(Settings::Get('system.awstats_conf').'/awstats.' . $domain . '.conf');
|
||||
|
||||
if (file_exists($domainconfig)) {
|
||||
|
||||
$outputdir = makeCorrectDir($outputdir . '/' . $domain);
|
||||
$staticOutputdir = makeCorrectDir($outputdir . '/' . date('Y') . '-' . date('m'));
|
||||
|
||||
if (!is_dir($staticOutputdir)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($staticOutputdir));
|
||||
}
|
||||
|
||||
//check for correct path of awstats_buildstaticpages.pl
|
||||
$awbsp = makeCorrectFile(Settings::Get('system.awstats_path').'/awstats_buildstaticpages.pl');
|
||||
$awprog = makeCorrectFile(Settings::Get('system.awstats_awstatspath').'/awstats.pl');
|
||||
|
||||
if (!file_exists($awbsp)) {
|
||||
echo "WANRING: Necessary awstats_buildstaticpages.pl script could not be found, no traffic is being calculated and no stats are generated. Please check your AWStats-Path setting";
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Necessary awstats_buildstaticpages.pl script could not be found, no traffic is being calculated and no stats are generated. Please check your AWStats-Path setting");
|
||||
exit;
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Running awstats_buildstaticpages.pl for domain '".$domain."' (Output: '".$staticOutputdir."')");
|
||||
safe_exec($awbsp.' -awstatsprog='.escapeshellarg($awprog).' -update -month=' . date('m') . ' -year=' . date('Y') . ' -config=' . $domain . ' -dir='.escapeshellarg($staticOutputdir));
|
||||
|
||||
// update our awstats index files
|
||||
awstatsGenerateIndex($domain, $outputdir);
|
||||
|
||||
// the default selection is 'current',
|
||||
// so link the latest dir to it
|
||||
$new_current = makeCorrectFile($outputdir . '/current');
|
||||
safe_exec('ln -fTs ' . escapeshellarg($staticOutputdir) . ' ' . escapeshellarg($new_current));
|
||||
|
||||
//statistics file looks like: 'awstats[month][year].[domain].txt'
|
||||
$file = makeCorrectFile($outputdir.'/awstats'.date('mY', time()).'.'.$domain.'.txt');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '".$file."'");
|
||||
|
||||
if (file_exists($file)) {
|
||||
|
||||
$content = @file_get_contents($file);
|
||||
if ($content !== false) {
|
||||
$content_array = explode("\n", $content);
|
||||
|
||||
$count_bdw = false;
|
||||
foreach ($content_array as $line) {
|
||||
// skip empty lines and comments
|
||||
if (trim($line) == ''
|
||||
|| substr(trim($line), 0, 1) == '#'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $line);
|
||||
|
||||
if (isset($parts[0])
|
||||
&& strtoupper($parts[0]) == 'BEGIN_DOMAIN'
|
||||
) {
|
||||
$count_bdw = true;
|
||||
}
|
||||
|
||||
if ($count_bdw) {
|
||||
if (isset($parts[0])
|
||||
&& strtoupper($parts[0]) == 'END_DOMAIN'
|
||||
) {
|
||||
$count_bdw = false;
|
||||
break;
|
||||
} elseif (isset($parts[3])) {
|
||||
$returnval += floatval($parts[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $returnval;
|
||||
}
|
||||
|
||||
|
||||
function awstatsGenerateIndex($domain, $outputdir) {
|
||||
|
||||
// Generation header
|
||||
$header = "<!-- GENERATED BY FROXLOR -->\n";
|
||||
|
||||
// Looking for {year}-{month} directories
|
||||
$entries = array();
|
||||
foreach (scandir($outputdir) as $a) {
|
||||
if (is_dir(makeCorrectDir($outputdir . '/' . $a)) && preg_match('/^[0-9]{4}-[0-9]{2}$/', $a)) {
|
||||
array_push($entries, '<option value="' . $a . '">' . $a . '</option>');
|
||||
}
|
||||
}
|
||||
|
||||
// These are the variables we will replace
|
||||
$regex = array(
|
||||
'/\{SITE_DOMAIN\}/',
|
||||
'/\{SELECT_ENTRIES\}/'
|
||||
);
|
||||
|
||||
$replace = array(
|
||||
$domain,
|
||||
implode($entries)
|
||||
);
|
||||
|
||||
// File names
|
||||
$index_file = FROXLOR_INSTALL_DIR.'/templates/misc/awstats/index.html';
|
||||
$index_file = makeCorrectFile($index_file);
|
||||
$nav_file = FROXLOR_INSTALL_DIR.'/templates/misc/awstats/nav.html';
|
||||
$nav_file = makeCorrectFile($nav_file);
|
||||
|
||||
// Write the index file
|
||||
{
|
||||
// 'index.html' used to be a symlink (ignore errors in case this is the first run and no index.html exists yet)
|
||||
@unlink(makeCorrectFile($outputdir . '/' . 'index.html'));
|
||||
|
||||
$awstats_index_file = fopen(makeCorrectFile($outputdir . '/' . 'index.html'), 'w');
|
||||
$awstats_index_tpl = fopen($index_file, 'r');
|
||||
|
||||
// Write the header
|
||||
fwrite($awstats_index_file, $header);
|
||||
|
||||
// Write the configuration file
|
||||
while (($line = fgets($awstats_index_tpl, 4096)) !== false) {
|
||||
if (!preg_match('/^#/', $line)
|
||||
&& trim($line) != ''
|
||||
) {
|
||||
fwrite($awstats_index_file, preg_replace($regex, $replace, $line));
|
||||
}
|
||||
}
|
||||
fclose($awstats_index_file);
|
||||
fclose($awstats_index_tpl);
|
||||
}
|
||||
|
||||
// Write the nav file
|
||||
{
|
||||
$awstats_nav_file = fopen(makeCorrectFile($outputdir . '/' . 'nav.html'), 'w');
|
||||
$awstats_nav_tpl = fopen($nav_file, 'r');
|
||||
|
||||
// Write the header
|
||||
fwrite($awstats_nav_file, $header);
|
||||
|
||||
// Write the configuration file
|
||||
while (($line = fgets($awstats_nav_tpl, 4096)) !== false) {
|
||||
if (!preg_match('/^#/', $line)
|
||||
&& trim($line) != ''
|
||||
) {
|
||||
fwrite($awstats_nav_file, preg_replace($regex, $replace, $line));
|
||||
}
|
||||
}
|
||||
fclose($awstats_nav_file);
|
||||
fclose($awstats_nav_tpl);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
function callAwstatsGetTraffic($customerid, $outputdir, $usersdomainlist) {
|
||||
|
||||
global $cronlog;
|
||||
|
||||
$returnval = 0;
|
||||
|
||||
foreach ($usersdomainlist as $domainid => $singledomain) {
|
||||
// as we check for the config-model awstats will only parse
|
||||
// 'real' domains and no subdomains which are aliases in the
|
||||
// model-config-file.
|
||||
$returnval += awstatsDoSingleDomain($singledomain, $outputdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* as of #124, awstats traffic is saved in bytes instead
|
||||
* of kilobytes (like webalizer does)
|
||||
*/
|
||||
$returnval = floatval($returnval / 1024);
|
||||
|
||||
/**
|
||||
* now, because this traffic is being saved daily, we have to
|
||||
* subtract the values from all the month's values to return
|
||||
* a sane value for our panel_traffic and to remain the whole stats
|
||||
* (awstats overwrites the customers .html stats-files)
|
||||
*/
|
||||
if ($customerid !== false) {
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT SUM(`http`) as `trafficmonth` FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `year` = :year AND `month` = :month
|
||||
");
|
||||
$result_data = array(
|
||||
'customerid' => $customerid,
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time())
|
||||
);
|
||||
$result = Database::pexecute_first($result_stmt, $result_data);
|
||||
|
||||
if (is_array($result)
|
||||
&& isset($result['trafficmonth'])
|
||||
) {
|
||||
$returnval = ($returnval - floatval($result['trafficmonth']));
|
||||
}
|
||||
}
|
||||
|
||||
return floatval($returnval);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function which make webalizer statistics and returns used traffic since last run
|
||||
*
|
||||
* @param string Name of logfile
|
||||
* @param string Place where stats should be build
|
||||
* @param string Caption for webalizer output
|
||||
* @return int Used traffic
|
||||
* @author Florian Lippert <flo@syscp.org>
|
||||
*/
|
||||
function callWebalizerGetTraffic($logfile, $outputdir, $caption, $usersdomainlist) {
|
||||
|
||||
global $cronlog;
|
||||
|
||||
$returnval = 0;
|
||||
|
||||
$logfile = makeCorrectFile(Settings::Get('system.logfiles_directory') . $logfile . '-access.log');
|
||||
if (file_exists($logfile)) {
|
||||
$domainargs = '';
|
||||
foreach ($usersdomainlist as $domainid => $domain) {
|
||||
// hide referer
|
||||
$domainargs.= ' -r ' . escapeshellarg($domain);
|
||||
}
|
||||
|
||||
$outputdir = makeCorrectDir($outputdir);
|
||||
if (!file_exists($outputdir)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($outputdir));
|
||||
}
|
||||
|
||||
if (file_exists($outputdir . 'webalizer.hist.1')) {
|
||||
@unlink($outputdir . 'webalizer.hist.1');
|
||||
}
|
||||
|
||||
if (file_exists($outputdir . 'webalizer.hist')
|
||||
&& !file_exists($outputdir . 'webalizer.hist.1')
|
||||
) {
|
||||
safe_exec('cp ' . escapeshellarg($outputdir . 'webalizer.hist') . ' ' . escapeshellarg($outputdir . 'webalizer.hist.1'));
|
||||
}
|
||||
|
||||
$verbosity = '';
|
||||
if (Settings::Get('system.webalizer_quiet') == '1') {
|
||||
$verbosity = '-q';
|
||||
} elseif (Settings::Get('system.webalizer_quiet') == '2') {
|
||||
$verbosity = '-Q';
|
||||
}
|
||||
|
||||
$we = '/usr/bin/webalizer';
|
||||
|
||||
// FreeBSD uses other paths, #140
|
||||
if (!file_exists($we)) {
|
||||
$we = '/usr/local/bin/webalizer';
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Running webalizer for domain '".$caption."'");
|
||||
safe_exec($we . ' ' . $verbosity . ' -p -o ' . escapeshellarg($outputdir) . ' -n ' . escapeshellarg($caption) . $domainargs . ' ' . escapeshellarg($logfile));
|
||||
|
||||
/**
|
||||
* Format of webalizer.hist-files:
|
||||
* Month: $webalizer_hist_row['0']
|
||||
* Year: $webalizer_hist_row['1']
|
||||
* KB: $webalizer_hist_row['5']
|
||||
*/
|
||||
$httptraffic = array();
|
||||
$webalizer_hist = @file_get_contents($outputdir . 'webalizer.hist');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '".$webalizer_hist."'");
|
||||
|
||||
$webalizer_hist_rows = explode("\n", $webalizer_hist);
|
||||
foreach ($webalizer_hist_rows as $webalizer_hist_row) {
|
||||
if ($webalizer_hist_row != '') {
|
||||
|
||||
$webalizer_hist_row = explode(' ', $webalizer_hist_row);
|
||||
|
||||
if (isset($webalizer_hist_row['0'])
|
||||
&& isset($webalizer_hist_row['1'])
|
||||
&& isset($webalizer_hist_row['5'])
|
||||
) {
|
||||
$month = intval($webalizer_hist_row['0']);
|
||||
$year = intval($webalizer_hist_row['1']);
|
||||
$traffic = floatval($webalizer_hist_row['5']);
|
||||
|
||||
if (!isset($httptraffic[$year])) {
|
||||
$httptraffic[$year] = array();
|
||||
}
|
||||
|
||||
$httptraffic[$year][$month] = $traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($httptraffic);
|
||||
$httptrafficlast = array();
|
||||
$webalizer_lasthist = @file_get_contents($outputdir . 'webalizer.hist.1');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '".$webalizer_lasthist."'");
|
||||
|
||||
$webalizer_lasthist_rows = explode("\n", $webalizer_lasthist);
|
||||
foreach ($webalizer_lasthist_rows as $webalizer_lasthist_row) {
|
||||
if ($webalizer_lasthist_row != '') {
|
||||
|
||||
$webalizer_lasthist_row = explode(' ', $webalizer_lasthist_row);
|
||||
|
||||
if (isset($webalizer_lasthist_row['0'])
|
||||
&& isset($webalizer_lasthist_row['1'])
|
||||
&& isset($webalizer_lasthist_row['5'])
|
||||
) {
|
||||
$month = intval($webalizer_lasthist_row['0']);
|
||||
$year = intval($webalizer_lasthist_row['1']);
|
||||
$traffic = floatval($webalizer_lasthist_row['5']);
|
||||
|
||||
if (!isset($httptrafficlast[$year])) {
|
||||
$httptrafficlast[$year] = array();
|
||||
}
|
||||
|
||||
$httptrafficlast[$year][$month] = $traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($httptrafficlast);
|
||||
foreach ($httptraffic as $year => $months) {
|
||||
foreach ($months as $month => $traffic) {
|
||||
if (!isset($httptrafficlast[$year][$month])) {
|
||||
$returnval+= $traffic;
|
||||
} elseif ($httptrafficlast[$year][$month] < $httptraffic[$year][$month]) {
|
||||
$returnval+= ($httptraffic[$year][$month] - $httptrafficlast[$year][$month]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return floatval($returnval);
|
||||
}
|
||||
@@ -1,615 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
|
||||
// Check Traffic-Lock
|
||||
if (function_exists('pcntl_fork') && !defined('CRON_NOFORK_FLAG')) {
|
||||
$TrafficLock = makeCorrectFile(dirname($lockfile)."/froxlor_cron_traffic.lock");
|
||||
if (file_exists($TrafficLock)
|
||||
&& is_numeric($TrafficPid=file_get_contents($TrafficLock))
|
||||
) {
|
||||
if (function_exists('posix_kill')) {
|
||||
$TrafficPidStatus = @posix_kill($TrafficPid,0);
|
||||
} else {
|
||||
system("kill -CHLD " . $TrafficPid . " 1> /dev/null 2> /dev/null", $TrafficPidStatus);
|
||||
$TrafficPidStatus = $TrafficPidStatus ? false : true;
|
||||
}
|
||||
if ($TrafficPidStatus) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Traffic Run already in progress');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Create Traffic Log and Fork
|
||||
// We close the database - connection before we fork, so we don't share resources with the child
|
||||
Database::needRoot(false); // this forces the connection to be set to null
|
||||
$TrafficPid = pcntl_fork();
|
||||
// Parent
|
||||
if ($TrafficPid) {
|
||||
file_put_contents($TrafficLock, $TrafficPid);
|
||||
// unnecessary to recreate database connection here
|
||||
return 0;
|
||||
|
||||
}
|
||||
//Child
|
||||
elseif ($TrafficPid == 0) {
|
||||
posix_setsid();
|
||||
fclose($debugHandler);
|
||||
// re-create db
|
||||
Database::needRoot(false);
|
||||
}
|
||||
//Fork failed
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (extension_loaded('pcntl')) {
|
||||
$msg = "PHP compiled with pcntl but pcntl_fork function is not available.";
|
||||
} else {
|
||||
$msg = "PHP compiled without pcntl.";
|
||||
}
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, $msg." Not forking traffic-cron, this may take a long time!");
|
||||
}
|
||||
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_traffic.inc.functions.php');
|
||||
|
||||
/**
|
||||
* TRAFFIC AND DISKUSAGE MESSURE
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Traffic run started...');
|
||||
$admin_traffic = array();
|
||||
$domainlist = array();
|
||||
$speciallogfile_domainlist = array();
|
||||
$result_domainlist_stmt = Database::query("
|
||||
SELECT `id`, `domain`, `customerid`, `parentdomainid`, `speciallogfile`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain` IS NULL AND `email_only` <> '1';
|
||||
");
|
||||
|
||||
while ($row_domainlist = $result_domainlist_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (!isset($domainlist[$row_domainlist['customerid']])) {
|
||||
$domainlist[$row_domainlist['customerid']] = array();
|
||||
}
|
||||
|
||||
$domainlist[$row_domainlist['customerid']][$row_domainlist['id']] = $row_domainlist['domain'];
|
||||
|
||||
if ($row_domainlist['parentdomainid'] == '0'
|
||||
&& $row_domainlist['speciallogfile'] == '1'
|
||||
) {
|
||||
if (!isset($speciallogfile_domainlist[$row_domainlist['customerid']])) {
|
||||
$speciallogfile_domainlist[$row_domainlist['customerid']] = array();
|
||||
}
|
||||
$speciallogfile_domainlist[$row_domainlist['customerid']][$row_domainlist['id']] = $row_domainlist['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
$mysqlusage_all = array();
|
||||
$databases_stmt = Database::query("SELECT * FROM " . TABLE_PANEL_DATABASES . " ORDER BY `dbserver`");
|
||||
$last_dbserver = 0;
|
||||
|
||||
$databases_list = array();
|
||||
Database::needRoot(true);
|
||||
$databases_list_result_stmt = Database::query("SHOW DATABASES");
|
||||
while ($databases_list_row = $databases_list_result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||
}
|
||||
|
||||
while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if ($last_dbserver != $row_database['dbserver']) {
|
||||
Database::needRoot(true, $row_database['dbserver']);
|
||||
$last_dbserver = $row_database['dbserver'];
|
||||
|
||||
$databases_list = array();
|
||||
$databases_list_result_stmt = Database::query("SHOW DATABASES");
|
||||
while ($databases_list_row = $databases_list_result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array(strtolower($row_database['databasename']), $databases_list)) {
|
||||
// sum up data_length and index_length
|
||||
$mysql_usage_result_stmt = Database::prepare("
|
||||
SELECT SUM(data_length + index_length) AS customerusage
|
||||
FROM information_schema.TABLES
|
||||
WHERE table_schema = :database
|
||||
GROUP BY table_schema;
|
||||
");
|
||||
// get the result
|
||||
$mysql_usage_row = Database::pexecute_first($mysql_usage_result_stmt, array('database' => $row_database['databasename']));
|
||||
// initialize counter for customer
|
||||
if (!isset($mysqlusage_all[$row_database['customerid']])) {
|
||||
$mysqlusage_all[$row_database['customerid']] = 0;
|
||||
}
|
||||
// sum up result
|
||||
$mysqlusage_all[$row_database['customerid']] += floatval($mysql_usage_row['customerusage']);
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Seems like the database " . $row_database['databasename'] . " had been removed manually.");
|
||||
}
|
||||
}
|
||||
|
||||
Database::needRoot(false);
|
||||
|
||||
// We are using the file-system quota, this will speed up the diskusage - collection
|
||||
if (Settings::Get('system.diskquota_enabled')) {
|
||||
$usedquota = getFilesystemQuota();
|
||||
}
|
||||
|
||||
/**
|
||||
* MAIL-Traffic
|
||||
*/
|
||||
if (Settings::Get("system.mailtraffic_enabled")) {
|
||||
$mailTrafficCalc = new \Froxlor\MailLogParser(Settings::Get("system.last_traffic_run"));
|
||||
}
|
||||
|
||||
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
/**
|
||||
* HTTP-Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'http traffic for ' . $row['loginname'] . ' started...');
|
||||
$httptraffic = 0;
|
||||
|
||||
if (isset($domainlist[$row['customerid']])
|
||||
&& is_array($domainlist[$row['customerid']])
|
||||
&& count($domainlist[$row['customerid']]) != 0
|
||||
) {
|
||||
// Examining which caption to use for default webalizer stats...
|
||||
if ($row['standardsubdomain'] != '0') {
|
||||
// ... of course we'd prefer to use the standardsubdomain ...
|
||||
$caption = $domainlist[$row['customerid']][$row['standardsubdomain']];
|
||||
} else {
|
||||
// ... but if there is no standardsubdomain, we have to use the loginname ...
|
||||
$caption = $row['loginname'];
|
||||
|
||||
// ... which results in non-usable links to files in the stats, so lets have a look if we find a domain which is not speciallogfiledomain
|
||||
foreach ($domainlist[$row['customerid']] as $domainid => $domain) {
|
||||
|
||||
if (!isset($speciallogfile_domainlist[$row['customerid']])
|
||||
|| !isset($speciallogfile_domainlist[$row['customerid']][$domainid])
|
||||
) {
|
||||
$caption = $domain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$httptraffic = 0;
|
||||
reset($domainlist[$row['customerid']]);
|
||||
|
||||
if (isset($speciallogfile_domainlist[$row['customerid']])
|
||||
&& is_array($speciallogfile_domainlist[$row['customerid']])
|
||||
&& count($speciallogfile_domainlist[$row['customerid']]) != 0
|
||||
) {
|
||||
reset($speciallogfile_domainlist[$row['customerid']]);
|
||||
if (Settings::Get('system.awstats_enabled') == '0') {
|
||||
foreach ($speciallogfile_domainlist[$row['customerid']] as $domainid => $domain) {
|
||||
$httptraffic+= floatval(callWebalizerGetTraffic($row['loginname'] . '-' . $domain, $row['documentroot'] . '/webalizer/' . $domain . '/', $domain, $domainlist[$row['customerid']]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($domainlist[$row['customerid']]);
|
||||
|
||||
// callAwstatsGetTraffic is called ONLY HERE and
|
||||
// *not* also in the special-logfiles-loop, because the function
|
||||
// will iterate through all customer-domains and the awstats-configs
|
||||
// know the logfile-name, #246
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
$httptraffic+= floatval(callAwstatsGetTraffic($row['customerid'], $row['documentroot'] . '/awstats/', $domainlist[$row['customerid']]));
|
||||
} else {
|
||||
$httptraffic+= floatval(callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']]));
|
||||
}
|
||||
|
||||
// make the stuff readable for the customer, #258
|
||||
makeChownWithNewStats($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* FTP-Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'ftp traffic for ' . $row['loginname'] . ' started...');
|
||||
$ftptraffic_stmt = Database::prepare("
|
||||
SELECT SUM(`up_bytes`) AS `up_bytes_sum`, SUM(`down_bytes`) AS `down_bytes_sum`
|
||||
FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :customerid
|
||||
");
|
||||
$ftptraffic = Database::pexecute_first($ftptraffic_stmt, array('customerid' => $row['customerid']));
|
||||
|
||||
if (!is_array($ftptraffic)) {
|
||||
$ftptraffic = array(
|
||||
'up_bytes_sum' => 0,
|
||||
'down_bytes_sum' => 0
|
||||
);
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_USERS . "` SET `up_bytes` = '0', `down_bytes` = '0' WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('customerid' => $row['customerid']));
|
||||
|
||||
/**
|
||||
* Mail-Traffic
|
||||
*/
|
||||
$mailtraffic = 0;
|
||||
if (Settings::Get("system.mailtraffic_enabled")) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'mail traffic usage for ' . $row['loginname'] . " started...");
|
||||
|
||||
$currentDate = date("Y-m-d");
|
||||
|
||||
$domains_stmt = Database::prepare("SELECT domain FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($domains_stmt, array("cid" => $row['customerid']));
|
||||
while ($domainRow = $domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$domainMailTraffic = $mailTrafficCalc->getDomainTraffic($domainRow["domain"]);
|
||||
if (!is_array($domainMailTraffic)) { continue; }
|
||||
|
||||
foreach ($domainMailTraffic as $dateTraffic => $dayTraffic) {
|
||||
$dayTraffic = floatval($dayTraffic / 1024);
|
||||
|
||||
list($year, $month, $day) = explode("-", $dateTraffic);
|
||||
if ($dateTraffic == $currentDate) {
|
||||
$mailtraffic = $dayTraffic;
|
||||
} else {
|
||||
// Check if an entry for the given day exists
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` = :cid
|
||||
AND `year` = :year
|
||||
AND `month` = :month
|
||||
AND `day` = :day");
|
||||
$params = array(
|
||||
"cid" => $row['customerid'],
|
||||
"year" => $year,
|
||||
"month" => $month,
|
||||
"day" => $day
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$updRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_TRAFFIC . "` SET
|
||||
`mail` = :mail
|
||||
WHERE `id` = :id");
|
||||
Database::pexecute($upd_stmt, array("mail" => $updRow['mail'] + $dayTraffic, "id" => $updRow['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Total Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'total traffic for ' . $row['loginname'] . ' started');
|
||||
$current_traffic = array();
|
||||
$current_traffic['http'] = floatval($httptraffic);
|
||||
$current_traffic['ftp_up'] = floatval(($ftptraffic['up_bytes_sum'] / 1024));
|
||||
$current_traffic['ftp_down'] = floatval(($ftptraffic['down_bytes_sum'] / 1024));
|
||||
$current_traffic['mail'] = floatval($mailtraffic);
|
||||
$current_traffic['all'] = $current_traffic['http'] + $current_traffic['ftp_up'] + $current_traffic['ftp_down'] + $current_traffic['mail'];
|
||||
|
||||
$ins_data = array(
|
||||
'customerid' => $row['customerid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'http' => $current_traffic['http'],
|
||||
'ftp_up' => $current_traffic['ftp_up'],
|
||||
'ftp_down' => $current_traffic['ftp_down'],
|
||||
'mail' => $current_traffic['mail']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TRAFFIC . "` SET
|
||||
`customerid` = :customerid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`http` = :http,
|
||||
`ftp_up` = :ftp_up,
|
||||
`ftp_down` = :ftp_down,
|
||||
`mail` = :mail
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
$sum_month_traffic_stmt = Database::prepare("
|
||||
SELECT SUM(`http`) AS `http`, SUM(`ftp_up`) AS `ftp_up`, SUM(`ftp_down`) AS `ftp_down`, SUM(`mail`) AS `mail`
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `year` = :year AND `month` = :month AND `customerid` = :customerid
|
||||
");
|
||||
$sum_month_traffic = Database::pexecute_first($sum_month_traffic_stmt, array('year' => date('Y', time()), 'month' => date('m', time()), 'customerid' => $row['customerid']));
|
||||
$sum_month_traffic['all'] = $sum_month_traffic['http'] + $sum_month_traffic['ftp_up'] + $sum_month_traffic['ftp_down'] + $sum_month_traffic['mail'];
|
||||
|
||||
if (!isset($admin_traffic[$row['adminid']])
|
||||
|| !is_array($admin_traffic[$row['adminid']])
|
||||
) {
|
||||
$admin_traffic[$row['adminid']]['http'] = 0;
|
||||
$admin_traffic[$row['adminid']]['ftp_up'] = 0;
|
||||
$admin_traffic[$row['adminid']]['ftp_down'] = 0;
|
||||
$admin_traffic[$row['adminid']]['mail'] = 0;
|
||||
$admin_traffic[$row['adminid']]['all'] = 0;
|
||||
$admin_traffic[$row['adminid']]['sum_month'] = 0;
|
||||
}
|
||||
|
||||
$admin_traffic[$row['adminid']]['http']+= $current_traffic['http'];
|
||||
$admin_traffic[$row['adminid']]['ftp_up']+= $current_traffic['ftp_up'];
|
||||
$admin_traffic[$row['adminid']]['ftp_down']+= $current_traffic['ftp_down'];
|
||||
$admin_traffic[$row['adminid']]['mail']+= $current_traffic['mail'];
|
||||
$admin_traffic[$row['adminid']]['all']+= $current_traffic['all'];
|
||||
$admin_traffic[$row['adminid']]['sum_month']+= $sum_month_traffic['all'];
|
||||
|
||||
/**
|
||||
* WebSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating webspace usage for ' . $row['loginname']);
|
||||
$webspaceusage = 0;
|
||||
|
||||
// Using repquota, it's faster using this tool than using du traversing the complete directory
|
||||
if (Settings::Get('system.diskquota_enabled')
|
||||
&& isset($usedquota[$row['guid']]['block']['used'])
|
||||
&& $usedquota[$row['guid']]['block']['used'] >= 1
|
||||
) {
|
||||
// We may use the array we created earlier, the used diskspace is stored in [<guid>][block][used]
|
||||
$webspaceusage = floatval($usedquota[$row['guid']]['block']['used']);
|
||||
|
||||
} else {
|
||||
|
||||
// Use the old fashioned way with "du"
|
||||
if (file_exists($row['documentroot'])
|
||||
&& is_dir($row['documentroot'])
|
||||
) {
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($row['documentroot']) . '');
|
||||
foreach ($back as $backrow) {
|
||||
$webspaceusage = explode(' ', $backrow);
|
||||
}
|
||||
|
||||
$webspaceusage = floatval($webspaceusage['0']);
|
||||
unset($back);
|
||||
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'documentroot ' . $row['documentroot'] . ' does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MailSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating mailspace usage for ' . $row['loginname']);
|
||||
$emailusage = 0;
|
||||
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . $row['loginname']);
|
||||
if (file_exists($maildir) && is_dir($maildir)) {
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($maildir) . '');
|
||||
foreach ($back as $backrow) {
|
||||
$emailusage = explode(' ', $backrow);
|
||||
}
|
||||
|
||||
$emailusage = floatval($emailusage['0']);
|
||||
unset($back);
|
||||
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'maildir ' . $maildir . ' does not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQLSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating mysqlspace usage for ' . $row['loginname']);
|
||||
$mysqlusage = 0;
|
||||
|
||||
if (isset($mysqlusage_all[$row['customerid']])) {
|
||||
$mysqlusage = floatval($mysqlusage_all[$row['customerid']] / 1024);
|
||||
}
|
||||
|
||||
$current_diskspace = array();
|
||||
$current_diskspace['webspace'] = floatval($webspaceusage);
|
||||
$current_diskspace['mail'] = floatval($emailusage);
|
||||
$current_diskspace['mysql'] = floatval($mysqlusage);
|
||||
$current_diskspace['all'] = $current_diskspace['webspace'] + $current_diskspace['mail'] + $current_diskspace['mysql'];
|
||||
|
||||
$ins_data = array(
|
||||
'customerid' => $row['customerid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'webspace' => $current_diskspace['webspace'],
|
||||
'mail' => $current_diskspace['mail'],
|
||||
'mysql' => $current_diskspace['mysql']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DISKSPACE . "` SET
|
||||
`customerid` = :customerid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`webspace` = :webspace,
|
||||
`mail` = :mail,
|
||||
`mysql` = :mysql
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
if (!isset($admin_diskspace[$row['adminid']])
|
||||
|| !is_array($admin_diskspace[$row['adminid']])
|
||||
) {
|
||||
$admin_diskspace[$row['adminid']] = array();
|
||||
$admin_diskspace[$row['adminid']]['webspace'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['mail'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['mysql'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['all'] = 0;
|
||||
}
|
||||
|
||||
$admin_diskspace[$row['adminid']]['webspace']+= $current_diskspace['webspace'];
|
||||
$admin_diskspace[$row['adminid']]['mail']+= $current_diskspace['mail'];
|
||||
$admin_diskspace[$row['adminid']]['mysql']+= $current_diskspace['mysql'];
|
||||
$admin_diskspace[$row['adminid']]['all']+= $current_diskspace['all'];
|
||||
|
||||
/**
|
||||
* Total Usage
|
||||
*/
|
||||
$diskusage = floatval($webspaceusage + $emailusage + $mysqlusage);
|
||||
|
||||
$upd_data = array(
|
||||
'diskspace' => $current_diskspace['all'],
|
||||
'traffic' => $sum_month_traffic['all'],
|
||||
'customerid' => $row['customerid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
|
||||
`diskspace_used` = :diskspace,
|
||||
`traffic_used` = :traffic
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
/**
|
||||
* Proftpd Quota
|
||||
*/
|
||||
$upd_data = array(
|
||||
'biu' => ($current_diskspace['all'] * 1024),
|
||||
'loginname' => $row['loginname'],
|
||||
'loginnamelike' => $row['loginname'] . Settings::Get('customer.ftpprefix') . "%"
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_QUOTATALLIES . "` SET
|
||||
`bytes_in_used` = :biu WHERE `name` = :loginname OR `name` LIKE :loginnamelike
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
/**
|
||||
* Pureftpd Quota
|
||||
*/
|
||||
if (Settings::Get('system.ftpserver') == "pureftpd") {
|
||||
|
||||
$result_quota_stmt = Database::prepare("
|
||||
SELECT homedir FROM `" . TABLE_FTP_USERS . "` WHERE customerid = :customerid
|
||||
");
|
||||
Database::pexecute($result_quota_stmt, array('customerid' => $row['customerid']));
|
||||
|
||||
// get correct user
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) && $row['deactivated'] == '0') {
|
||||
$user = $row['loginname'];
|
||||
$group = $row['loginname'];
|
||||
} else {
|
||||
$user = $row['guid'];
|
||||
$group = $row['guid'];
|
||||
}
|
||||
|
||||
while ($row_quota = $result_quota_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$quotafile = "" . $row_quota['homedir'] . ".ftpquota";
|
||||
$fh = fopen($quotafile, 'w');
|
||||
$stringdata = "0 " . $current_diskspace['all']*1024 . "";
|
||||
fwrite($fh, $stringdata);
|
||||
fclose($fh);
|
||||
safe_exec('chown ' . $user . ':' . $group . ' ' . escapeshellarg($quotafile) . '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Usage
|
||||
*/
|
||||
$result_stmt = Database::query("SELECT `adminid` FROM `" . TABLE_PANEL_ADMINS . "` ORDER BY `adminid` ASC");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($admin_traffic[$row['adminid']])) {
|
||||
|
||||
$ins_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'http' => $admin_traffic[$row['adminid']]['http'],
|
||||
'ftp_up' => $admin_traffic[$row['adminid']]['ftp_up'],
|
||||
'ftp_down' => $admin_traffic[$row['adminid']]['ftp_down'],
|
||||
'mail' => $admin_traffic[$row['adminid']]['mail']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TRAFFIC_ADMINS . "` SET
|
||||
`adminid` = :adminid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`http` = :http,
|
||||
`ftp_up` = :ftp_up,
|
||||
`ftp_down` = :ftp_down,
|
||||
`mail` = :mail
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
$upd_data = array(
|
||||
'traffic' => $admin_traffic[$row['adminid']]['sum_month'],
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`traffic_used` = :traffic
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
|
||||
if (isset($admin_diskspace[$row['adminid']])) {
|
||||
|
||||
$ins_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'webspace' => $admin_diskspace[$row['adminid']]['webspace'],
|
||||
'mail' => $admin_diskspace[$row['adminid']]['mail'],
|
||||
'mysql' => $admin_diskspace[$row['adminid']]['mysql']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DISKSPACE_ADMINS . "` SET
|
||||
`adminid` = :adminid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`webspace` = :webspace,
|
||||
`mail` = :mail,
|
||||
`mysql` = :mysql
|
||||
");
|
||||
|
||||
$upd_data = array(
|
||||
'diskspace' => $admin_diskspace[$row['adminid']]['all'],
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`diskspace_used` = :diskspace
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_traffic_run'");
|
||||
|
||||
if (function_exists('pcntl_fork') && !defined('CRON_NOFORK_FLAG')) {
|
||||
@unlink($TrafficLock);
|
||||
die();
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
|
||||
if ((int)Settings::Get('system.report_webmax') > 0)
|
||||
{
|
||||
/**
|
||||
* report about diskusage for customers
|
||||
*/
|
||||
$result_stmt = Database::query("
|
||||
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
||||
`c`.`company`, `c`.`diskspace`, `c`.`diskspace_used`, `c`.`email`, `c`.`def_language`,
|
||||
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
|
||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
||||
ON `a`.`adminid` = `c`.`adminid`
|
||||
WHERE `c`.`diskspace` > '0' AND `c`.`reportsent` <> '2'
|
||||
");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['diskspace'])
|
||||
&& $row['diskspace_used'] != null
|
||||
&& $row['diskspace_used'] > 0
|
||||
&& (($row['diskspace_used'] * 100) / $row['diskspace']) >= (int)Settings::Get('system.report_webmax')
|
||||
) {
|
||||
|
||||
$rep_userinfo = array(
|
||||
'name' => $row['name'],
|
||||
'firstname' => $row['firstname'],
|
||||
'company' => $row['company']
|
||||
);
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => getCorrectUserSalutation($rep_userinfo),
|
||||
'NAME' => $row['name'], // < keep this for compatibility
|
||||
'DISKAVAILABLE' => round(($row['diskspace'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['diskspace_used'] * 100) / $row['diskspace'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_webmax')
|
||||
);
|
||||
|
||||
$lngfile_stmt = Database::prepare("
|
||||
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
||||
WHERE `language` = :deflang
|
||||
");
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => $row['def_language']));
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => Settings::Get('panel.standardlanguage')));
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/' . $langfile);
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
$result2_stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||
WHERE `adminid` = :adminid
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'diskmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$result2_data['varname'] = 'diskmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom($row['adminmail'], $row['adminname']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(nl2br($mail_body));
|
||||
$mail->AddAddress($row['email'], $row['name']);
|
||||
$mail->Send();
|
||||
} catch(\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '2'
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('customerid' => $row['customerid']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* report about diskusage for admins/reseller
|
||||
*/
|
||||
$result_stmt = Database::query("
|
||||
SELECT `a`.* FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` <> '2'
|
||||
");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['diskspace'])
|
||||
&& $row['diskspace_used'] != null
|
||||
&& $row['diskspace_used'] > 0
|
||||
&& (($row['diskspace_used'] * 100) / $row['diskspace']) >= (int)Settings::Get('system.report_webmax')
|
||||
) {
|
||||
|
||||
$replace_arr = array(
|
||||
'NAME' => $row['name'],
|
||||
'DISKAVAILABLE' => ($row['diskspace'] / 1024), /* traffic is stored in KB, template uses MB */
|
||||
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => ($row['diskspace_used'] * 100) / $row['diskspace'],
|
||||
'MAX_PERCENT' => Settings::Get('system.report_webmax')
|
||||
);
|
||||
|
||||
$lngfile_stmt = Database::prepare("
|
||||
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
||||
WHERE `language` = :deflang
|
||||
");
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => $row['def_language']));
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => Settings::Get('panel.standardlanguage')));
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/' . $langfile);
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
$result2_stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||
WHERE `adminid` = :adminid
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'diskmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$result2_data['varname'] = 'diskmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom($row['email'], $row['name']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(nl2br($mail_body));
|
||||
$mail->AddAddress($row['email'], $row['name']);
|
||||
$mail->Send();
|
||||
} catch(\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '2'
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('adminid' => $row['adminid']));
|
||||
}
|
||||
}
|
||||
} // webmax > 0
|
||||
@@ -1,347 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Web- and Traffic-usage reporting started...');
|
||||
$yesterday = time() - (60 * 60 * 24);
|
||||
|
||||
/**
|
||||
* Initialize the mailingsystem
|
||||
*/
|
||||
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
|
||||
$mail->CharSet = "UTF-8";
|
||||
|
||||
if (Settings::Get('system.mail_use_smtp')) {
|
||||
$mail->isSMTP();
|
||||
$mail->Host = Settings::Get('system.mail_smtp_host');
|
||||
$mail->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
||||
$mail->Username = Settings::Get('system.mail_smtp_user');
|
||||
$mail->Password = Settings::Get('system.mail_smtp_passwd');
|
||||
if (Settings::Get('system.mail_smtp_usetls')) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} else {
|
||||
$mail->SMTPAutoTLS = false;
|
||||
}
|
||||
$mail->Port = Settings::Get('system.mail_smtp_port');
|
||||
}
|
||||
|
||||
if (\PHPMailer\PHPMailer\PHPMailer::ValidateAddress(Settings::Get('panel.adminmail')) !== false) {
|
||||
// set return-to address and custom sender-name, see #76
|
||||
$mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
|
||||
if (Settings::Get('panel.adminmail_return') != '') {
|
||||
$mail->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname'));
|
||||
}
|
||||
}
|
||||
|
||||
if ((int)Settings::Get('system.report_trafficmax') > 0)
|
||||
{
|
||||
// Warn the customers at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
||||
`c`.`company`, `c`.`traffic`, `c`.`email`, `c`.`def_language`,
|
||||
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` `t`
|
||||
WHERE `t`.`customerid` = `c`.`customerid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
|
||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
||||
ON `a`.`adminid` = `c`.`adminid` WHERE `c`.`reportsent` <> '1'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday)
|
||||
);
|
||||
Database::pexecute($result_stmt, $result_data);
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['traffic'])
|
||||
&& $row['traffic'] > 0
|
||||
&& $row['traffic_used'] != null
|
||||
&& (($row['traffic_used'] * 100) / $row['traffic']) >= (int)Settings::Get('system.report_trafficmax')
|
||||
) {
|
||||
$rep_userinfo = array(
|
||||
'name' => $row['name'],
|
||||
'firstname' => $row['firstname'],
|
||||
'company' => $row['company']
|
||||
);
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => getCorrectUserSalutation($rep_userinfo),
|
||||
'NAME' => $row['name'], // < keep this for compatibility
|
||||
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'TRAFFICUSED' => round(($row['traffic_used'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['traffic_used'] * 100) / $row['traffic'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
|
||||
);
|
||||
|
||||
$lngfile_stmt = Database::prepare("
|
||||
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
||||
WHERE `language` = :deflang
|
||||
");
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => $row['def_language']));
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => Settings::Get('panel.standardlanguage')));
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/' . $langfile);
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
$result2_stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||
WHERE `adminid` = :adminid
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$result2_data['varname'] = 'trafficmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom($row['adminmail'], $row['adminname']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(nl2br($mail_body));
|
||||
$mail->AddAddress($row['email'], $row['firstname'] . ' ' . $row['name']);
|
||||
$mail->Send();
|
||||
} catch(\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
echo 'Error sending mail: ' . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '1'
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('customerid' => $row['customerid']));
|
||||
}
|
||||
}
|
||||
|
||||
// Warn the admins at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `a`.*,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "` `t`
|
||||
WHERE `t`.`adminid` = `a`.`adminid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` = '0'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday)
|
||||
);
|
||||
Database::pexecute($result_stmt, $result_data);
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['traffic'])
|
||||
&& $row['traffic'] > 0
|
||||
&& (($row['traffic_used_total'] * 100) / $row['traffic']) >= (int)Settings::Get('system.report_trafficmax')
|
||||
) {
|
||||
|
||||
$replace_arr = array(
|
||||
'NAME' => $row['name'],
|
||||
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'TRAFFICUSED' => round(($row['traffic_used_total'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['traffic_used_total'] * 100) / $row['traffic'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
|
||||
);
|
||||
|
||||
$lngfile_stmt = Database::prepare("
|
||||
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
||||
WHERE `language` = :deflang
|
||||
");
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => $row['def_language']));
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array('deflang' => Settings::Get('panel.standardlanguage')));
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once makeCorrectFile(FROXLOR_INSTALL_DIR . '/' . $langfile);
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
$result2_stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||
WHERE `adminid` = :adminid
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$resul2_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$resul2_data['varname'] = 'trafficmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom($row['email'], $row['name']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(nl2br($mail_body));
|
||||
$mail->AddAddress($row['email'], $row['name']);
|
||||
$mail->Send();
|
||||
} catch(\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '1'
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('adminid' => $row['adminid']));
|
||||
}
|
||||
|
||||
// Another month, let's build our report
|
||||
if (date('d') == '01') {
|
||||
|
||||
$mail_subject = 'Trafficreport ' . date("m/y", $yesterday) . ' for ' . $row['name'];
|
||||
$mail_body = 'Trafficreport ' . date("m/y", $yesterday) . ' for ' . $row['name'] . "\n";
|
||||
$mail_body.= '---------------------------------------------------------------' . "\n";
|
||||
$mail_body.= 'Loginname Traffic used (Percent) | Traffic available' . "\n";
|
||||
$customers_stmt = Database::prepare("
|
||||
SELECT `c`.*,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` `t`
|
||||
WHERE `t`.`customerid` = `c`.`customerid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `c`.`adminid` = :adminid
|
||||
");
|
||||
$customers_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday),
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
Database::pexecute($customers_stmt, $customers_data);
|
||||
|
||||
while ($customer = $customers_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$t = $customer['traffic_used_total']/1048576;
|
||||
if ($customer['traffic'] > 0) {
|
||||
$p = (($customer['traffic_used_total'] * 100) / $customer['traffic'] );
|
||||
$tg = $customer['traffic']/1048576;
|
||||
$str = sprintf('%00.1f GB ( %00.1f %% )', $t, $p);
|
||||
$mail_body.= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . sprintf('%00.1f GB', $tg) . "\n";
|
||||
} else if ($customer['traffic'] == 0) {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . '0' . "\n";
|
||||
} else {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . 'unlimited' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$mail_body.= '---------------------------------------------------------------' . "\n";
|
||||
|
||||
$t = $row['traffic_used_total']/1048576;
|
||||
if ($row['traffic'] > 0) {
|
||||
$p = (($row['traffic_used_total'] * 100) / $row['traffic']);
|
||||
$tg = $row['traffic']/1048576;
|
||||
$str = sprintf('%00.1f GB ( %00.1f %% )', $t, $p);
|
||||
$mail_body.= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . sprintf('%00.1f GB', $tg) . "\n";
|
||||
} else if ($row['traffic'] == 0) {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . '0' . "\n";
|
||||
} else {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . 'unlimited' . "\n";
|
||||
}
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom($row['email'], $row['name']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->Body = $mail_body;
|
||||
$mail->AddAddress($row['email'], $row['name']);
|
||||
$mail->Send();
|
||||
} catch(\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
echo 'Error sending mail: ' . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
}
|
||||
}
|
||||
} // trafficmax > 0
|
||||
|
||||
// include diskspace-usage report, #466
|
||||
include dirname(__FILE__).'/cron_usage.inc.diskspace.php';
|
||||
|
||||
// Another month, reset the reportstatus
|
||||
if (date('d') == '01') {
|
||||
Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '0';");
|
||||
Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '0';");
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* RESET USED TICKETS COUNTER
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Resetting customers used ticket counter");
|
||||
Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `tickets_used` = '0'");
|
||||
Reference in New Issue
Block a user