diff --git a/admin_index.php b/admin_index.php index 3c52fd7d..cb651c06 100644 --- a/admin_index.php +++ b/admin_index.php @@ -22,39 +22,42 @@ define('AREA', 'admin'); /** * Include our init.php, which manages Sessions, Language etc. */ - require ("./lib/init.php"); -if($action == 'logout') -{ +if ($action == 'logout') { + $log->logAction(ADM_ACTION, LOG_NOTICE, "logged out"); - if($settings['session']['allow_multiple_login'] == '1') - { - $db->query("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = '" . (int)$userinfo['adminid'] . "' AND `adminsession` = '1' AND `hash` = '" . $s . "'"); - } - else - { - $db->query("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = '" . (int)$userinfo['adminid'] . "' AND `adminsession` = '1'"); + $params = array('adminid' => (int)$userinfo['adminid']); + + if ($settings['session']['allow_multiple_login'] == '1') { + $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` + WHERE `userid` = :adminid + AND `adminsession` = '1' + AND `hash` = :hash" + ); + $params['hash'] = $s; + } else { + $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` + WHERE `userid` = :adminid + AND `adminsession` = '1'" + ); } + Database::pexecute($stmt, $params); redirectTo('index.php'); exit; } -if(isset($_POST['id'])) -{ +if (isset($_POST['id'])) { $id = intval($_POST['id']); -} -elseif(isset($_GET['id'])) -{ +} elseif(isset($_GET['id'])) { $id = intval($_GET['id']); } -if($page == 'overview') -{ +if ($page == 'overview') { $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_index"); - $overview = $db->query_first("SELECT COUNT(*) AS `number_customers`, + $overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`, SUM(`diskspace_used`) AS `diskspace_used`, SUM(`mysqls_used`) AS `mysqls_used`, SUM(`emails_used`) AS `emails_used`, @@ -67,7 +70,10 @@ if($page == 'overview') SUM(`subdomains_used`) AS `subdomains_used`, SUM(`traffic_used`) AS `traffic_used`, SUM(`aps_packages_used`) AS `aps_packages_used` - FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = '" . (int)$userinfo['adminid'] . "' ")); + FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid ")); + Database::pexecute($overview_stmt, array('adminid' => $userinfo['adminid'])); + $overview = $overview_stmt->fetch(PDO::FETCH_ASSOC); + $overview['traffic_used'] = round($overview['traffic_used'] / (1024 * 1024), $settings['panel']['decimal_places']); $overview['diskspace_used'] = round($overview['diskspace_used'] / 1024, $settings['panel']['decimal_places']); $number_domains = $db->query_first("SELECT COUNT(*) AS `number_domains` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = '" . (int)$userinfo['adminid'] . "' ")); @@ -75,8 +81,7 @@ if($page == 'overview') $phpversion = phpversion(); $phpmemorylimit = @ini_get("memory_limit"); - if($phpmemorylimit == "") - { + if ($phpmemorylimit == "") { $phpmemorylimit = $lng['admin']['memorylimitdisabled']; } @@ -84,22 +89,20 @@ if($page == 'overview') $mysqlclientversion = mysql_get_client_info(); $webserverinterface = strtoupper(@php_sapi_name()); - if((isset($_GET['lookfornewversion']) && $_GET['lookfornewversion'] == 'yes') - || (isset($lookfornewversion) && $lookfornewversion == 'yes')) - { + if ((isset($_GET['lookfornewversion']) && $_GET['lookfornewversion'] == 'yes') + || (isset($lookfornewversion) && $lookfornewversion == 'yes') + ) { $update_check_uri = 'http://version.froxlor.org/Froxlor/legacy/' . $version; - if(ini_get('allow_url_fopen')) - { + if (ini_get('allow_url_fopen')) { $latestversion = @file($update_check_uri); - if (isset($latestversion[0])) - { + if (isset($latestversion[0])) { $latestversion = explode('|', $latestversion[0]); - if(is_array($latestversion) - && count($latestversion) >= 1) - { + if (is_array($latestversion) + && count($latestversion) >= 1 + ) { $_version = $latestversion[0]; $_message = isset($latestversion[1]) ? $latestversion[1] : ''; $_link = isset($latestversion[2]) ? $latestversion[2] : htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); @@ -115,24 +118,16 @@ if($page == 'overview') } else { $isnewerversion = 0; } - } - else - { + } else { redirectTo($update_check_uri.'/pretty', NULL); } - } - else - { + } else { redirectTo($update_check_uri.'/pretty', NULL); } - } - else - { + } else { redirectTo($update_check_uri.'/pretty', NULL); } - } - else - { + } else { $lookfornewversion_lable = $lng['admin']['lookfornewversion']['clickhere']; $lookfornewversion_link = htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); $lookfornewversion_addinfo = ''; @@ -148,44 +143,35 @@ if($page == 'overview') $cron_last_runs = getCronjobsLastRun(); $outstanding_tasks = getOutstandingTasks(); - if(function_exists('sys_getloadavg')) - { + if (function_exists('sys_getloadavg')) { $loadArray = sys_getloadavg(); $load = number_format($loadArray[0], 2, '.', '') . " / " . number_format($loadArray[1], 2, '.', '') . " / " . number_format($loadArray[2], 2, '.', ''); - } - else - { + } else { $load = @file_get_contents('/proc/loadavg'); - if(!$load) - { + if (!$load) { $load = $lng['admin']['noloadavailable']; } } - if(function_exists('posix_uname')) - { + if (function_exists('posix_uname')) { $showkernel = 1; $kernel_nfo = posix_uname(); $kernel = $kernel_nfo['release'] . ' (' . $kernel_nfo['machine'] . ')'; - } - else - { + } else { $showkernel = 0; $kernel = ''; } // Try to get the uptime // First: With exec (let's hope it's enabled for the Froxlor - vHost) - $uptime_array = explode(" ", @file_get_contents("/proc/uptime")); - if(is_array($uptime_array) - && isset($uptime_array[0]) - && is_numeric($uptime_array[0])) - { + if (is_array($uptime_array) + && isset($uptime_array[0]) + && is_numeric($uptime_array[0]) + ) { // Some calculatioon to get a nicly formatted display - $seconds = round($uptime_array[0], 0); $minutes = $seconds / 60; $hours = $minutes / 60; @@ -196,27 +182,22 @@ if($page == 'overview') $uptime = "{$days}d, {$hours}h, {$minutes}m, {$seconds}s"; // Just cleanup - unset($uptime_array, $seconds, $minutes, $hours, $days); - } - else - { + } else { // Nothing of the above worked, show an error :/ - $uptime = ''; } eval("echo \"" . getTemplate("index/index") . "\";"); -} -elseif($page == 'change_password') -{ - if(isset($_POST['send']) - && $_POST['send'] == 'send') - { + +} elseif($page == 'change_password') { + + if (isset($_POST['send']) + && $_POST['send'] == 'send' + ) { $old_password = validate($_POST['old_password'], 'old password'); - if(md5($old_password) != $userinfo['password']) - { + if (md5($old_password) != $userinfo['password']) { standard_error('oldpasswordnotcorrect'); exit; } @@ -224,92 +205,122 @@ elseif($page == 'change_password') $new_password = validate($_POST['new_password'], 'new password'); $new_password_confirm = validate($_POST['new_password_confirm'], 'new password confirm'); - if($old_password == '') - { + if ($old_password == '') { standard_error(array('stringisempty', 'oldpassword')); - } - elseif($new_password == '') - { + } elseif($new_password == '') { standard_error(array('stringisempty', 'newpassword')); - } - elseif($new_password_confirm == '') - { + } elseif($new_password_confirm == '') { standard_error(array('stringisempty', 'newpasswordconfirm')); - } - elseif($new_password != $new_password_confirm) - { + } elseif($new_password != $new_password_confirm) { standard_error('newpasswordconfirmerror'); - } - else - { - $db->query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `password`='" . md5($new_password) . "' WHERE `adminid`='" . (int)$userinfo['adminid'] . "' AND `password`='" . md5($old_password) . "'"); + } else { + $chgpwd_stmt = Database::prepare(" + UPDATE `" . TABLE_PANEL_ADMINS . "` + SET `password`= :newpasswd + WHERE `adminid`= :adminid + AND `password`= :oldpasswd" + ); + Database::pexecute($chgpwd_stmt, array( + 'newpasswd' => md5($new_password), + 'adminid' => (int)$userinfo['adminid'], + 'oldpasswd' => md5($old_password) + )); $log->logAction(ADM_ACTION, LOG_NOTICE, 'changed password'); redirectTo($filename, Array('s' => $s)); } - } - else - { + } else { eval("echo \"" . getTemplate("index/change_password") . "\";"); } -} -elseif($page == 'change_language') -{ - if(isset($_POST['send']) - && $_POST['send'] == 'send') - { + +} elseif($page == 'change_language') { + + if (isset($_POST['send']) + && $_POST['send'] == 'send' + ) { $def_language = validate($_POST['def_language'], 'default language'); - if(isset($languages[$def_language])) - { - $db->query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `def_language`='" . $db->escape($def_language) . "' WHERE `adminid`='" . (int)$userinfo['adminid'] . "'"); - $db->query("UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `language`='" . $db->escape($def_language) . "' WHERE `hash`='" . $db->escape($s) . "'"); + if (isset($languages[$def_language])) { + $lng_stmt = Database::prepare(" + UPDATE `" . TABLE_PANEL_ADMINS . "` + SET `def_language`= :deflng + WHERE `adminid`= :adminid" + ); + Database::pexecute($lng_stmt, array( + 'deflng' => $def_language, + 'adminid' => (int)$userinfo['adminid'] + )); + + $lng_stmt = Database::prepare(" + UPDATE `" . TABLE_PANEL_SESSIONS . "` + SET `language`= :lng + WHERE `hash`= :hash" + ); + Database::pexecute($lng_stmt, array( + 'lng' => $def_language, + 'hash' => $s + )); } $log->logAction(ADM_ACTION, LOG_NOTICE, "changed his/her default language to '" . $def_language . "'"); - redirectTo($filename, Array('s' => $s)); - } - else - { + redirectTo($filename, array('s' => $s)); + + } else { + $language_options = ''; $default_lang = $settings['panel']['standardlanguage']; - if($userinfo['def_language'] != '') { + if ($userinfo['def_language'] != '') { $default_lang = $userinfo['def_language']; } - while(list($language_file, $language_name) = each($languages)) - { + while (list($language_file, $language_name) = each($languages)) { $language_options.= makeoption($language_name, $language_file, $default_lang, true); } eval("echo \"" . getTemplate("index/change_language") . "\";"); } -} -elseif($page == 'change_theme') -{ - if(isset($_POST['send']) + +} elseif ($page == 'change_theme') { + + if (isset($_POST['send']) && $_POST['send'] == 'send' ) { $theme = validate($_POST['theme'], 'theme'); - $db->query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `theme`='" . $db->escape($theme) . "' WHERE `adminid`='" . (int)$userinfo['adminid'] . "'"); - $db->query("UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `theme`='" . $db->escape($theme) . "' WHERE `hash`='" . $db->escape($s) . "'"); + $theme_stmt = Database::prepare(" + UPDATE `" . TABLE_PANEL_ADMINS . "` + SET `theme`= :theme + WHERE `adminid`= :adminid" + ); + Database::pexecute($theme_stmt, array( + 'theme' => $theme, + 'adminid' => (int)$userinfo['adminid'] + )); + + $theme_stmt = Database::prepare(" + UPDATE `" . TABLE_PANEL_SESSIONS . "` + SET `theme`= :theme + WHERE `hash`= :hash" + ); + Database::pexecute($theme_stmt, array( + 'theme' => $theme, + 'hash' => $s + )); $log->logAction(ADM_ACTION, LOG_NOTICE, "changed his/her theme to '" . $theme . "'"); - redirectTo($filename, Array('s' => $s)); - } - else - { + redirectTo($filename, array('s' => $s)); + + } else { + $theme_options = ''; $default_theme = $settings['panel']['default_theme']; - if($userinfo['theme'] != '') { + if ($userinfo['theme'] != '') { $default_theme = $userinfo['theme']; } $themes_avail = getThemes(); - foreach($themes_avail as $t) - { + foreach ($themes_avail as $t) { $theme_options.= makeoption($t, $t, $default_theme, true); } diff --git a/install/lib/class.FroxlorInstall.php b/install/lib/class.FroxlorInstall.php index ad5919ee..524b72bd 100644 --- a/install/lib/class.FroxlorInstall.php +++ b/install/lib/class.FroxlorInstall.php @@ -761,6 +761,16 @@ class FroxlorInstall { $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); } + // check for php_pdo and pdo_mysql + $content .= $this->_status_message('begin', $this->_lng['requirements']['phppdo']); + + if (!extension_loaded('pdo') || in_array("mysql", PDO::getAvailableDrivers()) == false) { + $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); + $_die = true; + } else { + $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); + } + // check for xml-extension $content .= $this->_status_message('begin', $this->_lng['requirements']['phpxml']); diff --git a/install/lng/english.lng.php b/install/lng/english.lng.php index 67481984..d310ef4a 100644 --- a/install/lng/english.lng.php +++ b/install/lng/english.lng.php @@ -27,6 +27,7 @@ $lng['requirements']['phpversion'] = 'PHP version >= 5.2'; $lng['requirements']['phpmagic_quotes_runtime'] = 'magic_quotes_runtime...'; $lng['requirements']['phpmagic_quotes_runtime_description'] = 'PHP setting "magic_quotes_runtime" must be set to "Off". We have disabled it temporary for now please fix the coresponding php.ini.'; $lng['requirements']['phpmysql'] = 'MySQL-extension...'; +$lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...'; $lng['requirements']['phpxml'] = 'PHP XML-extension...'; $lng['requirements']['phpfilter'] = 'PHP filter-extension...'; $lng['requirements']['phpposix'] = 'PHP posix-extension...'; diff --git a/install/lng/german.lng.php b/install/lng/german.lng.php index 2ed9c469..9775d913 100644 --- a/install/lng/german.lng.php +++ b/install/lng/german.lng.php @@ -27,6 +27,7 @@ $lng['requirements']['phpversion'] = 'PHP Version >= 5.2'; $lng['requirements']['phpmagic_quotes_runtime'] = 'magic_quotes_runtime'; $lng['requirements']['phpmagic_quotes_runtime_description'] = 'Die PHP Einstellung "magic_quotes_runtime" muss deaktiviert sein ("Off"). Die Einstellung wurde temporär deaktiviert, bitte ändern Sie diese in der entsprechenden php.ini.'; $lng['requirements']['phpmysql'] = 'PHP MySQL-Erweiterung...'; +$lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...'; $lng['requirements']['phpxml'] = 'PHP XML-Erweiterung...'; $lng['requirements']['phpfilter'] = 'PHP filter-Erweiterung...'; $lng['requirements']['phpposix'] = 'PHP posix-Erweiterung...'; diff --git a/lib/classes/database/class.Database.php b/lib/classes/database/class.Database.php new file mode 100644 index 00000000..3cb214ee --- /dev/null +++ b/lib/classes/database/class.Database.php @@ -0,0 +1,188 @@ + + * @author Froxlor team (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Classes + * + * @since 0.9.31 + * + */ + +/** + * Class Database + * + * Wrapper-class for PHP-PDO + * + * @copyright (c) the authors + * @author Michael Kaufmann + * @author Froxlor team (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Classes + */ +class Database { + + /** + * current database link + * + * @var object + */ + private static $_link = null ; + + /** + * Wrapper for PDOStatement::execute so we can catch the PDOException + * and display the error nicely on the panel + * + * @param PDOStatement $stmt + * @param array $params (optional) + */ + public static function pexecute(&$stmt, $params = null) { + try { + $stmt->execute($params); + } catch (PDOException $e) { + self::_showerror($e); + } + } + + /** + * let's us interact with the PDO-Object by using static + * call like "Database::function()" + * + * @param string $name + * @param mixed $args + * + * @return mixed + */ + public static function __callStatic($name, $args) { + $callback = array(self::getDB(), $name); + $result = null; + try { + $result = call_user_func_array($callback, $args ); + } catch (PDOException $e) { + self::_showerror($e); + } + return $result; + } + + /** + * function that will be called on every static call + * which connects to the database if necessary + * + * @param bool $root + * + * @return object + */ + private static function getDB($root = false) { + + if (!extension_loaded('pdo') || in_array("mysql", PDO::getAvailableDrivers()) == false) { + self::_showerror(new Exception("The php PDO extension or PDO-MySQL driver is not available")); + } + + // do we got a connection already? + if (self::$_link) { + // return it + return self::$_link; + } + + // include userdata.inc.php + require FROXLOR_INSTALL_DIR."/lib/userdata.inc.php"; + + // le format + if ($root = true + && isset($sql['root_user']) + && isset($sql['root_password']) + && (!isset($sql_root) || !is_array($sql_root)) + ) { + $sql_root = array(0 => array('caption' => 'Default', 'host' => $sql['host'], 'user' => $sql['root_user'], 'password' => $sql['root_password'])); + unset($sql['root_user']); + unset($sql['root_password']); + } + + // either root or unprivileged user + if ($root) { + $user = $sql_root[0]['user']; + $password = $sql_root[0]['password']; + $host = $sql_root[0]['host']; + } else { + $user = $sql["user"]; + $password = $sql["password"]; + $host = $sql["host"]; + } + + // build up connection string + $driver = 'mysql'; + $dsn = $driver.":"; + $options = array('PDO::MYSQL_ATTR_INIT_COMMAND' => 'set names utf8'); + $attributes = array('ATTR_ERRMODE' => 'ERRMODE_EXCEPTION'); + + $dbconf["dsn"] = array( + 'host' => $host, + 'dbname' => $sql["db"] + ); + + // add options to dsn-string + foreach ($dbconf["dsn"] as $k => $v) { + $dsn .= $k."=".$v.";"; + } + + // clean up + unset($dbconf); + + // try to connect + try { + self::$_link = new PDO($dsn, $user, $password, $options); + } catch (PDOException $e) { + self::_showerror($e); + } + + // set attributes + foreach ($attributes as $k => $v) { + self::$_link->setAttribute(constant("PDO::".$k), constant("PDO::".$v)); + } + + // return PDO instance + return self::$_link; + } + + /** + * display a nice error if it occurs and log everything + * + * @param PDOException $error + */ + private static function _showerror($error) { + global $theme; + + /** + * log to a file, so we can actually ask people for the error + * (no one seems to find the stuff in the syslog) + */ + $sl_dir = makeCorrectDir(dirname(dirname(dirname(dirname(__FILE__))))."/logs/"); + if (!file_exists($sl_dir)) { + @mkdir($sl_dir, 0755); + } + $sl_file = makeCorrectFile($sl_dir."/sql-error.log"); + $sqllog = @fopen($sl_file, 'a'); + @fwrite($sqllog, date('d.m.Y H:i', time())." --- ".str_replace("\n", " ", $error->getMessage())."\n"); + @fclose($sqllog); + + if (!isset($_SERVER['SHELL']) || (isset($_SERVER['SHELL']) && $_SERVER['SHELL'] == '')) { + // if we're not on the shell, output a nicer error-message + $err_hint = file_get_contents(dirname($sl_dir).'/templates/'.$theme.'/misc/dberrornice.tpl'); + // replace values + $err_hint = str_replace("", $error->getMessage(), $err_hint); + $err_hint = str_replace("", $error->getTraceAsString(), $err_hint); + // show + die($err_hint); + } + die("We are sorry, but a MySQL - error occurred. The administrator may find more information in in the sql-error.log in the logs/ directory"); + } +} diff --git a/lib/classes/database/class.db.php b/lib/classes/database/class.db.php index 2b866422..20d3b17f 100644 --- a/lib/classes/database/class.db.php +++ b/lib/classes/database/class.db.php @@ -277,7 +277,7 @@ class db { private function _showerror($errormsg, $mysqlActive = true) { global $filename, $theme; - $text = 'MySQL - Error: ' . str_replace("\n", "\t", $errormsg); + $text = 'MySQL - Error: ' . $errormsg; if ($mysqlActive) { $this->_geterrdescno(); @@ -297,7 +297,7 @@ class db { /** * log to a file, so we can actually ask people for the error * (no one seems to find the stuff in the syslog) - */ + */ $sl_dir = makeCorrectDir(dirname(dirname(dirname(dirname(__FILE__))))."/logs/"); if (!file_exists($sl_dir)) { @mkdir($sl_dir, 0755); @@ -307,7 +307,7 @@ class db { @fwrite($sqllog, date('d.m.Y H:i', time())." --- ".$text."\n"); @fclose($sqllog); - if (isset($_SERVER['SHELL']) && $_SERVER['SHELL'] != '') { + if (!isset($_SERVER['SHELL']) || (isset($_SERVER['SHELL']) && $_SERVER['SHELL'] == '')) { // if we're not on the shell, output a nicer error-message $err_hint = file_get_contents(dirname($sl_dir).'/templates/'.$theme.'/misc/dberrornice.tpl'); // replace values diff --git a/lib/functions/output/function.standard_error.php b/lib/functions/output/function.standard_error.php index 3130a6d2..7733bf3b 100644 --- a/lib/functions/output/function.standard_error.php +++ b/lib/functions/output/function.standard_error.php @@ -41,7 +41,7 @@ function standard_error($errors = '', $replacer = '') $link = ''; if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST']) !== false) { - $link = ''.$lng['panel']['back'].''; + $link = ''.$lng['panel']['back'].''; } $error = ''; diff --git a/templates/Froxlor/misc/dberrornice.tpl b/templates/Froxlor/misc/dberrornice.tpl index 72458523..84b00ee8 100644 --- a/templates/Froxlor/misc/dberrornice.tpl +++ b/templates/Froxlor/misc/dberrornice.tpl @@ -28,7 +28,7 @@
A database error occured

-

+

diff --git a/templates/Sparkle/misc/dberrornice.tpl b/templates/Sparkle/misc/dberrornice.tpl index 60cb7038..4abaf8a4 100644 --- a/templates/Sparkle/misc/dberrornice.tpl +++ b/templates/Sparkle/misc/dberrornice.tpl @@ -30,7 +30,7 @@

 

-

+