Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../PluginsMakefile.mk
9 changes: 9 additions & 0 deletions front/computergroup.form.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion inc/computergroupdynamic.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -109,7 +110,7 @@ public static function getSpecificValueToDisplay($field, $values, array $options

foreach ($data['data']['rows'] as $colvalue) {
$value .= "<a href='" . Computer::getFormURLWithID($colvalue['id']) . "'>";
$value .= Dropdown::getDropdownName('glpi_computers', $colvalue['id']) . '</a>' . Search::LBBR;
$value .= htmlspecialchars(Dropdown::getDropdownName('glpi_computers', $colvalue['id'])) . '</a>' . Search::LBBR;
}
}

Expand Down
30 changes: 21 additions & 9 deletions inc/inventoryaction.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));
}
}

Expand Down
243 changes: 134 additions & 109 deletions inc/task.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -127,122 +137,14 @@ 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();

$database_param_found = [];

// 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);
}

/*
Expand Down Expand Up @@ -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;
}
}