transformLegacyQuery(); } /* Dictionary::translate('submenu_projectors'); Dictionary::translate('submenu_replace'); Dictionary::translate('submenu_hints'); */ foreach (['projectors', 'replace', 'hints'] as $section) { Dashboard::addSubmenu('?do=statistics&show=' . $section, Dictionary::translate('submenu_' . $section, true)); } $this->show = Request::any('show', false, 'string'); if ($this->show === false && Request::isGet()) { if (Request::get('uuid') !== false) { $this->show = 'machine'; } elseif (User::hasPermission('view.summary')) { $this->show = 'summary'; } elseif (User::hasPermission('view.list')) { $this->show = 'list'; } else { User::assertPermission('view.summary'); } } if ($this->show !== false) { $this->show = preg_replace('/[^a-z0-9_\-]/', '', $this->show); if (!file_exists('modules/statistics/pages/' . $this->show . '.inc.php')) { Message::addError('main.invalid-action', $this->show); } else { require_once 'modules/statistics/pages/' . $this->show . '.inc.php'; $this->haveSubpage = true; SubPage::doPreprocess(); } return; } if (!Request::isPost()) return; // POST $action = Request::post('action'); if ($action === 'setnotes') { $uuid = Request::post('uuid', '', 'string'); $res = Database::queryFirst('SELECT locationid FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid)); if ($res === false) { Message::addError('unknown-machine', $uuid); Util::redirect('?do=statistics'); } User::assertPermission("machine.note.edit", (int)$res['locationid']); $text = Request::post('content', null, 'string'); if (empty($text)) { $text = null; } Database::exec('UPDATE machine SET notes = :text WHERE machineuuid = :uuid', array( 'uuid' => $uuid, 'text' => $text, )); Message::addSuccess('notes-saved'); Util::redirect('?do=statistics&uuid=' . $uuid); } elseif ($action === 'clear-machines') { $this->deleteMachines(true); } elseif ($action === 'delmachines') { $this->deleteMachines(false); Util::redirect('?do=statistics', true); } elseif ($action === 'rebootmachines') { $this->rebootControl(true); } elseif ($action === 'shutdownmachines') { $this->rebootControl(false); } elseif ($action === 'wol') { $this->wol(); } elseif ($action === 'prepare-exec') { if (Module::isAvailable('rebootcontrol')) { RebootControl::prepareExec(); } } // Make sure we don't render any content for POST requests - should be handled above and then // redirected properly Util::redirect('?do=statistics'); } private function transformLegacyQuery() { if (!Request::isGet()) return; $query = Request::get('filters', false, 'string'); if ($query === false) return; foreach (explode(StatisticsFilter::LEGACY_DELIMITER, $query) as $q) { if (!preg_match('/^\s*(\w+)\s*([<>=!~]{1,2})\s*(.*?)\s*$/', $q, $out)) continue; $key = $out[1]; $_GET['filter'][$key] = '1'; $_GET['op'][$key] = $out[2]; $_GET['arg'][$key] = $out[3]; } unset($_GET['filters']); if (!empty($_GET['filter'])) { Util::redirect('?' . http_build_query($_GET)); } } private function wol() { if (!Module::isAvailable('rebootcontrol')) return; $ids = Request::post('uuid', [], 'array'); $ids = array_values($ids); if (empty($ids)) { Message::addError('main.parameter-empty', 'uuid'); return; } $this->getAllowedMachines(".rebootcontrol.action.wol", $ids, $allowedMachines); if (empty($allowedMachines)) return; $taskid = RebootControl::wakeMachines($allowedMachines); Util::redirect('?do=rebootcontrol&show=task&what=task&taskid=' . $taskid); } /** * @param bool $reboot true = reboot, false = shutdown */ private function rebootControl(bool $reboot) { if (!Module::isAvailable('rebootcontrol')) return; $ids = Request::post('uuid', [], 'array'); $ids = array_values($ids); if (empty($ids)) { Message::addError('main.parameter-empty', 'uuid'); return; } $this->getAllowedMachines(".rebootcontrol.action." . ($reboot ? 'reboot' : 'shutdown'), $ids, $allowedMachines); if (empty($allowedMachines)) return; if ($reboot && Request::post('kexec', false)) { $action = RebootControl::KEXEC_REBOOT; } elseif ($reboot) { $action = RebootControl::REBOOT; } else { $action = RebootControl::SHUTDOWN; } $task = RebootControl::execute($allowedMachines, $action, 0); if (Taskmanager::isTask($task)) { Util::redirect("?do=rebootcontrol&show=task&what=task&taskid=" . $task["id"]); } } private function getAllowedMachines($permission, $ids, &$allowedMachines) { $allowedLocations = User::getAllowedLocations($permission); if (empty($allowedLocations)) { Message::addError('main.no-permission'); Util::redirect('?do=statistics'); } $res = Database::simpleQuery('SELECT machineuuid, clientip, macaddr, locationid FROM machine WHERE machineuuid IN (:ids)', compact('ids')); $ids = array_flip($ids); $allowedMachines = []; $seenLocations = []; foreach ($res as $row) { unset($ids[$row['machineuuid']]); settype($row['locationid'], 'int'); if (in_array($row['locationid'], $allowedLocations)) { $allowedMachines[] = $row; } elseif (!isset($seenLocations[$row['locationid']])) { Message::addError('locations.no-permission-location', $row['locationid']); } $seenLocations[$row['locationid']] = true; } if (!empty($ids)) { Message::addWarning('unknown-machine', implode(', ', array_keys($ids))); } } private function deleteMachines($soft) { $ids = Request::post('uuid', [], 'array'); $ids = array_values($ids); if (empty($ids)) { Message::addError('main.parameter-empty', 'uuid'); return; } $allowedLocations = User::getAllowedLocations("machine.delete"); if (empty($allowedLocations)) { Message::addError('main.no-permission'); Util::redirect('?do=statistics'); } $res = Database::simpleQuery('SELECT machineuuid, locationid FROM machine WHERE machineuuid IN (:ids)', compact('ids')); $ids = array_flip($ids); $delete = []; foreach ($res as $row) { unset($ids[$row['machineuuid']]); if (in_array($row['locationid'], $allowedLocations)) { $delete[] = $row['machineuuid']; } else { Message::addError('locations.no-permission-location', $row['locationid']); } } if (!empty($delete)) { if ($soft) { // "Soft delete" -- keep all data, but set IP address to 0.0.0.0, so it will not be assigned to its // old location anymore. Upon next boot some time in the future, the machine is hopefully relocated // to somewhere else and will appear in a new location Database::exec("UPDATE machine SET clientip = '0.0.0.0', fixedlocationid = NULL, subnetlocationid = NULL WHERE machineuuid IN (:delete)", compact('delete')); Message::addSuccess('cleared-n-machines', count($delete)); } else { // Actually purge from DB Database::exec('DELETE FROM machine WHERE machineuuid IN (:delete)', compact('delete')); Message::addSuccess('deleted-n-machines', count($delete)); } } if (!empty($ids)) { Message::addWarning('unknown-machine', implode(', ', array_keys($ids))); } } protected function doRender() { if ($this->haveSubpage) { SubPage::doRender(); return; } Message::addError('main.value-invalid', 'show', $this->show); } protected function doAjax() { if (!User::load()) return; $action = Request::any('action'); if ($action === 'bios') { require_once 'modules/statistics/pages/machine.inc.php'; SubPage::ajaxCheckBios(); return; } if ($action === 'json-lookup') { $reply = []; foreach (Request::post('list', [], 'array') as $item) { $name = PciId::getPciId(PciId::AUTO, $item, true); if ($name === false) { $name = '?????'; } $reply[$item] = $name; } header('Content-Type: application/json'); die(json_encode($reply)); } $param = Request::any('lookup', false, 'string'); if ($param === false) { die('No lookup given'); } $add = ''; if (preg_match('/^([a-f0-9]{4}):([a-f0-9]{4})$/', $param, $out)) { $add = ' (' . $param . ')'; } $cached = PciId::getPciId(PciId::AUTO, $param, true); if ($cached === false) { $cached = 'Unknown'; } echo $cached, $add; exit; } }