diff --git a/html/jsonrpc.php b/html/jsonrpc.php index 717275b4041f42a18337254f3e3f548f3e41255d..4a35ba5479ef7168c7f49abb1bf6728b67f8183f 100644 --- a/html/jsonrpc.php +++ b/html/jsonrpc.php @@ -33,34 +33,24 @@ require_once("functions.inc"); require_once("variables.inc"); require_once("jsonrpcphp/jsonRPCServer.php"); -session::start(); +function initiate_rpc_session($id = NULL) +{ + global $config, $class_mapping, $BASE_DIR; -if (!session::global_is_set('LOGIN')) { - authenticate(); - session::global_set('LOGIN', TRUE); -} + session::start($id); -/* Reset errors */ -reset_errors(); -/* 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(); -} + if (!session::global_is_set('LOGIN')) { + authenticate(); + session::global_set('LOGIN', TRUE); + } + + /* Reset errors */ + reset_errors(); + /* Check if CONFIG_FILE is accessible */ + if (!is_readable(CONFIG_DIR."/".CONFIG_FILE)) { + die(sprintf(_("FusionDirectory configuration %s/%s is not readable. Aborted."), CONFIG_DIR, CONFIG_FILE)); + } -/* Parse configuration file */ -$config = new config(CONFIG_DIR."/".CONFIG_FILE, $BASE_DIR); -$config->set_current(key($config->data['LOCATIONS'])); -session::global_set('DEBUGLEVEL', 0); -$ui = ldap_login_user($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); -if (!$ui) { - header('WWW-Authenticate: Basic realm="FusionDirectory"'); - header('HTTP/1.0 401 Unauthorized'); - echo 'Invalid user or pwd '.$_SERVER['PHP_AUTH_USER'].'/'.$_SERVER['PHP_AUTH_PW']."\n"; - exit; -} /* Initially load all classes */ $class_list = get_declared_classes(); foreach ($class_mapping as $class => $path) { @@ -73,12 +63,29 @@ if (!$ui) { } } } -$plist = new pluglist($config, $ui); -session::global_set('plist', $plist); -$config->loadPlist($plist); -$config->get_departments(); -$config->make_idepartments(); -session::global_set('config', $config); + /* Parse configuration file */ + if (session::global_is_set('config') && session::global_is_set('plist')) { + $config = session::global_get('config'); + $plist = session::global_get('plist'); + } else { + $config = new config(CONFIG_DIR."/".CONFIG_FILE, $BASE_DIR); + $config->set_current(key($config->data['LOCATIONS'])); + session::global_set('DEBUGLEVEL', 0); + $ui = ldap_login_user($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + if (!$ui) { + header('WWW-Authenticate: Basic realm="FusionDirectory"'); + header('HTTP/1.0 401 Unauthorized'); + echo 'Invalid user or pwd '.$_SERVER['PHP_AUTH_USER'].'/'.$_SERVER['PHP_AUTH_PW']."\n"; + exit; + } + $plist = new pluglist($config, $ui); + session::global_set('plist', $plist); + $config->loadPlist($plist); + $config->get_departments(); + $config->make_idepartments(); + session::global_set('config', $config); + } +} /*! * \brief This class is the JSON-RPC webservice of FusionDirectory @@ -91,12 +98,20 @@ class fdRPCService function __construct () { + } + + function __call($method, $params) + { + initiate_rpc_session(array_shift($params)); + global $config; $this->ldap = $config->get_ldap_link(); if (!$this->ldap->success()) { die('Ldap error: '.$this->ldap->get_error()); } $this->ldap->cd($config->current['BASE']); + + return call_user_func_array(array($this, '_'.$method), $params); } /*! @@ -113,7 +128,7 @@ class fdRPCService * * \return The list of objects as an associative array (keys are dns) */ - function ls ($type, $attrs = NULL, $ou = NULL, $filter = '') + protected function _ls ($type, $attrs = NULL, $ou = NULL, $filter = '') { return objects::ls($type, $attrs, $ou, $filter); } @@ -126,7 +141,7 @@ class fdRPCService * * \return The attributes values as an associative array */ - function cat ($path, $type) + protected function _cat ($path, $type) { $tabobject = objects::open($path, $type); $object = $tabobject->getBaseObject(); @@ -145,7 +160,7 @@ class fdRPCService * * \return The informations on this type as an associative array */ - function infos($type) + protected function _infos($type) { global $config; $infos = objects::infos($type); @@ -164,7 +179,7 @@ class fdRPCService * * \return All attributes organized as sections */ - function fields($type, $dn = NULL, $tab = NULL) + protected function _fields($type, $dn = NULL, $tab = NULL) { if ($dn === NULL) { $tabobject = objects::create($type); @@ -207,7 +222,7 @@ class fdRPCService * * \return An array with errors if any, the resulting object dn otherwise */ - function update($type, $dn, $tab, $values) + protected function _update($type, $dn, $tab, $values) { if ($dn === NULL) { $tabobject = objects::create($type); @@ -229,11 +244,17 @@ class fdRPCService $tabobject->save(); return $tabobject->dn; } + + protected function _get_id () + { + return session_id(); + } } $service = new fdRPCService(); if (!jsonRPCServer::handle($service)) { - print 'no request'; + echo "no request\n"; + echo session_id()."\n"; print_r($_SERVER); } ?> diff --git a/include/class_session.inc b/include/class_session.inc index 2b6c10d4e1f2caafa9469bb1c3d7f8f4e321dd92..05954b971ab3a8a3196c7c4a1dd49e555b747e59 100644 --- a/include/class_session.inc +++ b/include/class_session.inc @@ -247,7 +247,7 @@ class session { /*! * \brief Start a session */ - public static function start() + public static function start($id = NULL) { session_name("FusionDirectory"); /* Set cookie lifetime to one day (The parameter is in seconds ) */ @@ -260,6 +260,9 @@ class session { !! The garbage collector is a cron job on debian systems, the cronjob will fetch the timeout from the php.ini, so if you use debian, you must hardcode session.gc_maxlifetime in your php.ini */ ini_set("session.gc_maxlifetime", 24 * 60 * 60); + if ($id !== NULL) { + session_id($id); + } session_start(); /* Check for changed browsers and bail out */ diff --git a/include/jsonrpcphp/jsonRPCServer.php b/include/jsonrpcphp/jsonRPCServer.php new file mode 100644 index 0000000000000000000000000000000000000000..4ed276d4aa068df59df8451d849b08a0557b6df6 --- /dev/null +++ b/include/jsonrpcphp/jsonRPCServer.php @@ -0,0 +1,86 @@ +<?php +/* + COPYRIGHT + +Copyright 2007 Sergio Vaccaro <sergio@inservibile.org> +Copyright 2013 FusionDirectory + +This file is part of JSON-RPC PHP. + +JSON-RPC PHP 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. + +JSON-RPC PHP 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 JSON-RPC PHP; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * This class build a json-RPC Server 1.0 + * http://json-rpc.org/wiki/specification + * + * @author sergio <jsonrpcphp@inservibile.org> + */ +class jsonRPCServer { + /** + * This function handle a request binding it to a given object + * + * @param object $object + * @return boolean + */ + public static function handle($object) { + + // checks if a JSON-RCP request has been received + if ( + $_SERVER['REQUEST_METHOD'] != 'POST' || + empty($_SERVER['CONTENT_TYPE']) || + $_SERVER['CONTENT_TYPE'] != 'application/json' + ) { + // This is not a JSON-RPC request + return false; + } + + // reads the input data + $request = json_decode(file_get_contents('php://input'),true); + + // executes the task on local object + try { + if ($result = @call_user_func_array(array($object,$request['method']),$request['params'])) { + $response = array ( + 'id' => $request['id'], + 'result' => $result, + 'error' => NULL + ); + } else { + $response = array ( + 'id' => $request['id'], + 'result' => NULL, + 'error' => 'unknown method or incorrect parameters' + ); + } + } catch (Exception $e) { + $response = array ( + 'id' => $request['id'], + 'result' => NULL, + 'error' => $e->getMessage() + ); + } + + // output the response + if (!empty($request['id'])) { // notifications don't want response + header('content-type: text/javascript'); + echo json_encode($response); + } + + // finish + return true; + } +} +?>