diff --git a/debian/conf/apache.conf b/debian/conf/apache.conf
index 3ebf8205..7a78bafc 100644
--- a/debian/conf/apache.conf
+++ b/debian/conf/apache.conf
@@ -5,5 +5,9 @@ Alias /ldapsaisie /usr/share/ldapsaisie
php_flag magic_quotes_gpc Off
php_flag register_globals Off
- Options -Indexes +FollowSymLinks
+ Options -Indexes +FollowSymLinks
+
+
+
+ Require all denied
diff --git a/debian/ldapsaisie.links b/debian/ldapsaisie.links
index ac5ab94f..ce6d4fed 100644
--- a/debian/ldapsaisie.links
+++ b/debian/ldapsaisie.links
@@ -2,3 +2,4 @@ var/cache/ldapsaisie usr/share/ldapsaisie/tmp
usr/local/share/ldapsaisie usr/share/ldapsaisie/local
usr/local/share/ldapsaisie etc/ldapsaisie/local
usr/share/ldapsaisie/lang/generate_lang_file.php usr/bin/ldapsaisie-generate-lang-file
+usr/share/ldapsaisie/bin/ldapsaisie.php usr/sbin/ldapsaisie
diff --git a/public_html/bin/ldapsaisie.php b/public_html/bin/ldapsaisie.php
new file mode 100755
index 00000000..d6d17708
--- /dev/null
+++ b/public_html/bin/ldapsaisie.php
@@ -0,0 +1,34 @@
+#!/usr/bin/php
+getExitStatus();
return array($exit_status, $result);
}
-
diff --git a/public_html/includes/class/class.LSauthMethod_CAS.php b/public_html/includes/class/class.LSauthMethod_CAS.php
index 0387daf3..0946300a 100644
--- a/public_html/includes/class/class.LSauthMethod_CAS.php
+++ b/public_html/includes/class/class.LSauthMethod_CAS.php
@@ -36,7 +36,7 @@ class LSauthMethod_CAS extends LSauthMethod {
if (!parent :: __construct())
return;
- if (LSsession :: includeFile(PHP_CAS_PATH)) {
+ if (LSsession :: includeFile(PHP_CAS_PATH, true)) {
if (defined('PHP_CAS_DEBUG_FILE')) {
LSlog :: debug('LSauthMethod_CAS : enable debug file '.PHP_CAS_DEBUG_FILE);
phpCAS::setDebug(PHP_CAS_DEBUG_FILE);
diff --git a/public_html/includes/class/class.LScli.php b/public_html/includes/class/class.LScli.php
new file mode 100644
index 00000000..325f4ad7
--- /dev/null
+++ b/public_html/includes/class/class.LScli.php
@@ -0,0 +1,178 @@
+
+ */
+class LScli {
+
+ // Configured commands
+ private static $commands = array();
+
+ /**
+ * Add a CLI command
+ *
+ * @param[in] $command string The CLI command name (required)
+ * @param[in] $handler callable The CLI command handler (must be callable, required)
+ * @param[in] $short_desc string|false A short description of what this command does (required)
+ * @param[in] $usage_args string|false A short list of commands available arguments show in usage message (optional, default: false)
+ * @param[in] $long_desc string|false A long description of what this command does (optional, default: false)
+ * @param[in] $override boolean Allow override if a command already exists with the same name (optional, default: false)
+ **/
+ public static function add_command($command, $handler, $short_desc, $usage_args=false, $long_desc=false, $override=false) {
+ if (array_key_exists($command, self :: $commands) && !$override) {
+ LSerror :: addErrorCode('LScli_01', $command);
+ return False;
+ }
+
+ if (!is_callable($handler)) {
+ LSerror :: addErrorCode('LScli_02', $command);
+ return False;
+ }
+
+ self :: $commands[$command] = array (
+ 'handler' => $handler,
+ 'short_desc' => $short_desc,
+ 'usage_args' => $usage_args,
+ 'long_desc' => $long_desc,
+ );
+ return True;
+ }
+
+ /**
+ * Show usage message
+ *
+ * @param[in] $error string|false Error message to display before usage message (optional, default: false)
+ * @retval void
+ **/
+ public static function usage($error=false) {
+ global $argv;
+
+ if ($error)
+ echo "$error\n\n";
+
+ echo "Usage : ".basename($argv[0])." [-h] [-qdC] command\n";
+ echo " -h Show this message\n";
+ echo " -q|--quiet Quiet mode\n";
+ echo " -d|--debug Debug mode\n";
+ echo " -C|--console Log on console\n";
+ echo " command Command to run\n";
+ echo "\n";
+ echo "Available commands :\n";
+
+ foreach (self :: $commands as $command => $info) {
+ echo " $command : ".$info['short_desc']."\n";
+ echo " ".basename($argv[0])." $command ".($info['usage_args']?$info['usage_args']:'')."\n";
+ if ($info['long_desc']) {
+ if (is_array($info['long_desc']))
+ $info['long_desc'] = implode("\n", $info['long_desc']);
+ echo "\n ".str_replace("\n", "\n ", wordwrap($info['long_desc']))."\n";
+ }
+ echo "\n";
+ }
+ if (empty(self :: $commands))
+ echo " Currently no available command is declared.\n";
+
+ exit(($error?1:0));
+ }
+
+ /**
+ * Handle CLI arguments and run command (if provided)
+ *
+ * @retval void
+ **/
+ public static function handle_args() {
+ global $argv;
+ $log_level = 'INFO';
+ $command = false;
+ $command_args = array();
+ LSlog :: debug("handle_args :\n".varDump($argv));
+ for ($i=1; $i < count($argv); $i++) {
+ if (array_key_exists($argv[$i], self :: $commands)) {
+ if (!$command)
+ $command = $argv[$i];
+ else
+ self :: usage(_("Only one command could be executed !"));
+ }
+ else {
+ switch($argv[$i]) {
+ case '-h':
+ case '--help':
+ self :: usage();
+ break;
+ case '-d':
+ case '--debug':
+ $log_level = 'DEBUG';
+ break;
+ case '-q':
+ case '--quiet':
+ $log_level = 'WARNING';
+ break;
+ case '-C':
+ case '--console':
+ LSlog :: logOnConsole();
+ break;
+ default:
+ if ($command)
+ $command_args[] = $argv[$i];
+ else
+ self :: usage(
+ getFData(_("Invalid parameter \"%{parameter}\".\nNote: Command's parameter/argument must be place after the command."), $argv[$i])
+ );
+ }
+ }
+ }
+
+ // Set log level
+ LSlog :: setLevel($log_level);
+
+ if (!$command) {
+ LSlog :: debug("LScli :: handle_args() : no detected command => show usage");
+ self :: usage();
+ }
+
+ // Run command
+ LSlog :: debug('Run '.basename($argv[0])." command $command with argument(s) '".implode("', '", $command_args)."'");
+ try {
+ $result = call_user_func($cli_commands[$command]['handler'], $command_args);
+
+ exit($result?0:1);
+ }
+ catch(Exception $e) {
+ LSlog :: exception($e, "An exception occured running CLI command $command");
+ exit(1);
+ }
+ }
+
+}
+
+/*
+ * Error Codes
+ */
+LSerror :: defineError('LScli_01',
+_("LScli : The CLI command '%{command}' already exists.")
+);
+LSerror :: defineError('LScli_02',
+_("LScli : The CLI command '%{command}' handler is not callable.")
+);
diff --git a/public_html/includes/class/class.LSformElement_image.php b/public_html/includes/class/class.LSformElement_image.php
index 16e70f8d..78d63ef7 100644
--- a/public_html/includes/class/class.LSformElement_image.php
+++ b/public_html/includes/class/class.LSformElement_image.php
@@ -61,9 +61,9 @@ class LSformElement_image extends LSformElement {
}
if (!empty($this -> values[0])) {
- $img_path = LSsession :: getTmpFile($this -> values[0]);
+ $img_url = LSsession :: getTmpFileURL($this -> values[0]);
LStemplate :: assign('LSformElement_image',array(
- 'img' => $img_path,
+ 'img' => $img_url,
'id' => $id,
));
if (!$this -> isFreeze()) {
@@ -100,10 +100,6 @@ class LSformElement_image extends LSformElement {
$fp = fopen($_FILES[$this -> name]['tmp_name'], "r");
$buf = fread($fp, filesize($_FILES[$this -> name]['tmp_name']));
fclose($fp);
- $tmp_file = LS_TMP_DIR.$this -> name.'_'.rand().'.tmp';
- if (move_uploaded_file($_FILES[$this -> name]['tmp_name'],$tmp_file)) {
- LSsession :: addTmpFile($buf,$tmp_file);
- }
$return[$this -> name][0] = $buf;
}
else {
diff --git a/public_html/includes/class/class.LSimport.php b/public_html/includes/class/class.LSimport.php
index 7f47b7cb..225b42f6 100644
--- a/public_html/includes/class/class.LSimport.php
+++ b/public_html/includes/class/class.LSimport.php
@@ -53,7 +53,7 @@ class LSimport {
$fp = fopen($_FILES['importfile']['tmp_name'], "r");
$buf = fread($fp, filesize($_FILES['importfile']['tmp_name']));
fclose($fp);
- $tmp_file = LS_TMP_DIR.'importfile'.'_'.rand().'.tmp';
+ $tmp_file = LS_TMP_DIR_PATH.'importfile'.'_'.rand().'.tmp';
if (move_uploaded_file($_FILES['importfile']['tmp_name'],$tmp_file)) {
LSsession :: addTmpFile($buf,$tmp_file);
}
diff --git a/public_html/includes/class/class.LSlog.php b/public_html/includes/class/class.LSlog.php
index 93d6c2f5..d2c3e506 100644
--- a/public_html/includes/class/class.LSlog.php
+++ b/public_html/includes/class/class.LSlog.php
@@ -20,7 +20,7 @@
******************************************************************************/
-/**
+/**
* Handle logging
*
* @author Benjamin Renard
@@ -61,8 +61,7 @@ class LSlog {
public static function start() {
// Load configuration
self :: $enabled = self :: getConfig('enable', false, 'bool');
- self :: $level = self :: getConfig('level', self :: $default_level, 'string');
- if (!array_key_exists(self :: $level, self :: $levels)) self :: $level = 'WARNING';
+ self :: setLevel();
// Load default handlers class
if (!LSsession :: loadLSclass('LSlog_handler', null, true)) {
@@ -80,31 +79,83 @@ class LSlog {
$handler_config = array('handler' => $handler);
else
$handler = (isset($handler_config['handler'])?$handler_config['handler']:'system');
-
- $handler_class = "LSlog_$handler";
- // Load handler class
- if (!LSsession :: loadLSclass($handler_class) || !class_exists($handler_class)) {
- LSerror :: addErrorCode('LSlog_01', $handler);
+ if (!self :: add_handler($handler, $handler_config))
continue;
- }
- $handler_obj = new $handler_class($handler_config);
- if ($handler_obj -> checkCompatibility())
- self :: $handlers[] = $handler_obj;
- else
- LSdebug("LSlog handler $handler not supported.");
$debug_handlers[] = $handler;
}
LSdebug('LSlog enabled with level='.self :: $level.' and following handlers : '.implode(', ', $debug_handlers));
+ set_exception_handler(array('LSlog', 'exception'));
+ return True;
+ }
+
+ /**
+ * Add handler
+ *
+ * @param[in] $handler string The handler name
+ * @param[in] $handler_config array The handler configuration (optional)
+ *
+ * @retval boolean True if handler added, false otherwise
+ **/
+ public static function add_handler($handler, $handler_config = array()) {
+ $handler_class = "LSlog_$handler";
+
+ // Load handler class
+ if (!LSsession :: loadLSclass($handler_class) || !class_exists($handler_class)) {
+ LSerror :: addErrorCode('LSlog_01', $handler);
+ return false;
+ }
+
+ $handler_obj = new $handler_class($handler_config);
+ if ($handler_obj -> checkCompatibility()) {
+ self :: $handlers[] = $handler_obj;
+ return True;
+ }
+ LSdebug("LSlog handler $handler not supported.");
+ return false;
+ }
+
+ /**
+ * Enable console handler (if not already enabled)
+ *
+ * @retval boolean True if log on console enabled, false otherwise
+ **/
+ public static function logOnConsole() {
+ for ($i=0; $i < count(self :: $handlers); $i++)
+ if (is_a(self :: $handlers[$i], 'LSlog_console'))
+ return true;
+ return self :: add_handler('console');
+ }
+
+
+ /**
+ * Set log level
+ *
+ * @param[in] $level string|null The log level (optinal, default: from configuration or 'WARNING')
+ *
+ * @retval boolean True if log level set, false otherwise
+ **/
+ public static function setLevel($level=null) {
+ if (!$level) {
+ $level = self :: getConfig('level', self :: $default_level, 'string');
+ if (!array_key_exists(self :: $level, self :: $levels)) {
+ self :: $level = 'WARNING';
+ if ($level)
+ self :: warning("Invalid log level '$level' configured. Set log level to WARNING.");
+ $level = 'WARNING';
+ }
+ }
+ else if (!array_key_exists($level, self :: $levels))
+ return false;
+ self :: $level = $level;
+
// Set PHP error/exception handlers
if (self :: $level == 'DEBUG')
set_error_handler(array('LSlog', 'php_error'), E_ALL & ~E_STRICT);
else
set_error_handler(array('LSlog', 'php_error'), E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
- set_exception_handler(array('LSlog', 'exception'));
-
return True;
}
@@ -236,7 +287,7 @@ class LSlog {
$traces = debug_backtrace();
if (!is_array($traces) || count($traces) <= 2)
return "";
-
+
$msg = array();
for ($i=2; $i < count($traces); $i++) {
$trace = array("#$i");
@@ -248,7 +299,7 @@ class LSlog {
$trace[] = $traces[$i]['function']. "()";
$msg[] = implode(" - ", $trace);
}
-
+
return implode("\n", $msg);
}
@@ -382,4 +433,3 @@ class LSlog {
LSerror :: defineError('LSlog_01',
_("LSlog : Fail to load logging handler %{handler}.")
);
-
diff --git a/public_html/includes/class/class.LSlog_console.php b/public_html/includes/class/class.LSlog_console.php
new file mode 100644
index 00000000..5e81e571
--- /dev/null
+++ b/public_html/includes/class/class.LSlog_console.php
@@ -0,0 +1,61 @@
+
+ */
+class LSlog_console extends LSlog_handler {
+
+ // File-descriptors for stdout/stderr
+ private $stdout;
+ private $stderr;
+
+ /**
+ * Constructor
+ *
+ * @param[in] $config array The handler configuration
+ *
+ * @retval void
+ **/
+ public function __construct($config) {
+ parent :: __construct($config);
+ $this -> stdout = fopen('php://stdout', 'w');
+ $this -> stderr = fopen('php://stderr', 'w');
+ }
+
+ /**
+ * Log a message
+ *
+ * @param[in] $level string The message level
+ * @param[in] $message string The message
+ *
+ * @retval void
+ **/
+ public function logging($level, $message) {
+ return fwrite(
+ ($level > 1?$this -> stderr:$this -> stdout),
+ date('Y/m/d H:i:s').' - '.$level.' - '.$message."\n"
+ );
+ }
+}
diff --git a/public_html/includes/class/class.LSlog_file.php b/public_html/includes/class/class.LSlog_file.php
index 233c9233..37f2ce62 100644
--- a/public_html/includes/class/class.LSlog_file.php
+++ b/public_html/includes/class/class.LSlog_file.php
@@ -20,7 +20,7 @@
******************************************************************************/
-/**
+/**
* Handle logging to file (using error_log PHP function with message_type = 3)
*
* @author Benjamin Renard
@@ -41,6 +41,8 @@ class LSlog_file extends LSlog_handler {
parent :: __construct($config);
// For reto-compatibilty, use LSlog.filename as default log path value
$this -> path = self :: getConfig('path', LSlog :: getConfig('filename', 'tmp/LS.log'));
+ if (substr($this -> path, 0, 1) != '/')
+ $this -> path = LS_ROOT_DIR."/".$this -> path;
}
/**
diff --git a/public_html/includes/class/class.LSsession.php b/public_html/includes/class/class.LSsession.php
index 286a1f7a..ed0b8da7 100644
--- a/public_html/includes/class/class.LSsession.php
+++ b/public_html/includes/class/class.LSsession.php
@@ -98,14 +98,14 @@ class LSsession {
*
* @retval true si tout c'est bien passé, false sinon
*/
- public static function includeFile($file) {
- if (file_exists(LS_LOCAL_DIR.'/'.$file)) {
- $file=LS_LOCAL_DIR.'/'.$file;
- }
- elseif (!file_exists($file)) {
+ public static function includeFile($file, $external=false) {
+ $path = ($external?'':LS_ROOT_DIR."/").$file;
+ $local_path = ($external?'':LS_ROOT_DIR."/").LS_LOCAL_DIR.'/'.$file;
+ $path = (file_exists($local_path)?$local_path:$path);
+ if (!file_exists($path)) {
return;
}
- return include_once($file);
+ return include_once($path);
}
/**
@@ -147,24 +147,24 @@ class LSsession {
* @author Benjamin Renard
*
* @retval true si tout c'est bien passé, false sinon
- */
+ */
private static function startLStemplate() {
if ( self :: loadLSclass('LStemplate') ) {
return LStemplate :: start(
array(
- 'smarty_path' => LSconfig :: get('Smarty'),
- 'template_dir' => LS_TEMPLATES_DIR,
- 'image_dir' => LS_IMAGES_DIR,
- 'css_dir' => LS_CSS_DIR,
- 'compile_dir' => LS_TMP_DIR,
- 'debug' => LSdebug,
- 'debug_smarty' => (isset($_REQUEST['LStemplate_debug'])),
+ 'smarty_path' => LSconfig :: get('Smarty'),
+ 'template_dir' => LS_ROOT_DIR . '/'. LS_TEMPLATES_DIR,
+ 'image_dir' => LS_IMAGES_DIR,
+ 'css_dir' => LS_CSS_DIR,
+ 'compile_dir' => LS_TMP_DIR_PATH,
+ 'debug' => LSdebug,
+ 'debug_smarty' => (isset($_REQUEST) && isset($_REQUEST['LStemplate_debug'])),
)
);
}
return False;
}
-
+
/**
* Retourne le topDn de la session
*
@@ -320,6 +320,23 @@ class LSsession {
return;
}
+ /**
+ * Load LdapSaisie CLI class
+ *
+ * @author Benjamin Renard
+ *
+ * @param[in] $value La valeur du fichier
+ *
+ * @retval mixed
+ **/
+ public static function getTmpFileURL($value) {
+ $path = self :: getTmpFile($value);
+ if (substr($path, 0, strlen(LS_ROOT_DIR)) == LS_ROOT_DIR)
+ return substr($path, strlen(LS_ROOT_DIR)+1);
+ return False;
+ }
+
/**
* Supprime les fichiers temporaires
*
diff --git a/public_html/includes/class/class.LStemplate.php b/public_html/includes/class/class.LStemplate.php
index a911c304..263639f2 100644
--- a/public_html/includes/class/class.LStemplate.php
+++ b/public_html/includes/class/class.LStemplate.php
@@ -86,12 +86,12 @@ class LStemplate {
self :: $config[$key] = $value;
}
- if (LSsession :: includeFile(self :: $config['smarty_path'])) {
+ if (LSsession :: includeFile(self :: $config['smarty_path'], true)) {
self :: $_smarty = new Smarty();
self :: $_smarty -> template_dir = self :: $config['template_dir'];
if ( ! is_writable(self :: $config['compile_dir']) ) {
- die(_('LStemplate : compile directory is not writable (dir : '.self :: $config['compile_dir'].')'));
+ LSlog :: fatal(getFData(_("LStemplate : compile directory is not writable (dir : %{dir})"), self :: $config['compile_dir']));
}
self :: $_smarty -> compile_dir = self :: $config['compile_dir'];
@@ -442,4 +442,3 @@ _("LStemplate : Fail to execute trigger %{callable} on event %{event} : is not c
LSerror :: defineError('LStemplate_03',
_("LStemplate : Error during the execution of the trigger %{callable} on event %{event}.")
);
-