diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e009a8..5b5cc2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] + +### Fixed + +- Fix missing validation checks in database inventory tasks and actions + ## [1.1.3] - 2026-05-05 ### Fixed diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ef1bed5 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +include ../../PluginsMakefile.mk diff --git a/front/computergroup.form.php b/front/computergroup.form.php index f9aa419..1dad2c8 100644 --- a/front/computergroup.form.php +++ b/front/computergroup.form.php @@ -67,6 +67,15 @@ Html::back(); } + $computer = new Computer(); + if ( + !$computer->getFromDB($_POST['computers_id']) + || !Session::haveAccessToEntity($computer->fields['entities_id']) + ) { + Session::addMessageAfterRedirect(__s('Please select a computer', 'databaseinventory'), false, ERROR); + Html::back(); + } + $computergroupstatic->check(-1, CREATE, $_POST); if ($newID = $computergroupstatic->add($_POST)) { Event::log( diff --git a/inc/computergroupdynamic.class.php b/inc/computergroupdynamic.class.php index 8c4492d..65eeafa 100644 --- a/inc/computergroupdynamic.class.php +++ b/inc/computergroupdynamic.class.php @@ -29,6 +29,7 @@ */ use function Safe\json_decode; +use function Safe\unserialize; use function Safe\json_encode; use function Safe\ob_start; use function Safe\ob_get_clean; @@ -109,7 +110,7 @@ public static function getSpecificValueToDisplay($field, $values, array $options foreach ($data['data']['rows'] as $colvalue) { $value .= ""; - $value .= Dropdown::getDropdownName('glpi_computers', $colvalue['id']) . '' . Search::LBBR; + $value .= htmlspecialchars(Dropdown::getDropdownName('glpi_computers', $colvalue['id'])) . '' . Search::LBBR; } } diff --git a/inc/inventoryaction.class.php b/inc/inventoryaction.class.php index 4fde077..f75fb39 100644 --- a/inc/inventoryaction.class.php +++ b/inc/inventoryaction.class.php @@ -57,11 +57,23 @@ public static function processMassiveActionsForOneItemtype(MassiveAction $ma, Co return; } + if (!Session::haveRight('database_inventory', PluginDatabaseinventoryProfile::RUN_DATABSE_INVENTORY)) { + foreach ($ids as $id) { + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); + } + + return; + } + switch ($item->getType()) { case Computer::getType(): foreach ($ids as $id) { $computer = new Computer(); - $computer->getFromDB($id); + if (!$computer->getFromDB($id) || !$computer->can($id, READ)) { + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); + continue; + } + if ($agent = self::findAgent($computer)) { if (PluginDatabaseinventoryInventoryAction::runPartialInventory($agent, true)) { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); @@ -79,16 +91,16 @@ public static function processMassiveActionsForOneItemtype(MassiveAction $ma, Co case Agent::getType(): foreach ($ids as $id) { $agent = new Agent(); - if ($agent->getFromDB($id)) { - if (PluginDatabaseinventoryInventoryAction::runPartialInventory($agent, true)) { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); - } else { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); - $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); - } + if (!$agent->getFromDB($id) || !$agent->can($id, READ)) { + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); + continue; + } + + if (PluginDatabaseinventoryInventoryAction::runPartialInventory($agent, true)) { + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); } else { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); - $ma->addMessage(sprintf(__s('Agent %1$s not found', 'databaseinventory'), $id)); + $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } diff --git a/inc/task.class.php b/inc/task.class.php index 86918eb..d9ab62d 100644 --- a/inc/task.class.php +++ b/inc/task.class.php @@ -38,6 +38,16 @@ public static function inventoryGetParams(array $params) $content = $params['options']['content']; $credential_found = []; + // only serve credentials for a database param actually reachable by the agent's computer + $computer = $agent->getLinkedItem(); + if ( + $computer::class !== Computer::getType() + || $computer->isNewItem() + || !in_array($content->params_id, self::getAccessibleDatabaseParams($computer)) + ) { + return $params; + } + $databaseparam_credential_table = PluginDatabaseinventoryDatabaseParam_Credential::getTable(); $credential_table = PluginDatabaseinventoryCredential::getTable(); $credential_type_table = PluginDatabaseinventoryCredentialType::getTable(); @@ -127,9 +137,6 @@ public static function inventoryGetParams(array $params) public static function handleInventoryTask(array $params) { - /** @var DBmysql $DB */ - global $DB; - // get asset related to the agent $computer = $params['item']->getLinkedItem(); @@ -137,112 +144,7 @@ public static function handleInventoryTask(array $params) // only Computer type if ($computer::class == Computer::getType() && !$computer->isNewItem()) { - $database_param_table = PluginDatabaseinventoryDatabaseParam::getTable() ; - $database_param_computergroup_table = PluginDatabaseinventoryDatabaseParam_ComputerGroup::getTable(); - $computer_group_static_table = PluginDatabaseinventoryComputerGroupStatic::getTable(); - $computer_group_dynamic_table = PluginDatabaseinventoryComputerGroupDynamic::getTable(); - $computer_group_table = PluginDatabaseinventoryComputerGroup::getTable(); - - /* - * First step : - * try to load all active 'PluginDatabaseinventoryDatabaseParam' - * related to the computer (from 'PluginDatabaseinventoryComputerGroupStatic') - */ - $criteria = [ - 'SELECT' => [ - $database_param_table . '.id', - ], - 'FROM' => $database_param_table, - 'JOIN' => [ - $database_param_computergroup_table => [ - 'ON' => [ - $database_param_computergroup_table => 'plugin_databaseinventory_databaseparams_id', - $database_param_table => 'id', - ], - ], - $computer_group_table => [ - 'ON' => [ - $database_param_computergroup_table => 'plugin_databaseinventory_computergroups_id', - $computer_group_table => 'id', - ], - ], - $computer_group_static_table => [ - 'ON' => [ - $computer_group_static_table => 'plugin_databaseinventory_computergroups_id', - $computer_group_table => 'id', - ], - ], - ], - 'WHERE' => [ - $computer_group_static_table . '.computers_id' => $computer->fields['id'], - $database_param_table . '.is_active' => 1, - ], - ]; - - // store databaseparam found - $iterator = $DB->request($criteria); - foreach ($iterator as $data) { - $database_param_found[] = $data['id']; - } - - /* - * Second step : - * Try to load all 'PluginDatabaseinventoryComputerGroupDynamic' - * linked to an active 'PluginDatabaseinventoryDatabaseParam' - * and check if the computer is part of it - */ - $criteria = [ - 'SELECT' => [ - $computer_group_dynamic_table . '.id', - $database_param_table . '.id AS database_param_id', - ], - 'FROM' => $computer_group_dynamic_table, - 'JOIN' => [ - $computer_group_table => [ - 'ON' => [ - $computer_group_dynamic_table => 'plugin_databaseinventory_computergroups_id', - $computer_group_table => 'id', - ], - ], - $database_param_computergroup_table => [ - 'ON' => [ - $database_param_computergroup_table => 'plugin_databaseinventory_computergroups_id', - $computer_group_table => 'id', - ], - ], - $database_param_table => [ - 'ON' => [ - $database_param_computergroup_table => 'plugin_databaseinventory_databaseparams_id', - $database_param_table => 'id', - ], - ], - ], - 'WHERE' => [ - $database_param_table . '.is_active' => 1, - ], - ]; - - if ($database_param_found !== []) { - $criteria['WHERE'] = [ - $database_param_table . '.is_active' => 1, - ['NOT' => [$database_param_table . '.id' => $database_param_found]], //no need to look for what is already found - ]; - } else { - $criteria['WHERE'] = [ - $database_param_table . '.is_active' => 1, - ]; - } - - // check if Dynamic group match computer - // if true, store databaseparam - $iterator = $DB->request($criteria); - foreach ($iterator as $data) { - $dynamic_group = new PluginDatabaseinventoryComputerGroupDynamic(); - $dynamic_group->getFromDB($data['id']); - if ($dynamic_group->isDynamicSearchMatchComputer($computer) && !in_array($data['database_param_id'], $database_param_found)) { - $database_param_found[] = $data['database_param_id']; - } - } + $database_param_found = self::getAccessibleDatabaseParams($computer); } /* @@ -289,4 +191,127 @@ public static function handleInventoryTask(array $params) return $params; } + + /** + * List ids of active PluginDatabaseinventoryDatabaseParam reachable by a computer, + * either through a static group or a dynamic group whose search criteria match it. + * + * @return int[] + */ + private static function getAccessibleDatabaseParams(Computer $computer): array + { + /** @var DBmysql $DB */ + global $DB; + + $database_param_found = []; + + $database_param_table = PluginDatabaseinventoryDatabaseParam::getTable(); + $database_param_computergroup_table = PluginDatabaseinventoryDatabaseParam_ComputerGroup::getTable(); + $computer_group_static_table = PluginDatabaseinventoryComputerGroupStatic::getTable(); + $computer_group_dynamic_table = PluginDatabaseinventoryComputerGroupDynamic::getTable(); + $computer_group_table = PluginDatabaseinventoryComputerGroup::getTable(); + + /* + * First step : + * try to load all active 'PluginDatabaseinventoryDatabaseParam' + * related to the computer (from 'PluginDatabaseinventoryComputerGroupStatic') + */ + $criteria = [ + 'SELECT' => [ + $database_param_table . '.id', + ], + 'FROM' => $database_param_table, + 'JOIN' => [ + $database_param_computergroup_table => [ + 'ON' => [ + $database_param_computergroup_table => 'plugin_databaseinventory_databaseparams_id', + $database_param_table => 'id', + ], + ], + $computer_group_table => [ + 'ON' => [ + $database_param_computergroup_table => 'plugin_databaseinventory_computergroups_id', + $computer_group_table => 'id', + ], + ], + $computer_group_static_table => [ + 'ON' => [ + $computer_group_static_table => 'plugin_databaseinventory_computergroups_id', + $computer_group_table => 'id', + ], + ], + ], + 'WHERE' => [ + $computer_group_static_table . '.computers_id' => $computer->fields['id'], + $database_param_table . '.is_active' => 1, + ], + ]; + + // store databaseparam found + $iterator = $DB->request($criteria); + foreach ($iterator as $data) { + $database_param_found[] = $data['id']; + } + + /* + * Second step : + * Try to load all 'PluginDatabaseinventoryComputerGroupDynamic' + * linked to an active 'PluginDatabaseinventoryDatabaseParam' + * and check if the computer is part of it + */ + $criteria = [ + 'SELECT' => [ + $computer_group_dynamic_table . '.id', + $database_param_table . '.id AS database_param_id', + ], + 'FROM' => $computer_group_dynamic_table, + 'JOIN' => [ + $computer_group_table => [ + 'ON' => [ + $computer_group_dynamic_table => 'plugin_databaseinventory_computergroups_id', + $computer_group_table => 'id', + ], + ], + $database_param_computergroup_table => [ + 'ON' => [ + $database_param_computergroup_table => 'plugin_databaseinventory_computergroups_id', + $computer_group_table => 'id', + ], + ], + $database_param_table => [ + 'ON' => [ + $database_param_computergroup_table => 'plugin_databaseinventory_databaseparams_id', + $database_param_table => 'id', + ], + ], + ], + 'WHERE' => [ + $database_param_table . '.is_active' => 1, + ], + ]; + + if ($database_param_found !== []) { + $criteria['WHERE'] = [ + $database_param_table . '.is_active' => 1, + ['NOT' => [$database_param_table . '.id' => $database_param_found]], //no need to look for what is already found + ]; + } else { + $criteria['WHERE'] = [ + $database_param_table . '.is_active' => 1, + ]; + } + + // check if Dynamic group match computer + // if true, store databaseparam + $iterator = $DB->request($criteria); + foreach ($iterator as $data) { + $dynamic_group = new PluginDatabaseinventoryComputerGroupDynamic(); + $dynamic_group->getFromDB($data['id']); + if ($dynamic_group->isDynamicSearchMatchComputer($computer) && !in_array($data['database_param_id'], $database_param_found)) { + $database_param_found[] = $data['database_param_id']; + } + } + + return $database_param_found; + } }