diff --git a/pandora_agents/pc/pandora_agent b/pandora_agents/pc/pandora_agent index b105a8c654..c5437d2225 100644 --- a/pandora_agents/pc/pandora_agent +++ b/pandora_agents/pc/pandora_agent @@ -1141,7 +1141,7 @@ sub guess_os_version { # Linux if ($os eq 'linux') { - $os_version = `lsb_release -sd 2>$DevNull`; + $os_version = `cat /etc/*ease|grep PRETTY| cut -f 2 -d= | tr -d '"' 2>$DevNull`; # AIX } elsif ($os eq 'aix') { $os_version = "$2.$1" if (`uname -rv` =~ /\s*(\d)\s+(\d)\s*/); diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index e81a2dd077..735369d2e7 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.760-220328 +Version: 7.0NG.760-220330 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index d7fb7a340c..b2cb2ea88b 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.760-220328" +pandora_version="7.0NG.760-220330" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index e60ee431d1..19f6a16d7b 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1015,7 +1015,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.760'; -use constant AGENT_BUILD => '220328'; +use constant AGENT_BUILD => '220330'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; @@ -2736,7 +2736,7 @@ sub guess_os_version ($) { # Linux if ($os eq 'linux') { - $os_version = `lsb_release -sd 2>$DevNull`; + $os_version = `cat /etc/*ease|grep PRETTY| cut -f 2 -d= | tr -d '"' 2>$DevNull`; # AIX } elsif ($os eq 'aix') { $os_version = "$2.$1" if (`uname -rv` =~ /\s*(\d)\s+(\d)\s*/); diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 03257eafbc..bd18df8bce 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.760 -%define release 220328 +%define release 220330 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 90ea38e90a..78979d3707 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.760 -%define release 220328 +%define release 220330 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 14fb1d1b35..b1b855189b 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.760" -PI_BUILD="220328" +PI_BUILD="220330" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 7f01f316d2..225f8c74a0 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{220328} +{220330} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 8acc633dbe..995f60c249 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.760 Build 220328") +#define PANDORA_VERSION ("7.0NG.760 Build 220330") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 56bc41ab03..cf91832174 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.760(Build 220328))" + VALUE "ProductVersion", "(7.0NG.760(Build 220330))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 0d701e3883..b91cb91ee5 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.760-220328 +Version: 7.0NG.760-220330 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 72783aa7f8..09fdcd3c0a 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.760-220328" +pandora_version="7.0NG.760-220330" package_pear=0 package_pandora=1 diff --git a/pandora_console/extensions/files_repo.php b/pandora_console/extensions/files_repo.php index 34e5fe52d2..c319954748 100644 --- a/pandora_console/extensions/files_repo.php +++ b/pandora_console/extensions/files_repo.php @@ -145,7 +145,7 @@ function pandora_files_repo_godmode() // Check for an anoying error that causes the $_POST and $_FILES arrays. // were empty if the file is larger than the post_max_size. if (intval($server_content_length) > 0 && empty($_POST)) { - ui_print_error_message(__('The file exceeds the maximum size')); + ui_print_error_message(__('Problem uploading. Please check this PHP runtime variable values:
  post_max_size (currently '.ini_get('post_max_size').')
')); } // GET and POST parameters. diff --git a/pandora_console/extensions/files_repo/files_repo_list.php b/pandora_console/extensions/files_repo/files_repo_list.php index cc1584dc17..783e155dc4 100644 --- a/pandora_console/extensions/files_repo/files_repo_list.php +++ b/pandora_console/extensions/files_repo/files_repo_list.php @@ -77,7 +77,7 @@ if (!empty($files)) { $file_name = explode('/', $file['location']); $file_decoded = $file_name[(count($file_name) - 1)]; $file_path = base64_encode($file_decoded); - $hash = md5($file_path.$config['dbpass']); + $hash = md5($file_path.$config['server_unique_identifier']); $url = ui_get_full_url( 'include/get_file.php?file='.urlencode($file_path).'&hash='.$hash ); diff --git a/pandora_console/extras/mr/53.sql b/pandora_console/extras/mr/53.sql index 86553a4e34..6dbda9a59f 100644 --- a/pandora_console/extras/mr/53.sql +++ b/pandora_console/extras/mr/53.sql @@ -1,6 +1,10 @@ START TRANSACTION; ALTER TABLE `tipam_vlan` ADD COLUMN `custom_id` bigint(20) unsigned DEFAULT NULL; +ALTER TABLE `tuser_task_scheduled`ADD COLUMN `enabled` TINYINT UNSIGNED NOT NULL DEFAULT 1; + +ALTER TABLE tagente MODIFY alias varchar(600) NOT NULL DEFAULT ''; +ALTER TABLE tagente MODIFY nombre varchar(600) NOT NULL DEFAULT ''; UPDATE `tuser_task` SET `parameters` = 'a:3:{i:0;a:2:{s:11:"description";s:11:"Description";s:4:"type";s:4:"text";}i:1;a:3:{s:11:"description";s:20:"Save to disk in path";s:4:"type";s:6:"string";s:13:"default_value";s:21:"_%_ATTACHMENT_PATH_%_";}i:2;a:3:{s:11:"description";s:14:"Active backups";s:4:"type";s:6:"number";s:13:"default_value";i:3;}}' WHERE `function_name` = 'cron_task_do_backup'; diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_759.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_759.mysql.sql index 535182d147..fcedcf16ae 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_759.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_759.mysql.sql @@ -1664,7 +1664,8 @@ UPDATE tagente SET tagente.alias = tagente.nombre; ALTER TABLE `tagente` MODIFY COLUMN `remote` tinyint(1) NOT NULL DEFAULT '0', MODIFY COLUMN `cascade_protection_module` int(10) unsigned NOT NULL DEFAULT '0', MODIFY COLUMN `update_secondary_groups` tinyint(1) NOT NULL DEFAULT '0', - MODIFY COLUMN `alias` varchar(600) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', + MODIFY COLUMN `alias` varchar(600) NOT NULL DEFAULT '', + MODIFY COLUMN `nombre` varchar(600) NOT NULL DEFAULT '', MODIFY COLUMN `alias_as_name` tinyint(2) NOT NULL DEFAULT '0'; -- --------------------------------------------------------------------- diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index f4a10a3fbb..ba690e8ce6 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -133,6 +133,11 @@ class DiscoveryTaskList extends HTML return $this->deleteConsoleTask(); } + $toggle_console_task = (int) get_parameter('toggle_console_task', -1); + if ($toggle_console_task === 1 || $toggle_console_task === 0) { + return $this->toggleConsoleTask($toggle_console_task); + } + $delete = (bool) get_parameter('delete', false); if ($delete === true) { return $this->deleteTask(); @@ -321,6 +326,49 @@ class DiscoveryTaskList extends HTML } + /** + * Toggle enable/disable status of selected Console Task. + * + * @param integer $enable If 1 enable the console task. + * + * @return void + */ + public function toggleConsoleTask(int $enable) + { + global $config; + + if ((bool) check_acl($config['id_user'], 0, 'RM') === false) { + db_pandora_audit( + AUDIT_LOG_ACL_VIOLATION, + 'Trying to access recon task viewer' + ); + include 'general/noaccess.php'; + return; + } + + $id_console_task = (int) get_parameter('id_console_task'); + + if ($id_console_task > 0) { + $result = db_process_sql_update( + 'tuser_task_scheduled', + ['enabled' => $enable], + ['id' => $id_console_task] + ); + + if ((int) $result === 1) { + return [ + 'result' => 0, + 'msg' => ((bool) $enable === true) ? __('Task successfully enabled') : __('Task succesfully disabled'), + 'id' => false, + ]; + } + + // Trick to avoid double execution. + header('Location: '.$this->url); + } + } + + /** * Delete a Console task. * diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index e8a0d5831a..8daf7bb786 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -26,6 +26,8 @@ * ============================================================================ */ +use PandoraFMS\Enterprise\Metaconsole\Node; + // Begin. global $config; @@ -86,6 +88,7 @@ $get_event_filters = get_parameter('get_event_filters', 0); $get_comments = (bool) get_parameter('get_comments', false); $get_events_fired = (bool) get_parameter('get_events_fired'); $get_id_source_event = get_parameter('get_id_source_event'); +$node_id = (int) get_parameter('node_id', 0); if ($get_comments === true) { $event = get_parameter('event', false); $filter = get_parameter('filter', false); @@ -195,7 +198,23 @@ if ($delete_event) { return; } - $r = events_delete($id_evento, $filter); + if ($node_id > 0) { + try { + $node = new Node($node_id); + $node->connect(); + $r = events_delete($id_evento, $filter, false, true); + } catch (\Exception $e) { + // Unexistent agent. + $node->disconnect(); + $success = false; + echo 'owner_error'; + } finally { + $node->disconnect(); + } + } else { + $r = events_delete($id_evento, $filter); + } + if ($r === false) { echo 'Failed'; } else { @@ -1261,18 +1280,42 @@ if ($change_status) { $event_ids = get_parameter('event_ids'); $new_status = get_parameter('new_status'); - $return = events_change_status( - explode(',', $event_ids), - $new_status, - $meta, - $history - ); + if ($node_id > 0) { + try { + $node = new Node($node_id); + $node->connect(); + $return = events_change_status( + explode(',', $event_ids), + $new_status, + $meta, + $history + ); + } catch (\Exception $e) { + // Unexistent agent. + $node->disconnect(); + $success = false; + echo 'owner_error'; + } finally { + $node->disconnect(); + } + } else { + $return = events_change_status( + explode(',', $event_ids), + $new_status, + $meta, + $history + ); + } if ($return !== false) { + $event_st = events_display_status($new_status); + echo json_encode( [ - 'status' => 'status_ok', - 'user' => db_get_value( + 'status_title' => $event_st['title'], + 'status_img' => html_print_image($event_st['img'], true, false, true), + 'status' => 'status_ok', + 'user' => db_get_value( 'fullname', 'tusuario', 'id_user', @@ -1306,7 +1349,22 @@ if ($change_owner) { $new_owner = ''; } - $return = events_change_owner($event_id, $new_owner, true, $meta, $history); + if ($node_id > 0) { + try { + $node = new Node($node_id); + $node->connect(); + $return = events_change_owner($event_id, $new_owner, true, $meta, $history); + } catch (\Exception $e) { + // Unexistent agent. + $node->disconnect(); + $success = false; + echo 'owner_error'; + } finally { + $node->disconnect(); + } + } else { + $return = events_change_owner($event_id, $new_owner, true, $meta, $history); + } if ($return) { echo 'owner_ok'; @@ -1322,7 +1380,7 @@ if ($change_owner) { if ($get_extended_event) { global $config; - $event = get_parameter('event', false); + $event = io_safe_output(get_parameter('event', false)); $filter = get_parameter('filter', false); if ($event === false) { @@ -1411,6 +1469,9 @@ if ($get_extended_event) { // Print group_rep in a hidden field to recover it from javascript. html_print_input_hidden('group_rep', (int) $group_rep); + if ($node_id > 0) { + html_print_input_hidden('node_id', (int) $node_id); + } if ($event === false) { return; @@ -1578,14 +1639,16 @@ if ($get_extended_event) { $comments = '
'; - $notifications = ''; - $notifications .= ''; - $notifications .= ''; - $notifications .= ''; - $notifications .= ''; - $notifications .= ''; + $notifications = '
'.ui_print_error_message(__('Error adding comment'), '', true).'
'; + $notifications .= '
'.ui_print_success_message(__('Comment added successfully'), '', true).'
'; + $notifications .= '
'.ui_print_error_message(__('Error changing event status'), '', true).'
'; + $notifications .= '
'.ui_print_success_message(__('Event status changed successfully'), '', true).'
'; + $notifications .= '
'.ui_print_error_message(__('Error changing event owner'), '', true).'
'; + $notifications .= '
'.ui_print_success_message(__('Event owner changed successfully'), '', true).'
'; + $notifications .= '
'.ui_print_error_message(__('Error deleting event'), '', true).'
'; - $loading = ''; + + $loading = '
'.html_print_image('images/spinner.gif', true).'
'; $i = 0; $tab['general'] = $i++; diff --git a/pandora_console/include/class/CredentialStore.class.php b/pandora_console/include/class/CredentialStore.class.php index 82ab94ee97..27486433ee 100644 --- a/pandora_console/include/class/CredentialStore.class.php +++ b/pandora_console/include/class/CredentialStore.class.php @@ -14,7 +14,7 @@ * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| * * ============================================================================ - * Copyright (c) 2005-2021 Artica Soluciones Tecnologicas + * Copyright (c) 2005-2022 Artica Soluciones Tecnologicas * Please see http://pandorafms.org for full contribution list * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -623,11 +623,13 @@ class CredentialStore extends Wizard $error = __('You must select a group where store this key!'); } else if (empty($product) === true) { $error = __('You must specify a product type'); - } else if (empty($username) === true && (empty($password) === true)) { + } else if (empty($username) === true || (empty($password) === true)) { $error = __('You must specify a username and/or password'); + } else if (evaluate_ascii_valid_string(io_safe_output($identifier)) === false) { + $error = __('Identifier with forbidden characters. Check the documentation.'); } - if (isset($error)) { + if (isset($error) === true) { $this->ajaxMsg('error', $error); exit; } @@ -644,8 +646,15 @@ class CredentialStore extends Wizard ]; // Spaces are not allowed. - $values['identifier'] = preg_replace('/\s+/', '-', trim($identifier)); - + $values['identifier'] = \io_safe_input( + preg_replace( + '/\s+/', + '-', + trim( + \io_safe_output($identifier) + ) + ) + ); return $values; } @@ -1270,7 +1279,7 @@ class CredentialStore extends Wizard }); } - + /** * Delete selected key */ diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 0b35391440..bf66713c09 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC220328'; +$build_version = 'PC220330'; $pandora_version = 'v7.0NG.760'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index c4f3e5ef3e..82f5ea6cca 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -2887,6 +2887,7 @@ function translate_file_upload_status($status_code) case UPLOAD_ERR_INI_SIZE: $message = __('The file exceeds the maximum size'); + $message .= __('Please check this PHP runtime variable values:
  upload_max_filesize (currently '.ini_get('upload_max_filesize').')
'); break; case UPLOAD_ERR_FORM_SIZE: diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index bbbac884b5..a311b7ec4a 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -1,23 +1,32 @@ '; - $data[0] .= html_print_image( - 'images/target.png', - true, - [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] - ); - $data[0] .= ''; + if ((bool) $task['enabled'] === true) { + $data[0] = html_print_anchor( + [ + 'href' => sprintf( + '%sforce_run=1&id_console_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true + ); + } else { + $data[0] = ''; + } $data[1] = $task['id_usuario']; $data[2] = db_get_value( @@ -501,18 +521,25 @@ function cron_list_table() break; case 'cron_task_generate_report': - if ($write_perms || $manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true && ($write_perms === true || $manage_pandora === true)) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -549,18 +576,25 @@ function cron_list_table() break; case 'cron_task_generate_report_by_template': - if ($write_perms || $manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true && ($write_perms === true || $manage_pandora === true)) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -634,18 +668,25 @@ function cron_list_table() break; case 'cron_task_execute_custom_script': - if ($manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -663,18 +704,25 @@ function cron_list_table() break; case 'cron_task_save_report_to_disk': - if ($write_perms || $manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -702,18 +750,25 @@ function cron_list_table() break; case 'cron_task_save_xml_report_to_disk': - if ($write_perms || $manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true && ($write_perms === true || $manage_pandora === true)) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -734,22 +789,28 @@ function cron_list_table() $data[2] .= '&id='.$args[0]."'>".$report['name'].''; $data[2] .= '
- '.__('Path').': '.$path.''; $data[2] .= '
- '.__('Report type').': '.$report_type; - break; case 'cron_task_do_backup': - if ($manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true && $manage_pandora === true) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -765,18 +826,25 @@ function cron_list_table() break; case 'cron_task_generate_csv_log': - if ($manage_pandora) { - $data[0] = ''; - $data[0] .= html_print_image( - 'images/target.png', - true, + if ((bool) $task['enabled'] === true && $manage_pandora === true) { + $data[0] = html_print_anchor( [ - 'title' => __('Force run'), - 'class' => 'invert_filter', - ] + 'href' => sprintf( + '%sforce_run=1&id_user_task=%s', + $url, + $task['id'] + ), + 'content' => html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force run'), + 'class' => 'invert_filter', + ] + ), + ], + true ); - $data[0] .= ''; } else { $data[0] = ''; } @@ -860,6 +928,26 @@ function cron_list_table() } } + $data[7] .= html_print_anchor( + [ + 'href' => sprintf( + '%stoggle_console_task=%s&id_user_task=%s', + $url, + ((bool) $task['enabled'] === true) ? '0' : '1', + $task['id'] + ), + 'content' => html_print_image( + ((bool) $task['enabled'] === true) ? 'images/lightbulb.png' : 'images/lightbulb_off.png', + true, + [ + 'title' => ((bool) $task['enabled'] === true) ? __('Disable task') : __('Enable task'), + 'class' => 'invert_filter', + ] + ), + ], + true + ); + array_push($table->data, $data); } diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 1eb5a1e34b..6ec66b0abd 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -352,13 +352,14 @@ function events_get_column_names($fields, $table_alias=false) /** * Validates all events matching target filter. * - * @param integer $id_evento Master event. - * @param array $filter Optional. Filter options. - * @param boolean $history Apply on historical table. + * @param integer $id_evento Master event. + * @param array $filter Optional. Filter options. + * @param boolean $history Apply on historical table. + * @param boolean $force_node Force node table. * * @return integer Events validated or false if error. */ -function events_delete($id_evento, $filter=null, $history=false) +function events_delete($id_evento, $filter=null, $history=false, $force_node=false) { if (!isset($id_evento) || $id_evento <= 0) { return false; @@ -368,7 +369,10 @@ function events_delete($id_evento, $filter=null, $history=false) $filter = ['group_rep' => 0]; } - $table = events_get_events_table(is_metaconsole(), $history); + $table = events_get_events_table( + ($force_node === false) ? is_metaconsole() : false, + $history + ); switch ($filter['group_rep']) { case '0': @@ -3752,7 +3756,7 @@ function events_page_responses($event, $childrens_ids=[]) $data = []; $data[0] = __('Delete event'); $data[1] = ''; - $data[2] = '
'; + $data[2] = ''; $data[2] .= html_print_button( __('Delete event'), 'delete_button', @@ -5043,6 +5047,8 @@ function events_page_general($event) $event_st = events_display_status($event['estado']); $data = []; + + $table_general->rowid[7] = 'general_status'; $data[0] = __('Status'); $data[1] = $event_st['title']; $data[2] = html_print_image($event_st['img'], true); diff --git a/pandora_console/include/functions_tactical.php b/pandora_console/include/functions_tactical.php index 942e88832c..bfd556981b 100644 --- a/pandora_console/include/functions_tactical.php +++ b/pandora_console/include/functions_tactical.php @@ -118,6 +118,7 @@ function tactical_get_data($id_user=false, $user_strict=false, $acltags, $return $user_groups_ids = implode(',', array_unique($user_group_children_ids)); } + // Subquery is needed for avoid possible duplicity in id_agente. $sql_stats = sprintf( 'SELECT tma.id_grupo, COUNT(tma.id_agente) AS agents_total, SUM(tma.total_count) AS monitors_total, @@ -128,10 +129,12 @@ function tactical_get_data($id_user=false, $user_strict=false, $acltags, $return SUM(tma.notinit_count) AS monitors_not_init, SUM(tma.fired_count) AS alerts_fired FROM tmetaconsole_agent tma - LEFT JOIN tmetaconsole_agent_secondary_group tmasg - ON tma.id_agente = tmasg.id_agent - WHERE tma.disabled = 0 - AND tma.id_grupo IN (%s) OR tmasg.id_group IN (%s) + WHERE tma.disabled = 0 + AND tma.id_agente IN ( + SELECT DISTINCT tmag.id_agente FROM tmetaconsole_agent tmag + LEFT JOIN tmetaconsole_agent_secondary_group tmasg + ON tmag.id_agente = tmasg.id_agent WHERE tmag.id_grupo IN (%s) OR tmasg.id_group IN (%s) + ) GROUP BY tma.id_grupo', $user_groups_ids, $user_groups_ids diff --git a/pandora_console/include/graphs/functions_utils.php b/pandora_console/include/graphs/functions_utils.php index 11737099a8..e68a11a9f1 100644 --- a/pandora_console/include/graphs/functions_utils.php +++ b/pandora_console/include/graphs/functions_utils.php @@ -328,3 +328,43 @@ function convert_array_multi($array, $glue) $result = substr($result, 0, (0 - strlen($glue))); return $result; } + + +/** + * Evaluate if the chars of coming variable has in the range stablished. + * + * @param string $string String for be evaluated. + * @param array $ranges Ranges for valid chars. Min: [ x <= Y ] Max: [ Y > x ]. + * Example of valid ranges: [ '32:126', '150:188' ]. + * + * @return boolean. + */ +function evaluate_ascii_valid_string(string $string='', array $ranges=[ '33:38', '40:126' ]) +{ + if (empty($string) === true) { + return false; + } + + $countChars = strlen($string); + // Let's explore all the chars. + for ($i = 0; $i < $countChars; $i++) { + // Get ascii number of the char. + $asciiNumber = ord($string[$i]); + // Check in all ranges. + $rangeValidation = false; + foreach ($ranges as $range) { + list($minRangeValue, $maxRangeValue) = explode(':', $range, 2); + // Check if is in range. + if ($asciiNumber > (int) $minRangeValue && $asciiNumber < (int) $maxRangeValue) { + $rangeValidation = true; + } + } + + // None of the ranges was validated. + if ($rangeValidation === false) { + return false; + } + } + + return true; +} diff --git a/pandora_console/include/javascript/multiselect_filtered.js b/pandora_console/include/javascript/multiselect_filtered.js index 74f24f5a0a..dcaee528b0 100644 --- a/pandora_console/include/javascript/multiselect_filtered.js +++ b/pandora_console/include/javascript/multiselect_filtered.js @@ -232,7 +232,6 @@ function fmModuleChange(uniqId, isMeta) { selection: showCommonModules }, function(data) { - debugger; $("#filtered-module-modules-" + uniqId).html(""); if (data) { jQuery.each(data, function(id, value) { diff --git a/pandora_console/include/javascript/pandora_dashboards.js b/pandora_console/include/javascript/pandora_dashboards.js index 49c8a91dd4..6e5a87b169 100644 --- a/pandora_console/include/javascript/pandora_dashboards.js +++ b/pandora_console/include/javascript/pandora_dashboards.js @@ -1404,7 +1404,8 @@ function dashboardShowEventDialog(settings) { dialog_page: "", meta: 0, history: 0, - filter: [] + filter: [], + node_id: settings.node_id }, dataType: "html", success: function(data) { @@ -1417,9 +1418,58 @@ function dashboardShowEventDialog(settings) { resizable: true, draggable: true, modal: true, + create: function() { + $("#button-delete_button").removeAttr("onclick"); + $("#button-delete_button").click(function() { + var confirm_message = $("#hidden-delete_confirm_message").val(); + if (confirm(confirm_message) == false) { + return false; + } + $.ajax({ + method: "post", + url: settings.ajaxUrl, + data: { + page: "include/ajax/events", + delete_event: 1, + node_id: settings.node_id, + id_evento: settings.event.id_evento, + filter: [] + }, + success: function() { + $("#notification_delete_error").show(); + $("#event_details_window").dialog("close"); + }, + error: function(error) { + console.error(error); + } + }); + }); + }, close: function() { //$("#refrcounter").countdown("resume"); //$("div.vc-countdown").countdown("resume"); + $.ajax({ + method: "post", + url: settings.ajaxUrl, + data: { + page: "operation/dashboard/dashboard", + method: "drawWidget", + dashboardId: settings.dashboardId, + cellId: settings.cellId, + widgetId: settings.widgetId, + redraw: 1 + }, + success: function(dataWidget) { + // Widget empty and reload. + $("#widget-" + settings.cellId + " .content-widget").empty(); + $("#widget-" + settings.cellId + " .content-widget").append( + dataWidget + ); + }, + error: function(error) { + console.error(error); + } + }); }, overlay: { opacity: 0.5, diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index 357e22318c..eda55136f5 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -476,6 +476,7 @@ function event_change_status(event_ids) { var new_status = $("#estado").val(); var meta = $("#hidden-meta").val(); var history = $("#hidden-history").val(); + var node_id = $("#hidden-node_id").val(); $("#button-status_button").attr("disabled", "disabled"); $("#response_loading").show(); @@ -487,6 +488,7 @@ function event_change_status(event_ids) { event_ids: event_ids, new_status: new_status, meta: meta, + node_id: node_id, history: history }, type: "POST", @@ -519,6 +521,13 @@ function event_change_status(event_ids) { "N/A" ); } + + $("#general_status") + .find(".general_status") + .text(data.status_title); + $("#general_status") + .find("img") + .attr("src", data.status_img); } else { $("#notification_status_error").show(); } @@ -533,6 +542,7 @@ function event_change_owner() { var new_owner = $("#id_owner").val(); var meta = $("#hidden-meta").val(); var history = $("#hidden-history").val(); + var node_id = $("#hidden-node_id").val(); $("#button-owner_button").attr("disabled", "disabled"); $("#response_loading").show(); @@ -544,6 +554,7 @@ function event_change_owner() { event_id: event_id, new_owner: new_owner, meta: meta, + node_id: node_id, history: history }, type: "POST", diff --git a/pandora_console/include/lib/Dashboard/Widgets/events_list.php b/pandora_console/include/lib/Dashboard/Widgets/events_list.php index 602533e73a..e0c1bfe3cf 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/events_list.php +++ b/pandora_console/include/lib/Dashboard/Widgets/events_list.php @@ -502,6 +502,7 @@ class EventsListWidget extends Widget \ui_require_css_file('events', 'include/styles/', true); \ui_require_css_file('tables', 'include/styles/', true); + \ui_require_javascript_file('pandora_events', 'include/javascript/', true); $this->values['groupId'] = explode(',', $this->values['groupId'][0]); $this->values['tagsId'] = explode(',', $this->values['tagsId'][0]); @@ -668,6 +669,18 @@ class EventsListWidget extends Widget true ); + $output .= \html_print_input_hidden( + 'meta', + is_metaconsole(), + true + ); + + $output .= \html_print_input_hidden( + 'delete_confirm_message', + __('Are you sure?'), + true + ); + $table = new \StdClass; $table->class = 'widget_groups_status databox'; $table->cellspacing = '1'; @@ -717,16 +730,20 @@ class EventsListWidget extends Widget $settings = json_encode( [ - 'event' => $event, - 'page' => 'include/ajax/events', - 'cellId' => $this->cellId, - 'ajaxUrl' => \ui_get_full_url( + 'event' => $event, + 'page' => 'include/ajax/events', + 'cellId' => $this->cellId, + 'ajaxUrl' => \ui_get_full_url( 'ajax.php', false, false, false ), - 'result' => false, + 'result' => false, + 'dashboardId' => $this->dashboardId, + 'widgetId' => $this->widgetId, + 'cellId' => $this->cellId, + 'node_id' => $this->nodeId, ] ); diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index cd60523341..a6ddcd02b9 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -875,6 +875,9 @@ select:-internal-list-box { .invisible_important { display: none !important; } +.invisible_events { + display: none; +} .visible { display: block; diff --git a/pandora_console/install.php b/pandora_console/install.php index c7d5588838..ed875862df 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
{'fields_values'}); - foreach my $field (@command_fields) { - unless (defined($action->{'field'.$index}) && $action->{'field'.$index} ne "") { - $action->{'field'.$index} = defined($field) ? $field : "" ; - } - } - if (!defined($alert->{'snmp_alert'})) { # Regular alerts $field1 = defined($action->{'field1'}) && $action->{'field1'} ne "" ? $action->{'field1'} : $alert->{'field1'}; @@ -1163,6 +1154,15 @@ sub pandora_execute_action ($$$$$$$$$;$$) { $field20 = defined($action->{'field20'}) && $action->{'field20'} ne "" ? $action->{'field20'} : $alert->{'field20'}; } else { + # Check for empty alert fields and assign command field. + my $index = 1; + my @command_fields = split(/,|\[|\]/, $action->{'fields_values'}); + foreach my $field (@command_fields) { + if (!defined($action->{'field'.$index}) || $action->{'field'.$index} eq "") { + $action->{'field'.$index} = defined($field) ? $field : "" ; + } + } + $field1 = defined($alert->{'field1'}) && $alert->{'field1'} ne "" ? $alert->{'field1'} : $action->{'field1'}; $field2 = defined($alert->{'field2'}) && $alert->{'field2'} ne "" ? $alert->{'field2'} : $action->{'field2'}; $field3 = defined($alert->{'field3'}) && $alert->{'field3'} ne "" ? $alert->{'field3'} : $action->{'field3'}; @@ -1185,7 +1185,6 @@ sub pandora_execute_action ($$$$$$$$$;$$) { $field20 = defined($alert->{'field20'}) && $alert->{'field20'} ne "" ? $alert->{'field20'} : $action->{'field20'}; } - # Recovery fields, thanks to Kato Atsushi if ($alert_mode == RECOVERED_ALERT) { # Field 1 is a special case where [RECOVER] prefix is not added even when it is defined diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index f7cd712293..ea29918e34 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -42,6 +42,7 @@ our @EXPORT = qw( db_disconnect db_do db_get_lock + db_get_pandora_lock db_insert db_insert_get_values db_insert_from_array_hash @@ -49,6 +50,7 @@ our @EXPORT = qw( db_process_insert db_process_update db_release_lock + db_release_pandora_lock db_string db_text db_update @@ -1575,6 +1577,52 @@ sub db_release_lock($$) { my ($lock) = $sth->fetchrow; } +######################################################################## +## Try to obtain a persistent lock using Pandora FMS's database. +######################################################################## +sub db_get_pandora_lock($$;$) { + my ($dbh, $lock_name, $lock_timeout) = @_; + my $rv; + + # Lock. + my $lock = db_get_lock($dbh, $lock_name, $lock_timeout); + if ($lock != 0) { + my $lock_value = get_db_value($dbh, "SELECT `value` FROM tconfig WHERE token = 'pandora_lock_$lock_name'"); + if (!defined($lock_value)) { + my $sth = $dbh->prepare('INSERT INTO tconfig (`token`, `value`) VALUES (?, ?)'); + $rv = $sth->execute('pandora_lock_' . $lock_name, '1'); + } elsif ($lock_value == 0) { + my $sth = $dbh->prepare('UPDATE tconfig SET `value`=? WHERE `token`=?'); + $rv = $sth->execute('1', 'pandora_lock_' . $lock_name); + } + db_release_lock($dbh, $lock_name); + } + + # Lock acquired. + if ($rv) { + return 1; + } + + # Something went wrong. + return 0; +} + +######################################################################## +## Release a persistent lock. +######################################################################## +sub db_release_pandora_lock($$;$) { + my ($dbh, $lock_name, $lock_timeout) = @_; + my $rv; + + # Lock. + my $lock = db_get_lock($dbh, $lock_name, $lock_timeout); + if ($lock != 0) { + my $sth = $dbh->prepare('UPDATE tconfig SET `value`=? WHERE `token`=?'); + $rv = $sth->execute('0', 'pandora_lock_' . $lock_name); + db_release_lock($dbh, $lock_name); + } +} + ######################################################################## ## Set SSL options globally for the module. ######################################################################## diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index 31b2e7322c..dd177b73aa 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -34,7 +34,7 @@ our @ISA = qw(Exporter); # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.760"; -my $pandora_build = "220328"; +my $pandora_build = "220330"; our $VERSION = $pandora_version." ".$pandora_build; our %EXPORT_TAGS = ( 'all' => [ qw() ] ); diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 734170b0ff..8a72170a3b 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -237,7 +237,7 @@ our $OS = $^O; our $OS_VERSION = "unknown"; our $DEVNULL = '/dev/null'; if ($OS eq 'linux') { - $OS_VERSION = `lsb_release -sd 2>/dev/null`; + $OS_VERSION = `cat /etc/*ease|grep PRETTY| cut -f 2 -d= | tr -d '"' 2>/dev/null`; } elsif ($OS eq 'aix') { $OS_VERSION = "$2.$1" if (`uname -rv` =~ /\s*(\d)\s+(\d)\s*/); } elsif ($OS =~ /win/i) { diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index bc8527ee61..fbf38a6d51 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.760 -%define release 220328 +%define release 220330 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index f095f8767a..263732c362 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.760 -%define release 220328 +%define release 220330 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index cc99421353..636b6f7f7b 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.760" -PI_BUILD="220328" +PI_BUILD="220330" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 9aa07c940c..7ae067a84c 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.760 Build 220328"; +my $version = "7.0NG.760 Build 220330"; # Pandora server configuration my %conf; @@ -47,6 +47,9 @@ my $BIG_OPERATION_STEP = 100; # 100 is default #Increate to 3000~5000 in fast systems decrease to 500 or 250 on systems with locks my $SMALL_OPERATION_STEP = 1000; # 1000 is default +# Timeout for lock acquisition. +my $LOCK_TIMEOUT = 60; + # FLUSH in each IO $| = 1; @@ -1082,6 +1085,10 @@ sub pandoradb_history ($$) { log_message ('', "\n"); } + # Update tconfig with last time of database maintance time (now) + db_do ($dbh, "DELETE FROM tconfig WHERE token = 'db_maintance'"); + db_do ($dbh, "INSERT INTO tconfig (token, value) VALUES ('db_maintance', '".time()."')"); + log_message ('', "Ending at ". strftime ("%Y-%m-%d %H:%M:%S", localtime()) . "\n"); } @@ -1214,10 +1221,18 @@ if ($conf{'_force'} == 0 && pandora_is_master(\%conf) == 0) { exit 1; } -# Get a lock on dbname. +# Set the lock name for pandora_db. my $lock_name = $conf{'dbname'}; -my $lock = db_get_lock ($dbh, $lock_name); -if ($lock == 0 && $conf{'_force'} == 0) { + +# Release the database lock in forced mode. +if ($conf{'_force'} == 1) { + log_message ('', " [*] Releasing database lock.\n\n"); + db_release_pandora_lock($dbh, $lock_name, $LOCK_TIMEOUT); +} + +# Get a lock on dbname. +my $lock = db_get_pandora_lock ($dbh, $lock_name, $LOCK_TIMEOUT); +if ($lock == 0) { log_message ('', " [*] Another instance of DB Tool seems to be running.\n\n"); exit 1; } @@ -1260,9 +1275,7 @@ if (scalar(@types) != 0) { } # Release the lock -if ($lock == 1) { - db_release_lock ($dbh, $lock_name); -} +db_release_pandora_lock ($dbh, $lock_name); # Cleanup and exit db_disconnect ($history_dbh) if defined ($history_dbh); diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 642f241556..6531bd7bbf 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.760 Build 220328"; +my $version = "7.0NG.760 Build 220330"; # save program name for logging my $progname = basename($0);