Skip to content
This repository has been archived by the owner on Jan 15, 2019. It is now read-only.

Commit

Permalink
* Added command restrictions (refs #1953) -> sql update is missing
Browse files Browse the repository at this point in the history
  • Loading branch information
Jannis Moßhammer committed Oct 19, 2011
1 parent f62d04b commit d3aff8d
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 35 deletions.
8 changes: 6 additions & 2 deletions app/modules/Api/actions/ApiCommandAction.class.php
Expand Up @@ -37,12 +37,16 @@ public function checkAuth(AgaviRequestDataHolder $rd) {
$validation->setError("Login error","Not logged in!");
return false;
}

if( $user->getNsmUser()->getNsmTarget()->hasTarget('IcingaCommandRo')) {
$validation->setError("Error","Commands are disabled for this user!");
return false;

}
if ($user->hasCredential("appkit.api.access") || $user->hasCredential("appkit.user")) {
return true;
}

$validation->setError("Error","Invalid credentials for api access!");
$validation->setError("Error","Invalid credentials for api command access!");
return false;
}

Expand Down
5 changes: 5 additions & 0 deletions app/modules/Api/config/commands/host.xml
Expand Up @@ -13,13 +13,16 @@

<ic:command name="SCHEDULE_HOST_CHECK">
<ic:definition>SCHEDULE_HOST_CHECK</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_CHECKTIME" />

</ic:parameters>
</ic:command>
<ic:command name="SCHEDULE_FORCED_HOST_CHECK">
<ic:definition>SCHEDULE_FORCED_HOST_CHECK</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_CHECKTIME" />
Expand Down Expand Up @@ -117,6 +120,7 @@
</ic:command>
<ic:command name="ADD_HOST_COMMENT">
<ic:definition>ADD_HOST_COMMENT</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_PERSISTENT" />
Expand Down Expand Up @@ -174,6 +178,7 @@
</ic:command>
<ic:command name="SEND_CUSTOM_HOST_NOTIFICATION">
<ic:definition>SEND_CUSTOM_HOST_NOTIFICATION</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_NOTIFICATION_OPTIONS" />
Expand Down
6 changes: 5 additions & 1 deletion app/modules/Api/config/commands/service.xml
Expand Up @@ -20,6 +20,7 @@
</ic:command>
<ic:command name="SCHEDULE_SVC_CHECK">
<ic:definition>SCHEDULE_SVC_CHECK</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_SERVICE" />
Expand All @@ -28,6 +29,7 @@
</ic:command>
<ic:command name="SCHEDULE_FORCED_SVC_CHECK">
<ic:definition>SCHEDULE_FORCED_SVC_CHECK</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_SERVICE" />
Expand Down Expand Up @@ -92,6 +94,7 @@
</ic:command>
<ic:command name="ADD_SVC_COMMENT">
<ic:definition>ADD_SVC_COMMENT</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_SERVICE" />
Expand Down Expand Up @@ -170,8 +173,9 @@
<ic:parameter ref="COMMAND_SERVICE" />
</ic:parameters>
</ic:command>
<ic:command name="SEND_CUSTOM_SVC_NOTIFICATION">
<ic:command name="SEND_CUSTOM_SVC_NOTIFICATION">
<ic:definition>SEND_CUSTOM_SVC_NOTIFICATION</ic:definition>
<ic:isSimple>true</ic:isSimple>
<ic:parameters>
<ic:parameter ref="COMMAND_HOST" />
<ic:parameter ref="COMMAND_SERVICE" />
Expand Down
Expand Up @@ -35,8 +35,12 @@ private function fetchCommands() {
}

$definition = $xpath->query("ic:definition",$command);

$isSimple = $xpath->query("ic:isSimple",$command);
$currentCommand["definition"] = $definition->item(0)->nodeValue;
if($isSimple->length>0)
$currentCommand["isSimple"] = $isSimple->item(0)->nodeValue;
else
$currentCommand["isSimple"] = false;
$currentCommand["parameters"] = $this->extractParamsFromCommandNode($command);;
$commandResult[$command->attributes->getNamedItem("name")->value] = $currentCommand;
}
Expand Down
1 change: 1 addition & 0 deletions app/modules/Api/lib/xml/xsd/parts/icingaCommands.xsd
Expand Up @@ -28,6 +28,7 @@
<xs:complexType name="command" mixed="true">
<xs:sequence>
<xs:element name="definition" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="isSimple" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="parameters" type="parameters" minOccurs="1"></xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
Expand Down
Expand Up @@ -29,8 +29,14 @@ public function submitCommand($cmd_name,array $params,
$commandClass = array("Console.ConsoleCommand","Api")) {

try {
$user = $this->getContext()->getUser()->getNsmUser();
$onlySimple = $user->hasTarget('IcingaCommandRestrictions');

$command = $this->getCommand($cmd_name);
$string = $this->buildCommandString($command,$params);

$string = $this->buildCommandString($command,$params);
if($onlySimple && !$command["isSimple"])
throw new Exception("Could not send command. Your user isn't allowed to send this command.");
$cmd = $this->getContext()->getModel($commandClass[0],$commandClass[1],
array(
"command" => "printf",
Expand Down
Expand Up @@ -146,8 +146,6 @@ public function executeWrite(AgaviRequestDataHolder $rd) {
$rd->getParameter('principal_value', array())
);

// Give notice!

Doctrine_Manager::connection()->commit();
} catch (Exception $e) {
try {
Expand Down
2 changes: 1 addition & 1 deletion app/modules/AppKit/config/javascript.xml
Expand Up @@ -5,7 +5,7 @@
<javascript>
<!-- ExtJS base files -->
<ae:parameter>%core.root_dir%/lib/ext3/adapter/ext/ext-base.js</ae:parameter>
<ae:parameter>%core.root_dir%/lib/ext3/ext-all-debug.js</ae:parameter>
<ae:parameter>%core.root_dir%/lib/ext3/ext-all.js</ae:parameter>
<ae:parameter>%core.root_dir%/lib/ext3/examples/ux/PagingMemoryProxy.js</ae:parameter>

<!--AppKit JS -->
Expand Down
17 changes: 3 additions & 14 deletions app/modules/AppKit/lib/js/admin/UserEditForm.js
Expand Up @@ -39,19 +39,7 @@ AppKit.Admin.UserEditForm = function(cfg) {
authTypes.push([type]);
});

var userFlags = [{
icon: 'icinga-icon-user-delete',
principal: 'IcingaCommandRo',
id: 'flag-command-only',
text: _('Disable commands for this user')
}, {
icon: 'icinga-icon-group',
principal: 'IcingaContactgroup',
id: 'flag-contacts-only',
text: _('Only show items that contain a contact with this name '+
' in their contactgroup definitions'
)
}];

var userRoleStore = new Ext.data.JsonStore({
idProperty: 'id',
fields: ['name','active','description','id']
Expand Down Expand Up @@ -212,7 +200,8 @@ AppKit.Admin.UserEditForm = function(cfg) {
params["principal_target["+i+"][name][]"] = p.get("target_name");
i++;
});
Ext.iterate(userFlags,function(flag) {

Ext.iterate(userRestrictionFlagsView.roleFlags,function(flag) {
if(!Ext.getCmp(flag.id).getValue())
return true;
params["principal_target["+i+"][set][]"] = 1;
Expand Down
Expand Up @@ -10,9 +10,15 @@ AppKit.Admin.Components.RestrictionFlagsView = Ext.extend(Ext.Panel, {
icon: 'icinga-icon-group',
principal: 'IcingaContactgroup',
id: 'flag-contacts-only',
text: _('Only show items that contain a contact with this name '+
text: _('Only show items that contain a contact with this name'+
' in their contactgroup definitions'
)
}, {
icon: 'icinga-icon-group',
principal: 'IcingaCommandRestrictions',
id: 'flag-commands-restricted',
text: _('Don\'t allow critical commands (like disabling host checks)'
)
}],
constructor: function(cfg) {
var items = [];
Expand Down Expand Up @@ -42,7 +48,7 @@ AppKit.Admin.Components.RestrictionFlagsView = Ext.extend(Ext.Panel, {
Ext.Panel.prototype.constructor.call(this,cfg);
},
title: _('Other restrictions'),
iconCls: 'icinga-icon-cancel',
iconCls: 'icinga-icon-lock',
padding: 10,
layout: 'fit',
selectedValue: [],
Expand Down
20 changes: 12 additions & 8 deletions app/modules/Cronks/lib/js/grid/IcingaCommandHandler.js
Expand Up @@ -53,11 +53,15 @@ IcingaCommandHandler.prototype = {
this.toolbaritem.menu.add('-');
}

b.on('click', function(b, e) { this.showCommandWindow(k, v.title) }, this);
b.on('click', function(b, e) {this.showCommandWindow(k, v.title)}, this);

}, this);


if(Ext.isEmpty(this.command_options.items))
this.toolbaritem.menu.add({
xtype: 'tbtext',
text: _("No commands are available for your user")

});

},

Expand Down Expand Up @@ -98,7 +102,7 @@ IcingaCommandHandler.prototype = {

getField : function(o) {

oDef = {
var oDef = {
fieldLabel: o.fieldLabel,
name: o.fieldName,
value: o.fieldValue,
Expand Down Expand Up @@ -201,7 +205,7 @@ IcingaCommandHandler.prototype = {
return new Ext.Container({
fieldLabel: o.fieldLabel,
defaults: {
style: { padding: '0 5px 0 5px' }
style: {padding: '0 5px 0 5px'}
},
items: [{
xtype: 'numberfield',
Expand Down Expand Up @@ -234,7 +238,7 @@ IcingaCommandHandler.prototype = {
minValue: 1,
width: 50,
readOnly: true,
style: { background: '#00cc00' }
style: {background: '#00cc00'}
}, {
xtype: 'label',
text: _('seconds')
Expand Down Expand Up @@ -356,15 +360,15 @@ IcingaCommandHandler.prototype = {
}, {
text: _('Abort'),
iconCls: 'icinga-icon-cross',
handler: function(b, e) { oWin.close(); }
handler: function(b, e) {oWin.close();}
}]
});

// This fixes the webkit (safari, chrome) width issue ...
oWin.on('afterrender', function() {
this.syncSize();
this.syncShadow();
}, oWin, { delay: 40, single: true });
}, oWin, {delay: 40, single: true});

var oForm = new Ext.form.FormPanel({
border: false,
Expand Down
Expand Up @@ -449,6 +449,32 @@ private function cacheContent($file) {
public function disableCache() {
$this->useCaching = false;
}


public function removeRestrictedCommands() {
$data = $this->data;
if(!isset($data["option"]))
return;
if(!isset($data["option"]["commands"]))
return;

$items = $data["option"]["commands"]["items"];
if(!is_array($items))
return;
$config = include AgaviConfigCache::checkConfig(AgaviToolkit::expandDirectives('%core.module_dir%/Api/config/icingaCommands.xml'));
$toRemove = array();
foreach($items as $cmd_name=>$cmd_def) {
if(!isset($config[$cmd_name])) {
$toRemove[] = $cmd_name;
continue;
}
if(!$config[$cmd_name]["isSimple"])
$toRemove[] = $cmd_name;
}
foreach($toRemove as $removeItem)
unset($data["option"]["commands"]["items"][$removeItem]);
$this->data = $data;
}
}

class CronkGridTemplateXmlParserException extends AppKitException { }
Expand Down
Expand Up @@ -90,7 +90,8 @@ function initGrid() {
var bCommands = (Options['commands'] && Options['commands']['enabled'] == true) ? true : false;

var bCommandRo = '<?php echo $us->getNsmUser()->hasTarget("IcingaCommandRo"); ?>';



if (bCommands == true && !bCommandRo == 1) {

var tbEntry = this.topToolbar.add({
Expand All @@ -100,7 +101,6 @@ function initGrid() {
items: []
}
});

// An instance to work with
var cHandler = new IcingaCommandHandler(meta);

Expand Down Expand Up @@ -157,6 +157,7 @@ function initGrid() {
url: "<?php echo $ro->gen('modules.cronks.viewProc.json.metaInfo', array('template' => $rd->getParameter('template'))); ?>",

success: function(response, opts) {

s.add(template, Ext.decode(response.responseText));
initGrid();
},
Expand Down
Expand Up @@ -12,7 +12,13 @@ public function executeJson(AgaviRequestDataHolder $rd) {
$file = AppKitFileUtil::getAlternateFilename(AgaviConfig::get('modules.cronks.xml.path.grid'), $rd->getParameter('template'), '.xml');
$template = new CronkGridTemplateXmlParser($file);
$template->parseTemplate();

$user = $this->getContext()->getUser()->getNsmUser();
$data = $template->getTemplateData();

if($user->hasTarget('IcingaCommandRestrictions')) {
$template->removeRestrictedCommands();
}

return json_encode(array(
'template' => $template->getTemplateData(),
'fields' => $template->getFields(),
Expand All @@ -25,6 +31,7 @@ public function executeJson(AgaviRequestDataHolder $rd) {
return $msg;
}
}

}

?>
1 change: 1 addition & 0 deletions app/modules/Web/config/autoload.xml
Expand Up @@ -11,6 +11,7 @@
<autoload name="IcingaConstantResolver">%core.module_dir%/Web/lib/constants/IcingaConstantResolver.class.php</autoload>
<autoload name="IcingaConstants">%core.module_dir%/Web/lib/constants/IcingaConstants.class.php</autoload>
<autoload name="IcingaDataCommandRoPrincipalTarget">%core.module_dir%/Web/lib/principal/IcingaDataCommandRoPrincipalTarget.class.php</autoload>
<autoload name="IcingaDataCommandRestrictionPrincipalTarget">%core.module_dir%/Web/lib/principal/IcingaDataCommandRestrictionPrincipalTarget.class.php</autoload>
<autoload name="IcingaDataContactgroupPrincipalTarget">%core.module_dir%/Web/lib/principal/IcingaDataContactgroupPrincipalTarget.class.php</autoload>
<autoload name="IcingaDataHostCustomVariablePrincipalTarget">%core.module_dir%/Web/lib/principal/IcingaDataHostCustomVariablePrincipalTarget.class.php</autoload>
<autoload name="IcingaDataHostgroupPrincipalTarget">%core.module_dir%/Web/lib/principal/IcingaDataHostgroupPrincipalTarget.class.php</autoload>
Expand Down
@@ -0,0 +1,14 @@
<?php

class IcingaDataCommandRestrictionPrincipalTarget extends IcingaDataPrincipalTarget {

public function __construct() {

parent::__construct();

$this->setType('IcingaDataTarget');

$this->setDescription('Limit data access to commands');

}
}

0 comments on commit d3aff8d

Please sign in to comment.