diff --git a/html/index.php b/html/index.php index 151a88567626b2508ec5babf24836e8f2b0d12e8..efe328bb390ab4a5a4289c914e98161a81fd88b6 100644 --- a/html/index.php +++ b/html/index.php @@ -89,16 +89,13 @@ if (!file_exists(CONFIG_DIR.'/'.CONFIG_FILE)) { /* Check if fusiondirectory.conf (.CONFIG_FILE) is accessible */ if (!is_readable(CONFIG_DIR.'/'.CONFIG_FILE)) { - msg_dialog::display( - _('Configuration error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('FusionDirectory configuration %s/%s is not readable. Please run fusiondirectory-setup --check-config to fix this.'), CONFIG_DIR, CONFIG_FILE - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } /* Parse configuration file */ @@ -115,15 +112,12 @@ $smarty->compile_dir = $config->get_cfg_value('templateCompileDirectory', SPOOL_ /* Check for compile directory */ if (!(is_dir($smarty->compile_dir) && is_writable($smarty->compile_dir))) { - msg_dialog::display( - _('Smarty error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('Directory "%s" specified as compile directory is not accessible!'), $smarty->compile_dir - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } /* Check for old files in compile directory */ diff --git a/html/main.php b/html/main.php index 0772eebdbe8cb300771740300a803c908910d7de..07a2c9c1ce7a8d2bc37aaa413e9c6c8df37d7404 100644 --- a/html/main.php +++ b/html/main.php @@ -221,12 +221,9 @@ $smarty->assign("sessionLifetime", $config->get_cfg_value("sessionLifetime", 60 /* If there's some post, take a look if everything is there... */ if (isset($_POST) && count($_POST) && !isset($_POST['php_c_check'])) { - msg_dialog::display( - _('Configuration Error'), - sprintf(_('Fatal error: not all POST variables have been transfered by PHP - please inform your administrator!')), - FATAL_ERROR_DIALOG + throw new FatalError( + htmlescape(_('Fatal error: not all POST variables have been transfered by PHP - please inform your administrator!')) ); - exit(); } /* Assign errors to smarty */ diff --git a/html/setup.php b/html/setup.php index 3d367f81c507f2d0bb1b8a07b5997fc824a30b6b..c405c8582a0b8b1aeaf96619fda0653255ddf462 100644 --- a/html/setup.php +++ b/html/setup.php @@ -61,9 +61,12 @@ $smarty->compile_dir = SPOOL_DIR; /* Check for compile directory */ if (!(is_dir($smarty->compile_dir) && is_writable($smarty->compile_dir))) { - msg_dialog::display(_("Smarty"), sprintf(_("Directory '%s' specified as compile directory is not accessible!"), - $smarty->compile_dir), FATAL_ERROR_DIALOG); - exit(); + throw new FatalError( + htmlescape(sprintf( + _('Directory "%s" specified as compile directory is not accessible!'), + $smarty->compile_dir + )) + ); } /* Get posted language */ diff --git a/include/class_config.inc b/include/class_config.inc index 169c4fcdf7c000252820ebade38551987d19d060..9b992d0319e8f2842f8195e9d60d0b1d52f2e0a5 100644 --- a/include/class_config.inc +++ b/include/class_config.inc @@ -143,11 +143,10 @@ class config xml_set_element_handler($this->parser, "tag_open", "tag_close"); if (!xml_parse($this->parser, chop($xmldata))) { - $msg = sprintf(_("XML error in fusiondirectory.conf: %s at line %d"), + $msg = sprintf(_('XML error in fusiondirectory.conf: %s at line %d'), xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser)); - msg_dialog::display(_("Configuration error"), $msg, FATAL_ERROR_DIALOG); - exit; + throw new FatalError(htmlescape($msg)); } xml_parser_free($this->parser); } @@ -274,13 +273,12 @@ class config $cache[$creds] = cred_decrypt($creds, $_SERVER['HTTP_FDKEY']); session::set('HTTP_FDKEY_CACHE', $cache); } catch (FusionDirectoryException $e) { - $msg = sprintf( - _('It seems you are trying to decode something which is not encoded : %s<br/>'."\n". + $msg = nl2br(htmlescape(sprintf( + _('It seems you are trying to decode something which is not encoded : %s'."\n". 'Please check you are not using a fusiondirectory.secrets file while your passwords are not encrypted.'), $e->getMessage() - ); - msg_dialog::display(_('Configuration error'), $msg, FATAL_ERROR_DIALOG); - exit; + ))); + throw new FatalError($msg); } } return $cache[$creds]; @@ -317,8 +315,7 @@ class config /* Check for connection */ if (is_null($this->ldapLink) || (is_int($this->ldapLink) && $this->ldapLink == 0)) { - msg_dialog::display(_("LDAP error"), _("Cannot bind to LDAP. Please contact the system administrator."), FATAL_ERROR_DIALOG); - exit(); + throw new FatalError(htmlescape(_('Cannot bind to LDAP. Please contact the system administrator.'))); } /* Move referrals */ @@ -348,8 +345,7 @@ class config global $ui; if (!isset($this->data['LOCATIONS'][$name])) { - msg_dialog::display(_('Error'), sprintf(_('Location "%s" could not be found in the configuration file'), $name), FATAL_ERROR_DIALOG); - exit; + throw new FatalError(htmlescape(sprintf(_('Location "%s" could not be found in the configuration file'), $name))); } $this->current = $this->data['LOCATIONS'][$name]; diff --git a/include/class_ldap.inc b/include/class_ldap.inc index e9e6c310965641eb84062e18cd00a09e471cf57f..7cce10a97e60f285c54019adceea0e673fca360b 100644 --- a/include/class_ldap.inc +++ b/include/class_ldap.inc @@ -1336,6 +1336,7 @@ class LDAP } $this->cd($dn); + $operation = LDAP_MOD; if (!$modify) { $this->cat($srp, $dn); if ($this->count($srp)) { @@ -1354,6 +1355,7 @@ class LDAP $ret = $this->modify($data); } else { /* The destination entry doesn't exists, create it */ + $operation = LDAP_ADD; $ret = $this->add($data); } } else { @@ -1363,7 +1365,8 @@ class LDAP } if (!$this->success()) { - msg_dialog::display(_('LDAP error'), msgPool::ldaperror($this->get_error(), $dn, '', get_class()), LDAP_ERROR); + $error = new SimplePluginLdapError(NULL, $dn, $operation, $this->get_error(), $this->get_errno()); + $error->display(); } return $ret; diff --git a/include/class_msg_dialog.inc b/include/class_msg_dialog.inc index a160224eb2ec19d2a3df399aabd70094f1bea1a9..dfb8e155eb31953616a68cab7543aae3971481e2 100644 --- a/include/class_msg_dialog.inc +++ b/include/class_msg_dialog.inc @@ -102,19 +102,13 @@ class msg_dialog } else { $this->a_Trace = []; } - if ($this->i_Type == FATAL_ERROR_DIALOG) { - restore_error_handler(); - error_reporting(E_ALL); - echo $this->renderFatalErrorDialog(); + if (session::is_set('msg_dialogs')) { + $msg_dialogs = session::get('msg_dialogs'); } else { - if (session::is_set('msg_dialogs')) { - $msg_dialogs = session::get('msg_dialogs'); - } else { - $msg_dialogs = []; - } - $msg_dialogs[] = $this; - session::set('msg_dialogs', $msg_dialogs); + $msg_dialogs = []; } + $msg_dialogs[] = $this; + session::set('msg_dialogs', $msg_dialogs); } /*! @@ -130,6 +124,10 @@ class msg_dialog */ public static function display ($title, string $message, int $type = INFO_DIALOG, array $trace = []) { + if ($type === FATAL_ERROR_DIALOG) { + /* Deprecated */ + throw new FatalError($message); + } if ($title instanceof FusionDirectoryError) { static::display(...$title->computeMsgDialogParameters()); return; @@ -164,39 +162,6 @@ class msg_dialog return $this->i_ID; } - /*! - * \brief Run the message dialog - */ - protected function renderFatalErrorDialog () - { - global $config; - - $display = - '<!DOCTYPE html> - <html><head> - <title>FusionDirectory startup failed</title> - </head><body>'; - if (isset($config) && is_object($config) && - $config->get_cfg_value('displayerrors') == 'TRUE') { - list($trace, ) = html_trace(); - $display .= $trace; - } - $display .= - '<table style="width:100%; border:2px solid red;"> - <tr> - <td style="vertical-align:top;padding:10px"> - <img src="geticon.php?context=status&icon=dialog-error&size=32" alt="'.htmlescape(_('Error')).'"/> - </td> - <td style="width:100%"> - <b>'.htmlescape($this->s_Title).'</b><br/> - '.$this->s_Message.'<br/><br/> - '.htmlescape(_('Please fix the above error and reload the page.')).' - </td> - </tr> - </table></body></html>'; - return $display; - } - /*! * \brief Check if the message is confirmed by user * diff --git a/include/class_pluglist.inc b/include/class_pluglist.inc index ceb769027cd50f332dc2b5a5e6f8ebfdbf348f31..78d652011fa213284b7255f06e3d6480f3273fb2 100644 --- a/include/class_pluglist.inc +++ b/include/class_pluglist.inc @@ -575,12 +575,13 @@ class pluglist } elseif (is_callable([$plugin, 'mainInc'])) { $plugin::mainInc(); } else { - msg_dialog::display( - _('Plugin'), - sprintf(_("Fatal error: Cannot find any plugin definitions for plugin '%s' ('%s' is not a file)!"), $plugin, "$plugin_dir/main.inc"), - FATAL_ERROR_DIALOG + throw new FatalError( + htmlescape(sprintf( + _('Fatal error: Cannot find any plugin definitions for plugin "%s" ("%s" is not a file)!'), + $plugin, + "$plugin_dir/main.inc" + )) ); - exit(); } if ($forceCleanup) { $cleanup = $remove_lock = FALSE; diff --git a/include/class_standAlonePage.inc b/include/class_standAlonePage.inc index b368b077e4a4a647c8589203ca1842d74a55192c..705d96fa8ce27dde55fa07868ae9b335dc41629c 100644 --- a/include/class_standAlonePage.inc +++ b/include/class_standAlonePage.inc @@ -120,10 +120,13 @@ class standAlonePage /* Check if CONFIG_FILE is accessible */ if (!is_readable(CONFIG_DIR.'/'.CONFIG_FILE)) { - msg_dialog::display(_('Fatal error'), - sprintf(_('FusionDirectory configuration %s/%s is not readable. Aborted.'), - CONFIG_DIR, CONFIG_FILE), FATAL_ERROR_DIALOG); - exit(); + throw new FatalError( + htmlescape(sprintf( + _('FusionDirectory configuration %s/%s is not readable. Aborted.'), + CONFIG_DIR, + CONFIG_FILE + )) + ); } /* Parse configuration file */ @@ -143,11 +146,12 @@ class standAlonePage /* Check for compile directory */ if (!(is_dir($smarty->compile_dir) && is_writable($smarty->compile_dir))) { - msg_dialog::display(_('Configuration error'), - sprintf(_("Directory '%s' specified as compile directory is not accessible!"), - $smarty->compile_dir), - FATAL_ERROR_DIALOG); - exit(); + throw new FatalError( + htmlescape(sprintf( + _('Directory "%s" specified as compile directory is not accessible!'), + $smarty->compile_dir + )) + ); } /* Check for old files in compile directory */ diff --git a/include/class_userinfo.inc b/include/class_userinfo.inc index 2f07fe7042f0635801f99db6169b96ea66e65170..682c68c6eb2c064fe33023fdf282e9b1b86c5cc5 100644 --- a/include/class_userinfo.inc +++ b/include/class_userinfo.inc @@ -233,14 +233,13 @@ class userinfo $targetFilter = templateHandling::parseString($ACLRule['targetfilter'], $this->cachedAttrs, 'ldap_escape_f'); $ldap->search($targetFilter, ['dn']); if ($ldap->hitSizeLimit()) { - msg_dialog::display( - _('Error'), - sprintf( + $error = new FusionDirectoryError( + htmlescape(sprintf( _('An ACL assignment for the connected user matched more than than the %d objects limit. This user will not have the ACL rights he should.'), $targetFilterLimit - ), - ERROR_DIALOG + )) ); + $error->display(); } $targetDns = []; while ($targetAttrs = $ldap->fetch()) { @@ -1035,10 +1034,7 @@ class userinfo /* look through the entire ldap */ $ldap = $config->get_ldap_link(); if (!$ldap->success()) { - msg_dialog::display(_('LDAP error'), - msgPool::ldaperror($ldap->get_error(FALSE), '', LDAP_AUTH), - FATAL_ERROR_DIALOG); - exit(); + throw new FatalError(msgPool::ldaperror($ldap->get_error(FALSE), '', LDAP_AUTH)); } $allowed_attributes = ['uid','mail']; @@ -1109,8 +1105,7 @@ class userinfo if ($ui === FALSE) { throw new LoginFailureException(ldap::invalidCredentialsError()); } elseif (is_string($ui)) { - msg_dialog::display(_('Internal error'), $ui, FATAL_ERROR_DIALOG); - exit(); + throw new LoginFailureException($ui); } /* password check, bind as user with supplied password */ diff --git a/include/errors/class_FatalError.inc b/include/errors/class_FatalError.inc new file mode 100644 index 0000000000000000000000000000000000000000..ae4841c20a62a668033f13cdc49dec42975b264d --- /dev/null +++ b/include/errors/class_FatalError.inc @@ -0,0 +1,93 @@ +<?php +/* + This code is part of FusionDirectory (http://www.fusiondirectory.org/) + + Copyright (C) 2019-2020 FusionDirectory + + 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/*! \class FatalError + \brief Fatal error class. Does not extend FusionDirectoryError. +*/ +class FatalError extends Error +{ + protected $htmlMessage; + + public function __construct (string $htmlMessage = '', int $code = 0, Throwable $previous = NULL) + { + $this->htmlMessage = $htmlMessage; + parent::__construct(htmlunescape(strip_tags($htmlMessage)), $code, $previous); + } + + public function getHtmlMessage () + { + return $this->htmlMessage; + } + + public function toArray (): array + { + return [ + 'message' => $this->getMessage(), + 'line' => $this->getLine(), + 'file' => $this->getFile(), + 'fatal' => TRUE, + ]; + } + + public function display () + { + restore_error_handler(); + error_reporting(E_ALL); + echo $this->renderFatalErrorDialog(); + } + + /*! + * \brief Render fatal error screen + */ + protected function renderFatalErrorDialog () + { + global $config; + + $display = + '<!DOCTYPE html> + <html><head> + <title>'.htmlescape(_('FusionDirectory Fatal Error')).'</title> + </head><body>'; + + $display .= + '<table style="width:100%; border:2px solid red;"> + <tr> + <td style="vertical-align:top;padding:10px"> + <img src="geticon.php?context=status&icon=dialog-error&size=32" alt="'.htmlescape(_('Error')).'"/> + </td> + <td style="width:100%"> + <h3>'.htmlescape(_('Fatal Error')).'</h3> + '.$this->getHtmlMessage().' + </td> + </tr> + </table>'; + + if (isset($config) && is_object($config) && + $config->get_cfg_value('displayerrors') == 'TRUE') { + $trace = FusionDirectoryError::formatTrace($this); + $display .= print_a($trace, TRUE); + } + + $display .= '</body></html>'; + + return $display; + } +} diff --git a/include/errors/class_FusionDirectoryError.inc b/include/errors/class_FusionDirectoryError.inc index 432d690f3fb45e6dbfcfe5fec1df0da6921d9270..9eb1576a90355d9d4923aa0ff3063c89ce52519f 100644 --- a/include/errors/class_FusionDirectoryError.inc +++ b/include/errors/class_FusionDirectoryError.inc @@ -47,21 +47,35 @@ class FusionDirectoryError extends Error public function computeMsgDialogParameters (): array { - $trace = $this->getTrace(); + return [_('Error'), $this->htmlMessage, ERROR_DIALOG, static::formatTrace($this)]; + } + + public function display () + { + msg_dialog::display(...$this->computeMsgDialogParameters()); + } + + public static function formatTrace(Throwable $throwable): array + { + $trace = $throwable->getTrace(); + + foreach ($trace as &$traceStep) { + if (isset($traceStep['function']) && isset($traceStep['class']) && isset($traceStep['type'])) { + $traceStep['function'] = $traceStep['class'].$traceStep['type'].$traceStep['function']; + unset($traceStep['class']); + unset($traceStep['type']); + } + } + unset($traceStep); array_unshift( $trace, [ - 'file' => $this->getFile(), - 'line' => $this->getLine(), + 'file' => $throwable->getFile(), + 'line' => $throwable->getLine(), ] ); - return [_('Error'), $this->htmlMessage, ERROR_DIALOG, $trace]; - } - - public function display () - { - msg_dialog::display(...$this->computeMsgDialogParameters()); + return $trace; } } diff --git a/include/errors/class_SimplePluginError.inc b/include/errors/class_SimplePluginError.inc index 57709e9082f0381c061c1e0180fa296acfc2fb9b..ea2eb5854c7639cd2c6f204047202cfa00852b2a 100644 --- a/include/errors/class_SimplePluginError.inc +++ b/include/errors/class_SimplePluginError.inc @@ -102,17 +102,7 @@ class SimplePluginError extends FusionDirectoryError $html .= '<br/><br/><i>'.htmlescape(sprintf(_('Example: %s'), $example)).'</i> '; } - $trace = $this->getTrace(); - - array_unshift( - $trace, - [ - 'file' => $this->getFile(), - 'line' => $this->getLine(), - ] - ); - - return [_('Error'), $html, ERROR_DIALOG, $trace]; + return [_('Error'), $html, ERROR_DIALOG, FusionDirectoryError::formatTrace($this)]; } public static function relocate ($origin, FusionDirectoryError $error) diff --git a/include/errors/class_SimplePluginHookError.inc b/include/errors/class_SimplePluginHookError.inc index 5941024c0736f9cdd8e2acccc9ed360ddb4b1056..ce119646f8d293606202de5cf9302387188ef896 100644 --- a/include/errors/class_SimplePluginHookError.inc +++ b/include/errors/class_SimplePluginHookError.inc @@ -73,16 +73,6 @@ class SimplePluginHookError extends SimplePluginError $html .= 'Result: '.$this->htmlMessage."\n"; } - $trace = $this->getTrace(); - - array_unshift( - $trace, - [ - 'file' => $this->getFile(), - 'line' => $this->getLine(), - ] - ); - - return [_('Error'), $html, ERROR_DIALOG, $trace]; + return [_('Error'), $html, ERROR_DIALOG, FusionDirectoryError::formatTrace($this)]; } } diff --git a/include/errors/class_SimplePluginLdapError.inc b/include/errors/class_SimplePluginLdapError.inc index 1c7eb5ced87f8f919880204ca0e473834ae63b91..b2830937a8d72d7187d406e7e5cfb807cee388d3 100644 --- a/include/errors/class_SimplePluginLdapError.inc +++ b/include/errors/class_SimplePluginLdapError.inc @@ -88,16 +88,6 @@ class SimplePluginLdapError extends SimplePluginError $html .= '<br/><br/><i>'.htmlescape(_('Error:')).'</i> '.$this->htmlMessage; - $trace = $this->getTrace(); - - array_unshift( - $trace, - [ - 'file' => $this->getFile(), - 'line' => $this->getLine(), - ] - ); - - return [_('LDAP error'), $html, LDAP_ERROR, $trace]; + return [_('LDAP error'), $html, LDAP_ERROR, FusionDirectoryError::formatTrace($this)]; } } diff --git a/include/functions.inc b/include/functions.inc index 8af0c9ab12d81c75181c6b42d1ac7fcd0c67ce65..8d1ccdf09d5c11925ee66ebe50e0ec40395c9bf3 100644 --- a/include/functions.inc +++ b/include/functions.inc @@ -358,10 +358,7 @@ function ldap_init ($server, $base, $binddn = '', $pass = '') /* Sadly we've no proper return values here. Use the error message instead. */ if (!$ldap->success()) { - msg_dialog::display(_('Fatal error'), - sprintf(_("FATAL: Error when connecting the LDAP. Server said '%s'."), $ldap->get_error()), - FATAL_ERROR_DIALOG); - exit(); + throw new FatalError(htmlescape(sprintf(_('FATAL: Error when connecting the LDAP. Server said "%s".'), $ldap->get_error()))); } /* Preset connection base to $base and return to caller */ @@ -1863,10 +1860,13 @@ function load_all_classes () if (is_readable("$BASE_DIR/$path")) { require_once("$BASE_DIR/$path"); } else { - msg_dialog::display(_('Fatal error'), - sprintf(_("Cannot locate file '%s' - please run '%s' to fix this"), - "$BASE_DIR/$path", '<b>fusiondirectory-setup</b>'), FATAL_ERROR_DIALOG); - exit; + throw new FatalError( + sprintf( + htmlescape(_('Cannot locate file "%s" - please run "%s" to fix this')), + htmlescape("$BASE_DIR/$path"), + '<b>fusiondirectory-setup --update-cache</b>' + ) + ); } } } diff --git a/include/login/class_LoginCAS.inc b/include/login/class_LoginCAS.inc index 8d87d6f017a86fcb54e0d41229a054a138c63c68..790425445cdc311292a9d48fb2ec141b0e1db208 100644 --- a/include/login/class_LoginCAS.inc +++ b/include/login/class_LoginCAS.inc @@ -62,26 +62,20 @@ class LoginCAS extends LoginMethod $ui = userinfo::getLdapUser(static::$username); if ($ui === FALSE) { - msg_dialog::display( - _('Error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('CAS user "%s" could not be found in the LDAP'), static::$username - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } elseif (is_string($ui)) { - msg_dialog::display( - _('Error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('Login with user "%s" triggered error: %s'), static::$username, $ui - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } $ui->loadACL(); @@ -98,14 +92,12 @@ class LoginCAS extends LoginMethod } else { echo msg_dialog::get_dialogs(); if (!empty($message)) { - msg_dialog::display( - _('Error'), + throw new FatalError( htmlescape(sprintf( _('Login with user "%s" triggered error: %s'), static::$username, $message - )), - FATAL_ERROR_DIALOG + )) ); } exit(); diff --git a/include/login/class_LoginHTTPHeader.inc b/include/login/class_LoginHTTPHeader.inc index 30cdd15f5152931c3ebd53d536cd8c2200bd9ce8..4d414e56e8467fb549c273c9177624ea3818c775 100644 --- a/include/login/class_LoginHTTPHeader.inc +++ b/include/login/class_LoginHTTPHeader.inc @@ -44,40 +44,31 @@ class LoginHTTPHeader extends LoginMethod static::$username = $_SERVER['HTTP_'.$header]; if (!static::$username) { - msg_dialog::display( - _('Error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('No value found in HTTP header "%s"'), $header - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } $ui = userinfo::getLdapUser(static::$username); if ($ui === FALSE) { - msg_dialog::display( - _('Error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('Header user "%s" could not be found in the LDAP'), static::$username - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } elseif (is_string($ui)) { - msg_dialog::display( - _('Error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('Login with user "%s" triggered error: %s'), static::$username, $ui - ), - FATAL_ERROR_DIALOG + )) ); - exit(); } $ui->loadACL(); @@ -94,14 +85,12 @@ class LoginHTTPHeader extends LoginMethod } else { echo msg_dialog::get_dialogs(); if (!empty($message)) { - msg_dialog::display( - _('Error'), + throw new FatalError( htmlescape(sprintf( _('Login with user "%s" triggered error: %s'), static::$username, $message - )), - FATAL_ERROR_DIALOG + )) ); } exit(); diff --git a/include/login/class_LoginMethod.inc b/include/login/class_LoginMethod.inc index dc71610a1ccbdbd86d6b55e8e2f1ee0d70363cf8..1753e49f19ad78b1e00f25aaf3b1d86eb768ba4b 100644 --- a/include/login/class_LoginMethod.inc +++ b/include/login/class_LoginMethod.inc @@ -51,9 +51,9 @@ class LoginMethod foreach ($str as $tr) { if (!$tr['STATUS']) { if ($tr['IS_MUST_HAVE']) { - return _('LDAP schema check reported errors:').'<br/><br/><i>'.$tr['MSG'].'</i>'; + return htmlescape(_('LDAP schema check reported errors:')).'<br/><br/><i>'.htmlescape($tr['MSG']).'</i>'; } else { - msg_dialog::display(_('LDAP schema error'), $tr['MSG'], WARNING_DIALOG); + msg_dialog::display(_('LDAP schema error'), htmlescape($tr['MSG']), WARNING_DIALOG); } } } @@ -61,7 +61,7 @@ class LoginMethod } /*! \brief Check if locking LDAP branch is here or create it */ - static function checkForLockingBranch () + static function checkForLockingBranch (): bool { global $config; $ldap = $config->get_ldap_link(); @@ -75,6 +75,8 @@ class LoginMethod $error->display(); } } + + return TRUE; } /*! \brief Check username for invalid characters and check password is not empty @@ -173,14 +175,20 @@ class LoginMethod /*! \brief Run each step in $steps, stop on errors */ static function runSteps ($steps) { - foreach ($steps as $step) { - $status = static::$step(); - if (is_string($status)) { - msg_dialog::display(_('LDAP error'), $status, LDAP_ERROR); - return FALSE; - } elseif ($status === FALSE) { - return FALSE; + try { + foreach ($steps as $step) { + $status = static::$step(); + if (is_string($status)) { + /* Deprecated */ + msg_dialog::display(_('LDAP error'), $status, LDAP_ERROR); + return FALSE; + } elseif ($status === FALSE) { + return FALSE; + } } + } catch (FusionDirectoryError $e) { + $e->display(); + return FALSE; } return TRUE; } diff --git a/include/php_setup.inc b/include/php_setup.inc index a86652a1160c84e90e26b896b60d7bd70a39d91d..7740b87340ab9a50ef8c0fe85b2deaa795d9bca7 100644 --- a/include/php_setup.inc +++ b/include/php_setup.inc @@ -284,6 +284,34 @@ function gosaRaiseError ($errno, $errstr, $errfile, $errline) set_error_handler('gosaRaiseError', E_WARNING | E_NOTICE | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_STRICT); } +/*! + * \brief Catches throwables that no one catched + * + * \param Throwable $throwable + */ +function fusiondirectoryExceptionHandler (Throwable $throwable) +{ + try { + logging::log('error', 'fatal', '', [], 'Uncaught '.get_class($throwable).': '.$throwable->getMessage()); + } catch (Throwable $t) { + /* Ignore exceptions/errors here */ + } + + try { + if ($throwable instanceof FatalError) { + $throwable->display(); + } else { + $error = new FatalError(htmlescape(sprintf(_('Uncaught %s: %s'), get_class($throwable), $throwable->getMessage())), 0, $throwable); + $error->display(); + } + } catch (Throwable $t) { + /* Minimal display if exceptions happens when building the pretty one */ + echo 'Uncaught '.get_class($throwable).': '.$throwable->getMessage(); + } + + exit(255); +} + /*! * \brief Dummy error handler */ @@ -310,6 +338,7 @@ $error_collector = ""; $error_collector_mailto = ""; set_error_handler('gosaRaiseError', E_WARNING | E_NOTICE | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_STRICT); +set_exception_handler('fusiondirectoryExceptionHandler'); $variables_order = "ES"; ini_set("track_vars", 1); diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc index a7493931dcbf6c288a262fbf96317c44ff4add22..666b8b8cbdbfca38f107b80365e22de1b234c1cc 100644 --- a/include/simpleplugin/class_simplePlugin.inc +++ b/include/simpleplugin/class_simplePlugin.inc @@ -470,31 +470,24 @@ class simplePlugin implements SimpleTab { global $config; if (!$this->mainTab) { - msg_dialog::display(_('Fatal error'), _('Only main tab can compute dn'), FATAL_ERROR_DIALOG); - exit; + throw new FatalError(htmlescape(_('Only main tab can compute dn'))); } if (!isset($this->parent) || !($this->parent instanceof simpleTabs)) { - msg_dialog::display( - _('Fatal error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('Could not compute dn: no parent tab class for "%s"'), get_class($this) - ), - FATAL_ERROR_DIALOG + )) ); - exit; } $infos = $this->parent->objectInfos(); if ($infos === FALSE) { - msg_dialog::display( - _('Fatal error'), - sprintf( + throw new FatalError( + htmlescape(sprintf( _('Could not compute dn: could not find objectType infos from tab class "%s"'), get_class($this->parent) - ), - FATAL_ERROR_DIALOG + )) ); - exit; } $attr = $infos['mainAttr']; $ou = $infos['ou'];