An error occurred while loading the file. Please try again.
-
Côme Chilliet authored
Adds FusionDirectoryError base class and one child class for check failures. Use this new class for IntAttribute as first test. Build HTML dialog from error class using attribute data. issue #6071
Unverified172f088f
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2003-2010 Cajus Pollmeier
Copyright (C) 2011-2016 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.
*/
/*!
* \file functions.inc
* Common functions and named definitions.
*/
/* Define common locations and variables */
require_once('variables.inc');
/* Include required files */
require_once(CACHE_DIR.'/'.CLASS_CACHE);
require_once('functions_debug.inc');
require_once('accept-to-gettext.inc');
/* Define constants for debugging */
define('DEBUG_TRACE', 1); /*! Debug level for tracing of common actions (save, check, etc.) */
define('DEBUG_LDAP', 2); /*! Debug level for LDAP queries */
define('DEBUG_DB', 4); /*! Debug level for database operations */
define('DEBUG_SHELL', 8); /*! Debug level for shell commands */
define('DEBUG_POST', 16); /*! Debug level for POST content */
define('DEBUG_SESSION', 32); /*! Debug level for SESSION content */
define('DEBUG_CONFIG', 64); /*! Debug level for CONFIG information */
define('DEBUG_ACL', 128); /*! Debug level for ACL infos */
define('DEBUG_SI', 256); /*! Debug level for communication with Argonaut */
define('DEBUG_MAIL', 512); /*! Debug level for all about mail (mailAccounts, imap, sieve etc.) */
define('DEBUG_FAI', 1024); /* FAI (incomplete) */
/* Rewrite german 'umlauts' and spanish 'accents'
to get better results */
$REWRITE = [ "ä" => "ae",
"ö" => "oe",
"ü" => "ue",
"Ä" => "Ae",
"Ö" => "Oe",
"Ü" => "Ue",
"ß" => "ss",
"á" => "a",
"é" => "e",
"í" => "i",
"ó" => "o",
"ú" => "u",
"Á" => "A",
"É" => "E",
"Í" => "I",
"Ó" => "O",
"Ú" => "U",
"ñ" => "ny",
"Ñ" => "Ny" ];
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
/*!
* \brief Does autoloading for classes used in FusionDirectory.
*
* Takes the list generated by 'fusiondirectory-setup' and loads the
* file containing the requested class.
*
* \param array $class_name list of class name
*/
function __fusiondirectory_autoload ($class_name)
{
global $class_mapping, $BASE_DIR, $config;
if ($class_mapping === NULL) {
if (isset($config) && is_object($config) &&
$config->get_cfg_value('displayerrors') == 'TRUE') {
list($trace, ) = html_trace();
echo $trace;
echo "<br/>\n";
}
echo sprintf(_("Fatal error: no class locations defined - please run '%s' to fix this"), "<b>fusiondirectory-setup --update-cache</b>");
exit;
}
/* Do not try to autoload smarty classes */
if (strpos($class_name, 'Smarty_') === 0) {
return;
}
if (isset($class_mapping["$class_name"])) {
require_once($BASE_DIR.'/'.$class_mapping["$class_name"]);
} else {
logging::debug(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $class_name, 'Could not load');
if (isset($config) && is_object($config) &&
$config->get_cfg_value('displayerrors') == 'TRUE') {
list($trace, ) = html_trace();
echo $trace;
echo "<br/>\n";
}
echo sprintf(_("Fatal error: cannot instantiate class '%s' - try running '%s' to fix this"), $class_name, "<b>fusiondirectory-setup --update-cache</b>");
exit;
}
}
spl_autoload_register('__fusiondirectory_autoload');
/*!
* \brief Checks if a class is available.
*
* \param string $name The subject of the test
*
* \return boolean Return TRUE if successfull FALSE otherwise
*/
function class_available ($name)
{
global $class_mapping;
return isset($class_mapping[$name]);
}
/*!
* \brief Check if plugin is available
*
* Checks if a given plugin is available and readable.
*
* \param string $plugin the subject of the check
*
* \return boolean Return TRUE if successfull FALSE otherwise
*/
function plugin_available ($plugin)
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
{
global $class_mapping, $BASE_DIR;
if (!isset($class_mapping[$plugin])) {
return FALSE;
} else {
return is_readable($BASE_DIR.'/'.$class_mapping[$plugin]);
}
}
/*!
* \brief Debug level action
*
* Print a DEBUG level if specified debug level of the level matches the
* the configured debug level.
*
* \param int $level The log level of the message (should use the constants,
* defined in functions.in (DEBUG_TRACE, DEBUG_LDAP, etc.)
*
* \param int $line Define the line of the logged action (using __LINE__ is common)
*
* \param string $function Define the function where the logged action happened in
* (using __FUNCTION__ is common)
*
* \param string $file Define the file where the logged action happend in
* (using __FILE__ is common)
*
* \param mixed $data The data to log. Can be a message or an array, which is printed
* with print_a
*
* \param string $info Optional: Additional information
*/
function DEBUG ($level, $line, $function, $file, $data, $info = '')
{
logging::debug($level, $line, $function, $file, $data, $info);
}
/*!
* \brief Return themed path for specified base file
*
* Depending on its parameters, this function returns the full
* path of a template file. First match wins while searching
* in this order:
*
* - load theme depending file
* - load global theme depending file
* - load default theme file
* - load global default theme file
*
* \param string $filename The base file name
*
* \param boolean $plugin Flag to take the plugin directory as search base
*
* \param string $path User specified path to take as search base
*
* \return string Full path to the template file
*/
function get_template_path ($filename = '', $plugin = FALSE, $path = '')
{
global $config, $BASE_DIR;
$default_theme = 'breezy';
/* Set theme */
if (isset($config)) {
$theme = $config->get_cfg_value('theme', $default_theme);
} else {
$theme = $default_theme;
}
/* Return path for empty filename */
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
if ($filename == '') {
return "themes/$theme/";
}
/* Return plugin dir or root directory? */
if ($plugin) {
if ($path == '') {
$path = session::get('plugin_dir');
$nf = preg_replace('!^'.$BASE_DIR.'/!', '', preg_replace('/^\.\.\//', '', $path));
} else {
$nf = preg_replace('!^'.$BASE_DIR.'/!', '', $path);
}
$paths = [
"$BASE_DIR/ihtml/themes/$theme/$nf/$filename",
"$BASE_DIR/ihtml/themes/$default_theme/$nf/$filename",
"$BASE_DIR/ihtml/themes/default/$nf/$filename",
$path."/$filename"
];
} else {
$paths = [
"themes/$theme/$filename",
"$BASE_DIR/ihtml/themes/$theme/$filename",
"themes/$default_theme/$filename",
"$BASE_DIR/ihtml/themes/$default_theme/$filename",
"themes/default/$filename",
"$BASE_DIR/ihtml/themes/default/$filename",
$filename
];
}
foreach ($paths as $path) {
if (file_exists($path)) {
return $path;
}
}
return end($paths);
}
/*!
* \brief Remove multiple entries from an array
*
* Removes every element that is in $needles from the
* array given as $haystack
*
* \param array $needles array of the entries to remove
*
* \param array $haystack original array to remove the entries from
*/
function array_remove_entries (array $needles, array $haystack)
{
return array_values(array_diff($haystack, $needles));
}
/*!
* \brief Remove multiple entries from an array (case-insensitive)
*
* Removes every element that is in $needles from the
* array given as $haystack but case insensitive
*
* \param array $needles array of the entries to remove
*
* \param array $haystack original array to remove the entries from
*/
function array_remove_entries_ics (array $needles, array $haystack)
{
// strcasecmp will work, because we only compare ASCII values here
return array_values(array_udiff($haystack, $needles, 'strcasecmp'));
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
}
/*!
* \brief Merge to array but remove duplicate entries (case-insensitive)
*
* Merges two arrays and removes duplicate entries. Triggers
* an error if first or second parametre is not an array.
*
* \param array $ar1 first array
*
* \param array $ar2 second array
*
* \return array
*/
function array_merge_unique (array $ar1, array $ar2)
{
return array_values(array_unique(array_merge($ar1, $ar2)));
}
/*!
* \brief Generate a system log info
*
* Creates a syslog message, containing user information.
*
* \param string $message the message to log
*/
function fusiondirectory_log ($message)
{
global $ui;
/* Preset to something reasonable */
$username = '[unauthenticated]';
/* Replace username if object is present */
if (isset($ui)) {
if ($ui->uid != '') {
$username = '['.$ui->uid.']';
} else {
$username = '[unknown]';
}
}
syslog(LOG_INFO, "FusionDirectory $username: $message");
}
/*!
* \brief Initialize a LDAP connection
*
* Initializes a LDAP connection.
*
* \param string $server The server we are connecting to
*
* \param string $base The base of our ldap tree
*
* \param string $binddn Default: empty
*
* \param string $pass Default: empty
*
* \return LDAP object
*/
function ldap_init ($server, $base, $binddn = '', $pass = '')
{
global $config;
$ldap = new LDAP($binddn, $pass, $server,
isset($config->current['LDAPFOLLOWREFERRALS']) && $config->current['LDAPFOLLOWREFERRALS'] == 'TRUE',
isset($config->current['LDAPTLS']) && $config->current['LDAPTLS'] == 'TRUE');
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
/* 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();
}
/* Preset connection base to $base and return to caller */
$ldap->cd($base);
return $ldap;
}
/*!
* \brief Add a lock for object(s)
*
* Adds a lock by the specified user for one ore multiple objects.
* If the lock for that object already exists, an error is triggered.
*
* \param array $object The object or array of objects to lock
*
* \param string $user The user who shall own the lock
*/
function add_lock ($object, $user)
{
global $config;
/* Remember which entries were opened as read only, because we
don't need to remove any locks for them later.
*/
if (!session::is_set('LOCK_CACHE')) {
session::set('LOCK_CACHE', ['']);
}
if (is_array($object)) {
foreach ($object as $obj) {
add_lock($obj, $user);
}
return;
}
$cache = &session::get_ref('LOCK_CACHE');
if (isset($_POST['open_readonly'])) {
$cache['READ_ONLY'][$object] = TRUE;
return;
}
if (isset($cache['READ_ONLY'][$object])) {
unset($cache['READ_ONLY'][$object]);
}
/* Just a sanity check... */
if ($object == '' || $user == '') {
msg_dialog::display(_('Internal error'), _('Error while adding a lock. Contact the developers!'), ERROR_DIALOG);
return;
}
/* Check for existing entries in lock area */
$ldap = $config->get_ldap_link();
$ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
$ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))',
['fdUserDn']);
if ($ldap->get_errno() == 32) {
/* No such object, means the locking branch is missing, create it */
$ldap->cd($config->current['BASE']);
$ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
$ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
$ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))',
['fdUserDn']);
}
if (!$ldap->success()) {
msg_dialog::display(_('Configuration error'), sprintf(_('Cannot create locking information in LDAP tree. Please contact your administrator!').'<br><br>'._('LDAP server returned: %s'), '<br><br><i>'.$ldap->get_error().'</i>'), ERROR_DIALOG);