mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-26 21:01:30 +02:00
first version of a setup command that can run via admins remote command execution
This commit is contained in:
parent
e74c6debaa
commit
4f77162f64
@ -78,6 +78,9 @@ switch($action)
|
|||||||
case '--check-acl';
|
case '--check-acl';
|
||||||
return do_check_acl();
|
return do_check_acl();
|
||||||
|
|
||||||
|
case '--show-header';
|
||||||
|
return run_command(new setup_cmd_showheader());
|
||||||
|
|
||||||
case '--exit-codes':
|
case '--exit-codes':
|
||||||
return list_exit_codes();
|
return list_exit_codes();
|
||||||
|
|
||||||
@ -123,6 +126,14 @@ function run_command(admin_cmd $cmd)
|
|||||||
case '--skip-checks': //do not yet run the checks for scheduled local commands
|
case '--skip-checks': //do not yet run the checks for scheduled local commands
|
||||||
$skip_checks = true;
|
$skip_checks = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '--header-access':
|
||||||
|
if ($cmd instanceof setup_cmd)
|
||||||
|
{
|
||||||
|
list($user,$pw) = explode(',',array_shift($arguments),2);
|
||||||
|
$cmd->set_header_secret($user,$pw);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//fail(99,lang('Unknown option %1',$extra);
|
//fail(99,lang('Unknown option %1',$extra);
|
||||||
@ -138,7 +149,15 @@ function run_command(admin_cmd $cmd)
|
|||||||
{
|
{
|
||||||
fail($cmd->errno,$cmd->error);
|
fail($cmd->errno,$cmd->error);
|
||||||
}
|
}
|
||||||
echo $msg."\n\n";
|
if (($value = unserialize($msg)) !== false && $msg !== serialize(false))
|
||||||
|
{
|
||||||
|
print_r($value);
|
||||||
|
echo "\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo $msg."\n\n";
|
||||||
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,4 +460,4 @@ function do_subscribe_other($account_lid,$pw=null)
|
|||||||
//$icServer->subscribeMailbox($mailbox);
|
//$icServer->subscribeMailbox($mailbox);
|
||||||
//exit;
|
//exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
abstract class admin_cmd
|
abstract class admin_cmd
|
||||||
{
|
{
|
||||||
const edit_user = 16;
|
|
||||||
|
|
||||||
const deleted = 0;
|
const deleted = 0;
|
||||||
const scheduled = 1;
|
const scheduled = 1;
|
||||||
const successful = 2;
|
const successful = 2;
|
||||||
@ -29,7 +27,7 @@ abstract class admin_cmd
|
|||||||
private $status;
|
private $status;
|
||||||
|
|
||||||
static $stati = array(
|
static $stati = array(
|
||||||
admin_cmd::scheduled => 'scheduled',
|
admin_cmd::scheduled => 'scheduled',
|
||||||
admin_cmd::successful => 'successful',
|
admin_cmd::successful => 'successful',
|
||||||
admin_cmd::failed => 'failed',
|
admin_cmd::failed => 'failed',
|
||||||
admin_cmd::deleted => 'deleted',
|
admin_cmd::deleted => 'deleted',
|
||||||
@ -48,7 +46,7 @@ abstract class admin_cmd
|
|||||||
public $requested_email;
|
public $requested_email;
|
||||||
public $comment;
|
public $comment;
|
||||||
private $id;
|
private $id;
|
||||||
private $uid;
|
protected $uid;
|
||||||
private $type = __CLASS__;
|
private $type = __CLASS__;
|
||||||
public $remote_id;
|
public $remote_id;
|
||||||
|
|
||||||
@ -394,8 +392,6 @@ abstract class admin_cmd
|
|||||||
{
|
{
|
||||||
if (is_null(admin_cmd::$sql))
|
if (is_null(admin_cmd::$sql))
|
||||||
{
|
{
|
||||||
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
|
|
||||||
|
|
||||||
admin_cmd::$sql = new so_sql('admin','egw_admin_queue',null,'cmd_');
|
admin_cmd::$sql = new so_sql('admin','egw_admin_queue',null,'cmd_');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,8 +405,6 @@ abstract class admin_cmd
|
|||||||
{
|
{
|
||||||
if (is_null(admin_cmd::$remote))
|
if (is_null(admin_cmd::$remote))
|
||||||
{
|
{
|
||||||
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
|
|
||||||
|
|
||||||
admin_cmd::$remote = new so_sql('admin','egw_admin_remote');
|
admin_cmd::$remote = new so_sql('admin','egw_admin_remote');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -815,7 +809,7 @@ abstract class admin_cmd
|
|||||||
* Save / adds a remote instance
|
* Save / adds a remote instance
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return array/boolean data including remote_id or false on failure
|
* @return int remote_id
|
||||||
*/
|
*/
|
||||||
static function save_remote(array $data)
|
static function save_remote(array $data)
|
||||||
{
|
{
|
||||||
@ -823,17 +817,21 @@ abstract class admin_cmd
|
|||||||
|
|
||||||
if ($data['install_id'] && $data['config_passwd']) // calculate hash
|
if ($data['install_id'] && $data['config_passwd']) // calculate hash
|
||||||
{
|
{
|
||||||
$pw = preg_match('/^[a-f0-9]{32}$/',$data['config_passwd']) ? $data['config_passwd'] : md5($data['config_passwd']);
|
$pw = self::is_md5($data['config_passwd']) ? $data['config_passwd'] : md5($data['config_passwd']);
|
||||||
$data['remote_hash'] = md5($pw.$data['install_id']);
|
$data['remote_hash'] = md5($pw.$data['install_id']);
|
||||||
}
|
}
|
||||||
elseif ($data['install_id'] || $data['config_passwd'] || !$data['remote_hash'])
|
elseif ($data['install_id'] || $data['config_passwd'] || !$data['remote_hash'])
|
||||||
{
|
{
|
||||||
return false; // we need either install_id AND config_passwd OR the remote_hash
|
throw new Exception(lang('Either Install ID AND config password needed OR the remote hash!'));
|
||||||
}
|
}
|
||||||
//_debug_array($data);
|
//_debug_array($data);
|
||||||
admin_cmd::$remote->init($data);
|
admin_cmd::$remote->init($data);
|
||||||
|
|
||||||
return admin_cmd::$remote->save() == 0 ? admin_cmd::$remote->data : false;
|
if (admin_cmd::$remote->save() != 0)
|
||||||
|
{
|
||||||
|
throw new Exception (lang('Error saving to db:').' '.$this->sql->db->Error.' ('.$this->sql->db->Errno.')',$this->sql->db->Errno);
|
||||||
|
}
|
||||||
|
return admin_cmd::$remote->data['remote_id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -850,4 +848,15 @@ abstract class admin_cmd
|
|||||||
|
|
||||||
return $account.' ('.$GLOBALS['egw']->common->grab_owner_name($id).')';
|
return $account.' ('.$GLOBALS['egw']->common->grab_owner_name($id).')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if string is a md5 hash (32 chars of 0-9 or a-f)
|
||||||
|
*
|
||||||
|
* @param string $str
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
static function is_md5($str)
|
||||||
|
{
|
||||||
|
return preg_match('/^[0-9a-f]{32}$/',$str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,9 +157,12 @@ class admin_cmds
|
|||||||
$content['msg'] = lang('You need to enter Install ID AND Password!');
|
$content['msg'] = lang('You need to enter Install ID AND Password!');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (($content['remote'] = admin_cmd::save_remote($content['remote'])))
|
try {
|
||||||
{
|
$content['remote']['remote_id'] = admin_cmd::save_remote($content['remote']);
|
||||||
$content['msg'] = lang('Remote instance saved');
|
$content['msg'] = lang('Remote instance saved');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$content['msg'] = lang('Error saving').': '.$e->getMessage().' ('.$e->getCode().')';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ($button == 'apply') break;
|
if ($button == 'apply') break;
|
||||||
// fall through for save
|
// fall through for save
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* eGgroupWare admin - remote admin comand execution
|
* eGgroupWare admin - remote admin command execution
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
@ -10,6 +10,9 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
$GLOBALS['egw_info'] = array(
|
$GLOBALS['egw_info'] = array(
|
||||||
'flags' => array(
|
'flags' => array(
|
||||||
'currentapp' => 'login',
|
'currentapp' => 'login',
|
||||||
@ -21,7 +24,7 @@ include('../header.inc.php');
|
|||||||
|
|
||||||
$GLOBALS['egw']->applications->read_installed_apps(); // set $GLOBALS['egw_info']['apps'] (not set for login)
|
$GLOBALS['egw']->applications->read_installed_apps(); // set $GLOBALS['egw_info']['apps'] (not set for login)
|
||||||
|
|
||||||
$instance = $_REQUEST['domain'];
|
$instance = isset($_GET['domain']) ? $_GET['domain'] : $_REQUEST['domain']; // use GET before the rest
|
||||||
if (!isset($GLOBALS['egw_domain'][$instance]))
|
if (!isset($GLOBALS['egw_domain'][$instance]))
|
||||||
{
|
{
|
||||||
$instance = $GLOBALS['egw_info']['server']['default_domain'];
|
$instance = $GLOBALS['egw_info']['server']['default_domain'];
|
||||||
@ -39,7 +42,7 @@ if (!$domain_data || is_numeric($_REQUEST['uid']) || !in_array($remote_admin_ins
|
|||||||
$_REQUEST['secret'] != ($md5=md5($_REQUEST['uid'].md5($domain_data['config_passwd'].$GLOBALS['egw_info']['server']['install_id']))))
|
$_REQUEST['secret'] != ($md5=md5($_REQUEST['uid'].md5($domain_data['config_passwd'].$GLOBALS['egw_info']['server']['install_id']))))
|
||||||
{
|
{
|
||||||
header("HTTP/1.1 200 Unauthorized");
|
header("HTTP/1.1 200 Unauthorized");
|
||||||
//die("0 secret != '$md5'");
|
die("0 secret != '$md5'");
|
||||||
echo lang('0 Permission denied!');
|
echo lang('0 Permission denied!');
|
||||||
if (!in_array($remote_admin_install_id,$allowed_remote_admin_ids))
|
if (!in_array($remote_admin_install_id,$allowed_remote_admin_ids))
|
||||||
{
|
{
|
||||||
|
68
setup/inc/class.setup_cmd.inc.php
Normal file
68
setup/inc/class.setup_cmd.inc.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* eGgroupWare setup - abstract baseclass for all setup commands, extending admin_cmd
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @package setup
|
||||||
|
* @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @version $Id: class.admin_cmd_check_acl.inc.php 24709 2007-11-27 03:20:28Z ralfbecker $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup command: abstract baseclass for all setup commands, extending admin_cmd
|
||||||
|
*/
|
||||||
|
abstract class setup_cmd extends admin_cmd
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Should be called by every command usually requiring header admin rights
|
||||||
|
*
|
||||||
|
* @throws Exception(lang('Wrong credentials to access the header.inc.php file!'),2);
|
||||||
|
*/
|
||||||
|
protected function _check_header_access()
|
||||||
|
{
|
||||||
|
if ($this->header_secret != ($secret = $this->_calc_header_secret($GLOBALS['egw_info']['server']['header_admin_user'],
|
||||||
|
$GLOBALS['egw_info']['server']['header_admin_password'])))
|
||||||
|
{
|
||||||
|
//echo "header_secret='$this->header_secret' != '$secret'=_calc_header_secret({$GLOBALS['egw_info']['server']['header_admin_user']},{$GLOBALS['egw_info']['server']['header_admin_password']})\n";
|
||||||
|
throw new Exception (lang('Wrong credentials to access the header.inc.php file!'),2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the user and pw required for any operation on the header file
|
||||||
|
*
|
||||||
|
* @param string $user
|
||||||
|
* @param string $pw password or md5 hash of it
|
||||||
|
*/
|
||||||
|
public function set_header_secret($user,$pw)
|
||||||
|
{
|
||||||
|
if ($this->uid || parent::save(false)) // we need to save first, to get the uid
|
||||||
|
{
|
||||||
|
$this->header_secret = $this->_calc_header_secret($user,$pw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception ('failed to set header_secret!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the header_secret used to access the header from this command
|
||||||
|
*
|
||||||
|
* It's an md5 over the uid, header-admin-user and -password.
|
||||||
|
*
|
||||||
|
* @param string $header_admin_user
|
||||||
|
* @param string $header_admin_password
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function _calc_header_secret($header_admin_user=null,$header_admin_password=null)
|
||||||
|
{
|
||||||
|
if (!self::is_md5($header_admin_password)) $header_admin_password = md5($header_admin_password);
|
||||||
|
|
||||||
|
$secret = md5($this->uid.$header_admin_user.$header_admin_password);
|
||||||
|
//echo "header_secret='$secret' = md5('$this->uid'.'$header_admin_user'.'$header_admin_password')\n";
|
||||||
|
return $secret;
|
||||||
|
}
|
||||||
|
}
|
77
setup/inc/class.setup_cmd_showheader.inc.php
Normal file
77
setup/inc/class.setup_cmd_showheader.inc.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* eGgroupWare setup - show/return the header.inc.php
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @package setup
|
||||||
|
* @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @version $Id: class.admin_cmd_check_acl.inc.php 24709 2007-11-27 03:20:28Z ralfbecker $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup command: show/return the header.inc.php
|
||||||
|
*
|
||||||
|
* Has no constructor, as we have no arguments beside the header admin user and password,
|
||||||
|
* which get set via setup_cmd::set_header_secret($user,$pw)
|
||||||
|
*/
|
||||||
|
class setup_cmd_showheader extends setup_cmd
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param array $data=array() default parm from parent class, no real parameters
|
||||||
|
*/
|
||||||
|
function __construct($data=array())
|
||||||
|
{
|
||||||
|
//echo __CLASS__.'::__construct()'; _debug_array($data);
|
||||||
|
admin_cmd::__construct($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show/return the header.inc.php
|
||||||
|
*
|
||||||
|
* @param boolean $check_only=false only run the checks (and throw the exceptions), but not the command itself
|
||||||
|
* @return string serialized $GLOBALS defined in the header.inc.php
|
||||||
|
* @throws Exception(lang('Wrong credentials to access the header.inc.php file!'),2);
|
||||||
|
* @throws Exception('header.inc.php not found!');
|
||||||
|
*/
|
||||||
|
function exec($check_only=false)
|
||||||
|
{
|
||||||
|
if ($this->remote_id && $check_only) return true; // cant check for the remote site locally!
|
||||||
|
|
||||||
|
$this->_check_header_access();
|
||||||
|
|
||||||
|
if ($check_only) return true;
|
||||||
|
|
||||||
|
$egw_info_backup = $GLOBALS['egw_info'];
|
||||||
|
$GLOBALS['egw_info'] = array (
|
||||||
|
'flags' => array(
|
||||||
|
'noapi' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (!($header = file_get_contents(EGW_SERVER_ROOT.'/header.inc.php')))
|
||||||
|
{
|
||||||
|
throw new Exception('header.inc.php not found!');
|
||||||
|
}
|
||||||
|
eval(str_replace(array('<?php','perfgetmicrotime'),array('','perfgetmicrotime2'),$header));
|
||||||
|
|
||||||
|
// unset the flags, they are not part of the header
|
||||||
|
unset($GLOBALS['egw_info']['flags']);
|
||||||
|
|
||||||
|
// include the api version of this instance
|
||||||
|
$GLOBALS['egw_info']['server']['versions']['phpgwapi'] = $egw_info_backup['server']['versions']['phpgwapi'];
|
||||||
|
|
||||||
|
$ret = serialize(array(
|
||||||
|
'egw_info' => $GLOBALS['egw_info'],
|
||||||
|
'egw_domain' => $GLOBALS['egw_domain'],
|
||||||
|
'EGW_SERVER_ROOT' => EGW_SERVER_ROOT,
|
||||||
|
'EGW_INCLUDE_ROOT' => EGW_INCLUDE_ROOT,
|
||||||
|
));
|
||||||
|
|
||||||
|
$GLOBALS['egw_info'] = $egw_info_backup;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user