major refactoring of almost all files
This commit is contained in:
@@ -1,27 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* @since 0.10.0
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
class CronConfig
|
||||
{
|
||||
@@ -33,7 +41,6 @@ class CronConfig
|
||||
*/
|
||||
public static function checkCrondConfigurationFile()
|
||||
{
|
||||
|
||||
// check for task
|
||||
Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '99'
|
||||
@@ -42,9 +49,8 @@ class CronConfig
|
||||
|
||||
// is there a task for re-generating the cron.d-file?
|
||||
if ($num_results > 0) {
|
||||
|
||||
// get all crons and their intervals
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
if (FileDir::isFreeBSD()) {
|
||||
// FreeBSD does not need a header as we are writing directly to the crontab
|
||||
$cronfile = "\n";
|
||||
} else {
|
||||
@@ -67,9 +73,9 @@ class CronConfig
|
||||
$hour_delay = 0;
|
||||
$day_delay = 5;
|
||||
$month_delay = 7;
|
||||
while ($row_cronentry = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
while ($row_cronentry = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// create cron.d-entry
|
||||
$matches = array();
|
||||
$matches = [];
|
||||
if (preg_match("/(\d+) (MINUTE|HOUR|DAY|WEEK|MONTH)/", $row_cronentry['interval'], $matches)) {
|
||||
if ($matches[1] == 1) {
|
||||
$minvalue = "*";
|
||||
@@ -104,17 +110,17 @@ class CronConfig
|
||||
}
|
||||
|
||||
// create entry-line
|
||||
$cronfile .= "root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n";
|
||||
$cronfile .= "root " . $binpath . " " . FileDir::makeCorrectFile(Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n";
|
||||
}
|
||||
}
|
||||
|
||||
// php sessionclean if enabled
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$cronfile .= "# Look for and purge old sessions every 30 minutes" . PHP_EOL;
|
||||
$cronfile .= "09,39 * * * * root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/bin/froxlor-cli") . " froxlor:php-sessionclean 1> /dev/null" . PHP_EOL;
|
||||
$cronfile .= "09,39 * * * * root " . $binpath . " " . FileDir::makeCorrectFile(Froxlor::getInstallDir() . "/bin/froxlor-cli") . " froxlor:php-sessionclean 1> /dev/null" . PHP_EOL;
|
||||
}
|
||||
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
if (FileDir::isFreeBSD()) {
|
||||
// FreeBSD handles the cron-stuff in another way. We need to directly
|
||||
// write to the crontab file as there is not cron.d/froxlor file
|
||||
// (settings for system.cronconfig should be set correctly of course)
|
||||
@@ -153,7 +159,7 @@ class CronConfig
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '99'");
|
||||
|
||||
// run reload command
|
||||
\Froxlor\FileDir::safe_exec(escapeshellcmd(Settings::Get('system.crondreload')));
|
||||
FileDir::safe_exec(escapeshellcmd(Settings::Get('system.crondreload')));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Dns\Dns;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Validate\Validate;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
class Bind extends DnsBase
|
||||
{
|
||||
|
||||
@@ -25,21 +41,21 @@ class Bind extends DnsBase
|
||||
public function writeConfigs()
|
||||
{
|
||||
// tell the world what we are doing
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 started - Rebuilding froxlor_bind.conf');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 started - Rebuilding froxlor_bind.conf');
|
||||
|
||||
// clean up
|
||||
$this->cleanZonefiles();
|
||||
|
||||
// check for subfolder in bind-config-directory
|
||||
if (! file_exists(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/'))) {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'mkdir ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
if (!file_exists(FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/'))) {
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'mkdir ' . escapeshellarg(FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
}
|
||||
|
||||
$domains = $this->getDomainList();
|
||||
|
||||
if (empty($domains)) {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,12 +69,33 @@ class Bind extends DnsBase
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
|
||||
$bindconf_file_handler = fopen(\Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
|
||||
$bindconf_file_handler = fopen(FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
|
||||
fwrite($bindconf_file_handler, $this->bindconf_file);
|
||||
fclose($bindconf_file_handler);
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'froxlor_bind.conf written');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'froxlor_bind.conf written');
|
||||
$this->reloadDaemon();
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
}
|
||||
|
||||
private function cleanZonefiles()
|
||||
{
|
||||
$config_dir = FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/domains/');
|
||||
|
||||
$this->logger->logAction(FroxlorLogger::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
|
||||
FileDir::safe_exec('rm -f ' . escapeshellarg(FileDir::makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function walkDomainList($domain, $domains)
|
||||
@@ -78,31 +115,31 @@ class Bind extends DnsBase
|
||||
}
|
||||
|
||||
if ($domain['ismainbutsubto'] == 0) {
|
||||
$zoneContent = (string) \Froxlor\Dns\Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
|
||||
$zoneContent = (string)Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
|
||||
$domain['zonefile'] = 'domains/' . $domain['domain'] . '.zone';
|
||||
$zonefile_name = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']);
|
||||
$zonefile_name = FileDir::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(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, '`' . $zonefile_name . '` written');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, '`' . $zonefile_name . '` written');
|
||||
$this->bindconf_file .= $this->generateDomainConfig($domain);
|
||||
} else {
|
||||
return (string) \Froxlor\Dns\Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname, true);
|
||||
return (string)Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname, true);
|
||||
}
|
||||
} else {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::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->logger->logAction(FroxlorLogger::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())
|
||||
private function generateDomainConfig($domain = [])
|
||||
{
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Generating dns config for ' . $domain['domain']);
|
||||
$this->logger->logAction(FroxlorLogger::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 "' . \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']) . '";' . "\n";
|
||||
$bindconf_file .= ' file "' . FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']) . '";' . "\n";
|
||||
$bindconf_file .= ' allow-query { any; };' . "\n";
|
||||
|
||||
if (count($this->ns) > 0 || count($this->axfr) > 0) {
|
||||
@@ -112,7 +149,7 @@ class Bind extends DnsBase
|
||||
if (count($this->ns) > 0) {
|
||||
foreach ($this->ns as $ns) {
|
||||
foreach ($ns["ips"] as $ip) {
|
||||
$ip = \Froxlor\Validate\Validate::validate_ip2($ip, true, 'invalidip', true, true, true);
|
||||
$ip = Validate::validate_ip2($ip, true, 'invalidip', true, true, true);
|
||||
if ($ip) {
|
||||
$bindconf_file .= ' ' . $ip . ";\n";
|
||||
}
|
||||
@@ -134,26 +171,4 @@ class Bind extends DnsBase
|
||||
|
||||
return $bindconf_file;
|
||||
}
|
||||
|
||||
private function cleanZonefiles()
|
||||
{
|
||||
$config_dir = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/domains/');
|
||||
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::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
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,37 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Class DnsBase
|
||||
*
|
||||
@@ -29,13 +42,11 @@ abstract class DnsBase
|
||||
|
||||
protected $logger = false;
|
||||
|
||||
protected $ns = array();
|
||||
protected $ns = [];
|
||||
|
||||
protected $mx = array();
|
||||
protected $mx = [];
|
||||
|
||||
protected $axfr = array();
|
||||
|
||||
abstract public function writeConfigs();
|
||||
protected $axfr = [];
|
||||
|
||||
public function __construct($logger)
|
||||
{
|
||||
@@ -48,31 +59,31 @@ abstract class DnsBase
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
$nameserver_ips = PhpHelper::gethostbynamel6($nameserver);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
if (substr($nameserver, -1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
if (!is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver_ips = [
|
||||
$nameserver
|
||||
);
|
||||
];
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
$this->ns[] = array(
|
||||
$this->ns[] = [
|
||||
'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) != '.') {
|
||||
if (substr($mxserver, -1, 1) != '.') {
|
||||
$mxserver .= '.';
|
||||
}
|
||||
$this->mx[] = $mxserver;
|
||||
@@ -90,6 +101,100 @@ abstract class DnsBase
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function writeConfigs();
|
||||
|
||||
public function reloadDaemon()
|
||||
{
|
||||
// reload DNS daemon
|
||||
$cmd = Settings::Get('system.bindreload_command');
|
||||
$cmdStatus = 1;
|
||||
FileDir::safe_exec(escapeshellcmd($cmd), $cmdStatus);
|
||||
if ($cmdStatus === 0) {
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, Settings::Get('system.dns_server') . ' daemon reloaded');
|
||||
} else {
|
||||
$this->logger->logAction(FroxlorLogger::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(FileDir::makeCorrectDir(Settings::Get('dkim.dkim_prefix')))) {
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir(Settings::Get('dkim.dkim_prefix'))));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::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 = FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
|
||||
$pubkey_filename = FileDir::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 = FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
|
||||
FileDir::safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
|
||||
$domain['dkim_privkey'] = file_get_contents($privkey_filename);
|
||||
FileDir::safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));
|
||||
$pubkey_filename = FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
|
||||
FileDir::safe_exec('openssl rsa -in ' . escapeshellarg($privkey_filename) . ' -pubout -outform pem -out ' . escapeshellarg($pubkey_filename));
|
||||
$domain['dkim_pubkey'] = file_get_contents($pubkey_filename);
|
||||
FileDir::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 = [
|
||||
'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);
|
||||
FileDir::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);
|
||||
FileDir::safe_exec("chmod 0644 " . escapeshellarg($pubkey_filename));
|
||||
}
|
||||
|
||||
$dkimdomains .= $domain['domain'] . "\n";
|
||||
$dkimkeys .= "*@" . $domain['domain'] . ":" . $domain['domain'] . ":" . $privkey_filename . "\n";
|
||||
}
|
||||
|
||||
$dkimdomains_filename = FileDir::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 = FileDir::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);
|
||||
|
||||
FileDir::safe_exec(escapeshellcmd(Settings::Get('dkim.dkimrestart_command')));
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Dkim-milter reloaded');
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDomainList()
|
||||
{
|
||||
$result_domains_stmt = Database::query("
|
||||
@@ -117,16 +222,16 @@ abstract class DnsBase
|
||||
`d`.`domain` ASC
|
||||
");
|
||||
|
||||
$domains = array();
|
||||
$domains = [];
|
||||
// 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)) {
|
||||
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(
|
||||
$hostname_arr = [
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'isbinddomain' => '1',
|
||||
@@ -139,7 +244,7 @@ abstract class DnsBase
|
||||
'ismainbutsubto' => '0',
|
||||
'zonefile' => '',
|
||||
'froxlorhost' => '1'
|
||||
);
|
||||
];
|
||||
$domains['none'] = $hostname_arr;
|
||||
}
|
||||
|
||||
@@ -149,8 +254,8 @@ abstract class DnsBase
|
||||
|
||||
// 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 (!isset($domains[$key]['children'])) {
|
||||
$domains[$key]['children'] = [];
|
||||
}
|
||||
if ($domains[$key]['ismainbutsubto'] > 0) {
|
||||
if (isset($domains[$domains[$key]['ismainbutsubto']])) {
|
||||
@@ -161,105 +266,12 @@ abstract class DnsBase
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, str_pad('domId', 9, ' ') . str_pad('domain', 40, ' ') . 'ismainbutsubto ' . str_pad('parent domain', 40, ' ') . "list of child domain ids");
|
||||
$this->logger->logAction(FroxlorLogger::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(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, $logLine);
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, $logLine);
|
||||
}
|
||||
|
||||
return $domains;
|
||||
}
|
||||
|
||||
public function reloadDaemon()
|
||||
{
|
||||
// reload DNS daemon
|
||||
$cmd = Settings::Get('system.bindreload_command');
|
||||
$cmdStatus = 1;
|
||||
\Froxlor\FileDir::safe_exec(escapeshellcmd($cmd), $cmdStatus);
|
||||
if ($cmdStatus === 0) {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, Settings::Get('system.dns_server') . ' daemon reloaded');
|
||||
} else {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::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(\Froxlor\FileDir::makeCorrectDir(Settings::Get('dkim.dkim_prefix')))) {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir(Settings::Get('dkim.dkim_prefix'))));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::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 = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
|
||||
$pubkey_filename = \Froxlor\FileDir::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 = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
|
||||
\Froxlor\FileDir::safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
|
||||
$domain['dkim_privkey'] = file_get_contents($privkey_filename);
|
||||
\Froxlor\FileDir::safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));
|
||||
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
|
||||
\Froxlor\FileDir::safe_exec('openssl rsa -in ' . escapeshellarg($privkey_filename) . ' -pubout -outform pem -out ' . escapeshellarg($pubkey_filename));
|
||||
$domain['dkim_pubkey'] = file_get_contents($pubkey_filename);
|
||||
\Froxlor\FileDir::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);
|
||||
\Froxlor\FileDir::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);
|
||||
\Froxlor\FileDir::safe_exec("chmod 0644 " . escapeshellarg($pubkey_filename));
|
||||
}
|
||||
|
||||
$dkimdomains .= $domain['domain'] . "\n";
|
||||
$dkimkeys .= "*@" . $domain['domain'] . ":" . $domain['domain'] . ":" . $privkey_filename . "\n";
|
||||
}
|
||||
|
||||
$dkimdomains_filename = \Froxlor\FileDir::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 = \Froxlor\FileDir::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);
|
||||
|
||||
\Froxlor\FileDir::safe_exec(escapeshellcmd(Settings::Get('dkim.dkimrestart_command')));
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Dkim-milter reloaded');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,43 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Dns\Dns;
|
||||
use Froxlor\Dns\DnsZone;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
class PowerDNS extends DnsBase
|
||||
{
|
||||
|
||||
public function writeConfigs()
|
||||
{
|
||||
// tell the world what we are doing
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 started - Refreshing DNS database');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 started - Refreshing DNS database');
|
||||
|
||||
$domains = $this->getDomainList();
|
||||
|
||||
@@ -31,7 +45,7 @@ class PowerDNS extends DnsBase
|
||||
$this->clearZoneTables($domains);
|
||||
|
||||
if (empty($domains)) {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,15 +57,45 @@ class PowerDNS extends DnsBase
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'PowerDNS database updated');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'PowerDNS database updated');
|
||||
$this->reloadDaemon();
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
}
|
||||
|
||||
private function clearZoneTables($domains = null)
|
||||
{
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Cleaning dns zone entries from database');
|
||||
|
||||
$pdns_domains_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("SELECT `id`, `name` FROM `domains` WHERE `name` = :domain");
|
||||
|
||||
$del_rec_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `records` WHERE `domain_id` = :did");
|
||||
$del_meta_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `domainmetadata` WHERE `domain_id` = :did");
|
||||
$del_dom_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `domains` WHERE `id` = :did");
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$pdns_domains_stmt->execute([
|
||||
'domain' => $domain['domain']
|
||||
]);
|
||||
$pdns_domain = $pdns_domains_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($pdns_domain && !empty($pdns_domain['id'])) {
|
||||
$del_rec_stmt->execute([
|
||||
'did' => $pdns_domain['id']
|
||||
]);
|
||||
$del_meta_stmt->execute([
|
||||
'did' => $pdns_domain['id']
|
||||
]);
|
||||
$del_dom_stmt->execute([
|
||||
'did' => $pdns_domain['id']
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function walkDomainList($domain, $domains)
|
||||
{
|
||||
$zoneContent = '';
|
||||
$subzones = array();
|
||||
$subzones = [];
|
||||
|
||||
foreach ($domain['children'] as $child_domain_id) {
|
||||
$subzones[] = $this->walkDomainList($domains[$child_domain_id], $domains);
|
||||
@@ -65,7 +109,7 @@ class PowerDNS extends DnsBase
|
||||
}
|
||||
|
||||
if ($domain['ismainbutsubto'] == 0) {
|
||||
$zoneContent = \Froxlor\Dns\Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
|
||||
$zoneContent = Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
|
||||
if (count($subzones)) {
|
||||
foreach ($subzones as $subzone) {
|
||||
$zoneContent->records[] = $subzone;
|
||||
@@ -74,42 +118,12 @@ class PowerDNS extends DnsBase
|
||||
$pdnsDomId = $this->insertZone($zoneContent->origin, $zoneContent->serial);
|
||||
$this->insertRecords($pdnsDomId, $zoneContent->records, $zoneContent->origin);
|
||||
$this->insertAllowedTransfers($pdnsDomId);
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'DB entries stored for zone `' . $domain['domain'] . '`');
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'DB entries stored for zone `' . $domain['domain'] . '`');
|
||||
} else {
|
||||
return \Froxlor\Dns\Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname, true);
|
||||
return Dns::createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname, true);
|
||||
}
|
||||
} else {
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, 'Custom zonefiles are NOT supported when PowerDNS is selected as DNS daemon (triggered by: ' . $domain['domain'] . ')');
|
||||
}
|
||||
}
|
||||
|
||||
private function clearZoneTables($domains = null)
|
||||
{
|
||||
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Cleaning dns zone entries from database');
|
||||
|
||||
$pdns_domains_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("SELECT `id`, `name` FROM `domains` WHERE `name` = :domain");
|
||||
|
||||
$del_rec_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `records` WHERE `domain_id` = :did");
|
||||
$del_meta_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `domainmetadata` WHERE `domain_id` = :did");
|
||||
$del_dom_stmt = \Froxlor\Dns\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);
|
||||
|
||||
if ($pdns_domain && ! empty($pdns_domain['id'])) {
|
||||
$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']
|
||||
));
|
||||
}
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'Custom zonefiles are NOT supported when PowerDNS is selected as DNS daemon (triggered by: ' . $domain['domain'] . ')');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,16 +132,16 @@ class PowerDNS extends DnsBase
|
||||
$ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("
|
||||
INSERT INTO domains set `name` = :domainname, `notified_serial` = :serial, `type` = :type
|
||||
");
|
||||
$ins_stmt->execute(array(
|
||||
$ins_stmt->execute([
|
||||
'domainname' => $domainname,
|
||||
'serial' => $serial,
|
||||
'type' => strtoupper(Settings::Get('system.powerdns_mode'))
|
||||
));
|
||||
]);
|
||||
$lastid = \Froxlor\Dns\PowerDNS::getDB()->lastInsertId();
|
||||
return $lastid;
|
||||
}
|
||||
|
||||
private function insertRecords($domainid = 0, $records = array(), $origin = "")
|
||||
private function insertRecords($domainid = 0, $records = [], $origin = "")
|
||||
{
|
||||
$ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("
|
||||
INSERT INTO records set
|
||||
@@ -141,7 +155,7 @@ class PowerDNS extends DnsBase
|
||||
");
|
||||
|
||||
foreach ($records as $record) {
|
||||
if ($record instanceof \Froxlor\Dns\DnsZone) {
|
||||
if ($record instanceof DnsZone) {
|
||||
$this->insertRecords($domainid, $record->records, $record->origin);
|
||||
continue;
|
||||
}
|
||||
@@ -152,14 +166,14 @@ class PowerDNS extends DnsBase
|
||||
$_record = $record->record . "." . $origin;
|
||||
}
|
||||
|
||||
$ins_data = array(
|
||||
$ins_data = [
|
||||
'did' => $domainid,
|
||||
'rec' => $_record,
|
||||
'type' => $record->type,
|
||||
'content' => $record->content,
|
||||
'ttl' => $record->ttl,
|
||||
'prio' => $record->priority
|
||||
);
|
||||
];
|
||||
$ins_stmt->execute($ins_data);
|
||||
}
|
||||
}
|
||||
@@ -170,9 +184,9 @@ class PowerDNS extends DnsBase
|
||||
INSERT INTO domainmetadata set `domain_id` = :did, `kind` = 'ALLOW-AXFR-FROM', `content` = :value
|
||||
");
|
||||
|
||||
$ins_data = array(
|
||||
$ins_data = [
|
||||
'did' => $domainid
|
||||
);
|
||||
];
|
||||
|
||||
if (count($this->ns) > 0 || count($this->axfr) > 0) {
|
||||
// put nameservers in allow-transfer
|
||||
|
||||
@@ -1,32 +1,38 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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.10.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
abstract class FroxlorCron
|
||||
{
|
||||
|
||||
abstract public static function run();
|
||||
|
||||
protected static $cronlog = null;
|
||||
|
||||
protected static $lockfile = null;
|
||||
|
||||
abstract public static function run();
|
||||
|
||||
public static function getLockfile()
|
||||
{
|
||||
return static::$lockfile;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,45 +1,124 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
use Froxlor\Customer\Customer;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Http\Directory;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
*/
|
||||
class ApacheFcgi extends Apache
|
||||
{
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('system.mod_fcgid_ownvhost') == '1' || (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1')) {
|
||||
$mypath = Froxlor::getInstallDir();
|
||||
|
||||
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, [
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
]);
|
||||
}
|
||||
|
||||
$domain = [
|
||||
'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
|
||||
FileDir::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);
|
||||
}
|
||||
}
|
||||
|
||||
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']);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
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 (\Froxlor\Customer\Customer::customerHasPerlEnabled($domain['customerid'])) {
|
||||
if (Customer::customerHasPerlEnabled($domain['customerid'])) {
|
||||
$php_options_text .= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
|
||||
}
|
||||
|
||||
@@ -54,19 +133,19 @@ class ApacheFcgi extends Apache
|
||||
$filesmatch .= substr($ext, 1) . '|';
|
||||
}
|
||||
// start block, cut off last pipe and close block
|
||||
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, - 1)) . ')';
|
||||
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, -1)) . ')';
|
||||
$php_options_text .= ' <FilesMatch \.' . $filesmatch . '$>' . "\n";
|
||||
$php_options_text .= ' <If "-f %{SCRIPT_FILENAME}">' . "\n";
|
||||
$php_options_text .= ' SetHandler proxy:unix:' . $domain['fpm_socket'] . '|fcgi://localhost' . "\n";
|
||||
$php_options_text .= ' </If>' . "\n";
|
||||
$php_options_text .= ' </FilesMatch>' . "\n";
|
||||
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
$mypath_dir = new Directory($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 "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text .= ' <Directory "' . FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
if ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
$php_options_text .= ' CGIPassAuth On' . "\n";
|
||||
}
|
||||
@@ -75,7 +154,7 @@ class ApacheFcgi extends Apache
|
||||
$php_options_text .= ' </Directory>' . "\n";
|
||||
} elseif ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
// allow Pass of Authorization header
|
||||
$php_options_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text .= ' <Directory "' . FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text .= ' CGIPassAuth On' . "\n";
|
||||
$php_options_text .= ' </Directory>' . "\n";
|
||||
}
|
||||
@@ -85,7 +164,7 @@ class ApacheFcgi extends Apache
|
||||
$addheader = " -pass-header Authorization";
|
||||
}
|
||||
$php_options_text .= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $domain['fpm_socket'] . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n";
|
||||
$php_options_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text .= ' <Directory "' . FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
|
||||
$extensions = explode(" ", $filesmatch);
|
||||
$filesmatch = "";
|
||||
@@ -93,7 +172,7 @@ class ApacheFcgi extends Apache
|
||||
$filesmatch .= substr($ext, 1) . '|';
|
||||
}
|
||||
// start block, cut off last pipe and close block
|
||||
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, - 1)) . ')';
|
||||
$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";
|
||||
@@ -101,7 +180,7 @@ class ApacheFcgi extends Apache
|
||||
$php_options_text .= ' </FilesMatch>' . "\n";
|
||||
// >=apache-2.4 enabled?
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
$mypath_dir = new Directory($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) {
|
||||
@@ -117,12 +196,12 @@ class ApacheFcgi extends Apache
|
||||
}
|
||||
} else {
|
||||
$php_options_text .= ' FcgidIdleTimeout ' . Settings::Get('system.mod_fcgid_idle_timeout') . "\n";
|
||||
if ((int) Settings::Get('system.mod_fcgid_wrapper') == 0) {
|
||||
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 "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text .= ' <Directory "' . FileDir::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";
|
||||
@@ -133,7 +212,7 @@ class ApacheFcgi extends Apache
|
||||
$php_options_text .= ' </FilesMatch>' . "\n";
|
||||
// >=apache-2.4 enabled?
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
$mypath_dir = new Directory($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) {
|
||||
@@ -160,67 +239,4 @@ class ApacheFcgi extends Apache
|
||||
|
||||
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 = \Froxlor\Froxlor::getInstallDir();
|
||||
|
||||
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
|
||||
\Froxlor\FileDir::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,25 +1,38 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
class ConfigIO
|
||||
{
|
||||
|
||||
@@ -32,7 +45,6 @@ class ConfigIO
|
||||
*/
|
||||
public function cleanUp()
|
||||
{
|
||||
|
||||
// old error logs
|
||||
$this->cleanErrLogs();
|
||||
|
||||
@@ -57,107 +69,12 @@ class ConfigIO
|
||||
|
||||
private function cleanErrLogs()
|
||||
{
|
||||
$err_dir = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . "/logs/");
|
||||
$err_dir = FileDir::makeCorrectDir(Froxlor::getInstallDir() . "/logs/");
|
||||
if (@is_dir($err_dir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /*.log so we don't delete the directory)
|
||||
$err_dir .= '/*.log';
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($err_dir));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove customer-specified auto-generated ssl-certificates
|
||||
* (they are being regenerated)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function cleanCustomerSslCerts()
|
||||
{
|
||||
|
||||
/*
|
||||
* only clean up if we're actually using SSL
|
||||
*/
|
||||
if (Settings::Get('system.use_ssl') == '1') {
|
||||
// get correct directory
|
||||
$configdir = $this->getFile('system', 'customer_ssl_path');
|
||||
if ($configdir !== false) {
|
||||
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove webserver related configuration files before regeneration
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function cleanWebserverConfigs()
|
||||
{
|
||||
|
||||
// get directories
|
||||
$configdirs = array();
|
||||
$dir = $this->getFile('system', 'apacheconf_vhost');
|
||||
if ($dir !== false)
|
||||
$configdirs[] = \Froxlor\FileDir::makeCorrectDir($dir);
|
||||
|
||||
$dir = $this->getFile('system', 'apacheconf_diroptions');
|
||||
if ($dir !== false)
|
||||
$configdirs[] = \Froxlor\FileDir::makeCorrectDir($dir);
|
||||
|
||||
// file pattern
|
||||
$pattern = "/^([0-9]){2}_(froxlor|syscp)_(.+)\.conf$/";
|
||||
|
||||
// check ALL the folders
|
||||
foreach ($configdirs as $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 vhost/diroption files
|
||||
// and delete them
|
||||
foreach ($its as $it) {
|
||||
if ($it->isFile() && preg_match($pattern, $it->getFilename())) {
|
||||
// remove file
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove htpasswd files before regeneration
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function cleanHtpasswdFiles()
|
||||
{
|
||||
|
||||
// get correct directory
|
||||
$configdir = $this->getFile('system', 'apacheconf_htpasswddir');
|
||||
|
||||
if ($configdir !== false) {
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
FileDir::safe_exec('rm -f ' . FileDir::makeCorrectFile($err_dir));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +90,7 @@ class ConfigIO
|
||||
}
|
||||
|
||||
// dhr: cleanout froxlor-generated awstats configs prior to re-creation
|
||||
$awstatsclean = array();
|
||||
$awstatsclean = [];
|
||||
$awstatsclean['header'] = "## GENERATED BY FROXLOR\n";
|
||||
$awstatsclean['headerold'] = "## GENERATED BY SYSCP\n";
|
||||
$awstatsclean['path'] = $this->getFile('system', 'awstats_conf');
|
||||
@@ -187,7 +104,7 @@ class ConfigIO
|
||||
if ($awstatsclean['path'] !== false && is_dir($awstatsclean['path'])) {
|
||||
$awstatsclean['dir'] = dir($awstatsclean['path']);
|
||||
while ($awstatsclean['entry'] = $awstatsclean['dir']->read()) {
|
||||
$awstatsclean['fullentry'] = \Froxlor\FileDir::makeCorrectFile($awstatsclean['path'] . '/' . $awstatsclean['entry']);
|
||||
$awstatsclean['fullentry'] = FileDir::makeCorrectFile($awstatsclean['path'] . '/' . $awstatsclean['entry']);
|
||||
/**
|
||||
* don't do anything if the file does not exist
|
||||
*/
|
||||
@@ -197,7 +114,7 @@ class ConfigIO
|
||||
fclose($awstatsclean['fh']);
|
||||
|
||||
if ($awstatsclean['headerRead'] == $awstatsclean['header'] || $awstatsclean['headerRead'] == $awstatsclean['headerold']) {
|
||||
$awstats_conf_file = \Froxlor\FileDir::makeCorrectFile($awstatsclean['fullentry']);
|
||||
$awstats_conf_file = FileDir::makeCorrectFile($awstatsclean['fullentry']);
|
||||
@unlink($awstats_conf_file);
|
||||
}
|
||||
}
|
||||
@@ -207,6 +124,30 @@ class ConfigIO
|
||||
// end dhr
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a file/directory from the settings and checks whether it exists
|
||||
*
|
||||
* @param string $group
|
||||
* settings-group
|
||||
* @param string $varname
|
||||
* var-name
|
||||
* @param boolean $check_exists
|
||||
* check if the file exists
|
||||
*
|
||||
* @return string|boolean complete path including filename if any or false on error
|
||||
*/
|
||||
private function getFile($group, $varname, $check_exists = true)
|
||||
{
|
||||
// read from settings
|
||||
$file = Settings::Get($group . '.' . $varname);
|
||||
|
||||
// check whether it exists
|
||||
if ($check_exists && @file_exists($file) == false) {
|
||||
return false;
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove fcgid related configuration files before regeneration
|
||||
*
|
||||
@@ -221,12 +162,11 @@ class ConfigIO
|
||||
// get correct directory
|
||||
$configdir = $this->getFile('system', 'mod_fcgid_configdir');
|
||||
if ($configdir !== false) {
|
||||
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir);
|
||||
$configdir = FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// create directory iterator
|
||||
$its = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($configdir));
|
||||
$its = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configdir));
|
||||
|
||||
// iterate through all subdirs,
|
||||
// look for php-fcgi-starter files
|
||||
@@ -235,14 +175,14 @@ class ConfigIO
|
||||
foreach ($its as $it) {
|
||||
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter') {
|
||||
// set chattr -i
|
||||
\Froxlor\FileDir::removeImmutable($its->getPathname());
|
||||
FileDir::removeImmutable($its->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
FileDir::safe_exec('rm -rf ' . FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,55 +199,121 @@ class ConfigIO
|
||||
}
|
||||
|
||||
// get all fpm config paths
|
||||
$fpmconf_sel = \Froxlor\Database\Database::prepare("SELECT config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
\Froxlor\Database\Database::pexecute($fpmconf_sel);
|
||||
$fpmconf_paths = $fpmconf_sel->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$fpmconf_sel = Database::prepare("SELECT config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($fpmconf_sel);
|
||||
$fpmconf_paths = $fpmconf_sel->fetchAll(PDO::FETCH_ASSOC);
|
||||
// clean all php-fpm config-dirs
|
||||
foreach ($fpmconf_paths as $configdir) {
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir['config_dir']);
|
||||
$configdir = FileDir::makeCorrectDir($configdir['config_dir']);
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /*.conf so we don't delete the directory)
|
||||
$configdir .= '/*.conf';
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
FileDir::safe_exec('rm -f ' . FileDir::makeCorrectFile($configdir));
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . $configdir);
|
||||
FileDir::safe_exec('mkdir -p ' . $configdir);
|
||||
}
|
||||
}
|
||||
|
||||
// also remove aliasconfigdir #1273
|
||||
$aliasconfigdir = $this->getFile('phpfpm', 'aliasconfigdir');
|
||||
if ($aliasconfigdir !== false) {
|
||||
$aliasconfigdir = \Froxlor\FileDir::makeCorrectDir($aliasconfigdir);
|
||||
$aliasconfigdir = FileDir::makeCorrectDir($aliasconfigdir);
|
||||
if (@is_dir($aliasconfigdir)) {
|
||||
$aliasconfigdir .= '/*';
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . \Froxlor\FileDir::makeCorrectFile($aliasconfigdir));
|
||||
FileDir::safe_exec('rm -rf ' . FileDir::makeCorrectFile($aliasconfigdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a file/directory from the settings and checks whether it exists
|
||||
* remove webserver related configuration files before regeneration
|
||||
*
|
||||
* @param string $group
|
||||
* settings-group
|
||||
* @param string $varname
|
||||
* var-name
|
||||
* @param boolean $check_exists
|
||||
* check if the file exists
|
||||
*
|
||||
* @return string|boolean complete path including filename if any or false on error
|
||||
* @return null
|
||||
*/
|
||||
private function getFile($group, $varname, $check_exists = true)
|
||||
private function cleanWebserverConfigs()
|
||||
{
|
||||
|
||||
// read from settings
|
||||
$file = Settings::Get($group . '.' . $varname);
|
||||
|
||||
// check whether it exists
|
||||
if ($check_exists && @file_exists($file) == false) {
|
||||
return false;
|
||||
// get directories
|
||||
$configdirs = [];
|
||||
$dir = $this->getFile('system', 'apacheconf_vhost');
|
||||
if ($dir !== false) {
|
||||
$configdirs[] = FileDir::makeCorrectDir($dir);
|
||||
}
|
||||
|
||||
$dir = $this->getFile('system', 'apacheconf_diroptions');
|
||||
if ($dir !== false) {
|
||||
$configdirs[] = FileDir::makeCorrectDir($dir);
|
||||
}
|
||||
|
||||
// file pattern
|
||||
$pattern = "/^([0-9]){2}_(froxlor|syscp)_(.+)\.conf$/";
|
||||
|
||||
// check ALL the folders
|
||||
foreach ($configdirs as $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 vhost/diroption files
|
||||
// and delete them
|
||||
foreach ($its as $it) {
|
||||
if ($it->isFile() && preg_match($pattern, $it->getFilename())) {
|
||||
// remove file
|
||||
FileDir::safe_exec('rm -f ' . escapeshellarg(FileDir::makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove htpasswd files before regeneration
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function cleanHtpasswdFiles()
|
||||
{
|
||||
// get correct directory
|
||||
$configdir = $this->getFile('system', 'apacheconf_htpasswddir');
|
||||
|
||||
if ($configdir !== false) {
|
||||
$configdir = FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
FileDir::safe_exec('rm -f ' . FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove customer-specified auto-generated ssl-certificates
|
||||
* (they are being regenerated)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function cleanCustomerSslCerts()
|
||||
{
|
||||
/*
|
||||
* only clean up if we're actually using SSL
|
||||
*/
|
||||
if (Settings::Get('system.use_ssl') == '1') {
|
||||
// get correct directory
|
||||
$configdir = $this->getFile('system', 'customer_ssl_path');
|
||||
if ($configdir !== false) {
|
||||
$configdir = FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
FileDir::safe_exec('rm -f ' . FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class DomainSSL
|
||||
{
|
||||
|
||||
@@ -31,8 +40,8 @@ class DomainSSL
|
||||
* Hence the parameter as reference.
|
||||
*
|
||||
* @param array $domain
|
||||
* domain-array as reference so we can set the corresponding array-indices
|
||||
*
|
||||
* domain-array as reference so we can set the corresponding array-indices
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function setDomainSSLFilesArray(array &$domain = null)
|
||||
@@ -41,35 +50,35 @@ class DomainSSL
|
||||
$dom_certs_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domid
|
||||
");
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, array(
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, [
|
||||
'domid' => $domain['id']
|
||||
));
|
||||
]);
|
||||
|
||||
if (! is_array($dom_certs) || ! isset($dom_certs['ssl_cert_file']) || $dom_certs['ssl_cert_file'] == '') {
|
||||
if (!is_array($dom_certs) || !isset($dom_certs['ssl_cert_file']) || $dom_certs['ssl_cert_file'] == '') {
|
||||
// maybe its parent?
|
||||
if (isset($domain['parentdomainid']) && $domain['parentdomainid'] != 0) {
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, array(
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, [
|
||||
'domid' => $domain['parentdomainid']
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// check if it's an array and if the most important field is set
|
||||
if (is_array($dom_certs) && isset($dom_certs['ssl_cert_file']) && $dom_certs['ssl_cert_file'] != '') {
|
||||
// get destination path
|
||||
$sslcertpath = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.customer_ssl_path'));
|
||||
$sslcertpath = FileDir::makeCorrectDir(Settings::Get('system.customer_ssl_path'));
|
||||
// create path if it does not exist
|
||||
if (! file_exists($sslcertpath)) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($sslcertpath));
|
||||
if (!file_exists($sslcertpath)) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($sslcertpath));
|
||||
}
|
||||
// make correct files for the certificates
|
||||
$ssl_files = array(
|
||||
'ssl_cert_file' => \Froxlor\FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.crt'),
|
||||
'ssl_key_file' => \Froxlor\FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.key')
|
||||
);
|
||||
$ssl_files = [
|
||||
'ssl_cert_file' => FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.crt'),
|
||||
'ssl_key_file' => FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.key')
|
||||
];
|
||||
|
||||
if (! $this->validateCertificate($dom_certs)) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, 'Given SSL private key for ' . $domain['domain'] . ' does not seem to match the certificate. Cannot create ssl-directives');
|
||||
if (!$this->validateCertificate($dom_certs)) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'Given SSL private key for ' . $domain['domain'] . ' does not seem to match the certificate. Cannot create ssl-directives');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -84,19 +93,19 @@ class DomainSSL
|
||||
$ssl_files['ssl_cert_chainfile'] = '';
|
||||
// set them if they are != empty
|
||||
if ($dom_certs['ssl_ca_file'] != '') {
|
||||
$ssl_files['ssl_ca_file'] = \Froxlor\FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_CA.pem');
|
||||
$ssl_files['ssl_ca_file'] = FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_CA.pem');
|
||||
}
|
||||
if ($dom_certs['ssl_cert_chainfile'] != '') {
|
||||
if (Settings::Get('system.webserver') == 'nginx') {
|
||||
// put ca.crt in my.crt, as nginx does not support a separate chain file.
|
||||
$dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file']) . "\n" . trim($dom_certs['ssl_cert_chainfile']) . "\n";
|
||||
} else {
|
||||
$ssl_files['ssl_cert_chainfile'] = \Froxlor\FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_chain.pem');
|
||||
$ssl_files['ssl_cert_chainfile'] = FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_chain.pem');
|
||||
}
|
||||
}
|
||||
// will only be generated to be used externally, froxlor does not need this
|
||||
if ($dom_certs['ssl_fullchain_file'] != '') {
|
||||
$ssl_files['ssl_fullchain_file'] = \Froxlor\FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_fullchain.pem');
|
||||
$ssl_files['ssl_fullchain_file'] = FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_fullchain.pem');
|
||||
}
|
||||
// create them on the filesystem
|
||||
foreach ($ssl_files as $type => $filename) {
|
||||
@@ -122,7 +131,7 @@ class DomainSSL
|
||||
return;
|
||||
}
|
||||
|
||||
private function validateCertificate($dom_certs = array())
|
||||
private function validateCertificate($dom_certs = [])
|
||||
{
|
||||
return openssl_x509_check_private_key($dom_certs['ssl_cert_file'], $dom_certs['ssl_key_file']);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,41 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\Fpm;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Cron\Http\LetsEncrypt\AcmeSh;
|
||||
use Froxlor\Cron\Http\Php\Fpm;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\System\Cronjob;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Class HttpConfigBase
|
||||
*
|
||||
@@ -32,44 +48,44 @@ class HttpConfigBase
|
||||
{
|
||||
// if Let's Encrypt is activated, run it before regeneration of webserver configfiles
|
||||
if (Settings::Get('system.leenabled') == 1) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Running Let\'s Encrypt cronjob prior to regenerating webserver config files');
|
||||
\Froxlor\Cron\Http\LetsEncrypt\AcmeSh::$no_inserttask = true;
|
||||
\Froxlor\Cron\Http\LetsEncrypt\AcmeSh::run(true);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Running Let\'s Encrypt cronjob prior to regenerating webserver config files');
|
||||
AcmeSh::$no_inserttask = true;
|
||||
AcmeSh::run(true);
|
||||
// set last run timestamp of cronjob
|
||||
\Froxlor\System\Cronjob::updateLastRunOfCron('letsencrypt');
|
||||
Cronjob::updateLastRunOfCron('letsencrypt');
|
||||
}
|
||||
}
|
||||
|
||||
public function reload()
|
||||
{
|
||||
$called_class = get_called_class();
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
// get all start/stop commands
|
||||
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($startstop_sel);
|
||||
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$restart_cmds = $startstop_sel->fetchAll(PDO::FETCH_ASSOC);
|
||||
// restart all php-fpm instances
|
||||
foreach ($restart_cmds as $restart_cmd) {
|
||||
// check whether the config dir is empty (no domains uses this daemon)
|
||||
// so we need to create a dummy
|
||||
$_conffiles = glob(\Froxlor\FileDir::makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
|
||||
$_conffiles = glob(FileDir::makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
|
||||
if ($_conffiles === false || empty($_conffiles)) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
|
||||
Fpm::createDummyPool($restart_cmd['config_dir']);
|
||||
}
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: running ' . $restart_cmd['reload_cmd']);
|
||||
\Froxlor\FileDir::safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: running ' . $restart_cmd['reload_cmd']);
|
||||
FileDir::safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
|
||||
}
|
||||
}
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: reloading ' . $called_class);
|
||||
\Froxlor\FileDir::safe_exec(escapeshellcmd(Settings::Get('system.apachereload_command')));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: reloading ' . $called_class);
|
||||
FileDir::safe_exec(escapeshellcmd(Settings::Get('system.apachereload_command')));
|
||||
|
||||
/**
|
||||
* nginx does not auto-spawn fcgi-processes
|
||||
*/
|
||||
if (Settings::Get('system.webserver') == "nginx" && Settings::Get('system.phpreload_command') != '' && (int) Settings::Get('phpfpm.enabled') == 0) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: restarting php processes');
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.phpreload_command'));
|
||||
if (Settings::Get('system.webserver') == "nginx" && Settings::Get('system.phpreload_command') != '' && (int)Settings::Get('phpfpm.enabled') == 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: restarting php processes');
|
||||
FileDir::safe_exec(Settings::Get('system.phpreload_command'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,12 +103,12 @@ class HttpConfigBase
|
||||
* {DOCROOT} - document root for this domain
|
||||
*
|
||||
* @param
|
||||
* $template
|
||||
* $template
|
||||
* @return string
|
||||
*/
|
||||
protected function processSpecialConfigTemplate($template, $domain, $ip, $port, $is_ssl_vhost)
|
||||
{
|
||||
$templateVars = array(
|
||||
$templateVars = [
|
||||
'DOMAIN' => $domain['domain'],
|
||||
'CUSTOMER' => $domain['loginname'],
|
||||
'IP' => $ip,
|
||||
@@ -100,24 +116,24 @@ class HttpConfigBase
|
||||
'SCHEME' => ($is_ssl_vhost) ? 'https' : 'http',
|
||||
'DOCROOT' => $domain['documentroot'],
|
||||
'FPMSOCKET' => ''
|
||||
);
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1 && isset($domain['fpm_socket']) && !empty($domain['fpm_socket'])) {
|
||||
];
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1 && isset($domain['fpm_socket']) && !empty($domain['fpm_socket'])) {
|
||||
$templateVars['FPMSOCKET'] = $domain['fpm_socket'];
|
||||
}
|
||||
return \Froxlor\PhpHelper::replaceVariables($template, $templateVars);
|
||||
return PhpHelper::replaceVariables($template, $templateVars);
|
||||
}
|
||||
|
||||
protected function getMyPath($ip_port = null)
|
||||
{
|
||||
if (! empty($ip_port) && $ip_port['docroot'] == '') {
|
||||
if (!empty($ip_port) && $ip_port['docroot'] == '') {
|
||||
if (Settings::Get('system.froxlordirectlyviahostname')) {
|
||||
$mypath = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir());
|
||||
$mypath = FileDir::makeCorrectDir(Froxlor::getInstallDir());
|
||||
} else {
|
||||
$mypath = \Froxlor\FileDir::makeCorrectDir(dirname(\Froxlor\Froxlor::getInstallDir()));
|
||||
$mypath = FileDir::makeCorrectDir(dirname(Froxlor::getInstallDir()));
|
||||
}
|
||||
} else {
|
||||
// user-defined docroot, #417
|
||||
$mypath = \Froxlor\FileDir::makeCorrectDir($ip_port['docroot']);
|
||||
$mypath = FileDir::makeCorrectDir($ip_port['docroot']);
|
||||
}
|
||||
return $mypath;
|
||||
}
|
||||
@@ -152,7 +168,7 @@ class HttpConfigBase
|
||||
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'])) {
|
||||
if ($froxlor_ssl && !empty($froxlor_ssl['ssl_cert_file'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -166,7 +182,7 @@ class HttpConfigBase
|
||||
(`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'])) {
|
||||
if ($froxlor_ssl && !empty($froxlor_ssl['ssl_cert_file'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,31 +1,44 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\LetsEncrypt;
|
||||
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\FileDir;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
namespace Froxlor\Cron\Http\LetsEncrypt;
|
||||
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\System\Cronjob;
|
||||
use Froxlor\Validate\Validate;
|
||||
use PDO;
|
||||
use PDOStatement;
|
||||
|
||||
class AcmeSh extends FroxlorCron
|
||||
{
|
||||
|
||||
const ACME_PROVIDER = [
|
||||
@@ -35,25 +48,20 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
'buypass_test' => "https://api.test4.buypass.no/acme/directory",
|
||||
'zerossl' => "https://acme.zerossl.com/v2/DV90"
|
||||
];
|
||||
|
||||
public static $no_inserttask = false;
|
||||
private static $apiserver = "";
|
||||
|
||||
private static $acmesh = "/root/.acme.sh/acme.sh";
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \PDOStatement
|
||||
* @var PDOStatement
|
||||
*/
|
||||
private static $updcert_stmt = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \PDOStatement
|
||||
* @var PDOStatement
|
||||
*/
|
||||
private static $upddom_stmt = null;
|
||||
|
||||
public static $no_inserttask = false;
|
||||
|
||||
/**
|
||||
* run the task
|
||||
*
|
||||
@@ -63,7 +71,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
public static function run($internal = false)
|
||||
{
|
||||
// usually, this is action is called from within the tasks-jobs
|
||||
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
|
||||
if (!defined('CRON_IS_FORCED') && !defined('CRON_DEBUG_FLAG') && $internal == false) {
|
||||
// Let's Encrypt cronjob is combined with regeneration of webserver configuration files.
|
||||
// For debugging purposes you can use the --debug switch and the --force switch to run the cron manually.
|
||||
// check whether we MIGHT need to run although there is no task to regenerate config-files
|
||||
@@ -71,9 +79,9 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
$issue_domains = self::issueDomains();
|
||||
$renew_froxlor = self::renewFroxlorVhost();
|
||||
$renew_domains = self::renewDomains(true);
|
||||
if ($issue_froxlor || ! empty($issue_domains) || ! empty($renew_froxlor) || $renew_domains) {
|
||||
if ($issue_froxlor || !empty($issue_domains) || !empty($renew_froxlor) || $renew_domains) {
|
||||
// insert task to generate certificates and vhost-configs
|
||||
\Froxlor\System\Cronjob::inserttask(1);
|
||||
Cronjob::inserttask(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -82,8 +90,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
self::$apiserver = self::ACME_PROVIDER[Settings::Get('system.letsencryptca')];
|
||||
|
||||
// validate acme.sh installation
|
||||
if (! self::checkInstall()) {
|
||||
return - 1;
|
||||
if (!self::checkInstall()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self::checkUpgrade();
|
||||
@@ -117,11 +125,11 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
// first - generate LE for system-vhost if enabled
|
||||
if ($issue_froxlor) {
|
||||
// build row
|
||||
$certrow = array(
|
||||
$certrow = [
|
||||
'loginname' => 'froxlor.panel',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'domainid' => 0,
|
||||
'documentroot' => \Froxlor\Froxlor::getInstallDir(),
|
||||
'documentroot' => Froxlor::getInstallDir(),
|
||||
'leprivatekey' => Settings::Get('system.leprivatekey'),
|
||||
'lepublickey' => Settings::Get('system.lepublickey'),
|
||||
'leregistered' => Settings::Get('system.leregistered'),
|
||||
@@ -133,7 +141,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
'ssl_csr_file' => null,
|
||||
'id' => null,
|
||||
'wwwserveralias' => 0
|
||||
);
|
||||
];
|
||||
|
||||
// add to queue
|
||||
$issue_domains[] = $certrow;
|
||||
@@ -152,11 +160,11 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
if ($renew_froxlor) {
|
||||
// build row
|
||||
$certrow = array(
|
||||
$certrow = [
|
||||
'loginname' => 'froxlor.panel',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'domainid' => 0,
|
||||
'documentroot' => \Froxlor\Froxlor::getInstallDir(),
|
||||
'documentroot' => Froxlor::getInstallDir(),
|
||||
'leprivatekey' => Settings::Get('system.leprivatekey'),
|
||||
'lepublickey' => Settings::Get('system.lepublickey'),
|
||||
'leregistered' => Settings::Get('system.leregistered'),
|
||||
@@ -168,17 +176,17 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
'ssl_csr_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_csr_file'] : null,
|
||||
'id' => is_array($renew_froxlor) ? $renew_froxlor['id'] : null,
|
||||
'wwwserveralias' => 0
|
||||
);
|
||||
];
|
||||
$renew_domains[] = $certrow;
|
||||
}
|
||||
|
||||
foreach ($renew_domains as $domain) {
|
||||
$cronlog = FroxlorLogger::getInstanceOf(array(
|
||||
$cronlog = FroxlorLogger::getInstanceOf([
|
||||
'loginname' => $domain['loginname'],
|
||||
'adminsession' => 0
|
||||
));
|
||||
]);
|
||||
if (defined('CRON_IS_FORCED') || self::checkFsFilesAreNewer($domain['domain'], $domain['expirationdate'])) {
|
||||
self::certToDb($domain, $cronlog, array());
|
||||
self::certToDb($domain, $cronlog, []);
|
||||
$changedetected = 1;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +195,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
// This is easiest done by just creating a new task ;)
|
||||
if ($changedetected) {
|
||||
if (self::$no_inserttask == false) {
|
||||
\Froxlor\System\Cronjob::inserttask(1);
|
||||
Cronjob::inserttask(1);
|
||||
}
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
|
||||
} else {
|
||||
@@ -195,189 +203,6 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* issue certificates for a list of domains
|
||||
*/
|
||||
private static function runIssueFor($certrows = array())
|
||||
{
|
||||
// prepare aliasdomain-check
|
||||
$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
|
||||
");
|
||||
// iterate through all domains
|
||||
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'],
|
||||
'adminsession' => 0
|
||||
));
|
||||
// Only issue let's encrypt certificate if no broken ssl_redirect is enabled
|
||||
if ($certrow['ssl_redirect'] != 2) {
|
||||
$do_force = false;
|
||||
if (! empty($certrow['ssl_cert_file']) && empty($certrow['expirationdate'])) {
|
||||
// domain changed (SAN or similar)
|
||||
$do_force = true;
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Re-creating certificate for " . $certrow['domain']);
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
|
||||
}
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding common-name: " . $certrow['domain']);
|
||||
$domains = array(
|
||||
strtolower($certrow['domain'])
|
||||
);
|
||||
// add www.<domain> to SAN list
|
||||
if ($certrow['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
|
||||
$domains[] = strtolower('www.' . $certrow['domain']);
|
||||
}
|
||||
if ($certrow['domainid'] == 0) {
|
||||
$froxlor_aliases = Settings::Get('system.froxloraliases');
|
||||
if (! empty($froxlor_aliases)) {
|
||||
$froxlor_aliases = explode(",", $froxlor_aliases);
|
||||
foreach ($froxlor_aliases as $falias) {
|
||||
if (\Froxlor\Validate\Validate::validateDomain(trim($falias))) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . strtolower(trim($falias)));
|
||||
$domains[] = strtolower(trim($falias));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
|
||||
$domains[] = strtolower($aliasdomain['domain']);
|
||||
if ($aliasdomain['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
|
||||
$domains[] = strtolower('www.' . $aliasdomain['domain']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::validateDns($domains, $certrow['domainid'], $cronlog);
|
||||
|
||||
self::runAcmeSh($certrow, $domains, $cronlog, $do_force);
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validate dns (A / AAAA record) of domain against known system ips
|
||||
*
|
||||
* @param array $domains
|
||||
* @param int $domain_id
|
||||
* @param FroxlorLogger $cronlog
|
||||
*/
|
||||
private static function validateDns(array &$domains, $domain_id, &$cronlog)
|
||||
{
|
||||
if (Settings::Get('system.le_domain_dnscheck') == '1' && ! empty($domains)) {
|
||||
$loop_domains = $domains;
|
||||
// ips according to our system
|
||||
$our_ips = Domain::getIpsOfDomain($domain_id);
|
||||
foreach ($loop_domains as $idx => $domain) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Validating DNS of " . $domain);
|
||||
// ips according to NS
|
||||
$domain_ips = PhpHelper::gethostbynamel6($domain);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
// no common ips...
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $domain . " due to no system known IP address via DNS check");
|
||||
unset($domains[$idx]);
|
||||
// in order to avoid a cron-loop that tries to get a certificate every 5 minutes, we disable let's encrypt for this domain
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `letsencrypt` = '0' WHERE `id` = :did");
|
||||
Database::pexecute($upd_stmt, [
|
||||
'did' => $domain_id
|
||||
]);
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Let's Encrypt deactivated for domain " . $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function runAcmeSh(array $certrow, array $domains, &$cronlog = null, $force = false)
|
||||
{
|
||||
if (! empty($domains)) {
|
||||
|
||||
$acmesh_cmd = self::getAcmeSh() . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
|
||||
// challenge path
|
||||
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
|
||||
if (Settings::Get('system.leecc') > 0) {
|
||||
// ecc certificate
|
||||
$acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc');
|
||||
} else {
|
||||
$acmesh_cmd .= " --keylength " . Settings::Get('system.letsencryptkeysize');
|
||||
}
|
||||
if (Settings::Get('system.letsencryptreuseold') != '1') {
|
||||
$acmesh_cmd .= " --always-force-new-domain-key";
|
||||
}
|
||||
if (Settings::Get('system.letsencryptca') == 'letsencrypt_test') {
|
||||
$acmesh_cmd .= " --staging";
|
||||
}
|
||||
if ($force) {
|
||||
$acmesh_cmd .= " --force";
|
||||
}
|
||||
if (defined('CRON_DEBUG_FLAG')) {
|
||||
$acmesh_cmd .= " --debug";
|
||||
}
|
||||
|
||||
$acme_result = \Froxlor\FileDir::safe_exec($acmesh_cmd);
|
||||
// debug output of acme.sh run
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, implode("\n", $acme_result));
|
||||
|
||||
self::certToDb($certrow, $cronlog, $acme_result);
|
||||
}
|
||||
}
|
||||
|
||||
private static function certToDb($certrow, &$cronlog, $acme_result)
|
||||
{
|
||||
$return = array();
|
||||
self::readCertificateToVar(strtolower($certrow['domain']), $return, $cronlog);
|
||||
|
||||
if (! empty($return['crt'])) {
|
||||
|
||||
$newcert = openssl_x509_parse($return['crt']);
|
||||
|
||||
if ($newcert) {
|
||||
// Store the new data
|
||||
Database::pexecute(self::$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(self::$upddom_stmt, array(
|
||||
'domainid' => $certrow['domainid']
|
||||
));
|
||||
}
|
||||
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Got non-successful Let's Encrypt response for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
|
||||
}
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether we need to issue a new certificate for froxlor itself
|
||||
*
|
||||
@@ -393,13 +218,100 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
");
|
||||
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
|
||||
// also check for possible existing certificate
|
||||
if (! $froxlor_ssl && ! self::checkFsFilesAreNewer(Settings::Get('system.hostname'), date('Y-m-d H:i:s'))) {
|
||||
if (!$froxlor_ssl && !self::checkFsFilesAreNewer(Settings::Get('system.hostname'), date('Y-m-d H:i:s'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
|
||||
{
|
||||
$certificate_folder = self::getWorkingDirFromEnv(strtolower($domain));
|
||||
$ssl_file = FileDir::makeCorrectFile($certificate_folder . '/' . strtolower($domain) . '.cer');
|
||||
|
||||
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
|
||||
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));
|
||||
if ($cert_data && $cert_data['validTo_time_t'] > strtotime($cert_date)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getWorkingDirFromEnv($domain = "", $forced_noecc = false)
|
||||
{
|
||||
if (Settings::Get('system.leecc') > 0 && !$forced_noecc) {
|
||||
$domain .= "_ecc";
|
||||
}
|
||||
$env_file = FileDir::makeCorrectFile(dirname(self::getAcmeSh()) . '/acme.sh.env');
|
||||
if (file_exists($env_file)) {
|
||||
$output = [];
|
||||
$cut = <<<EOC
|
||||
cut -d'"' -f2
|
||||
EOC;
|
||||
exec('grep "LE_WORKING_DIR" ' . escapeshellarg($env_file) . ' | ' . $cut, $output);
|
||||
if (is_array($output) && !empty($output) && isset($output[0]) && !empty($output[0])) {
|
||||
return FileDir::makeCorrectDir($output[0] . "/" . $domain);
|
||||
}
|
||||
}
|
||||
return FileDir::makeCorrectDir(dirname(self::getAcmeSh()) . "/" . $domain);
|
||||
}
|
||||
|
||||
public static function getAcmeSh()
|
||||
{
|
||||
$from_settings = Settings::Get('system.acmeshpath');
|
||||
if (file_exists($from_settings)) {
|
||||
return $from_settings;
|
||||
}
|
||||
return self::$acmesh;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a list of domains that require a new certificate (issue)
|
||||
*/
|
||||
private static function issueDomains()
|
||||
{
|
||||
$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` IS NULL
|
||||
");
|
||||
$customer_ssl = $certificates_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($customer_ssl) {
|
||||
return $customer_ssl;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether we need to renew-check the certificate for froxlor itself
|
||||
*
|
||||
@@ -451,7 +363,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
AND dom.`aliasdomain` IS NULL
|
||||
AND dom.`iswildcarddomain` = 0
|
||||
");
|
||||
$renew_certs = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$renew_certs = $certificates_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($renew_certs) {
|
||||
if ($check) {
|
||||
foreach ($renew_certs as $cert) {
|
||||
@@ -463,94 +375,230 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
}
|
||||
return $renew_certs;
|
||||
}
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* get a list of domains that require a new certificate (issue)
|
||||
* install acme.sh if not found yet
|
||||
*/
|
||||
private static function issueDomains()
|
||||
private static function checkInstall($tries = 0)
|
||||
{
|
||||
$certificates_stmt = Database::query("
|
||||
if (!file_exists(self::getAcmeSh()) && $tries > 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'");
|
||||
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'" . PHP_EOL;
|
||||
return false;
|
||||
} else {
|
||||
if (!file_exists(self::getAcmeSh())) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/");
|
||||
$return = false;
|
||||
FileDir::safe_exec("wget -O - https://get.acme.sh | sh -s email=" . Settings::Get('panel.adminmail'), $return, [
|
||||
'|'
|
||||
]);
|
||||
$set_path = self::getAcmeSh();
|
||||
// after this, regardless of what the user specified, the acme.sh installation will be in /root/.acme.sh
|
||||
if ($set_path != '/root/.acme.sh/acme.sh') {
|
||||
Settings::Set('system.acmeshpath', '/root/.acme.sh/acme.sh', true);
|
||||
// let the user know
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'");
|
||||
echo PHP_EOL . "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'" . PHP_EOL;
|
||||
}
|
||||
// check whether the installation worked
|
||||
return self::checkInstall(++$tries);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* run upgrade
|
||||
*/
|
||||
private static function checkUpgrade()
|
||||
{
|
||||
$acmesh_result = FileDir::safe_exec(self::getAcmeSh() . " --upgrade --auto-upgrade 0");
|
||||
// check for activated cron
|
||||
$acmesh_result2 = FileDir::safe_exec(self::getAcmeSh() . " --install-cronjob");
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));
|
||||
}
|
||||
|
||||
/**
|
||||
* issue certificates for a list of domains
|
||||
*/
|
||||
private static function runIssueFor($certrows = [])
|
||||
{
|
||||
// prepare aliasdomain-check
|
||||
$aliasdomains_stmt = Database::prepare("
|
||||
SELECT
|
||||
domssl.`id`,
|
||||
domssl.`domainid`,
|
||||
domssl.`expirationdate`,
|
||||
domssl.`ssl_cert_file`,
|
||||
domssl.`ssl_key_file`,
|
||||
domssl.`ssl_ca_file`,
|
||||
domssl.`ssl_csr_file`,
|
||||
dom.`id` as domainid,
|
||||
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`
|
||||
dom.`wwwserveralias`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` AS dom
|
||||
WHERE
|
||||
dom.`customerid` = cust.`customerid`
|
||||
AND cust.deactivated = 0
|
||||
dom.`aliasdomain` = :id
|
||||
AND dom.`letsencrypt` = 1
|
||||
AND dom.`aliasdomain` IS NULL
|
||||
AND dom.`iswildcarddomain` = 0
|
||||
AND domssl.`expirationdate` IS NULL
|
||||
");
|
||||
$customer_ssl = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if ($customer_ssl) {
|
||||
return $customer_ssl;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
// iterate through all domains
|
||||
foreach ($certrows as $certrow) {
|
||||
// set logger to corresponding loginname for the log to appear in the users system-log
|
||||
$cronlog = FroxlorLogger::getInstanceOf([
|
||||
'loginname' => $certrow['loginname'],
|
||||
'adminsession' => 0
|
||||
]);
|
||||
// Only issue let's encrypt certificate if no broken ssl_redirect is enabled
|
||||
if ($certrow['ssl_redirect'] != 2) {
|
||||
$do_force = false;
|
||||
if (!empty($certrow['ssl_cert_file']) && empty($certrow['expirationdate'])) {
|
||||
// domain changed (SAN or similar)
|
||||
$do_force = true;
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Re-creating certificate for " . $certrow['domain']);
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
|
||||
}
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding common-name: " . $certrow['domain']);
|
||||
$domains = [
|
||||
strtolower($certrow['domain'])
|
||||
];
|
||||
// add www.<domain> to SAN list
|
||||
if ($certrow['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
|
||||
$domains[] = strtolower('www.' . $certrow['domain']);
|
||||
}
|
||||
if ($certrow['domainid'] == 0) {
|
||||
$froxlor_aliases = Settings::Get('system.froxloraliases');
|
||||
if (!empty($froxlor_aliases)) {
|
||||
$froxlor_aliases = explode(",", $froxlor_aliases);
|
||||
foreach ($froxlor_aliases as $falias) {
|
||||
if (Validate::validateDomain(trim($falias))) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . strtolower(trim($falias)));
|
||||
$domains[] = strtolower(trim($falias));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add alias domains (and possibly www.<aliasdomain>) to SAN list
|
||||
Database::pexecute($aliasdomains_stmt, [
|
||||
'id' => $certrow['domainid']
|
||||
]);
|
||||
$aliasdomains = $aliasdomains_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($aliasdomains as $aliasdomain) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
|
||||
$domains[] = strtolower($aliasdomain['domain']);
|
||||
if ($aliasdomain['wwwserveralias'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
|
||||
$domains[] = strtolower('www.' . $aliasdomain['domain']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
|
||||
{
|
||||
$certificate_folder = self::getWorkingDirFromEnv(strtolower($domain));
|
||||
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . strtolower($domain) . '.cer');
|
||||
self::validateDns($domains, $certrow['domainid'], $cronlog);
|
||||
|
||||
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
|
||||
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));
|
||||
if ($cert_data && $cert_data['validTo_time_t'] > strtotime($cert_date)) {
|
||||
return true;
|
||||
self::runAcmeSh($certrow, $domains, $cronlog, $do_force);
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getWorkingDirFromEnv($domain = "", $forced_noecc = false)
|
||||
/**
|
||||
* validate dns (A / AAAA record) of domain against known system ips
|
||||
*
|
||||
* @param array $domains
|
||||
* @param int $domain_id
|
||||
* @param FroxlorLogger $cronlog
|
||||
*/
|
||||
private static function validateDns(array &$domains, $domain_id, &$cronlog)
|
||||
{
|
||||
if (Settings::Get('system.leecc') > 0 && ! $forced_noecc) {
|
||||
$domain .= "_ecc";
|
||||
}
|
||||
$env_file = FileDir::makeCorrectFile(dirname(self::getAcmeSh()) . '/acme.sh.env');
|
||||
if (file_exists($env_file)) {
|
||||
$output = [];
|
||||
$cut = <<<EOC
|
||||
cut -d'"' -f2
|
||||
EOC;
|
||||
exec('grep "LE_WORKING_DIR" ' . escapeshellarg($env_file) . ' | ' . $cut, $output);
|
||||
if (is_array($output) && ! empty($output) && isset($output[0]) && ! empty($output[0])) {
|
||||
return FileDir::makeCorrectDir($output[0] . "/" . $domain);
|
||||
if (Settings::Get('system.le_domain_dnscheck') == '1' && !empty($domains)) {
|
||||
$loop_domains = $domains;
|
||||
// ips according to our system
|
||||
$our_ips = Domain::getIpsOfDomain($domain_id);
|
||||
foreach ($loop_domains as $idx => $domain) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Validating DNS of " . $domain);
|
||||
// ips according to NS
|
||||
$domain_ips = PhpHelper::gethostbynamel6($domain);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
// no common ips...
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $domain . " due to no system known IP address via DNS check");
|
||||
unset($domains[$idx]);
|
||||
// in order to avoid a cron-loop that tries to get a certificate every 5 minutes, we disable let's encrypt for this domain
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `letsencrypt` = '0' WHERE `id` = :did");
|
||||
Database::pexecute($upd_stmt, [
|
||||
'did' => $domain_id
|
||||
]);
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Let's Encrypt deactivated for domain " . $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
return FileDir::makeCorrectDir(dirname(self::getAcmeSh()) . "/" . $domain);
|
||||
}
|
||||
|
||||
public static function getAcmeSh()
|
||||
private static function runAcmeSh(array $certrow, array $domains, &$cronlog = null, $force = false)
|
||||
{
|
||||
$from_settings = Settings::Get('system.acmeshpath');
|
||||
if (file_exists($from_settings)) {
|
||||
return $from_settings;
|
||||
if (!empty($domains)) {
|
||||
$acmesh_cmd = self::getAcmeSh() . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
|
||||
// challenge path
|
||||
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
|
||||
if (Settings::Get('system.leecc') > 0) {
|
||||
// ecc certificate
|
||||
$acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc');
|
||||
} else {
|
||||
$acmesh_cmd .= " --keylength " . Settings::Get('system.letsencryptkeysize');
|
||||
}
|
||||
if (Settings::Get('system.letsencryptreuseold') != '1') {
|
||||
$acmesh_cmd .= " --always-force-new-domain-key";
|
||||
}
|
||||
if (Settings::Get('system.letsencryptca') == 'letsencrypt_test') {
|
||||
$acmesh_cmd .= " --staging";
|
||||
}
|
||||
if ($force) {
|
||||
$acmesh_cmd .= " --force";
|
||||
}
|
||||
if (defined('CRON_DEBUG_FLAG')) {
|
||||
$acmesh_cmd .= " --debug";
|
||||
}
|
||||
|
||||
$acme_result = FileDir::safe_exec($acmesh_cmd);
|
||||
// debug output of acme.sh run
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, implode("\n", $acme_result));
|
||||
|
||||
self::certToDb($certrow, $cronlog, $acme_result);
|
||||
}
|
||||
}
|
||||
|
||||
private static function certToDb($certrow, &$cronlog, $acme_result)
|
||||
{
|
||||
$return = [];
|
||||
self::readCertificateToVar(strtolower($certrow['domain']), $return, $cronlog);
|
||||
|
||||
if (!empty($return['crt'])) {
|
||||
$newcert = openssl_x509_parse($return['crt']);
|
||||
|
||||
if ($newcert) {
|
||||
// Store the new data
|
||||
Database::pexecute(self::$updcert_stmt, [
|
||||
'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(self::$upddom_stmt, [
|
||||
'domainid' => $certrow['domainid']
|
||||
]);
|
||||
}
|
||||
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Got non-successful Let's Encrypt response for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
|
||||
}
|
||||
} else {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
|
||||
}
|
||||
return self::$acmesh;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -567,22 +615,24 @@ EOC;
|
||||
if (Settings::Get('system.leecc') > 0) {
|
||||
$certificate_folder_noecc = self::getWorkingDirFromEnv($domain, true);
|
||||
}
|
||||
$certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder);
|
||||
$certificate_folder = FileDir::makeCorrectDir($certificate_folder);
|
||||
|
||||
if (is_dir($certificate_folder) || is_dir($certificate_folder_noecc)) {
|
||||
foreach ([
|
||||
'crt' => $domain . '.cer',
|
||||
'key' => $domain . '.key',
|
||||
'chain' => 'ca.cer',
|
||||
'fullchain' => 'fullchain.cer',
|
||||
'csr' => $domain . '.csr'
|
||||
] as $index => $sslfile) {
|
||||
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $sslfile);
|
||||
foreach (
|
||||
[
|
||||
'crt' => $domain . '.cer',
|
||||
'key' => $domain . '.key',
|
||||
'chain' => 'ca.cer',
|
||||
'fullchain' => 'fullchain.cer',
|
||||
'csr' => $domain . '.csr'
|
||||
] as $index => $sslfile
|
||||
) {
|
||||
$ssl_file = FileDir::makeCorrectFile($certificate_folder . '/' . $sslfile);
|
||||
if (file_exists($ssl_file)) {
|
||||
$return[$index] = file_get_contents($ssl_file);
|
||||
} else {
|
||||
if (! empty($certificate_folder_noecc)) {
|
||||
$ssl_file_fb = \Froxlor\FileDir::makeCorrectFile($certificate_folder_noecc . '/' . $sslfile);
|
||||
if (!empty($certificate_folder_noecc)) {
|
||||
$ssl_file_fb = FileDir::makeCorrectFile($certificate_folder_noecc . '/' . $sslfile);
|
||||
if (file_exists($ssl_file_fb)) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "ECC certificates activated but found only non-ecc file");
|
||||
$return[$index] = file_get_contents($ssl_file_fb);
|
||||
@@ -597,44 +647,4 @@ EOC;
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not find certificate-folder '" . $certificate_folder . "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* install acme.sh if not found yet
|
||||
*/
|
||||
private static function checkInstall($tries = 0)
|
||||
{
|
||||
if (! file_exists(self::getAcmeSh()) && $tries > 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'");
|
||||
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'" . PHP_EOL;
|
||||
return false;
|
||||
} else if (! file_exists(self::getAcmeSh())) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/");
|
||||
$return = false;
|
||||
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh -s email=" . Settings::Get('panel.adminmail'), $return, array(
|
||||
'|'
|
||||
));
|
||||
$set_path = self::getAcmeSh();
|
||||
// after this, regardless of what the user specified, the acme.sh installation will be in /root/.acme.sh
|
||||
if ($set_path != '/root/.acme.sh/acme.sh') {
|
||||
Settings::Set('system.acmeshpath', '/root/.acme.sh/acme.sh', true);
|
||||
// let the user know
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'");
|
||||
echo PHP_EOL . "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'" . PHP_EOL;
|
||||
}
|
||||
// check whether the installation worked
|
||||
return self::checkInstall(++ $tries);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* run upgrade
|
||||
*/
|
||||
private static function checkUpgrade()
|
||||
{
|
||||
$acmesh_result = \Froxlor\FileDir::safe_exec(self::getAcmeSh() . " --upgrade --auto-upgrade 0");
|
||||
// check for activated cron
|
||||
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::getAcmeSh() . " --install-cronjob");
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,37 +1,106 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class LighttpdFcgi extends Lighttpd
|
||||
{
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1') {
|
||||
$mypath = FileDir::makeCorrectDir(dirname(__FILE__, 3)); // /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, [
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
]);
|
||||
|
||||
$domain = [
|
||||
'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
|
||||
FileDir::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);
|
||||
}
|
||||
}
|
||||
|
||||
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']);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
// vhost data for php-fpm
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$domain['fpm_socket'] = $php->getInterface()->getSocketFile();
|
||||
$php_options_text = ' fastcgi.server = ( ' . "\n";
|
||||
$php_options_text .= "\t" . '".php" => (' . "\n";
|
||||
@@ -42,7 +111,7 @@ class LighttpdFcgi extends Lighttpd
|
||||
$php_options_text .= "\t" . ')' . "\n";
|
||||
$php_options_text .= "\t" . ')' . "\n";
|
||||
$php_options_text .= ' )' . "\n";
|
||||
} elseif ((int) Settings::Get('system.mod_fcgid') == 1) {
|
||||
} elseif ((int)Settings::Get('system.mod_fcgid') == 1) {
|
||||
// vhost data for fcgid
|
||||
$php_options_text = ' fastcgi.server = ( ' . "\n";
|
||||
$file_extensions = explode(' ', $phpconfig['file_extensions']);
|
||||
@@ -52,23 +121,23 @@ class LighttpdFcgi extends Lighttpd
|
||||
$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";
|
||||
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";
|
||||
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";
|
||||
$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";
|
||||
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";
|
||||
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\t" . '"PHP_FCGI_MAX_REQUESTS" => "' . (int)Settings::Get('system.mod_fcgid_maxrequests') . '"' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,62 +160,4 @@ class LighttpdFcgi extends Lighttpd
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1') {
|
||||
$mypath = \Froxlor\FileDir::makeCorrectDir(dirname(__FILE__, 3)); // /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
|
||||
\Froxlor\FileDir::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,34 +1,103 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class NginxFcgi extends Nginx
|
||||
{
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1') {
|
||||
$mypath = FileDir::makeCorrectDir(dirname(__FILE__, 3)); // /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, [
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
]);
|
||||
|
||||
$domain = [
|
||||
'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
|
||||
FileDir::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);
|
||||
}
|
||||
}
|
||||
|
||||
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']);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
$php_options_text = "\t" . 'location ~ ^(.+?\.php)(/.*)?$ {' . "\n";
|
||||
$php_options_text .= "\t\t" . 'try_files ' . $domain['nonexistinguri'] . ' @php;' . "\n";
|
||||
@@ -60,62 +129,4 @@ class NginxFcgi extends Nginx
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1') {
|
||||
$mypath = \Froxlor\FileDir::makeCorrectDir(dirname(__FILE__, 3)); // /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
|
||||
\Froxlor\FileDir::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,27 +1,36 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class Fcgid
|
||||
{
|
||||
|
||||
@@ -30,14 +39,14 @@ class Fcgid
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $domain = array();
|
||||
private $domain = [];
|
||||
|
||||
/**
|
||||
* Admin-Date cache array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $admin_cache = array();
|
||||
private $admin_cache = [];
|
||||
|
||||
/**
|
||||
* main constructor
|
||||
@@ -54,7 +63,6 @@ class Fcgid
|
||||
*/
|
||||
public function createConfig($phpconfig)
|
||||
{
|
||||
|
||||
// create starter
|
||||
$starter_file = "#!/bin/sh\n\n";
|
||||
$starter_file .= "#\n";
|
||||
@@ -66,26 +74,26 @@ class Fcgid
|
||||
$starter_file .= "export PHPRC\n";
|
||||
|
||||
// set number of processes for one domain
|
||||
if ((int) $this->domain['mod_fcgid_starter'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int) $this->domain['mod_fcgid_starter'] . "\n";
|
||||
if ((int)$this->domain['mod_fcgid_starter'] != -1) {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int)$this->domain['mod_fcgid_starter'] . "\n";
|
||||
} else {
|
||||
if ((int) $phpconfig['mod_fcgid_starter'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int) $phpconfig['mod_fcgid_starter'] . "\n";
|
||||
if ((int)$phpconfig['mod_fcgid_starter'] != -1) {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int)$phpconfig['mod_fcgid_starter'] . "\n";
|
||||
} else {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int) Settings::Get('system.mod_fcgid_starter') . "\n";
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int)Settings::Get('system.mod_fcgid_starter') . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$starter_file .= "export PHP_FCGI_CHILDREN\n";
|
||||
|
||||
// set number of maximum requests for one domain
|
||||
if ((int) $this->domain['mod_fcgid_maxrequests'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int) $this->domain['mod_fcgid_maxrequests'] . "\n";
|
||||
if ((int)$this->domain['mod_fcgid_maxrequests'] != -1) {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int)$this->domain['mod_fcgid_maxrequests'] . "\n";
|
||||
} else {
|
||||
if ((int) $phpconfig['mod_fcgid_maxrequests'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int) $phpconfig['mod_fcgid_maxrequests'] . "\n";
|
||||
if ((int)$phpconfig['mod_fcgid_maxrequests'] != -1) {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int)$phpconfig['mod_fcgid_maxrequests'] . "\n";
|
||||
} else {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int) Settings::Get('system.mod_fcgid_maxrequests') . "\n";
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int)Settings::Get('system.mod_fcgid_maxrequests') . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,15 +104,46 @@ class Fcgid
|
||||
|
||||
// remove +i attribute, so starter can be overwritten
|
||||
if (file_exists($this->getStarterFile())) {
|
||||
\Froxlor\FileDir::removeImmutable($this->getStarterFile());
|
||||
FileDir::removeImmutable($this->getStarterFile());
|
||||
}
|
||||
|
||||
$starter_file_handler = fopen($this->getStarterFile(), 'w');
|
||||
fwrite($starter_file_handler, $starter_file);
|
||||
fclose($starter_file_handler);
|
||||
\Froxlor\FileDir::safe_exec('chmod 750 ' . escapeshellarg($this->getStarterFile()));
|
||||
\Froxlor\FileDir::safe_exec('chown ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($this->getStarterFile()));
|
||||
\Froxlor\FileDir::setImmutable($this->getStarterFile());
|
||||
FileDir::safe_exec('chmod 750 ' . escapeshellarg($this->getStarterFile()));
|
||||
FileDir::safe_exec('chown ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($this->getStarterFile()));
|
||||
FileDir::setImmutable($this->getStarterFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgid-config directory
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getConfigDir($createifnotexists = true)
|
||||
{
|
||||
$configdir = FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_configdir') . '/' . $this->domain['loginname'] . '/' . $this->domain['domain'] . '/');
|
||||
|
||||
if (!is_dir($configdir) && $createifnotexists) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
FileDir::safe_exec('chown ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
return $configdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* return path of php-starter file
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getStarterFile()
|
||||
{
|
||||
$starter_filename = FileDir::makeCorrectFile($this->getConfigDir() . '/php-fcgi-starter');
|
||||
return $starter_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,27 +157,26 @@ class Fcgid
|
||||
$openbasedirc = ';';
|
||||
|
||||
if ($this->domain['openbasedir'] == '1') {
|
||||
|
||||
$openbasedirc = '';
|
||||
$_phpappendopenbasedir = '';
|
||||
|
||||
$_custom_openbasedir = explode(':', Settings::Get('system.mod_fcgid_peardir'));
|
||||
foreach ($_custom_openbasedir as $cobd) {
|
||||
$_phpappendopenbasedir .= \Froxlor\Domain\Domain::appendOpenBasedirPath($cobd);
|
||||
$_phpappendopenbasedir .= Domain::appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
$_custom_openbasedir = explode(':', Settings::Get('system.phpappendopenbasedir'));
|
||||
foreach ($_custom_openbasedir as $cobd) {
|
||||
$_phpappendopenbasedir .= \Froxlor\Domain\Domain::appendOpenBasedirPath($cobd);
|
||||
$_phpappendopenbasedir .= Domain::appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
if ($this->domain['openbasedir_path'] == '0' && strstr($this->domain['documentroot'], ":") === false) {
|
||||
$openbasedir = \Froxlor\Domain\Domain::appendOpenBasedirPath($this->domain['documentroot'], true);
|
||||
$openbasedir = Domain::appendOpenBasedirPath($this->domain['documentroot'], true);
|
||||
} else {
|
||||
$openbasedir = \Froxlor\Domain\Domain::appendOpenBasedirPath($this->domain['customerroot'], true);
|
||||
$openbasedir = Domain::appendOpenBasedirPath($this->domain['customerroot'], true);
|
||||
}
|
||||
|
||||
$openbasedir .= \Froxlor\Domain\Domain::appendOpenBasedirPath($this->getTempDir());
|
||||
$openbasedir .= Domain::appendOpenBasedirPath($this->getTempDir());
|
||||
$openbasedir .= $_phpappendopenbasedir;
|
||||
} else {
|
||||
$openbasedir = 'none';
|
||||
@@ -146,7 +184,7 @@ class Fcgid
|
||||
}
|
||||
|
||||
$admin = $this->getAdminData($this->domain['adminid']);
|
||||
$php_ini_variables = array(
|
||||
$php_ini_variables = [
|
||||
'SAFE_MODE' => 'Off', // keep this for compatibility, just in case
|
||||
'PEAR_DIR' => Settings::Get('system.mod_fcgid_peardir'),
|
||||
'TMP_DIR' => $this->getTempDir(),
|
||||
@@ -158,75 +196,66 @@ class Fcgid
|
||||
'OPEN_BASEDIR' => $openbasedir,
|
||||
'OPEN_BASEDIR_C' => $openbasedirc,
|
||||
'OPEN_BASEDIR_GLOBAL' => Settings::Get('system.phpappendopenbasedir'),
|
||||
'DOCUMENT_ROOT' => \Froxlor\FileDir::makeCorrectDir($this->domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => \Froxlor\FileDir::makeCorrectDir($this->domain['customerroot'])
|
||||
);
|
||||
'DOCUMENT_ROOT' => FileDir::makeCorrectDir($this->domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => FileDir::makeCorrectDir($this->domain['customerroot'])
|
||||
];
|
||||
|
||||
// insert a small header for the file
|
||||
$phpini_file = ";\n";
|
||||
$phpini_file .= "; php.ini created/changed on " . date("Y.m.d H:i:s") . " for domain '" . $this->domain['domain'] . "' with id #" . $this->domain['id'] . " from php template '" . $phpconfig['description'] . "' with id #" . $phpconfig['id'] . "\n";
|
||||
$phpini_file .= "; Do not change anything in this file, it will be overwritten by the Froxlor Cronjob!\n";
|
||||
$phpini_file .= ";\n\n";
|
||||
$phpini_file .= \Froxlor\PhpHelper::replaceVariables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini_file .= PhpHelper::replaceVariables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini_file = str_replace('"none"', 'none', $phpini_file);
|
||||
// $phpini_file = preg_replace('/\"+/', '"', $phpini_file);
|
||||
$phpini_file_handler = fopen($this->getIniFile(), 'w');
|
||||
fwrite($phpini_file_handler, $phpini_file);
|
||||
fclose($phpini_file_handler);
|
||||
\Froxlor\FileDir::safe_exec('chown root:0 ' . escapeshellarg($this->getIniFile()));
|
||||
\Froxlor\FileDir::safe_exec('chmod 0644 ' . escapeshellarg($this->getIniFile()));
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgid-config directory
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getConfigDir($createifnotexists = true)
|
||||
{
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_configdir') . '/' . $this->domain['loginname'] . '/' . $this->domain['domain'] . '/');
|
||||
|
||||
if (! is_dir($configdir) && $createifnotexists) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
\Froxlor\FileDir::safe_exec('chown ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
return $configdir;
|
||||
FileDir::safe_exec('chown root:0 ' . escapeshellarg($this->getIniFile()));
|
||||
FileDir::safe_exec('chmod 0644 ' . escapeshellarg($this->getIniFile()));
|
||||
}
|
||||
|
||||
/**
|
||||
* fcgid-temp directory
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getTempDir($createifnotexists = true)
|
||||
{
|
||||
$tmpdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $this->domain['loginname'] . '/');
|
||||
$tmpdir = FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $this->domain['loginname'] . '/');
|
||||
|
||||
if (! is_dir($tmpdir) && $createifnotexists) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('chmod 0750 ' . escapeshellarg($tmpdir));
|
||||
if (!is_dir($tmpdir) && $createifnotexists) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('chown -R ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('chmod 0750 ' . escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
return $tmpdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* return path of php-starter file
|
||||
* return the admin-data of a specific admin
|
||||
*
|
||||
* @return string the directory
|
||||
* @param int $adminid
|
||||
* id of the admin-user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStarterFile()
|
||||
private function getAdminData($adminid)
|
||||
{
|
||||
$starter_filename = \Froxlor\FileDir::makeCorrectFile($this->getConfigDir() . '/php-fcgi-starter');
|
||||
return $starter_filename;
|
||||
$adminid = intval($adminid);
|
||||
|
||||
if (!isset($this->admin_cache[$adminid])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id");
|
||||
$this->admin_cache[$adminid] = Database::pexecute_first($stmt, [
|
||||
'id' => $adminid
|
||||
]);
|
||||
}
|
||||
return $this->admin_cache[$adminid];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,29 +265,7 @@ class Fcgid
|
||||
*/
|
||||
public function getIniFile()
|
||||
{
|
||||
$phpini_filename = \Froxlor\FileDir::makeCorrectFile($this->getConfigDir() . '/php.ini');
|
||||
$phpini_filename = FileDir::makeCorrectFile($this->getConfigDir() . '/php.ini');
|
||||
return $phpini_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the admin-data of a specific admin
|
||||
*
|
||||
* @param int $adminid
|
||||
* id of the admin-user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAdminData($adminid)
|
||||
{
|
||||
$adminid = intval($adminid);
|
||||
|
||||
if (! isset($this->admin_cache[$adminid])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id");
|
||||
$this->admin_cache[$adminid] = Database::pexecute_first($stmt, array(
|
||||
'id' => $adminid
|
||||
));
|
||||
}
|
||||
return $this->admin_cache[$adminid];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,36 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class Fpm
|
||||
{
|
||||
|
||||
@@ -30,21 +39,21 @@ class Fpm
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $domain = array();
|
||||
private $domain = [];
|
||||
|
||||
/**
|
||||
* fpm config
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $fpm_cfg = array();
|
||||
private $fpm_cfg = [];
|
||||
|
||||
/**
|
||||
* Admin-Date cache array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $admin_cache = array();
|
||||
private $admin_cache = [];
|
||||
|
||||
/**
|
||||
* defines what can be used for pool-config from php.ini
|
||||
@@ -52,14 +61,14 @@ class Fpm
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $ini = array();
|
||||
private $ini = [];
|
||||
|
||||
/**
|
||||
* main constructor
|
||||
*/
|
||||
public function __construct($domain)
|
||||
{
|
||||
if (! isset($domain['fpm_config_id']) || empty($domain['fpm_config_id'])) {
|
||||
if (!isset($domain['fpm_config_id']) || empty($domain['fpm_config_id'])) {
|
||||
$domain['fpm_config_id'] = 1;
|
||||
}
|
||||
$this->domain = $domain;
|
||||
@@ -67,22 +76,43 @@ class Fpm
|
||||
$this->buildIniMapping();
|
||||
}
|
||||
|
||||
private function readFpmConfig($fpm_config_id)
|
||||
{
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id");
|
||||
$this->fpm_cfg = Database::pexecute_first($stmt, [
|
||||
'id' => $fpm_config_id
|
||||
]);
|
||||
}
|
||||
|
||||
private function buildIniMapping()
|
||||
{
|
||||
$this->ini = array(
|
||||
$this->ini = [
|
||||
'php_flag' => explode("\n", Settings::Get('phpfpm.ini_flags')),
|
||||
'php_value' => explode("\n", Settings::Get('phpfpm.ini_values')),
|
||||
'php_admin_flag' => explode("\n", Settings::Get('phpfpm.ini_admin_flags')),
|
||||
'php_admin_value' => explode("\n", Settings::Get('phpfpm.ini_admin_values'))
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
private function readFpmConfig($fpm_config_id)
|
||||
/**
|
||||
* create a dummy fpm pool config with minimal configuration
|
||||
* (this is used whenever a config directory is empty but needs at least one pool to startup/restart)
|
||||
*
|
||||
* @param string $configdir
|
||||
*/
|
||||
public static function createDummyPool($configdir)
|
||||
{
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id");
|
||||
$this->fpm_cfg = Database::pexecute_first($stmt, array(
|
||||
'id' => $fpm_config_id
|
||||
));
|
||||
if (!is_dir($configdir)) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
}
|
||||
$config = FileDir::makeCorrectFile($configdir . '/dummy.conf');
|
||||
$dummy = "[dummy]
|
||||
user = " . Settings::Get('system.httpuser') . "
|
||||
listen = /run/" . md5($configdir) . "-fpm.sock
|
||||
pm = static
|
||||
pm.max_children = 1
|
||||
";
|
||||
file_put_contents($config, $dummy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +125,6 @@ class Fpm
|
||||
$fh = @fopen($this->getConfigFile(), 'w');
|
||||
|
||||
if ($fh) {
|
||||
|
||||
if ($phpconfig['override_fpmconfig'] == 1) {
|
||||
$this->fpm_cfg['pm'] = $phpconfig['pm'];
|
||||
$this->fpm_cfg['max_children'] = $phpconfig['max_children'];
|
||||
@@ -108,12 +137,12 @@ class Fpm
|
||||
}
|
||||
|
||||
$fpm_pm = $this->fpm_cfg['pm'];
|
||||
$fpm_children = (int) $this->fpm_cfg['max_children'];
|
||||
$fpm_start_servers = (int) $this->fpm_cfg['start_servers'];
|
||||
$fpm_min_spare_servers = (int) $this->fpm_cfg['min_spare_servers'];
|
||||
$fpm_max_spare_servers = (int) $this->fpm_cfg['max_spare_servers'];
|
||||
$fpm_requests = (int) $this->fpm_cfg['max_requests'];
|
||||
$fpm_process_idle_timeout = (int) $this->fpm_cfg['idle_timeout'];
|
||||
$fpm_children = (int)$this->fpm_cfg['max_children'];
|
||||
$fpm_start_servers = (int)$this->fpm_cfg['start_servers'];
|
||||
$fpm_min_spare_servers = (int)$this->fpm_cfg['min_spare_servers'];
|
||||
$fpm_max_spare_servers = (int)$this->fpm_cfg['max_spare_servers'];
|
||||
$fpm_requests = (int)$this->fpm_cfg['max_requests'];
|
||||
$fpm_process_idle_timeout = (int)$this->fpm_cfg['idle_timeout'];
|
||||
$fpm_limit_extensions = $this->fpm_cfg['limit_extensions'];
|
||||
$fpm_custom_config = $this->fpm_cfg['custom_config'];
|
||||
|
||||
@@ -173,21 +202,21 @@ class Fpm
|
||||
if ($phpconfig['fpm_slowlog'] == '1') {
|
||||
$fpm_config .= 'request_terminate_timeout = ' . $phpconfig['fpm_reqterm'] . "\n";
|
||||
$fpm_config .= 'request_slowlog_timeout = ' . $phpconfig['fpm_reqslow'] . "\n";
|
||||
$slowlog = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.logfiles_directory') . '/' . $this->domain['loginname'] . '-php-slow.log');
|
||||
$slowlog = FileDir::makeCorrectFile(Settings::Get('system.logfiles_directory') . '/' . $this->domain['loginname'] . '-php-slow.log');
|
||||
$fpm_config .= 'slowlog = ' . $slowlog . "\n";
|
||||
$fpm_config .= 'catch_workers_output = yes' . "\n";
|
||||
}
|
||||
|
||||
$fpm_config .= ';chroot = ' . \Froxlor\FileDir::makeCorrectDir($this->domain['documentroot']) . "\n";
|
||||
$fpm_config .= ';chroot = ' . FileDir::makeCorrectDir($this->domain['documentroot']) . "\n";
|
||||
$fpm_config .= 'security.limit_extensions = ' . $fpm_limit_extensions . "\n";
|
||||
|
||||
$tmpdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/');
|
||||
if (! is_dir($tmpdir)) {
|
||||
$tmpdir = FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/');
|
||||
if (!is_dir($tmpdir)) {
|
||||
$this->getTempDir();
|
||||
}
|
||||
|
||||
$env_path = Settings::Get('phpfpm.envpath');
|
||||
if (! empty($env_path)) {
|
||||
if (!empty($env_path)) {
|
||||
$fpm_config .= 'env[PATH] = ' . $env_path . "\n";
|
||||
}
|
||||
$fpm_config .= 'env[TMP] = ' . $tmpdir . "\n";
|
||||
@@ -200,29 +229,29 @@ class Fpm
|
||||
$_phpappendopenbasedir = '';
|
||||
$_custom_openbasedir = explode(':', Settings::Get('phpfpm.peardir'));
|
||||
foreach ($_custom_openbasedir as $cobd) {
|
||||
$_phpappendopenbasedir .= \Froxlor\Domain\Domain::appendOpenBasedirPath($cobd);
|
||||
$_phpappendopenbasedir .= Domain::appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
$_custom_openbasedir = explode(':', Settings::Get('system.phpappendopenbasedir'));
|
||||
foreach ($_custom_openbasedir as $cobd) {
|
||||
$_phpappendopenbasedir .= \Froxlor\Domain\Domain::appendOpenBasedirPath($cobd);
|
||||
$_phpappendopenbasedir .= Domain::appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
if ($this->domain['openbasedir_path'] == '0' && strstr($this->domain['documentroot'], ":") === false) {
|
||||
$openbasedir = \Froxlor\Domain\Domain::appendOpenBasedirPath($this->domain['documentroot'], true);
|
||||
$openbasedir = Domain::appendOpenBasedirPath($this->domain['documentroot'], true);
|
||||
} else {
|
||||
$openbasedir = \Froxlor\Domain\Domain::appendOpenBasedirPath($this->domain['customerroot'], true);
|
||||
$openbasedir = Domain::appendOpenBasedirPath($this->domain['customerroot'], true);
|
||||
}
|
||||
|
||||
$openbasedir .= \Froxlor\Domain\Domain::appendOpenBasedirPath($this->getTempDir());
|
||||
$openbasedir .= Domain::appendOpenBasedirPath($this->getTempDir());
|
||||
$openbasedir .= $_phpappendopenbasedir;
|
||||
}
|
||||
}
|
||||
|
||||
$fpm_config .= 'php_admin_value[upload_tmp_dir] = ' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n";
|
||||
$fpm_config .= 'php_admin_value[upload_tmp_dir] = ' . FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n";
|
||||
|
||||
$admin = $this->getAdminData($this->domain['adminid']);
|
||||
$php_ini_variables = array(
|
||||
$php_ini_variables = [
|
||||
'SAFE_MODE' => 'Off', // keep this for compatibility, just in case
|
||||
'PEAR_DIR' => Settings::Get('phpfpm.peardir'),
|
||||
'TMP_DIR' => $this->getTempDir(),
|
||||
@@ -234,11 +263,11 @@ class Fpm
|
||||
'OPEN_BASEDIR' => $openbasedir,
|
||||
'OPEN_BASEDIR_C' => '',
|
||||
'OPEN_BASEDIR_GLOBAL' => Settings::Get('system.phpappendopenbasedir'),
|
||||
'DOCUMENT_ROOT' => \Froxlor\FileDir::makeCorrectDir($this->domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => \Froxlor\FileDir::makeCorrectDir($this->domain['customerroot'])
|
||||
);
|
||||
'DOCUMENT_ROOT' => FileDir::makeCorrectDir($this->domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => FileDir::makeCorrectDir($this->domain['customerroot'])
|
||||
];
|
||||
|
||||
$phpini = \Froxlor\PhpHelper::replaceVariables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini = PhpHelper::replaceVariables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini_array = explode("\n", $phpini);
|
||||
|
||||
$fpm_config .= "\n\n";
|
||||
@@ -270,9 +299,9 @@ class Fpm
|
||||
}
|
||||
|
||||
// append custom phpfpm configuration
|
||||
if (! empty($fpm_custom_config)) {
|
||||
if (!empty($fpm_custom_config)) {
|
||||
$fpm_config .= "\n; Custom Configuration\n";
|
||||
$fpm_config .= \Froxlor\PhpHelper::replaceVariables($fpm_custom_config, $php_ini_variables);
|
||||
$fpm_config .= PhpHelper::replaceVariables($fpm_custom_config, $php_ini_variables);
|
||||
}
|
||||
|
||||
fwrite($fh, $fpm_config, strlen($fpm_config));
|
||||
@@ -280,6 +309,91 @@ class Fpm
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fpm-config file
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the full path to the file
|
||||
*/
|
||||
public function getConfigFile($createifnotexists = true)
|
||||
{
|
||||
$configdir = $this->fpm_cfg['config_dir'];
|
||||
$config = FileDir::makeCorrectFile($configdir . '/' . $this->domain['domain'] . '.conf');
|
||||
|
||||
if (!is_dir($configdir) && $createifnotexists) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* return path of fpm-socket file
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the full path to the socket
|
||||
*/
|
||||
public function getSocketFile($createifnotexists = true)
|
||||
{
|
||||
$socketdir = FileDir::makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir'));
|
||||
// add fpm-config-id to filename so it's unique for the fpm-daemon and doesn't interfere with running configs when reuilding
|
||||
$socket = strtolower(FileDir::makeCorrectFile($socketdir . '/' . $this->domain['fpm_config_id'] . '-' . $this->domain['loginname'] . '-' . $this->domain['domain'] . '-php-fpm.socket'));
|
||||
|
||||
if (!is_dir($socketdir) && $createifnotexists) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($socketdir));
|
||||
FileDir::safe_exec('chown -R ' . Settings::Get('system.httpuser') . ':' . Settings::Get('system.httpgroup') . ' ' . escapeshellarg($socketdir));
|
||||
}
|
||||
|
||||
return $socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpm-temp directory
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getTempDir($createifnotexists = true)
|
||||
{
|
||||
$tmpdir = FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/');
|
||||
|
||||
if (!is_dir($tmpdir) && $createifnotexists) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('chown -R ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('chmod 0750 ' . escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
return $tmpdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the admin-data of a specific admin
|
||||
*
|
||||
* @param int $adminid
|
||||
* id of the admin-user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAdminData($adminid)
|
||||
{
|
||||
$adminid = intval($adminid);
|
||||
|
||||
if (!isset($this->admin_cache[$adminid])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id");
|
||||
$this->admin_cache[$adminid] = Database::pexecute_first($stmt, [
|
||||
'id' => $adminid
|
||||
]);
|
||||
}
|
||||
return $this->admin_cache[$adminid];
|
||||
}
|
||||
|
||||
/**
|
||||
* this is done via createConfig as php-fpm defines
|
||||
* the ini-values/flags in its pool-config
|
||||
@@ -291,134 +405,27 @@ class Fpm
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpm-config file
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the full path to the file
|
||||
*/
|
||||
public function getConfigFile($createifnotexists = true)
|
||||
{
|
||||
$configdir = $this->fpm_cfg['config_dir'];
|
||||
$config = \Froxlor\FileDir::makeCorrectFile($configdir . '/' . $this->domain['domain'] . '.conf');
|
||||
|
||||
if (! is_dir($configdir) && $createifnotexists) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* return path of fpm-socket file
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the full path to the socket
|
||||
*/
|
||||
public function getSocketFile($createifnotexists = true)
|
||||
{
|
||||
$socketdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir'));
|
||||
// add fpm-config-id to filename so it's unique for the fpm-daemon and doesn't interfere with running configs when reuilding
|
||||
$socket = strtolower(\Froxlor\FileDir::makeCorrectFile($socketdir . '/' . $this->domain['fpm_config_id'] . '-' . $this->domain['loginname'] . '-' . $this->domain['domain'] . '-php-fpm.socket'));
|
||||
|
||||
if (! is_dir($socketdir) && $createifnotexists) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($socketdir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . Settings::Get('system.httpuser') . ':' . Settings::Get('system.httpgroup') . ' ' . escapeshellarg($socketdir));
|
||||
}
|
||||
|
||||
return $socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpm-temp directory
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getTempDir($createifnotexists = true)
|
||||
{
|
||||
$tmpdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/');
|
||||
|
||||
if (! is_dir($tmpdir) && $createifnotexists) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('chmod 0750 ' . escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
return $tmpdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* fastcgi-fakedirectory directory
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getAliasConfigDir($createifnotexists = true)
|
||||
{
|
||||
|
||||
// ensure default...
|
||||
if (Settings::Get('phpfpm.aliasconfigdir') == null) {
|
||||
Settings::Set('phpfpm.aliasconfigdir', '/var/www/php-fpm');
|
||||
}
|
||||
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.aliasconfigdir') . '/' . $this->domain['loginname'] . '/' . $this->domain['domain'] . '/');
|
||||
if (! is_dir($configdir) && $createifnotexists) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
\Froxlor\FileDir::safe_exec('chown ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($configdir));
|
||||
$configdir = FileDir::makeCorrectDir(Settings::Get('phpfpm.aliasconfigdir') . '/' . $this->domain['loginname'] . '/' . $this->domain['domain'] . '/');
|
||||
if (!is_dir($configdir) && $createifnotexists) {
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
FileDir::safe_exec('chown ' . $this->domain['guid'] . ':' . $this->domain['guid'] . ' ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
return $configdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a dummy fpm pool config with minimal configuration
|
||||
* (this is used whenever a config directory is empty but needs at least one pool to startup/restart)
|
||||
*
|
||||
* @param string $configdir
|
||||
*/
|
||||
public static function createDummyPool($configdir)
|
||||
{
|
||||
if (! is_dir($configdir)) {
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
}
|
||||
$config = \Froxlor\FileDir::makeCorrectFile($configdir . '/dummy.conf');
|
||||
$dummy = "[dummy]
|
||||
user = " . Settings::Get('system.httpuser') . "
|
||||
listen = /run/" . md5($configdir) . "-fpm.sock
|
||||
pm = static
|
||||
pm.max_children = 1
|
||||
";
|
||||
file_put_contents($config, $dummy);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the admin-data of a specific admin
|
||||
*
|
||||
* @param int $adminid
|
||||
* id of the admin-user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAdminData($adminid)
|
||||
{
|
||||
$adminid = intval($adminid);
|
||||
|
||||
if (! isset($this->admin_cache[$adminid])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id");
|
||||
$this->admin_cache[$adminid] = Database::pexecute_first($stmt, array(
|
||||
'id' => $adminid
|
||||
));
|
||||
}
|
||||
return $this->admin_cache[$adminid];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class PhpInterface
|
||||
{
|
||||
|
||||
@@ -30,7 +36,7 @@ class PhpInterface
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $domain = array();
|
||||
private $domain = [];
|
||||
|
||||
/**
|
||||
* Interface object
|
||||
@@ -44,7 +50,7 @@ class PhpInterface
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $admin_cache = array();
|
||||
private $admin_cache = [];
|
||||
|
||||
/**
|
||||
* main constructor
|
||||
@@ -55,6 +61,21 @@ class PhpInterface
|
||||
$this->setInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* set interface-object by type of
|
||||
* php-interface: fcgid or php-fpm
|
||||
* sets private $_interface variable
|
||||
*/
|
||||
private function setInterface()
|
||||
{
|
||||
// php-fpm
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$this->interface = new Fpm($this->domain);
|
||||
} elseif ((int)Settings::Get('system.mod_fcgid') == 1) {
|
||||
$this->interface = new Fcgid($this->domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the interface-object
|
||||
* from where we can control it
|
||||
@@ -64,27 +85,12 @@ class PhpInterface
|
||||
return $this->interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* set interface-object by type of
|
||||
* php-interface: fcgid or php-fpm
|
||||
* sets private $_interface variable
|
||||
*/
|
||||
private function setInterface()
|
||||
{
|
||||
// php-fpm
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
$this->interface = new Fpm($this->domain);
|
||||
} elseif ((int) Settings::Get('system.mod_fcgid') == 1) {
|
||||
$this->interface = new Fcgid($this->domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the php-configuration from the database
|
||||
*
|
||||
* @param int $php_config_id
|
||||
* id of the php-configuration
|
||||
*
|
||||
* id of the php-configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPhpConfig($php_config_id)
|
||||
@@ -96,18 +102,18 @@ class PhpInterface
|
||||
$php_config_id = 1;
|
||||
}
|
||||
|
||||
if (! isset($this->php_configs_cache[$php_config_id])) {
|
||||
if (!isset($this->php_configs_cache[$php_config_id])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id");
|
||||
$this->_php_configs_cache[$php_config_id] = Database::pexecute_first($stmt, array(
|
||||
$this->_php_configs_cache[$php_config_id] = Database::pexecute_first($stmt, [
|
||||
'id' => $php_config_id
|
||||
));
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
]);
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id");
|
||||
$this->_php_configs_cache[$php_config_id]['fpm_settings'] = Database::pexecute_first($stmt, array(
|
||||
$this->_php_configs_cache[$php_config_id]['fpm_settings'] = Database::pexecute_first($stmt, [
|
||||
'id' => $this->_php_configs_cache[$php_config_id]['fpmsettingid']
|
||||
));
|
||||
]);
|
||||
// override fpm daemon settings if set in php-config
|
||||
if ($this->_php_configs_cache[$php_config_id]['override_fpmconfig'] == 1) {
|
||||
$this->_php_configs_cache[$php_config_id]['fpm_settings']['limit_extensions'] = $this->_php_configs_cache[$php_config_id]['limit_extensions'];
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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.31
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
class WebserverBase
|
||||
{
|
||||
|
||||
@@ -64,9 +73,8 @@ class WebserverBase
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
|
||||
$domains = array();
|
||||
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$domains = [];
|
||||
while ($domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// set whole domain
|
||||
$domains[$domain['domain']] = $domain;
|
||||
// set empty-defaults for non-ssl
|
||||
@@ -78,11 +86,10 @@ class WebserverBase
|
||||
|
||||
// now, if the domain has an ssl ip/port assigned, get
|
||||
// the corresponding information from the db
|
||||
if (\Froxlor\Domain\Domain::domainHasSslIpPort($domain['id'])) {
|
||||
|
||||
$ssl_ip = Database::pexecute_first($ip_stmt, array(
|
||||
if (Domain::domainHasSslIpPort($domain['id'])) {
|
||||
$ssl_ip = Database::pexecute_first($ip_stmt, [
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
]);
|
||||
|
||||
// set ssl info for domain
|
||||
$domains[$domain['domain']]['ssl'] = '1';
|
||||
@@ -93,11 +100,10 @@ class WebserverBase
|
||||
}
|
||||
|
||||
// read fpm-config-id if using fpm
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, array(
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, [
|
||||
'phpconfigid' => $domain['phpsettingid']
|
||||
));
|
||||
]);
|
||||
if ($fpm_config) {
|
||||
$domains[$domain['domain']]['fpm_config_id'] = $fpm_config['id'];
|
||||
} else {
|
||||
|
||||
@@ -1,23 +1,41 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
use Exception;
|
||||
use Froxlor\Cron\System\Extrausers;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\System\Cronjob;
|
||||
use PDO;
|
||||
|
||||
class MasterCron extends FroxlorCron
|
||||
{
|
||||
|
||||
private static $argv = null;
|
||||
@@ -40,7 +58,7 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
self::init();
|
||||
|
||||
$jobs_to_run = array();
|
||||
$jobs_to_run = [];
|
||||
|
||||
$argv = self::$argv;
|
||||
/**
|
||||
@@ -64,20 +82,20 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
* --force to include cron_tasks even if it's not its turn
|
||||
* --debug to output debug information
|
||||
*/
|
||||
for ($x = 1; $x < count($argv); $x ++) {
|
||||
for ($x = 1; $x < count($argv); $x++) {
|
||||
// check argument
|
||||
if (isset($argv[$x])) {
|
||||
// --force
|
||||
if (strtolower($argv[$x]) == '--force') {
|
||||
// really force re-generating of config-files by
|
||||
// inserting task 1
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
Cronjob::inserttask(TaskId::REBUILD_VHOST);
|
||||
// bind (if enabled, \Froxlor\System\Cronjob::inserttask() checks this)
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
Cronjob::inserttask(TaskId::REBUILD_DNS);
|
||||
// set quotas (if enabled)
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
Cronjob::inserttask(TaskId::CREATE_QUOTA);
|
||||
// also regenerate cron.d-file
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
Cronjob::inserttask(TaskId::REBUILD_CRON);
|
||||
array_push($jobs_to_run, 'tasks');
|
||||
define('CRON_IS_FORCED', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--debug') {
|
||||
@@ -85,8 +103,8 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
} elseif (strtolower($argv[$x]) == '--no-fork') {
|
||||
define('CRON_NOFORK_FLAG', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--run-task') {
|
||||
if (isset($argv[$x+1]) && in_array($argv[$x+1], [1,4,10,99])) {
|
||||
\Froxlor\System\Cronjob::inserttask($argv[$x+1]);
|
||||
if (isset($argv[$x + 1]) && in_array($argv[$x + 1], [1, 4, 10, 99])) {
|
||||
Cronjob::inserttask($argv[$x + 1]);
|
||||
array_push($jobs_to_run, 'tasks');
|
||||
} else {
|
||||
echo "Invalid argument for --run-task\n";
|
||||
@@ -106,14 +124,14 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
self::$cronlog->setCronDebugFlag(defined('CRON_DEBUG_FLAG'));
|
||||
|
||||
$tasks_cnt_stmt = \Froxlor\Database\Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$tasks_cnt_stmt = Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// do we have anything to include?
|
||||
if (count($jobs_to_run) > 0) {
|
||||
// include all jobs we want to execute
|
||||
foreach ($jobs_to_run as $cron) {
|
||||
\Froxlor\System\Cronjob::updateLastRunOfCron($cron);
|
||||
Cronjob::updateLastRunOfCron($cron);
|
||||
$cronfile = self::getCronModule($cron);
|
||||
if ($cronfile && class_exists($cronfile)) {
|
||||
$cronfile::run();
|
||||
@@ -127,33 +145,13 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
* in case the admin installed new software which added a new user
|
||||
* so users in the database don't conflict with system users
|
||||
*/
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Checking system\'s last guid');
|
||||
\Froxlor\System\Cronjob::checkLastGuid();
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Checking system\'s last guid');
|
||||
Cronjob::checkLastGuid();
|
||||
|
||||
// shutdown cron
|
||||
self::shutdown();
|
||||
}
|
||||
|
||||
private static function refreshUsers($jobcount = 0)
|
||||
{
|
||||
if ($jobcount > 0) {
|
||||
if (\Froxlor\Settings::Get('system.nssextrausers') == 1) {
|
||||
\Froxlor\Cron\System\Extrausers::generateFiles(self::$cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
|
||||
if ((\Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1) && \Froxlor\Settings::Get('system.nssextrausers') == 0) {
|
||||
$false_val = false;
|
||||
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
|
||||
'>'
|
||||
));
|
||||
\Froxlor\FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, array(
|
||||
'>'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function init()
|
||||
{
|
||||
if (@php_sapi_name() != 'cli' && @php_sapi_name() != 'cgi' && @php_sapi_name() != 'cgi-fcgi') {
|
||||
@@ -168,8 +166,8 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
$basename = basename($_SERVER['PHP_SELF'], '.php');
|
||||
$crontype = "";
|
||||
if (isset(self::$argv) && is_array(self::$argv) && count(self::$argv) > 1) {
|
||||
for ($x = 1; $x < count(self::$argv); $x ++) {
|
||||
if (substr(self::$argv[$x], 0, 2) == '--' && strlen(self::$argv[$x]) > 3 && !in_array(substr(strtolower(self::$argv[$x]), 2),self::$noncron_params)) {
|
||||
for ($x = 1; $x < count(self::$argv); $x++) {
|
||||
if (substr(self::$argv[$x], 0, 2) == '--' && strlen(self::$argv[$x]) > 3 && !in_array(substr(strtolower(self::$argv[$x]), 2), self::$noncron_params)) {
|
||||
$crontype = substr(strtolower(self::$argv[$x]), 2);
|
||||
$basename .= "-" . $crontype;
|
||||
break;
|
||||
@@ -185,41 +183,41 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
// create and open the lockfile!
|
||||
self::$debugHandler = fopen($lockfile, 'w');
|
||||
fwrite(self::$debugHandler, 'Setting Lockfile to ' . $lockfile . "\n");
|
||||
fwrite(self::$debugHandler, 'Setting Froxlor installation path to ' . \Froxlor\Froxlor::getInstallDir() . "\n");
|
||||
fwrite(self::$debugHandler, 'Setting Froxlor installation path to ' . Froxlor::getInstallDir() . "\n");
|
||||
|
||||
if (! file_exists(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
|
||||
if (!file_exists(Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
|
||||
die("Froxlor does not seem to be installed yet - skipping cronjob");
|
||||
}
|
||||
|
||||
$sql = array();
|
||||
$sql_root = array();
|
||||
$sql = [];
|
||||
$sql_root = [];
|
||||
// Includes the Usersettings eg. MySQL-Username/Passwort etc.
|
||||
require \Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php';
|
||||
require Froxlor::getInstallDir() . '/lib/userdata.inc.php';
|
||||
fwrite(self::$debugHandler, 'Userdatas included' . "\n");
|
||||
|
||||
// Legacy sql-root-information
|
||||
if (isset($sql['root_user']) && isset($sql['root_password']) && (! isset($sql_root) || ! is_array($sql_root))) {
|
||||
$sql_root = array(
|
||||
0 => array(
|
||||
if (isset($sql['root_user']) && isset($sql['root_password']) && (!isset($sql_root) || !is_array($sql_root))) {
|
||||
$sql_root = [
|
||||
0 => [
|
||||
'caption' => 'Default',
|
||||
'host' => $sql['host'],
|
||||
'user' => $sql['root_user'],
|
||||
'password' => $sql['root_password']
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
unset($sql['root_user']);
|
||||
unset($sql['root_password']);
|
||||
}
|
||||
|
||||
// Includes the MySQL-Tabledefinitions etc.
|
||||
require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||
fwrite(self::$debugHandler, 'Table definitions included' . "\n");
|
||||
|
||||
// try database connection, it will throw
|
||||
// and exception itself if failed
|
||||
try {
|
||||
\Froxlor\Database\Database::query("SELECT 1");
|
||||
} catch (\Exception $e) {
|
||||
Database::query("SELECT 1");
|
||||
} catch (Exception $e) {
|
||||
// Do not proceed further if no database connection could be established
|
||||
fclose(self::$debugHandler);
|
||||
unlink($lockfile);
|
||||
@@ -232,7 +230,6 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
$lockDirHandle = opendir($lockdir);
|
||||
|
||||
while ($fName = readdir($lockDirHandle)) {
|
||||
|
||||
if ($lockFilename == substr($fName, 0, strlen($lockFilename)) && $lockfName != $fName) {
|
||||
// Check if last run jailed out with an exception
|
||||
$croncontent = file($lockdir . $fName);
|
||||
@@ -241,13 +238,13 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
if ($lastline == '=== Keep lockfile because of exception ===') {
|
||||
fclose(self::$debugHandler);
|
||||
unlink($lockfile);
|
||||
\Froxlor\System\Cronjob::dieWithMail('Last cron jailed out with an exception. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $fName . '* for more information!' . "\n");
|
||||
Cronjob::dieWithMail('Last cron jailed out with an exception. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $fName . '* for more information!' . "\n");
|
||||
}
|
||||
|
||||
// Check if cron is running or has died.
|
||||
$check_pid = substr(strrchr($fName, "-"), 1);
|
||||
$check_pid_return = null;
|
||||
system("kill -CHLD " . (int) $check_pid . " 1> /dev/null 2> /dev/null", $check_pid_return);
|
||||
system("kill -CHLD " . (int)$check_pid . " 1> /dev/null 2> /dev/null", $check_pid_return);
|
||||
|
||||
if ($check_pid_return == 1) {
|
||||
// Result: Existing lockfile/pid isn't running
|
||||
@@ -268,7 +265,7 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
// ... and delete it
|
||||
unlink($lockfile);
|
||||
\Froxlor\System\Cronjob::dieWithMail('There is already a Cronjob for ' . $crontype . ' in progress. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $lockFilename . '* for more information!' . "\n");
|
||||
Cronjob::dieWithMail('There is already a Cronjob for ' . $crontype . ' in progress. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $lockFilename . '* for more information!' . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,34 +275,34 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
* whether the permission of the files are still correct
|
||||
*/
|
||||
fwrite(self::$debugHandler, 'Checking froxlor file permissions' . "\n");
|
||||
$_mypath = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir());
|
||||
$_mypath = FileDir::makeCorrectDir(Froxlor::getInstallDir());
|
||||
|
||||
if (((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 && (int) \Froxlor\Settings::Get('system.mod_fcgid_ownvhost') == 1) || ((int) \Froxlor\Settings::Get('phpfpm.enabled') == 1 && (int) \Froxlor\Settings::Get('phpfpm.enabled_ownvhost') == 1)) {
|
||||
$user = \Froxlor\Settings::Get('system.mod_fcgid_httpuser');
|
||||
$group = \Froxlor\Settings::Get('system.mod_fcgid_httpgroup');
|
||||
if (((int)Settings::Get('system.mod_fcgid') == 1 && (int)Settings::Get('system.mod_fcgid_ownvhost') == 1) || ((int)Settings::Get('phpfpm.enabled') == 1 && (int)Settings::Get('phpfpm.enabled_ownvhost') == 1)) {
|
||||
$user = Settings::Get('system.mod_fcgid_httpuser');
|
||||
$group = Settings::Get('system.mod_fcgid_httpgroup');
|
||||
|
||||
if (\Froxlor\Settings::Get('phpfpm.enabled') == 1) {
|
||||
$user = \Froxlor\Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = \Froxlor\Settings::Get('phpfpm.vhost_httpgroup');
|
||||
if (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
}
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
} else {
|
||||
// back to webserver permission
|
||||
$user = \Froxlor\Settings::Get('system.httpuser');
|
||||
$group = \Froxlor\Settings::Get('system.httpgroup');
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
$user = Settings::Get('system.httpuser');
|
||||
$group = Settings::Get('system.httpgroup');
|
||||
FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
}
|
||||
|
||||
// Initialize logging
|
||||
self::$cronlog = \Froxlor\FroxlorLogger::getInstanceOf(array(
|
||||
self::$cronlog = FroxlorLogger::getInstanceOf([
|
||||
'loginname' => 'cronjob'
|
||||
));
|
||||
]);
|
||||
fwrite(self::$debugHandler, 'Logger has been included' . "\n");
|
||||
|
||||
if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) {
|
||||
if (\Froxlor\Settings::Get('system.cron_allowautoupdate') == null || \Froxlor\Settings::Get('system.cron_allowautoupdate') == 0) {
|
||||
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
|
||||
if (Settings::Get('system.cron_allowautoupdate') == null || Settings::Get('system.cron_allowautoupdate') == 0) {
|
||||
/**
|
||||
* Do not proceed further if the Database version is not the same as the script version
|
||||
*/
|
||||
@@ -313,26 +310,26 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
unlink($lockfile);
|
||||
$errormessage = "Version of file doesn't match version of database. Exiting...\n\n";
|
||||
$errormessage .= "Possible reason: Froxlor update\n";
|
||||
$errormessage .= "Information: Current version in database: " . \Froxlor\Settings::Get('panel.version') . (! empty(\Froxlor\Froxlor::BRANDING) ? "-" . \Froxlor\Froxlor::BRANDING : "") . " (DB: " . \Froxlor\Settings::Get('panel.db_version') . ") - version of Froxlor files: " . \Froxlor\Froxlor::getVersionString() . ")\n";
|
||||
$errormessage .= "Information: Current version in database: " . Settings::Get('panel.version') . (!empty(Froxlor::BRANDING) ? "-" . Froxlor::BRANDING : "") . " (DB: " . Settings::Get('panel.db_version') . ") - version of Froxlor files: " . Froxlor::getVersionString() . ")\n";
|
||||
$errormessage .= "Solution: Please visit your Foxlor admin interface for further information.\n";
|
||||
\Froxlor\System\Cronjob::dieWithMail($errormessage);
|
||||
Cronjob::dieWithMail($errormessage);
|
||||
}
|
||||
|
||||
if (\Froxlor\Settings::Get('system.cron_allowautoupdate') == 1) {
|
||||
if (Settings::Get('system.cron_allowautoupdate') == 1) {
|
||||
/**
|
||||
* let's walk the walk - do the dangerous shit
|
||||
*/
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, 'Automatic update is activated and we are going to proceed without any notices');
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, 'all new settings etc. will be stored with the default value, that might not always be right for your system!');
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, "If you don't want this to happen in the future consider removing the --allow-autoupdate flag from the cronjob");
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'Automatic update is activated and we are going to proceed without any notices');
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'all new settings etc. will be stored with the default value, that might not always be right for your system!');
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "If you don't want this to happen in the future consider removing the --allow-autoupdate flag from the cronjob");
|
||||
fwrite(self::$debugHandler, '*** WARNING *** - Automatic update is activated and we are going to proceed without any notices' . "\n");
|
||||
fwrite(self::$debugHandler, '*** WARNING *** - all new settings etc. will be stored with the default value, that might not always be right for your system!' . "\n");
|
||||
fwrite(self::$debugHandler, "*** WARNING *** - If you don't want this to happen in the future consider removing the --allow-autoupdate flag from the cronjob\n");
|
||||
// including update procedures
|
||||
define('_CRON_UPDATE', 1);
|
||||
include_once \Froxlor\Froxlor::getInstallDir() . '/install/updatesql.php';
|
||||
include_once Froxlor::getInstallDir() . '/install/updatesql.php';
|
||||
// pew - everything went better than expected
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, 'Automatic update done - you should check your settings to be sure everything is fine');
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'Automatic update done - you should check your settings to be sure everything is fine');
|
||||
fwrite(self::$debugHandler, '*** WARNING *** - Automatic update done - you should check your settings to be sure everything is fine' . "\n");
|
||||
}
|
||||
}
|
||||
@@ -340,35 +337,55 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
fwrite(self::$debugHandler, 'Froxlor version and database version are correct' . "\n");
|
||||
}
|
||||
|
||||
private static function shutdown()
|
||||
{
|
||||
// check for cron.d-generation task and create it if necessary
|
||||
\Froxlor\Cron\CronConfig::checkCrondConfigurationFile();
|
||||
|
||||
if (\Froxlor\Settings::Get('logger.log_cron') == '1') {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->setCronLog(0);
|
||||
fwrite(self::$debugHandler, 'Logging for cron has been shutdown' . "\n");
|
||||
}
|
||||
|
||||
fclose(self::$debugHandler);
|
||||
|
||||
if (\Froxlor\Settings::Get('system.debug_cron') != '1') {
|
||||
unlink(self::getLockfile());
|
||||
}
|
||||
}
|
||||
|
||||
private static function getCronModule($cronname)
|
||||
{
|
||||
$upd_stmt = Database::prepare("
|
||||
SELECT `cronclass` FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `cronfile` = :cron;
|
||||
");
|
||||
$cron = Database::pexecute_first($upd_stmt, array(
|
||||
$cron = Database::pexecute_first($upd_stmt, [
|
||||
'cron' => $cronname
|
||||
));
|
||||
]);
|
||||
if ($cron) {
|
||||
return $cron['cronclass'];
|
||||
}
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, "Requested cronjob '" . $cronname . "' could not be found.");
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Requested cronjob '" . $cronname . "' could not be found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function refreshUsers($jobcount = 0)
|
||||
{
|
||||
if ($jobcount > 0) {
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
Extrausers::generateFiles(self::$cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) && Settings::Get('system.nssextrausers') == 0) {
|
||||
$false_val = false;
|
||||
FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
]);
|
||||
FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function shutdown()
|
||||
{
|
||||
// check for cron.d-generation task and create it if necessary
|
||||
CronConfig::checkCrondConfigurationFile();
|
||||
|
||||
if (Settings::Get('logger.log_cron') == '1') {
|
||||
FroxlorLogger::getInstanceOf()->setCronLog(0);
|
||||
fwrite(self::$debugHandler, 'Logging for cron has been shutdown' . "\n");
|
||||
}
|
||||
|
||||
fclose(self::$debugHandler);
|
||||
|
||||
if (Settings::Get('system.debug_cron') != '1') {
|
||||
unlink(self::getLockfile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\FroxlorLogger;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* @since 0.9.35.1
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class BackupCron extends FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
// Check Traffic-Lock
|
||||
if (function_exists('pcntl_fork')) {
|
||||
$BackupLock = \Froxlor\FileDir::makeCorrectFile(dirname(self::getLockfile()) . "/froxlor_cron_backup.lock");
|
||||
$BackupLock = FileDir::makeCorrectFile(dirname(self::getLockfile()) . "/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);
|
||||
@@ -38,7 +47,7 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
$BackupPidStatus = !$BackupPidStatus;
|
||||
}
|
||||
if ($BackupPidStatus) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Backup run already in progress');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Backup run already in progress');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -66,10 +75,10 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
} else {
|
||||
$msg = "PHP compiled without pcntl.";
|
||||
}
|
||||
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, $msg . " Not forking backup-cron, this may take a long time!");
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, $msg . " Not forking backup-cron, this may take a long time!");
|
||||
}
|
||||
|
||||
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'BackupCron: started - creating customer backup');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'BackupCron: started - creating customer backup');
|
||||
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20' ORDER BY `id` ASC
|
||||
@@ -80,21 +89,19 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
$cronlog = FroxlorLogger::getInstanceOf();
|
||||
$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'] = \Froxlor\FileDir::makeCorrectDir($row['data']['destdir']);
|
||||
$customerdocroot = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$row['data']['destdir'] = FileDir::makeCorrectDir($row['data']['destdir']);
|
||||
$customerdocroot = FileDir::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) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating backup-destination path for customer: ' . escapeshellarg($row['data']['destdir']));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($row['data']['destdir']));
|
||||
if (!file_exists($row['data']['destdir']) && $row['data']['destdir'] != '/' && $row['data']['destdir'] != Settings::Get('system.documentroot_prefix') && $row['data']['destdir'] != $customerdocroot) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating backup-destination path for customer: ' . escapeshellarg($row['data']['destdir']));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($row['data']['destdir']));
|
||||
}
|
||||
|
||||
self::createCustomerBackup($row['data'], $customerdocroot, $cronlog);
|
||||
@@ -102,9 +109,9 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
}
|
||||
|
||||
// remove entry
|
||||
Database::pexecute($del_stmt, array(
|
||||
Database::pexecute($del_stmt, [
|
||||
'id' => $row['id']
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
if (function_exists('pcntl_fork')) {
|
||||
@@ -123,27 +130,26 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
*/
|
||||
private static function createCustomerBackup($data = null, $customerdocroot = null, &$cronlog = null)
|
||||
{
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating Backup for user "' . $data['loginname'] . '"');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating Backup for user "' . $data['loginname'] . '"');
|
||||
|
||||
// create tmp folder
|
||||
$tmpdir = \Froxlor\FileDir::makeCorrectDir($data['destdir'] . '/.tmp/');
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating tmp-folder "' . $tmpdir . '"');
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
$tmpdir = FileDir::makeCorrectDir($data['destdir'] . '/.tmp/');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating tmp-folder "' . $tmpdir . '"');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
$create_backup_tar_data = "";
|
||||
|
||||
// MySQL databases
|
||||
if ($data['backup_dbs'] == 1) {
|
||||
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating mysql-folder "' . \Froxlor\FileDir::makeCorrectDir($tmpdir . '/mysql') . '"');
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir($tmpdir . '/mysql')));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir($tmpdir . '/mysql')));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating mysql-folder "' . FileDir::makeCorrectDir($tmpdir . '/mysql') . '"');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/mysql')));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/mysql')));
|
||||
|
||||
// get all customer database-names
|
||||
$sel_stmt = Database::prepare("SELECT `databasename` FROM `" . TABLE_PANEL_DATABASES . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
Database::pexecute($sel_stmt, [
|
||||
'cid' => $data['customerid']
|
||||
));
|
||||
]);
|
||||
|
||||
Database::needRoot(true);
|
||||
Database::needSqlData();
|
||||
@@ -152,11 +158,11 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
$has_dbs = false;
|
||||
while ($row = $sel_stmt->fetch()) {
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . \Froxlor\FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
|
||||
$bool_false = false;
|
||||
\Froxlor\FileDir::safe_exec('mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -p' . $sql_root['passwd'] . ' ' . $row['databasename'] . ' > ' . \Froxlor\FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, array(
|
||||
FileDir::safe_exec('mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -p' . $sql_root['passwd'] . ' ' . $row['databasename'] . ' > ' . FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, [
|
||||
'>'
|
||||
));
|
||||
]);
|
||||
$has_dbs = true;
|
||||
}
|
||||
|
||||
@@ -169,15 +175,14 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
// E-mail data
|
||||
if ($data['backup_mail'] == 1) {
|
||||
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating mail-folder "' . \Froxlor\FileDir::makeCorrectDir($tmpdir . '/mail') . '"');
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir($tmpdir . '/mail')));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating mail-folder "' . FileDir::makeCorrectDir($tmpdir . '/mail') . '"');
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/mail')));
|
||||
|
||||
// get all customer mail-accounts
|
||||
$sel_stmt = Database::prepare("SELECT `homedir`, `maildir` FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
Database::pexecute($sel_stmt, [
|
||||
'cid' => $data['customerid']
|
||||
));
|
||||
]);
|
||||
|
||||
$tar_file_list = "";
|
||||
$mail_homedir = "";
|
||||
@@ -186,38 +191,37 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
$mail_homedir = $row['homedir'];
|
||||
}
|
||||
|
||||
if (! empty($tar_file_list)) {
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
\Froxlor\FileDir::safe_exec('tar cfz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
if (!empty($tar_file_list)) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
$create_backup_tar_data .= './mail ';
|
||||
}
|
||||
}
|
||||
|
||||
// Web data
|
||||
if ($data['backup_web'] == 1) {
|
||||
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating web-folder "' . \Froxlor\FileDir::makeCorrectDir($tmpdir . '/web') . '"');
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir($tmpdir . '/web')));
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", \Froxlor\FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(\Froxlor\FileDir::makeCorrectDir($tmpdir), 0, - 1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
\Froxlor\FileDir::safe_exec('tar cfz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", \Froxlor\FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(\Froxlor\FileDir::makeCorrectFile($tmpdir), 0, - 1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating web-folder "' . FileDir::makeCorrectDir($tmpdir . '/web') . '"');
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/web')));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(FileDir::makeCorrectDir($tmpdir), 0, -1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(FileDir::makeCorrectFile($tmpdir), 0, -1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
$create_backup_tar_data .= './web ';
|
||||
}
|
||||
|
||||
if (! empty($create_backup_tar_data)) {
|
||||
$backup_file = \Froxlor\FileDir::makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-backup_' . date('YmdHi', time()) . '.tar.gz');
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating backup-file "' . $backup_file . '"');
|
||||
if (!empty($create_backup_tar_data)) {
|
||||
$backup_file = FileDir::makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-backup_' . date('YmdHi', time()) . '.tar.gz');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating backup-file "' . $backup_file . '"');
|
||||
// pack all archives in tmp-dir to one
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
\Froxlor\FileDir::safe_exec('tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
// move to destination directory
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
\Froxlor\FileDir::safe_exec('mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
FileDir::safe_exec('mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
// remove tmp-files
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> rm -rf ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> rm -rf ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
// set owner to customer
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> chown -R ' . (int) $data['uid'] . ':' . (int) $data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . (int) $data['uid'] . ':' . (int) $data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
FileDir::safe_exec('chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2017 the Froxlor 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2017-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Customer\Customer;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\User;
|
||||
use PDO;
|
||||
|
||||
class Extrausers
|
||||
{
|
||||
|
||||
@@ -49,27 +63,27 @@ class Extrausers
|
||||
private static function generateFile($file, $query, &$cronlog, &$result_list = null)
|
||||
{
|
||||
$type = basename($file);
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating ' . $type . ' file');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating ' . $type . ' file');
|
||||
|
||||
if (! file_exists($file)) {
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, $type . ' file does not yet exist');
|
||||
if (!file_exists($file)) {
|
||||
$cronlog->logAction(FroxlorLogger::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(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Writing ' . $data_sel_stmt->rowCount() . ' entries to ' . $type . ' file');
|
||||
while ($u = $data_sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$cronlog->logAction(FroxlorLogger::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':
|
||||
// get user real name
|
||||
$salutation_array = array(
|
||||
'firstname' => \Froxlor\Customer\Customer::getCustomerDetail($u['customerid'], 'firstname'),
|
||||
'name' => \Froxlor\Customer\Customer::getCustomerDetail($u['customerid'], 'name'),
|
||||
'company' => \Froxlor\Customer\Customer::getCustomerDetail($u['customerid'], 'company')
|
||||
);
|
||||
$u['comment'] = self::cleanString(\Froxlor\User::getCorrectUserSalutation($salutation_array));
|
||||
$salutation_array = [
|
||||
'firstname' => Customer::getCustomerDetail($u['customerid'], 'firstname'),
|
||||
'name' => Customer::getCustomerDetail($u['customerid'], 'name'),
|
||||
'company' => Customer::getCustomerDetail($u['customerid'], 'company')
|
||||
];
|
||||
$u['comment'] = self::cleanString(User::getCorrectUserSalutation($salutation_array));
|
||||
if ($u['login_enabled'] != 'Y') {
|
||||
$u['password'] = '*';
|
||||
$u['shell'] = '/bin/false';
|
||||
@@ -103,9 +117,9 @@ class Extrausers
|
||||
}
|
||||
|
||||
if (file_put_contents($file, $data_content) !== false) {
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Succesfully wrote ' . $type . ' file');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Succesfully wrote ' . $type . ' file');
|
||||
} else {
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Error when writing ' . $type . ' file entries');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Error when writing ' . $type . ' file entries');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +1,61 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
class MailboxsizeCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
class MailboxsizeCron extends FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'calculating mailspace usage');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'calculating mailspace usage');
|
||||
|
||||
$maildirs_stmt = \Froxlor\Database\Database::query("
|
||||
$maildirs_stmt = Database::query("
|
||||
SELECT `id`, CONCAT(`homedir`, `maildir`) AS `maildirpath` FROM `" . TABLE_MAIL_USERS . "` ORDER BY `id`
|
||||
");
|
||||
|
||||
$upd_stmt = \Froxlor\Database\Database::prepare("
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_USERS . "` SET `mboxsize` = :size WHERE `id` = :id
|
||||
");
|
||||
|
||||
while ($maildir = $maildirs_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$_maildir = \Froxlor\FileDir::makeCorrectDir($maildir['maildirpath']);
|
||||
while ($maildir = $maildirs_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$_maildir = FileDir::makeCorrectDir($maildir['maildirpath']);
|
||||
|
||||
if (file_exists($_maildir) && is_dir($_maildir)) {
|
||||
$maildirsize = \Froxlor\FileDir::makeCorrectFile($_maildir . '/maildirsize');
|
||||
|
||||
$maildirsize = FileDir::makeCorrectFile($_maildir . '/maildirsize');
|
||||
|
||||
// When quota is enabled and maildirsize file exists, use that to calculate size
|
||||
if (\Froxlor\Settings::Get('system.mail_quota_enabled') == 1 && file_exists($maildirsize)) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'found maildirsize file in ' . $_maildir);
|
||||
if (Settings::Get('system.mail_quota_enabled') == 1 && file_exists($maildirsize)) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'found maildirsize file in ' . $_maildir);
|
||||
$file = file($maildirsize, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
// Remove header
|
||||
array_shift($file);
|
||||
@@ -58,14 +71,14 @@ class MailboxsizeCron extends \Froxlor\Cron\FroxlorCron
|
||||
// if quota is disabled or maildirsize file does not exist, compute with du
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
$back = \Froxlor\FileDir::safe_exec('du -sk ' . escapeshellarg($_maildir), $return, array(
|
||||
$back = FileDir::safe_exec('du -sk ' . escapeshellarg($_maildir), $return, [
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'~',
|
||||
'?'
|
||||
));
|
||||
]);
|
||||
foreach ($back as $backrow) {
|
||||
$emailusage = explode(' ', $backrow);
|
||||
}
|
||||
@@ -77,12 +90,12 @@ class MailboxsizeCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
unset($back);
|
||||
}
|
||||
\Froxlor\Database\Database::pexecute($upd_stmt, array(
|
||||
Database::pexecute($upd_stmt, [
|
||||
'size' => $emailusage,
|
||||
'id' => $maildir['id']
|
||||
));
|
||||
]);
|
||||
} else {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, 'maildir ' . $_maildir . ' does not exist');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'maildir ' . $_maildir . ' does not exist');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
use Froxlor\Cron\TaskId;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Cron\Http\ConfigIO;
|
||||
use Froxlor\Cron\TaskId;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Dns\PowerDNS;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
class TasksCron extends FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
@@ -30,17 +44,16 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
/**
|
||||
* LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS
|
||||
*/
|
||||
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do");
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do");
|
||||
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
|
||||
// order by type descending to re-create bind and then webserver at the end
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `type` DESC, `id` ASC
|
||||
");
|
||||
$num_results = Database::num_rows();
|
||||
$resultIDs = array();
|
||||
|
||||
while ($row = $result_tasks_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$resultIDs = [];
|
||||
|
||||
while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$resultIDs[] = $row['id'];
|
||||
|
||||
if ($row['data'] != '') {
|
||||
@@ -57,7 +70,7 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
* TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN
|
||||
*/
|
||||
self::createNewHome($row);
|
||||
} elseif ($row['type'] == TaskId::REBUILD_DNS && (int) Settings::Get('system.bind_enable') != 0) {
|
||||
} elseif ($row['type'] == TaskId::REBUILD_DNS && (int)Settings::Get('system.bind_enable') != 0) {
|
||||
/**
|
||||
* TYPE=4 MEANS THAT SOMETHING IN THE BIND CONFIG HAS CHANGED.
|
||||
* REBUILD froxlor_bind.conf IF BIND IS ENABLED
|
||||
@@ -84,7 +97,7 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
* refs #293
|
||||
*/
|
||||
self::deleteFtpData($row);
|
||||
} elseif ($row['type'] == TaskId::CREATE_QUOTA && (int) Settings::Get('system.diskquota_enabled') != 0) {
|
||||
} elseif ($row['type'] == TaskId::CREATE_QUOTA && (int)Settings::Get('system.diskquota_enabled') != 0) {
|
||||
/**
|
||||
* TYPE=10 Set the filesystem - quota
|
||||
*/
|
||||
@@ -93,22 +106,22 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
/**
|
||||
* TYPE=11 domain has been deleted, remove from pdns database if used
|
||||
*/
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
|
||||
\Froxlor\Dns\PowerDNS::cleanDomainZone($row['data']['domain']);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
|
||||
PowerDNS::cleanDomainZone($row['data']['domain']);
|
||||
} elseif ($row['type'] == TaskId::DELETE_DOMAIN_SSL) {
|
||||
/**
|
||||
* TYPE=12 domain has been deleted, remove from acme.sh/let's encrypt directory if used
|
||||
*/
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing Let's Encrypt entries for domain " . $row['data']['domain']);
|
||||
\Froxlor\Domain\Domain::doLetsEncryptCleanUp($row['data']['domain']);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing Let's Encrypt entries for domain " . $row['data']['domain']);
|
||||
Domain::doLetsEncryptCleanUp($row['data']['domain']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($num_results != 0) {
|
||||
$where = array();
|
||||
$where_data = array();
|
||||
$where = [];
|
||||
$where_data = [];
|
||||
foreach ($resultIDs as $id) {
|
||||
$where[] = "`id` = :id_" . (int) $id;
|
||||
$where[] = "`id` = :id_" . (int)$id;
|
||||
$where_data['id_' . $id] = $id;
|
||||
}
|
||||
$where = implode(' OR ', $where);
|
||||
@@ -123,7 +136,6 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function rebuildWebserverConfigs()
|
||||
{
|
||||
|
||||
if (Settings::Get('system.webserver') == "apache2") {
|
||||
$websrv = '\\Froxlor\\Cron\\Http\\Apache';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
@@ -142,7 +154,7 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
}
|
||||
|
||||
// get configuration-I/O object
|
||||
$configio = new \Froxlor\Cron\Http\ConfigIO();
|
||||
$configio = new ConfigIO();
|
||||
// get webserver object
|
||||
$webserver = new $websrv();
|
||||
|
||||
@@ -167,12 +179,12 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
// 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'])) {
|
||||
if (isset($groupinfo['members']) && !in_array(Settings::Get('system.httpuser'), $groupinfo['members'])) {
|
||||
// webserver has no access, add it
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
\Froxlor\FileDir::safe_exec('pw usermod ' . escapeshellarg(Settings::Get('system.httpuser')) . ' -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')));
|
||||
if (FileDir::isFreeBSD()) {
|
||||
FileDir::safe_exec('pw usermod ' . escapeshellarg(Settings::Get('system.httpuser')) . ' -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')));
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec('usermod -a -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')) . ' ' . escapeshellarg(Settings::Get('system.httpuser')));
|
||||
FileDir::safe_exec('usermod -a -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')) . ' ' . escapeshellarg(Settings::Get('system.httpuser')));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,73 +196,73 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function createNewHome($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task2 started - create new home');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task2 started - create new home');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
// define paths
|
||||
$userhomedir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$usermaildir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/');
|
||||
$userhomedir = FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$usermaildir = FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
// stats directory
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
FileDir::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')) {
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
}
|
||||
} else {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
FileDir::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')) {
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
}
|
||||
}
|
||||
|
||||
// maildir
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($usermaildir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
||||
FileDir::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) {
|
||||
\Froxlor\FileDir::storeDefaultIndex($row['data']['loginname'], $userhomedir, \Froxlor\FroxlorLogger::getInstanceOf(), true);
|
||||
if ((int)$row['data']['store_defaultindex'] == 1) {
|
||||
FileDir::storeDefaultIndex($row['data']['loginname'], $userhomedir, FroxlorLogger::getInstanceOf(), 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;
|
||||
$userhomedir = (substr($userhomedir, 0, -1) == '/') ? substr($userhomedir, 0, -1) : $userhomedir;
|
||||
$usermaildir = (substr($usermaildir, 0, -1) == '/') ? substr($usermaildir, 0, -1) : $usermaildir;
|
||||
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int) $row['data']['uid'] . ':' . (int) $row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . (int) $row['data']['uid'] . ':' . (int) $row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
FileDir::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
|
||||
\Froxlor\FileDir::safe_exec('chmod 0750 ' . escapeshellarg($userhomedir));
|
||||
FileDir::safe_exec('chmod 0750 ' . escapeshellarg($userhomedir));
|
||||
} else {
|
||||
// mod_php -> no libnss-mysql -> no webserver-user in group
|
||||
\Froxlor\FileDir::safe_exec('chmod 0755 ' . escapeshellarg($userhomedir));
|
||||
FileDir::safe_exec('chmod 0755 ' . escapeshellarg($userhomedir));
|
||||
}
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int) Settings::Get('system.vmail_uid') . ':' . (int) Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . (int) Settings::Get('system.vmail_uid') . ':' . (int) Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)Settings::Get('system.vmail_uid') . ':' . (int)Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
FileDir::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
|
||||
$extrausers_log = \Froxlor\FroxlorLogger::getInstanceOf();
|
||||
$extrausers_log = FroxlorLogger::getInstanceOf();
|
||||
Extrausers::generateFiles($extrausers_log);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) && Settings::Get('system.nssextrausers') == 0) {
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) && Settings::Get('system.nssextrausers') == 0) {
|
||||
$false_val = false;
|
||||
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
|
||||
FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
));
|
||||
\Froxlor\FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, array(
|
||||
]);
|
||||
FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,7 +271,7 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
$dnssrv = '\\Froxlor\\Cron\\Dns\\' . Settings::Get('system.dns_server');
|
||||
|
||||
$nameserver = new $dnssrv(\Froxlor\FroxlorLogger::getInstanceOf());
|
||||
$nameserver = new $dnssrv(FroxlorLogger::getInstanceOf());
|
||||
|
||||
if (Settings::Get('dkim.use_dkim') == '1') {
|
||||
$nameserver->writeDKIMconfigs();
|
||||
@@ -270,62 +282,62 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function createNewFtpHome($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating new FTP-home');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::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)) {
|
||||
\Froxlor\FileDir::mkDirWithCorrectOwnership($directory['customerroot'], $directory['homedir'], $directory['uid'], $directory['gid']);
|
||||
while ($directory = $result_directories_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
FileDir::mkDirWithCorrectOwnership($directory['customerroot'], $directory['homedir'], $directory['uid'], $directory['gid']);
|
||||
}
|
||||
}
|
||||
|
||||
private static function deleteCustomerData($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task6 started - deleting customer data');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task6 started - deleting customer data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
if (isset($row['data']['loginname'])) {
|
||||
// remove homedir
|
||||
$homedir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname']);
|
||||
$homedir = FileDir::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')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($homedir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($homedir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($homedir));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($homedir));
|
||||
}
|
||||
|
||||
// remove maildir
|
||||
$maildir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname']);
|
||||
$maildir = FileDir::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')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::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;
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir), $return, array(
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir), $return, [
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'?'
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
// remove tmpdir if it exists
|
||||
$tmpdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $row['data']['loginname'] . '/');
|
||||
$tmpdir = FileDir::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')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
// webserver logs
|
||||
$logsdir = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.logfiles_directory') . '/' . $row['data']['loginname']);
|
||||
$logsdir = FileDir::makeCorrectFile(Settings::Get('system.logfiles_directory') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($logsdir) && $logsdir != '/' && $logsdir != \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.logfiles_directory')) && substr($logsdir, 0, strlen(Settings::Get('system.logfiles_directory'))) == Settings::Get('system.logfiles_directory')) {
|
||||
if (file_exists($logsdir) && $logsdir != '/' && $logsdir != FileDir::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{*}
|
||||
$logsdir .= '-*';
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg($logsdir));
|
||||
FileDir::safe_exec('rm -f ' . escapeshellarg($logsdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,55 +345,54 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function deleteEmailData($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task7 started - deleting customer e-mail data');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: 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)) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, 'FATAL: Task7 asks to delete a email account but email field is empty!');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, '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) != "/") {
|
||||
if (!empty($maildirname) and substr($maildirname, -1) != "/") {
|
||||
$maildirpath .= "/";
|
||||
}
|
||||
|
||||
$maildir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $email_domain . '/' . $email_user);
|
||||
$maildir = FileDir::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(\Froxlor\FileDir::makeCorrectDir($maildir . '/' . $maildirpath)) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
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(FileDir::makeCorrectDir($maildir . '/' . $maildirpath)) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::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;
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir), $return, array(
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir), $return, [
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'~',
|
||||
'?'
|
||||
));
|
||||
]);
|
||||
} else {
|
||||
// backward-compatibility for old folder-structure
|
||||
$maildir_old = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $row['data']['email']);
|
||||
$maildir_old = FileDir::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')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir_old));
|
||||
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')) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::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;
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir_old), $return, array(
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir_old), $return, [
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'~',
|
||||
'?'
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,18 +401,17 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function deleteFtpData($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task8 started - deleting customer ftp homedir');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task8 started - deleting customer ftp homedir');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname']) && isset($row['data']['homedir'])) {
|
||||
// remove specific homedir
|
||||
$ftphomedir = \Froxlor\FileDir::makeCorrectDir($row['data']['homedir']);
|
||||
$customerdocroot = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$ftphomedir = FileDir::makeCorrectDir($row['data']['homedir']);
|
||||
$customerdocroot = FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
if (file_exists($ftphomedir) && $ftphomedir != '/' && $ftphomedir != Settings::Get('system.documentroot_prefix') && $ftphomedir != $customerdocroot) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($ftphomedir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($ftphomedir));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($ftphomedir));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($ftphomedir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,33 +419,33 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function setFilesystemQuota()
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task10 started - setting filesystem quota');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task10 started - setting filesystem quota');
|
||||
|
||||
$usedquota = \Froxlor\FileDir::getFilesystemQuota();
|
||||
$usedquota = FileDir::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)) {
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// We do not want to set a quota for root by accident
|
||||
if ($row['guid'] != 0) {
|
||||
$used_quota = isset($usedquota[$row['guid']]) ? $usedquota[$row['guid']]['block']['hard'] : 0;
|
||||
// The user has no quota in Froxlor, but on the filesystem
|
||||
if (($row['diskspace'] == 0 || $row['diskspace'] == - 1024) && $used_quota != 0) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']);
|
||||
if (($row['diskspace'] == 0 || $row['diskspace'] == -1024) && $used_quota != 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
|
||||
if (FileDir::isFreeBSD()) {
|
||||
FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']);
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
} elseif ($row['diskspace'] != $used_quota && $row['diskspace'] != - 1024) {
|
||||
} elseif ($row['diskspace'] != $used_quota && $row['diskspace'] != -1024) {
|
||||
// The user quota in Froxlor is different than on the filesystem
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $used_quota . " to " . $row['diskspace']);
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $used_quota . " to " . $row['diskspace']);
|
||||
if (FileDir::isFreeBSD()) {
|
||||
FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']);
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
use ReflectionClass;
|
||||
|
||||
class TaskId {
|
||||
class TaskId
|
||||
{
|
||||
/**
|
||||
* TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF
|
||||
*/
|
||||
@@ -52,33 +77,35 @@ class TaskId {
|
||||
const DELETE_DOMAIN_PDNS = 11;
|
||||
|
||||
/**
|
||||
* TYPE=12 domain has been deleted, remove from acme.sh/let's encrypt directory if used
|
||||
* TYPE=12 domain has been deleted, remove from acme.sh/let's encrypt directory if used
|
||||
*/
|
||||
const DELETE_DOMAIN_SSL = 12;
|
||||
|
||||
/**
|
||||
* TYPE=20 COSTUMERBACKUP
|
||||
* TYPE=20 COSTUMERBACKUP
|
||||
*/
|
||||
const CREATE_CUSTOMER_BACKUP = 20;
|
||||
|
||||
/**
|
||||
* TYPE=99 REGENERATE CRON
|
||||
* TYPE=99 REGENERATE CRON
|
||||
*/
|
||||
const REBUILD_CRON = 99;
|
||||
|
||||
/**
|
||||
* Return if a cron task id is valid
|
||||
*
|
||||
* @param int|string $id cron task id (legacy string support)
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isValid($id) {
|
||||
public static function isValid($id)
|
||||
{
|
||||
static $reflContants;
|
||||
if (!is_numeric($id)) {
|
||||
return false;
|
||||
}
|
||||
$numericid = (int)$id;
|
||||
if (!is_array($reflContants)) {
|
||||
$reflClass = new \ReflectionClass(get_called_class());
|
||||
$reflClass = new ReflectionClass(get_called_class());
|
||||
$reflContants = $reflClass->getConstants();
|
||||
}
|
||||
return in_array($numericid, $reflContants, true);
|
||||
@@ -86,20 +113,21 @@ class TaskId {
|
||||
|
||||
/**
|
||||
* Get constant name by id
|
||||
*
|
||||
* @param int|string $id cron task id (legacy string support)
|
||||
* @return string|false constant name or false if not found
|
||||
*/
|
||||
public static function convertToConstant($id) {
|
||||
public static function convertToConstant($id)
|
||||
{
|
||||
static $reflContants;
|
||||
if (!is_numeric($id)) {
|
||||
return false;
|
||||
}
|
||||
$numericid = (int)$id;
|
||||
if (!is_array($reflContants)) {
|
||||
$reflClass = new \ReflectionClass(get_called_class());
|
||||
$reflClass = new ReflectionClass(get_called_class());
|
||||
$reflContants = $reflClass->getConstants();
|
||||
}
|
||||
return array_search($numericid, $reflContants, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +1,61 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Traffic;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* @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
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
namespace Froxlor\Cron\Traffic;
|
||||
|
||||
/**
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
*/
|
||||
|
||||
use Exception;
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\System\Mailer;
|
||||
use Froxlor\User;
|
||||
use PDO;
|
||||
|
||||
class ReportsCron extends FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Web- and Traffic-usage reporting started...');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Web- and Traffic-usage reporting started...');
|
||||
$yesterday = time() - (60 * 60 * 24);
|
||||
|
||||
/**
|
||||
* Initialize the mailingsystem
|
||||
*/
|
||||
$mail = new \Froxlor\System\Mailer(true);
|
||||
$mail = new Mailer(true);
|
||||
|
||||
if ((int) Settings::Get('system.report_trafficmax') > 0) {
|
||||
if ((int)Settings::Get('system.report_trafficmax') > 0) {
|
||||
// Warn the customers at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `c`.`customerid`, `c`.`customernumber`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
||||
@@ -48,54 +70,56 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
ON `a`.`adminid` = `c`.`adminid` WHERE `c`.`reportsent` <> '1'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
$result_data = [
|
||||
'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(
|
||||
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 = [
|
||||
'name' => $row['name'],
|
||||
'firstname' => $row['firstname'],
|
||||
'company' => $row['company'],
|
||||
'customernumber' => $row['customernumber']
|
||||
);
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($rep_userinfo),
|
||||
];
|
||||
$replace_arr = [
|
||||
'SALUTATION' => User::getCorrectUserSalutation($rep_userinfo),
|
||||
'NAME' => $rep_userinfo['name'],
|
||||
'FIRSTNAME' => $rep_userinfo['firstname'],
|
||||
'COMPANY' => $rep_userinfo['company'],
|
||||
'CUSTOMER_NO' => $rep_userinfo['customernumber'],
|
||||
'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 */
|
||||
'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(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => $row['def_language']
|
||||
));
|
||||
]);
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => Settings::Get('panel.standardlanguage')
|
||||
));
|
||||
]);
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
if ($lngfile != 'lng/english.lng.php') {
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/' . $langfile);
|
||||
}
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
@@ -105,17 +129,17 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
$result2_data = [
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
];
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
$mail_subject = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $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(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
|
||||
$mail_body = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
@@ -129,13 +153,13 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
echo 'Error sending mail: ' . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
@@ -144,9 +168,9 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '1'
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
Database::pexecute($upd_stmt, [
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
]);
|
||||
|
||||
unset($lng);
|
||||
}
|
||||
@@ -162,46 +186,46 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` = '0'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
$result_data = [
|
||||
'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(
|
||||
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 = [
|
||||
'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 */
|
||||
'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(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => $row['def_language']
|
||||
));
|
||||
]);
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => Settings::Get('panel.standardlanguage')
|
||||
));
|
||||
]);
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
if ($lngfile != 'lng/english.lng.php') {
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/' . $langfile);
|
||||
}
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
@@ -211,17 +235,17 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
$result2_data = [
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
];
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
$mail_subject = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $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(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
|
||||
$mail_body = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
@@ -235,13 +259,13 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
@@ -250,14 +274,13 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '1'
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
Database::pexecute($upd_stmt, [
|
||||
'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";
|
||||
@@ -270,14 +293,14 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `c`.`adminid` = :adminid
|
||||
");
|
||||
$customers_data = array(
|
||||
$customers_data = [
|
||||
'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)) {
|
||||
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']);
|
||||
@@ -320,13 +343,13 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
echo 'Error sending mail: ' . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
@@ -349,7 +372,7 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static function usageDiskspace()
|
||||
{
|
||||
if ((int) Settings::Get('system.report_webmax') > 0) {
|
||||
if ((int)Settings::Get('system.report_webmax') > 0) {
|
||||
/**
|
||||
* report about diskusage for customers
|
||||
*/
|
||||
@@ -363,52 +386,52 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
WHERE `c`.`diskspace` > '0' AND `c`.`reportsent` <> '2'
|
||||
");
|
||||
|
||||
$mail = new \Froxlor\System\Mailer(true);
|
||||
$mail = new Mailer(true);
|
||||
|
||||
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(
|
||||
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 = [
|
||||
'name' => $row['name'],
|
||||
'firstname' => $row['firstname'],
|
||||
'company' => $row['company'],
|
||||
'customernumber' => $row['customernumber']
|
||||
);
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($rep_userinfo),
|
||||
];
|
||||
$replace_arr = [
|
||||
'SALUTATION' => User::getCorrectUserSalutation($rep_userinfo),
|
||||
'NAME' => $rep_userinfo['name'],
|
||||
'FIRSTNAME' => $rep_userinfo['firstname'],
|
||||
'COMPANY' => $rep_userinfo['company'],
|
||||
'CUSTOMER_NO' => $rep_userinfo['customernumber'],
|
||||
'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 */
|
||||
'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(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => $row['def_language']
|
||||
));
|
||||
]);
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => Settings::Get('panel.standardlanguage')
|
||||
));
|
||||
]);
|
||||
$langfile = $lngfile['file'] ?? 'lng/english.lng.php';
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
if ($lngfile != 'lng/english.lng.php') {
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/' . $langfile);
|
||||
}
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
@@ -418,17 +441,17 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
$result2_data = [
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'diskmaxpercent_subject'
|
||||
);
|
||||
];
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
||||
$mail_subject = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $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(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||
$mail_body = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
@@ -442,13 +465,13 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
@@ -457,9 +480,9 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '2'
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
Database::pexecute($upd_stmt, [
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
]);
|
||||
|
||||
unset($lng);
|
||||
}
|
||||
@@ -472,40 +495,40 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
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(
|
||||
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 = [
|
||||
'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 */
|
||||
'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(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => $row['def_language']
|
||||
));
|
||||
]);
|
||||
|
||||
if ($lngfile !== null) {
|
||||
$langfile = $lngfile['file'];
|
||||
} else {
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||
$lngfile = Database::pexecute_first($lngfile_stmt, [
|
||||
'deflang' => Settings::Get('panel.standardlanguage')
|
||||
));
|
||||
]);
|
||||
$langfile = $lngfile['file'];
|
||||
}
|
||||
|
||||
// include english language file (fallback)
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
if ($lngfile != 'lng/english.lng.php') {
|
||||
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
||||
include FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/' . $langfile);
|
||||
}
|
||||
|
||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||
@@ -515,17 +538,17 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
AND `language` = :lang
|
||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||
");
|
||||
$result2_data = array(
|
||||
$result2_data = [
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'diskmaxpercent_subject'
|
||||
);
|
||||
];
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
||||
$mail_subject = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $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(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||
$mail_body = html_entity_decode(PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
@@ -539,13 +562,13 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
@@ -554,9 +577,9 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '2'
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
Database::pexecute($upd_stmt, [
|
||||
'adminid' => $row['adminid']
|
||||
));
|
||||
]);
|
||||
|
||||
unset($lng);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user