haveSubpage = true; SubPage::doPreprocess(); } else { Message::addError('main.invalid-action', $section); return; } } else { $action = Request::post('action', 'show', 'string'); if ($action === 'reboot' || $action === 'shutdown') { $this->execRebootShutdown($action); } elseif ($action === 'toggle-wol') { User::assertPermission('woldiscover'); $enabled = Request::post('enabled', false); $c2c = Request::post('enabled-c2c', false); $port = Request::post('port', 9, 'int'); $dbcast = Request::post('dbcast', '', 'string'); Property::set(RebootControl::KEY_AUTOSCAN_DISABLED, !$enabled); Property::set(RebootControl::KEY_SCAN_CLIENT_TO_CLIENT, $c2c); Property::set(RebootControl::KEY_UDP_PORT, $port); Property::set(RebootControl::KEY_BROADCAST_ADDRESS, $dbcast); if ($enabled) { Message::addInfo('woldiscover-enabled'); } else { Message::addInfo('woldiscover-disabled'); } $section = 'subnet'; // For redirect below } } if (Request::isPost()) { Util::redirect('?do=rebootcontrol' . ($section ? '&show=' . $section : '')); } elseif ($section === false) { if (User::hasPermission('action.*')) { Util::redirect('?do=rebootcontrol&show=task'); } elseif (User::hasPermission('jumphost.*')) { Util::redirect('?do=rebootcontrol&show=jumphost'); } else { Util::redirect('?do=rebootcontrol&show=subnet'); } } } private function execRebootShutdown($action) { $requestedClients = Request::post('clients', false, 'array'); if (!is_array($requestedClients) || empty($requestedClients)) { Message::addError('no-clients-selected'); return; } $actualClients = RebootUtils::getFilteredMachineList($requestedClients, 'action.' . $action); if ($actualClients === false) return; RebootUtils::sortRunningFirst($actualClients); if ($action === 'shutdown') { $mode = 'SHUTDOWN'; $minutes = Request::post('s-minutes', 0, 'int'); } elseif (Request::any('quick', false, 'string') === 'on') { $mode = 'KEXEC_REBOOT'; $minutes = Request::post('r-minutes', 0, 'int'); } else { $mode = 'REBOOT'; $minutes = Request::post('r-minutes', 0, 'int'); } $task = RebootControl::execute($actualClients, $mode, $minutes); if (Taskmanager::isTask($task)) { Util::redirect("?do=rebootcontrol&show=task&what=task&taskid=" . $task["id"]); } } /** * Menu etc. has already been generated, now it's time to generate page content. */ protected function doRender() { $port = (int)Property::get(RebootControl::KEY_UDP_PORT); if ($port < 1 || $port > 65535) { $port = 9; } // Always show public key (it's public, isn't it?) $data = [ 'pubkey' => SSHKey::getPublicKey(), 'wol_auto_checked' => Property::get(RebootControl::KEY_AUTOSCAN_DISABLED) ? '' : 'checked', 'wol_c2c_checked' => Property::get(RebootControl::KEY_SCAN_CLIENT_TO_CLIENT) ? 'checked' : '', 'port' => $port, 'dbcast' => Property::get(RebootControl::KEY_BROADCAST_ADDRESS), ]; Permission::addGlobalTags($data['perms'], null, ['newkeypair', 'woldiscover']); Render::addTemplate('header', $data); if ($this->haveSubpage) { SubPage::doRender(); } } protected function doAjax() { $action = Request::post('action', false, 'string'); if ($action === 'generateNewKeypair') { User::assertPermission("newkeypair"); Property::set("rebootcontrol-private-key", false); echo SSHKey::getPublicKey(); } elseif ($action === 'clientstatus') { $clients = Request::post('clients'); if (is_array($clients)) { // XXX No permission check here, should we consider this as leaking sensitive information? $machines = RebootUtils::getMachinesByUuid(array_values($clients), false, ['machineuuid', 'state']); $ret = []; foreach ($machines as $machine) { switch ($machine['state']) { case 'OFFLINE': $val = 'glyphicon-off'; break; case 'IDLE': $val = 'glyphicon-ok green'; break; case 'OCCUPIED': $val = 'glyphicon-user red'; break; case 'STANDBY': $val = 'glyphicon-off green'; break; default: $val = 'glyphicon-question-sign'; break; } $ret[$machine['machineuuid']] = $val; } Header('Content-Type: application/json; charset=utf-8'); echo json_encode($ret); } } else { echo 'Invalid action.'; } } }