diff --git a/library/Icingadb/Common/Auth.php b/library/Icingadb/Common/Auth.php index c415d62d2..d25526e65 100644 --- a/library/Icingadb/Common/Auth.php +++ b/library/Icingadb/Common/Auth.php @@ -137,6 +137,9 @@ public function applyRestrictions(Query $query) // Hence why the hosts restriction is also applied if only services are queried. || $applyServiceRestriction; + $hostStateRelation = array_search('host_state', $relations, true); + $serviceStateRelation = array_search('service_state', $relations, true); + $resolver = $query->getResolver(); $queryFilter = Filter::any(); @@ -196,6 +199,34 @@ public function applyRestrictions(Query $query) } } + if (! $this->getAuth()->hasPermission('icingadb/object/show-source')) { + // In case the user does not have permission to see the object's `Source` tab, then the user must be + // restricted from accessing the executed command for the object. + $columns = $query->getColumns(); + $commandColumns = []; + if ($hostStateRelation !== false) { + $commandColumns[] = $resolver->qualifyColumn('check_commandline', $hostStateRelation); + } + + if ($serviceStateRelation !== false) { + $commandColumns[] = $resolver->qualifyColumn('check_commandline', $serviceStateRelation); + } + + if (! empty($columns)) { + foreach ($commandColumns as $commandColumn) { + $commandColumnPath = array_search($commandColumn, $columns, true); + if ($commandColumnPath !== false) { + $columns[$commandColumn] = new Expression("'***'"); + unset($columns[$commandColumnPath]); + } + } + + $query->columns($columns); + } else { + $query->withoutColumns($commandColumns); + } + } + if (! $obfuscationRules->isEmpty()) { $flatvaluePath = $customVarRelationName ? $resolver->qualifyColumn('flatvalue', $customVarRelationName) diff --git a/library/Icingadb/Redis/VolatileStateResults.php b/library/Icingadb/Redis/VolatileStateResults.php index 186022a30..af9211cbb 100644 --- a/library/Icingadb/Redis/VolatileStateResults.php +++ b/library/Icingadb/Redis/VolatileStateResults.php @@ -7,6 +7,7 @@ use Exception; use Generator; use Icinga\Application\Benchmark; +use Icinga\Module\Icingadb\Common\Auth; use Icinga\Module\Icingadb\Common\IcingaRedis; use Icinga\Module\Icingadb\Model\Host; use Icinga\Module\Icingadb\Model\Service; @@ -18,6 +19,8 @@ class VolatileStateResults extends ResultSet { + use Auth; + /** @var Resolver */ private $resolver; @@ -91,6 +94,8 @@ protected function applyRedisUpdates() $keys = []; $hostStateKeys = []; + $showSourceGranted = $this->getAuth()->hasPermission('icingadb/object/show-source'); + $states = []; $hostStates = []; foreach ($this as $row) { @@ -112,6 +117,9 @@ protected function applyRedisUpdates() $states[bin2hex($row->id)] = $row->state; if (empty($keys)) { $keys = $row->state->getColumns(); + if (! $showSourceGranted) { + $keys = array_diff($keys, ['check_commandline']); + } } if ($type === 'service' && $row->host instanceof Host) {