(2003-2009) * @author Froxlor team (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt * @package Cron * */ /* * necessary includes */ require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.dns.10.bind.php')); require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.10.apache.php')); require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.15.apache_fcgid.php')); require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.20.lighttpd.php')); require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.25.lighttpd_fcgid.php')); require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.30.nginx.php')); require_once(makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.35.nginx_phpfpm.php')); /** * LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS */ fwrite($debugHandler, ' cron_tasks: Searching for tasks to do' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, "Searching for tasks to do"); $result_tasks = $db->query("SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` ORDER BY `id` ASC"); $resultIDs = array(); while($row = $db->fetch_array($result_tasks)) { $resultIDs[] = $row['id']; if($row['data'] != '') { $row['data'] = unserialize($row['data']); } /** * TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF */ if($row['type'] == '1') { //dhr: cleanout froxlor-generated awstats configs prior to re-creation if ($settings['system']['awstats_enabled'] == '1') { $awstatsclean['header'] = "## GENERATED BY FROXLOR\n"; $awstatsclean['headerold'] = "## GENERATED BY SYSCP\n"; $awstatsclean['path'] = $settings['system']['awstats_conf']; /** * dont do anyting if the directory not exists * (e.g. awstats not installed yet or whatever) * fixes #45 */ if (is_dir($awstatsclean['path'])) { $awstatsclean['dir'] = dir($awstatsclean['path']); while($awstatsclean['entry'] = $awstatsclean['dir']->read()) { $awstatsclean['fullentry'] = makeCorrectFile($awstatsclean['path'].'/'.$awstatsclean['entry']); /** * dont do anything if the file does not exist */ if (file_exists($awstatsclean['fullentry'])) { $awstatsclean['fh'] = fopen($awstatsclean['fullentry'], 'r'); $awstatsclean['headerRead'] = fgets($awstatsclean['fh'], strlen($awstatsclean['header'])+1); fclose($awstatsclean['fh']); if($awstatsclean['headerRead'] == $awstatsclean['header'] || $awstatsclean['headerRead'] == $awstatsclean['headerold']) { $awstats_conf_file = makeCorrectFile($awstatsclean['fullentry']); $cronlog->logAction(CRON_ACTION, LOG_INFO, "Removing awstats configuration ".$awstats_conf_file." for re-creation"); @unlink($awstats_conf_file); } } else { $cronlog->logAction(CRON_ACTION, LOG_WARNING, "File '".$awstatsclean['fullentry']."' could not be found, please check if you followed all the instructions on the configuration page"); } } } unset($awstatsclean); } //end dhr // clear fcgid - starter files prior to re-creation to keep it clean, #367 if ($settings['system']['mod_fcgid'] == '1') { $configdir = makeCorrectDir($settings['system']['mod_fcgid_configdir']); if (is_dir($configdir)) { $its = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($configdir) ); // iterate through all subdirs, // look for php-fcgi-starter files // and take immutable-flag away from them // so we can delete them :) foreach ($its as $fullFileName => $it ) { if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter') { removeImmutable($its->getPathname()); } } // now get rid of old stuff //(but append /* so we don't delete the directory) $configdir.='/*'; safe_exec('rm -rf '. makeCorrectFile($configdir)); } } // clear php-fpm-configurations prior to re-creation to keep it clean if ($settings['phpfpm']['enabled'] == '1') { $configdir = makeCorrectDir($settings['phpfpm']['configdir']); if (is_dir($configdir)) { // now get rid of old stuff //(but append /* so we don't delete the directory) $configdir.='/*'; safe_exec('rm -rf '. makeCorrectFile($configdir)); } } if(!isset($webserver)) { if($settings['system']['webserver'] == "apache2") { if($settings['system']['mod_fcgid'] == 1 || $settings['phpfpm']['enabled'] == 1) { $webserver = new apache_fcgid($db, $cronlog, $debugHandler, $idna_convert, $settings); } else { $webserver = new apache($db, $cronlog, $debugHandler, $idna_convert, $settings); } } elseif($settings['system']['webserver'] == "lighttpd") { if($settings['system']['mod_fcgid'] == 1 || $settings['phpfpm']['enabled'] == 1) { $webserver = new lighttpd_fcgid($db, $cronlog, $debugHandler, $idna_convert, $settings); } else { $webserver = new lighttpd($db, $cronlog, $debugHandler, $idna_convert, $settings); } } elseif($settings['system']['webserver'] == "nginx") { if($settings['phpfpm']['enabled'] == 1) { $webserver = new nginx_phpfpm($db, $cronlog, $debugHandler, $idna_convert, $settings); } else { $webserver = new nginx($db, $cronlog, $debugHandler, $idna_convert, $settings); } } } if(isset($webserver)) { $webserver->createIpPort(); $webserver->createVirtualHosts(); $webserver->createFileDirOptions(); $webserver->writeConfigs(); $webserver->createOwnVhostStarter(); $webserver->reload(); } else { echo "Please check you Webserver settings\n"; } } /** * TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN */ elseif ($row['type'] == '2') { fwrite($debugHandler, ' cron_tasks: Task2 started - create new home' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task2 started - create new home'); if(is_array($row['data'])) { // define paths $userhomedir = makeCorrectDir($settings['system']['documentroot_prefix'] . '/' . $row['data']['loginname'] . '/'); $usermaildir = makeCorrectDir($settings['system']['vmail_homedir'] . '/' . $row['data']['loginname'] . '/'); // stats directory if($settings['system']['awstats_enabled'] == '1') { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'awstats')); safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'awstats')); } else { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer')); safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer')); } // maildir $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir)); safe_exec('mkdir -p ' . escapeshellarg($usermaildir)); //check if admin of customer has added template for new customer directories if((int)$row['data']['store_defaultindex'] == 1) { storeDefaultIndex($row['data']['loginname'], $userhomedir, $cronlog, true); } // strip of last slash of paths to have correct chown results $userhomedir = (substr($userhomedir, 0, -1) == '/') ? substr($userhomedir, 0, -1) : $userhomedir; $usermaildir = (substr($usermaildir, 0, -1) == '/') ? substr($usermaildir, 0, -1) : $usermaildir; $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir)); safe_exec('chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir)); $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)$settings['system']['vmail_uid'] . ':' . (int)$settings['system']['vmail_gid'] . ' ' . escapeshellarg($usermaildir)); safe_exec('chown -R ' . (int)$settings['system']['vmail_uid'] . ':' . (int)$settings['system']['vmail_gid'] . ' ' . escapeshellarg($usermaildir)); } } /** * TYPE=3 MEANS TO DO NOTHING */ elseif ($row['type'] == '3') { } /** * TYPE=4 MEANS THAT SOMETHING IN THE BIND CONFIG HAS CHANGED. REBUILD froxlor_bind.conf */ elseif ($row['type'] == '4') { if(!isset($nameserver)) { $nameserver = new bind($db, $cronlog, $debugHandler, $settings); } if($settings['dkim']['use_dkim'] == '1') { $nameserver->writeDKIMconfigs(); } $nameserver->writeConfigs(); } /** * TYPE=5 MEANS THAT A NEW FTP-ACCOUNT HAS BEEN CREATED, CREATE THE DIRECTORY */ elseif ($row['type'] == '5') { $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating new FTP-home'); $result_directories = $db->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 = $db->fetch_array($result_directories)) { mkDirWithCorrectOwnership($directory['customerroot'], $directory['homedir'], $directory['uid'], $directory['gid']); } } /** * TYPE=6 MEANS THAT A CUSTOMER HAS BEEN DELETED AND THAT WE HAVE TO REMOVE ITS FILES */ elseif ($row['type'] == '6') { fwrite($debugHandler, ' cron_tasks: Task6 started - deleting customer data' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task6 started - deleting customer data'); if(is_array($row['data'])) { if(isset($row['data']['loginname'])) { /* * remove homedir */ $homedir = makeCorrectDir($settings['system']['documentroot_prefix'] . '/' . $row['data']['loginname']); if($homedir != '/' && $homedir != $settings['system']['documentroot_prefix'] && substr($homedir, 0, strlen($settings['system']['documentroot_prefix'])) == $settings['system']['documentroot_prefix']) { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($homedir)); safe_exec('rm -rf '.escapeshellarg($homedir)); } /* * remove maildir */ $maildir = makeCorrectDir($settings['system']['vmail_homedir'] . '/' . $row['data']['loginname']); if($maildir != '/' && $maildir != $settings['system']['vmail_homedir'] && substr($maildir, 0, strlen($settings['system']['vmail_homedir'])) == $settings['system']['vmail_homedir']) { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir)); safe_exec('rm -rf '.escapeshellarg($maildir)); } /* * see if we have some php-fcgid leftovers if used * and remove them, #200 */ if($settings['system']['mod_fcgid'] == 1) { // e.g. /var/www/php-fcgi-starter/web1/ $configdir = makeCorrectDir($settings['system']['mod_fcgid_configdir'] . '/' . $row['data']['loginname'] . '/'); if (is_dir($configdir)) { $its = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($configdir) ); // iterate through all subdirs, // look for php-fcgi-starter files // and take immutable-flag away from them // so we can delete them :) foreach ($its as $fullFileName => $it ) { if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter') { removeImmutable($its->getPathname()); } } // now get rid of old stuff safe_exec('rm -rf '. escapeshellarg($configdir)); } } } } } /** * TYPE=7 Customer deleted an email account and wants the data to be deleted on the filesystem */ elseif ($row['type'] == '7') { fwrite($debugHandler, ' cron_tasks: Task7 started - deleting customer e-mail data' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task7 started - deleting customer e-mail data'); if(is_array($row['data'])) { if(isset($row['data']['loginname']) && isset($row['data']['email']) ) { /* * remove specific maildir */ $maildir = makeCorrectDir($settings['system']['vmail_homedir'] .'/'. $row['data']['loginname'] .'/'. $row['data']['email']); if($maildir != '/' && $maildir != $settings['system']['vmail_homedir'] && substr($maildir, 0, strlen($settings['system']['vmail_homedir'])) == $settings['system']['vmail_homedir']) { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir)); safe_exec('rm -rf '.escapeshellarg($maildir)); } } } } /** * TYPE=8 Customer deleted a ftp account and wants the homedir to be deleted on the filesystem * refs #293 */ elseif ($row['type'] == '8') { fwrite($debugHandler, ' cron_tasks: Task8 started - deleting customer ftp homedir' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task8 started - deleting customer ftp homedir'); if(is_array($row['data'])) { if(isset($row['data']['loginname']) && isset($row['data']['homedir']) ) { /* * remove specific homedir */ $ftphomedir = makeCorrectDir($row['data']['homedir']); $customerdocroot = makeCorrectDir($settings['system']['documentroot_prefix'].'/'.$row['data']['loginname'].'/'); if($ftphomedir != '/' && $ftphomedir != $settings['system']['documentroot_prefix'] && $ftphomedir != $customerdocroot ) { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($ftphomedir)); safe_exec('rm -rf '.escapeshellarg($ftphomedir)); } } } } /** * TYPE=9 Create backup dir protection (no download of backups via webserver) */ elseif ($row['type'] == '9') { fwrite($debugHandler, ' cron_tasks: Task9 started - creating backup dir protection' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task9 started - creating backup dir protection'); $result = $db->query("SELECT documentroot, backup_allowed, backup_enabled FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE 1"); while($row = $db->fetch_array($result)){ if ($row['backup_allowed'] == '1' && $row['backup_enabled'] == '1'){ $backupprotectfile = $settings['system']['apacheconf_diroptions'] . '50_froxlor_diroption_' . md5($row['documentroot'] . $settings['system']['backup_dir']) . '.conf'; $fh = fopen($backupprotectfile, 'w'); if($settings['system']['webserver'] == 'apache2'){ $filedata = '# ' . basename($backupprotectfile) . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n" . '' . "\n" . ' deny from all' . "\n" . '' . "\n"; } elseif($settings['system']['webserver'] == 'lighttpd'){ $filedata = '# ' . basename($backupprotectfile) . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n" . '$PHYSICAL["path"] !~ "^' . $row['documentroot'] . $settings['system']['backup_dir'] . '/$" {' . "\n" . ' access.deny-all = "enable"' . "\n" . '}' . "\n"; } elseif($settings['system']['webserver'] == 'nginx'){ $filedata = '# ' . basename($backupprotectfile) . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n" . 'location ' . $row['documentroot'] . $settings['system']['backup_dir'] . ' {' . "\n" . ' deny all;' . "\n" . ' return 403;' . "\n" . '}' . "\n"; } fwrite($fh, $filedata); fclose($fh); } else{ // deletes backup if customer or admin disables backup because backup protection is not set if (file_exists($row['documentroot'] . $settings['system']['backup_dir'] . '/')){ $files = scandir($row['documentroot'] . $settings['system']['backup_dir']); foreach ($files as $file){ if(preg_match('/.*\.tar\.gz$/', $file)){ safe_exec('rm ' . escapeshellarg($row['documentroot']) . escapeshellarg($settings['system']['backup_dir']) . '/' . $file . ''); } } } } } } /** * TYPE=10 Set the filesystem - quota */ elseif ($row['type'] == '10') { if ($settings['system']['diskquota_enabled']) { fwrite($debugHandler, ' cron_tasks: Task10 started - setting filesystem quota' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task10 started - setting filesystem quota'); # Fetch all quota in the desired partition exec($settings['system']['diskquota_repquota_path'] . " -n " . escapeshellarg($settings['system']['diskquota_customer_partition']), $repquota); $usedquota = array(); foreach ($repquota as $tmpquota) { # Let's see if the line matches a quota - line if (preg_match('/^#([0-9]+)\s*[+-]{2}\s*(\d+)\s*(\d+)\s*(\d+)\s*(\ddays)?\s*(\d+)\s*(\d+)\s*(\d+)/i', $tmpquota, $matches)) { # It matches - put it into an array with userid as key (for easy lookup later) $usedquota[$matches[1]] = array( 'block' => array( 'used' => $matches[2], 'soft' => $matches[3], 'hard' => $matches[4], 'grace' => $matches[5] ), 'file' => array( 'used' => $matches[6], 'soft' => $matches[7], 'hard' => $matches[8], 'grace' => $matches[9] ), ); } } # Select all customers Froxlor knows about $result = $db->query("SELECT `guid`, `loginname`, `diskspace` FROM `" . TABLE_PANEL_CUSTOMERS . "`;"); while($row = $db->fetch_array($result)) { # We do not want to set a quota for root by accident if ($row['guid'] != 0) { # The user has no quota in Froxlor, but on the filesystem if (($row['diskspace'] == 0 || $row['diskspace'] == -1024) && $usedquota[$row['guid']]['block']['hard'] != 0) { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']); safe_exec($settings['system']['diskquota_quotatool_path'] . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg($settings['system']['diskquota_customer_partition'])); } # The user quota in Froxlor is different than on the filesystem elseif($row['diskspace'] != $usedquota[$row['guid']]['block']['hard'] && $row['diskspace'] != -1024) { $cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $usedquota[$row['guid']]['block']['hard'] . " to " . $row['diskspace']); safe_exec($settings['system']['diskquota_quotatool_path'] . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg($settings['system']['diskquota_customer_partition'])); } } } } else { fwrite($debugHandler, ' cron_tasks: Task10 skipped - filesystem quota not enabled' . "\n"); $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task10 skipped - filesystem quota not enabled'); } } } if($db->num_rows($result_tasks) != 0) { $where = array(); foreach($resultIDs as $id) { $where[] = '`id`=\'' . (int)$id . '\''; } $where = implode($where, ' OR '); $db->query('DELETE FROM `' . TABLE_PANEL_TASKS . '` WHERE ' . $where); unset($resultIDs); unset($where); } $db->query('UPDATE `' . TABLE_PANEL_SETTINGS . '` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = \'system\' AND `varname` = \'last_tasks_run\' '); ?>