diff --git a/extras/pandora_update_version.sh b/extras/pandora_update_version.sh index 90c4bf6519..10e5534459 100755 --- a/extras/pandora_update_version.sh +++ b/extras/pandora_update_version.sh @@ -54,7 +54,8 @@ AGENT_WIN_FILE="$CODEHOME/pandora_agents/win32/pandora.cc" AGENT_WIN_MPI_FILE="$CODEHOME/pandora_agents/win32/installer/pandora.mpi" AGENT_WIN_RC_FILE="$CODEHOME/pandora_agents/win32/versioninfo.rc" SATELLITE_FILE="$PANDHOME_ENT/satellite_server/satellite_server.pl" -PERL_PLUGIN_FILES="$PANDHOME_ENT/pandora_server/util/plugin/vmware-plugin.pl \ +PERL_PLUGIN_FILES="$PANDHOME_ENT/pandora_server/util/recon_script/vmware-plugin.pl \ +$PANDHOME_ENT/pandora_server/util/recon_script/pcm_client.pl \ $PANDHOME_ENT/pandora_plugins/NGINX/nginx_requests_queued.pl \ $PANDHOME_ENT/pandora_plugins/Sybase/sybase_plugin.pl \ $PANDHOME_ENT/pandora_plugins/SNMP/dynamic_snmp.pl \ diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 6af9c8cebe..e9d22f629b 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.731-190225 +Version: 7.0NG.731-190226 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 885349a84a..64c13e926e 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.731-190225" +pandora_version="7.0NG.731-190226" 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 1b0beb6592..bb7d98e310 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -42,7 +42,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.731'; -use constant AGENT_BUILD => '190225'; +use constant AGENT_BUILD => '190226'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 479ec78469..d4e33903d4 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.731 -%define release 190225 +%define release 190226 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 958ec6edb9..87436366bb 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.731 -%define release 190225 +%define release 190226 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 324749839f..3ff9b6a963 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.731" -PI_BUILD="190225" +PI_BUILD="190226" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index a9f356dcf9..abdf2e0ce4 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{190225} +{190226} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 1cdb4731e9..01f027089d 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.731(Build 190225)") +#define PANDORA_VERSION ("7.0NG.731(Build 190226)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 4ed34ac285..cb30f2163d 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.731(Build 190225))" + VALUE "ProductVersion", "(7.0NG.731(Build 190226))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 84bd5108d8..fe87752dff 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.731-190225 +Version: 7.0NG.731-190226 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 ed29060a70..60d17de09e 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.731-190225" +pandora_version="7.0NG.731-190226" package_pear=0 package_pandora=1 diff --git a/pandora_console/extras/mr/25.sql b/pandora_console/extras/mr/25.sql index b8a1eca9ae..0809bc486e 100644 --- a/pandora_console/extras/mr/25.sql +++ b/pandora_console/extras/mr/25.sql @@ -1,5 +1,147 @@ START TRANSACTION; +UPDATE `twidget` SET `unique_name`='example' WHERE `class_name` LIKE 'WelcomeWidget'; + INSERT INTO `tconfig` (`token`, `value`) VALUES ('status_monitor_fields', 'policy,agent,data_type,module_name,server_type,interval,status,graph,warn,data,timestamp'); -COMMIT; \ No newline at end of file +ALTER TABLE `trecon_task` ADD COLUMN `wmi_enabled` tinyint(1) unsigned DEFAULT '0'; +ALTER TABLE `trecon_task` ADD COLUMN `auth_strings` text; +ALTER TABLE `trecon_task` ADD COLUMN `autoconfiguration_enabled` tinyint(1) unsigned default '0'; + + +INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Application.VMware', 'Discovery Application script to monitor VMware technologies (ESXi, VCenter, VSphere)', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); + +CREATE TABLE IF NOT EXISTS `tevent_extended` ( + `id` serial PRIMARY KEY, + `id_evento` bigint(20) unsigned NOT NULL, + `external_id` bigint(20) unsigned, + `utimestamp` bigint(20) NOT NULL default '0', + `description` text, + FOREIGN KEY `tevent_ext_fk`(`id_evento`) REFERENCES `tevento`(`id_evento`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `tnotification_source` ( + `id` serial, + `description` VARCHAR(255) DEFAULT NULL, + `icon` text, + `max_postpone_time` int(11) DEFAULT NULL, + `enabled` int(1) DEFAULT NULL, + `user_editable` int(1) DEFAULT NULL, + `also_mail` int(1) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `tnotification_source` +-- +INSERT INTO `tnotification_source`(`description`, `icon`, `max_postpone_time`, `enabled`, `user_editable`, `also_mail`) VALUES + ("System status", "icono_info_mr.png", 86400, 1, 1, 0), + ("Message", "icono_info_mr.png", 86400, 1, 1, 0), + ("Pending task", "icono_info_mr.png", 86400, 1, 1, 0), + ("Advertisement", "icono_info_mr.png", 86400, 1, 1, 0), + ("Official communication", "icono_info_mr.png", 86400, 1, 1, 0), + ("Sugerence", "icono_info_mr.png", 86400, 1, 1, 0); + +-- ----------------------------------------------------- +-- Table `tmensajes` +-- ----------------------------------------------------- +ALTER TABLE `tmensajes` ADD COLUMN `url` TEXT; +ALTER TABLE `tmensajes` ADD COLUMN `response_mode` VARCHAR(200) DEFAULT NULL; +ALTER TABLE `tmensajes` ADD COLUMN `citicity` INT(10) UNSIGNED DEFAULT '0'; +ALTER TABLE `tmensajes` ADD COLUMN `id_source` BIGINT(20) UNSIGNED NOT NULL; +ALTER TABLE `tmensajes` ADD COLUMN `subtype` VARCHAR(255) DEFAULT ''; +ALTER TABLE `tmensajes` ADD INDEX (`id_source`); +UPDATE `tmensajes` SET `id_source`=(SELECT `id` FROM `tnotification_source` WHERE `description` = "Message"); +ALTER TABLE `tmensajes` ADD CONSTRAINT `tsource_fk` FOREIGN KEY (`id_source`) REFERENCES `tnotification_source` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + + +CREATE TABLE IF NOT EXISTS `tnotification_user` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL, + `id_user` VARCHAR(60) NOT NULL, + `utimestamp_read` BIGINT(20), + `utimestamp_erased` BIGINT(20), + `postpone` INT, + PRIMARY KEY (`id_mensaje`,`id_user`), + FOREIGN KEY (`id_mensaje`) REFERENCES `tmensajes`(`id_mensaje`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tnotification_group` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL, + `id_group` mediumint(4) UNSIGNED NOT NULL, + PRIMARY KEY (`id_mensaje`,`id_group`), + FOREIGN KEY (`id_mensaje`) REFERENCES `tmensajes`(`id_mensaje`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tnotification_source_user` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_user` VARCHAR(60), + `enabled` INT(1) DEFAULT NULL, + `also_mail` INT(1) DEFAULT NULL, + PRIMARY KEY (`id_source`,`id_user`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tnotification_source_group` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL, + PRIMARY KEY (`id_source`,`id_group`), + INDEX (`id_group`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tnotification_source_group_user`( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL, + `id_user` VARCHAR(60), + `enabled` INT(1) DEFAULT NULL, + `also_mail` INT(1) DEFAULT NULL, + PRIMARY KEY (`id_source`,`id_user`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_group`) REFERENCES `tnotification_source_group`(`id_group`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `talert_commands` (`name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES ('Generate Notification','Internal type','This command allows you to send an internal notification to any user or group.',1,'[\"Destination user\",\"Destination group\",\"Title\",\"Message\",\"Link\",\"Criticity\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); + +INSERT INTO `tnotification_source_user` (`id_source`, `id_user`, `enabled`, `also_mail`) VALUES ((SELECT `id` FROM `tnotification_source` WHERE `description`="System status"), "admin", 1, 0); +INSERT INTO `tnotification_source_group` SELECT `id`,0 FROM `tnotification_source` WHERE `description`="Message"; +INSERT INTO `tnotification_user` (`id_mensaje`, `id_user`) SELECT `id_mensaje`, `id_usuario_destino` FROM `tmensajes` WHERE `id_usuario_destino` != ''; + +INSERT INTO tlog_graph_models (`title`,`regexp`,`fields`,`average`) VALUES ('Apache accesses per client and status', +'(.*?)\ -.*1.1"\ (\d+)\ \d+', +'host,status', 1); + +INSERT INTO tlog_graph_models (`title`,`regexp`,`fields`,`average`) VALUES ('Apache time per requester and html code', +'(.*?)\ -.*1.1"\ (\d+)\ (\d+)', +'origin,respose,_time_', 1); + +INSERT INTO tlog_graph_models (`title`,`regexp`,`fields`,`average`) VALUES ('Count output', +'.*', +'Coincidences', 0); + +INSERT INTO tlog_graph_models (`title`,`regexp`,`fields`,`average`) VALUES ('Events replicated to metaconsole', +'.* (.*?) .* (\d+) events replicated to metaconsole', +'server,_events_', 0); + +INSERT INTO tlog_graph_models (`title`,`regexp`,`fields`,`average`) VALUES ('Pages with warnings', +'PHP Warning:.*in (.*?) on', +'page', 0); + +INSERT INTO tlog_graph_models (`title`,`regexp`,`fields`,`average`) VALUES ('Users login', +'Starting Session \d+\ of user (.*)', +'user', 0); + +COMMIT; diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 99a5dae2be..2492a9913f 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -1407,12 +1407,16 @@ ALTER TABLE twidget_dashboard MODIFY options LONGTEXT NOT NULL default ""; ALTER TABLE trecon_task ADD `alias_as_name` int(2) unsigned default '0'; ALTER TABLE trecon_task ADD `snmp_enabled` int(2) unsigned default '0'; ALTER TABLE trecon_task ADD `vlan_enabled` int(2) unsigned default '0'; +ALTER TABLE trecon_task ADD `wmi_enabled` tinyint(1) unsigned DEFAULT '0'; +ALTER TABLE trecon_task ADD `auth_strings` text; +ALTER TABLE trecon_task ADD `autoconfiguration_enabled` tinyint(1) unsigned default '0'; -- --------------------------------------------------------------------- -- Table `twidget` AND Table `twidget_dashboard` -- --------------------------------------------------------------------- UPDATE twidget_dashboard SET id_widget = (SELECT id FROM twidget WHERE unique_name = 'graph_module_histogram') WHERE id_widget = (SELECT id FROM twidget WHERE unique_name = 'graph_availability'); DELETE FROM twidget WHERE unique_name = 'graph_availability'; +UPDATE `twidget` SET `unique_name`='example' WHERE `class_name` LIKE 'WelcomeWidget'; -- --------------------------------------------------------------------- -- Table `tbackup` (Extension table. Modify only if exists) @@ -1817,7 +1821,30 @@ CREATE TABLE IF NOT EXISTS `tlog_graph_models` ( INSERT INTO tlog_graph_models VALUES (1, 'Apache log model', '^.*?\s+.*".*?\s(\/.*?)\?.*1.1"\s+(.*?)\s+(.*?)\s+', 'pagina, html_err_code, _tiempo_', 1); - + +INSERT INTO tlog_graph_models VALUES (2, 'Apache accesses per client and status', +'(.*?)\ -.*1.1"\ (\d+)\ \d+', +'host,status', 1); + +INSERT INTO tlog_graph_models VALUES (3, 'Apache time per requester and html code', +'(.*?)\ -.*1.1"\ (\d+)\ (\d+)', +'origin,respose,_time_', 1); + +INSERT INTO tlog_graph_models VALUES (4, 'Count output', +'.*', +'Coincidences', 0); + +INSERT INTO tlog_graph_models VALUES (5, 'Events replicated to metaconsole', +'.* (.*?) .* (\d+) events replicated to metaconsole', +'server,_events_', 0); + +INSERT INTO tlog_graph_models VALUES (6, 'Pages with warnings', +'PHP Warning:.*in (.*?) on', +'page', 0); + +INSERT INTO tlog_graph_models VALUES (7, 'Users login', +'Starting Session \d+\ of user (.*)', +'user', 0); -- ----------------------------------------------------- -- Add column in table `treport` -- ----------------------------------------------------- @@ -1857,6 +1884,19 @@ ALTER TABLE `tevento` ADD COLUMN `data` double(22,5) default NULL; ALTER TABLE `tevento` ADD COLUMN `module_status` int(4) NOT NULL default '0'; +-- --------------------------------------------------------------------- +-- Table `tevent_extended` +-- --------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tevent_extended` ( + `id` serial PRIMARY KEY, + `id_evento` bigint(20) unsigned NOT NULL, + `external_id` bigint(20) unsigned, + `utimestamp` bigint(20) NOT NULL default '0', + `description` text, + FOREIGN KEY `tevent_ext_fk`(`id_evento`) REFERENCES `tevento`(`id_evento`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- ----------------------------------------------------- -- Table `tgis_map_layer_groups` -- ----------------------------------------------------- @@ -1869,3 +1909,128 @@ CREATE TABLE IF NOT EXISTS `tgis_map_layer_groups` ( FOREIGN KEY (`group_id`) REFERENCES `tgrupo` (`id_grupo`) ON DELETE CASCADE, FOREIGN KEY (`agent_id`) REFERENCES `tagente` (`id_agente`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ----------------------------------------------------- +-- Table `tnotification_source` +-- ----------------------------------------------------- +CREATE TABLE `tnotification_source` ( + `id` serial, + `description` VARCHAR(255) DEFAULT NULL, + `icon` text, + `max_postpone_time` int(11) DEFAULT NULL, + `enabled` int(1) DEFAULT NULL, + `user_editable` int(1) DEFAULT NULL, + `also_mail` int(1) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `tnotification_source` +-- +INSERT INTO `tnotification_source`(`description`, `icon`, `max_postpone_time`, `enabled`, `user_editable`, `also_mail`) VALUES + ("System status", "icono_info_mr.png", 86400, 1, 1, 0), + ("Message", "icono_info_mr.png", 86400, 1, 1, 0), + ("Pending task", "icono_info_mr.png", 86400, 1, 1, 0), + ("Advertisement", "icono_info_mr.png", 86400, 1, 1, 0), + ("Official communication", "icono_info_mr.png", 86400, 1, 1, 0), + ("Sugerence", "icono_info_mr.png", 86400, 1, 1, 0); + +-- ----------------------------------------------------- +-- Table `tmensajes` +-- ----------------------------------------------------- +ALTER TABLE `tmensajes` ADD COLUMN `url` TEXT; +ALTER TABLE `tmensajes` ADD COLUMN `response_mode` VARCHAR(200) DEFAULT NULL; +ALTER TABLE `tmensajes` ADD COLUMN `citicity` INT(10) UNSIGNED DEFAULT '0'; +ALTER TABLE `tmensajes` ADD COLUMN `id_source` BIGINT(20) UNSIGNED NOT NULL; +ALTER TABLE `tmensajes` ADD COLUMN `subtype` VARCHAR(255) DEFAULT ''; +ALTER TABLE `tmensajes` ADD CONSTRAINT `tsource_fk` FOREIGN KEY (`id_source`) REFERENCES `tnotification_source` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + + +-- ---------------------------------------------------------------------- +-- Table `tnotification_user` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_user` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL, + `id_user` VARCHAR(60) NOT NULL, + `utimestamp_read` BIGINT(20), + `utimestamp_erased` BIGINT(20), + `postpone` INT, + PRIMARY KEY (`id_mensaje`,`id_user`), + FOREIGN KEY (`id_mensaje`) REFERENCES `tmensajes`(`id_mensaje`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_group` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_group` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL, + `id_group` mediumint(4) UNSIGNED NOT NULL, + PRIMARY KEY (`id_mensaje`,`id_group`), + FOREIGN KEY (`id_mensaje`) REFERENCES `tmensajes`(`id_mensaje`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_source_user` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_source_user` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_user` VARCHAR(60), + `enabled` INT(1) DEFAULT NULL, + `also_mail` INT(1) DEFAULT NULL, + PRIMARY KEY (`id_source`,`id_user`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_source_group` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_source_group` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL, + PRIMARY KEY (`id_source`,`id_group`), + INDEX (`id_group`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_source_user` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_source_group_user` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL, + `id_user` VARCHAR(60), + `enabled` INT(1) DEFAULT NULL, + `also_mail` INT(1) DEFAULT NULL, + PRIMARY KEY (`id_source`,`id_user`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_group`) REFERENCES `tnotification_source_group`(`id_group`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Add alert command 'Generate notification' +-- ---------------------------------------------------------------------- +INSERT INTO `talert_commands` (`name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES ('Generate Notification','Internal type','This command allows you to send an internal notification to any user or group.',1,'[\"Destination user\",\"Destination group\",\"Title\",\"Message\",\"Link\",\"Criticity\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); + +-- ---------------------------------------------------------------------- +-- Update message references and pre-configure notifications +-- ---------------------------------------------------------------------- +INSERT INTO `tnotification_source_user` (`id_source`, `id_user`, `enabled`, `also_mail`) VALUES ((SELECT `id` FROM `tnotification_source` WHERE `description`="System status"), "admin", 1, 0); +INSERT INTO `tnotification_source_group` SELECT `id`,0 FROM `tnotification_source` WHERE `description`="Message"; +INSERT INTO `tnotification_user` (`id_mensaje`, `id_user`) SELECT `id_mensaje`, `id_usuario_destino` FROM `tmensajes` WHERE `id_usuario_destino` != ''; +-- ---------------------------------------------------------------------- +-- Add custom internal recon scripts +-- ---------------------------------------------------------------------- +INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Application.VMware', 'Discovery Application script to monitor VMware technologies (ESXi, VCenter, VSphere)', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); diff --git a/pandora_console/general/firts_task/recon_view.php b/pandora_console/general/firts_task/recon_view.php index 026d0f5673..2377ce7c20 100755 --- a/pandora_console/general/firts_task/recon_view.php +++ b/pandora_console/general/firts_task/recon_view.php @@ -15,17 +15,17 @@ global $config; check_login(); ui_require_css_file('firts_task'); ?> - true, 'message' => __('There are no recon task defined yet.') ]); ?> + true, 'message' => __('There are no discovery tasks defined yet.') ]); ?>
- __('Recon server')]); ?> + __('Discovery server')]); ?>
-

+

ICMP (pings), SNMP (detecting the topology of networks and their interfaces), and other customized @@ -33,8 +33,8 @@ ui_require_css_file('firts_task'); ); ?>

-
- + +

diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 846f20677b..e35d401502 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -1,5 +1,4 @@ cellspacing = 0; $table->head = []; $table->data = []; - $table->style[0] = $table->style['clippy'] = $table->style[1] = $table->style[3] = $table->style[4] = $table->style[5] = $table->style[6] = $table->style[8] = $table->style[9] = $table->style['qr'] = 'width: 22px; text-align:center; height: 22px; padding-right: 9px;padding-left: 9px;'; + $table->style['clippy'] = $table->style[1] = $table->style[4] = $table->style[5] = $table->style[6] = $table->style[8] = $table->style[9] = $table->style['qr'] = $table->style['notifications'] = 'width: 22px; text-align:center; height: 22px; padding-right: 9px;padding-left: 9px;'; $table->style[7] = 'width: 20px; padding-right: 9px;'; $table->style['searchbar'] = 'width: 180px; min-width: 180px;'; $table->style[11] = 'padding-left: 10px; padding-right: 5px;width: 16px;'; @@ -110,27 +110,6 @@ config_check(); $table->data[0]['searchbar'] = $search_bar; } - // Servers check - $servers = []; - $servers['all'] = (int) db_get_value('COUNT(id_server)', 'tserver'); - $servers['up'] = (int) servers_check_status(); - $servers['down'] = ($servers['all'] - $servers['up']); - if ($servers['up'] == 0) { - // All Servers down or no servers at all - $servers_check_img = html_print_image('images/header_down.png', true, ['alt' => 'cross', 'class' => 'bot', 'title' => __('All systems').': '.__('Down')]); - } else if ($servers['down'] != 0) { - // Some servers down - $servers_check_img = html_print_image('images/header_warning.png', true, ['alt' => 'error', 'class' => 'bot', 'title' => $servers['down'].' '.__('servers down')]); - } else { - // All servers up - $servers_check_img = html_print_image('images/header_ready.png', true, ['alt' => 'ok', 'class' => 'bot', 'title' => __('All systems').': '.__('Ready')]); - } - - unset($servers); - // Since this is the header, we don't like to trickle down variables. - $servers_link_open = ''; - $servers_link_close = ''; - if ($config['show_qr_code_header'] == 0) { $show_qr_code_header = 'display: none;'; } else { @@ -175,12 +154,6 @@ config_check(); ).''; } - - $table->data[0][0] = $servers_link_open.$servers_check_img.$servers_link_close; - - - - // ======= Autorefresh code ============================= $autorefresh_txt = ''; $autorefresh_additional = ''; @@ -254,57 +227,8 @@ config_check(); $table->data[0][1] = $autorefresh_link_open_img.$autorefresh_img.$autorefresh_link_close; $table->data[0][2] = $autorefresh_link_open_txt.$autorefresh_txt.$autorefresh_link_close.$autorefresh_additional; // ====================================================== - $check_minor_release_available = false; $pandora_management = check_acl($config['id_user'], 0, 'PM'); - $check_minor_release_available = db_check_minor_relase_available(); - - if ($check_minor_release_available) { - if (users_is_admin($config['id_user'])) { - if ($config['language'] == 'es') { - set_pandora_error_for_header('Hay una o mas revisiones menores en espera para ser actualizadas. '.__('Sobre actualización de revisión menor').'', 'Revisión/es menor/es disponible/s'); - } else { - set_pandora_error_for_header('There are one or more minor releases waiting for update. '.__('About minor release update').'', 'minor release/s available'); - } - } - } - - echo ''; - - if ($config['alert_cnt'] > 0) { - $maintenance_link = 'javascript:'; - $maintenance_title = __('System alerts detected - Please fix as soon as possible'); - $maintenance_class = $maintenance_id = 'show_systemalert_dialog white'; - - $maintenance_link_open_txt = ''; - $maintenance_link_open_img = ''; - $maintenance_link_close = ''; - if (!$pandora_management) { - $maintenance_img = ''; - } else { - $maintenance_img = $maintenance_link_open_img.html_print_image( - 'images/header_yellow.png', - true, - [ - 'title' => __( - 'You have %d warning(s)', - $config['alert_cnt'] - ), - 'id' => 'yougotalert', - 'class' => 'bot', - ] - ).$maintenance_link_close; - } - } else { - if (!$pandora_management) { - $maintenance_img = ''; - } else { - $maintenance_img = html_print_image('images/header_ready.png', true, ['title' => __('There are not warnings'), 'id' => 'yougotalert', 'class' => 'bot']); - } - } - - $table->data[0][3] = $maintenance_img; - // Main help icon if (!$config['disable_help']) { $table->data[0][4] = ''.html_print_image( @@ -318,6 +242,12 @@ config_check(); ).''; } + $notifications_numbers = notifications_get_counters(); + $table->data[0]['notifications'] = notifications_print_ball( + $notifications_numbers['notifications'], + $notifications_numbers['last_id'] + ); + // Logout $table->data[0][5] = ''; $table->data[0][5] .= html_print_image('images/header_logout.png', true, ['alt' => __('Logout'), 'class' => 'bot', 'title' => __('Logout')]); @@ -341,18 +271,6 @@ config_check(); $table->data[0][8] .= ''; $table->data[0][8] .= ''; - // Messages - $msg_cnt = messages_get_count($config['id_user']); - if ($msg_cnt > 0) { - echo ''; - - $table->data[0][9] = ''; - $table->data[0][9] .= html_print_image('images/header_email.png', true, ['title' => __('You have %d unread message(s)', $msg_cnt), 'id' => 'yougotmail', 'class' => 'bot', 'style' => 'width:24px;']); - $table->data[0][9] .= ''; - } - - - html_print_table($table); unset($table); @@ -373,6 +291,9 @@ config_check(); + + + + \ No newline at end of file diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 5b3a91d0d7..9c10099042 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -159,8 +159,8 @@ $module_macros = []; // Create agent if ($create_agent) { $mssg_warning = 0; - $alias_safe_output = io_safe_output(get_parameter("alias","")); - $alias = io_safe_input(trim (preg_replace('/[\/\\\|%#&$-]/', '', $alias_safe_output))); + $alias_safe_output = io_safe_output(get_parameter('alias', '')); + $alias = io_safe_input(trim(preg_replace('/[\/\\\|%#&$-]/', '', $alias_safe_output))); $alias_as_name = (int) get_parameter_post('alias_as_name', 0); $direccion_agente = (string) get_parameter_post('direccion', ''); $unique_ip = (int) get_parameter_post('unique_ip', 0); @@ -765,8 +765,8 @@ if ($update_agent) { $mssg_warning = 0; $id_agente = (int) get_parameter_post('id_agente'); $nombre_agente = str_replace('`', '‘', (string) get_parameter_post('agente', '')); - $alias_safe_output = io_safe_output(get_parameter("alias","")); - $alias = io_safe_input(trim (preg_replace('/[\/\\\|%#&$-]/', '', $alias_safe_output))); + $alias_safe_output = io_safe_output(get_parameter('alias', '')); + $alias = io_safe_input(trim(preg_replace('/[\/\\\|%#&$-]/', '', $alias_safe_output))); $alias_as_name = (int) get_parameter_post('alias_as_name', 0); $direccion_agente = (string) get_parameter_post('direccion', ''); $unique_ip = (int) get_parameter_post('unique_ip', 0); diff --git a/pandora_console/godmode/agentes/status_monitor_custom_fields.php b/pandora_console/godmode/agentes/status_monitor_custom_fields.php index 2c82c1e4f7..7e9ae48bdd 100644 --- a/pandora_console/godmode/agentes/status_monitor_custom_fields.php +++ b/pandora_console/godmode/agentes/status_monitor_custom_fields.php @@ -4,27 +4,27 @@ // ================================================== // Copyright (c) 2005-2011 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 // as published by the Free Software Foundation; version 2 - // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. - global $config; -check_login (); +check_login(); -if (! check_acl ($config['id_user'], 0, 'AR') - && ! check_acl ($config['id_user'], 0, 'AW') && - ! check_acl ($config['id_user'], 0, 'AM')) { - db_pandora_audit('ACL Violation', - 'Trying to access Agent Management'); - require ('general/noaccess.php'); - return; +if (! check_acl($config['id_user'], 0, 'AR') + && ! check_acl($config['id_user'], 0, 'AW') + && ! check_acl($config['id_user'], 0, 'AM') +) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access Agent Management' + ); + include 'general/noaccess.php'; + return; } $update = get_parameter('upd_button', ''); @@ -32,81 +32,94 @@ $default = (int) get_parameter('default', 0); if ($default != 0) { - $fields_selected = explode (',', $config['status_monitor_fields']); -} -else if ($update != '') { - $fields_selected = (array)get_parameter('fields_selected'); - - if ($fields_selected[0] == '') { - $fields_selected = explode (',', $config['status_monitor_fields']); - } - else { - $status_monitor_fields = implode (',', $fields_selected); - } - - $values = array( - 'token' => 'status_monitor_fields', - 'value' => $status_monitor_fields - ); + $fields_selected = explode(',', $config['status_monitor_fields']); +} else if ($update != '') { + $fields_selected = (array) get_parameter('fields_selected'); - //update 'status_monitor_fields' in tconfig table to keep the value at update. - $result = db_process_sql_update('tconfig', $values, - array ('token' => 'status_monitor_fields')); + if ($fields_selected[0] == '') { + $fields_selected = explode(',', $config['status_monitor_fields']); + } else { + $status_monitor_fields = implode(',', $fields_selected); + } - ui_print_result_message ($result, __('Successfully updated'), __('Could not be updated')); + $values = [ + 'token' => 'status_monitor_fields', + 'value' => $status_monitor_fields, + ]; - $config['status_monitor_fields'] = $status_monitor_fields; + // update 'status_monitor_fields' in tconfig table to keep the value at update. + $result = db_process_sql_update( + 'tconfig', + $values, + ['token' => 'status_monitor_fields'] + ); + + ui_print_result_message($result, __('Successfully updated'), __('Could not be updated')); + + $config['status_monitor_fields'] = $status_monitor_fields; } -$fields_selected = array(); +$fields_selected = []; $status_monitor_fields = ''; -$fields_selected = explode (',', $config['status_monitor_fields']); +$fields_selected = explode(',', $config['status_monitor_fields']); -$result_selected = array(); +$result_selected = []; -//show list of fields selected. -if ($fields_selected[0]!='') { - foreach ($fields_selected as $field_selected) { - switch ($field_selected) { - case 'policy': - $result = __('Policy'); - break; - case 'agent': - $result = __('Agent'); - break; - case 'data_type': - $result = __('Data type'); - break; - case 'module_name': - $result = __('Module name'); - break; - case 'server_type': - $result = __('Server type'); - break; - case 'interval': - $result = __('Interval'); - break; - case 'status': - $result = __('Status'); - break; - case 'graph': - $result = __('Graph'); - break; - case 'warn': - $result = __('Warn'); - break; - case 'data': - $result = __('Data'); - break; - case 'timestamp': - $result = __('Timestamp'); - break; - case 'to_critical': - $result = __('Last status change'); - break; - } - $result_selected[$field_selected] = $result; - } +// show list of fields selected. +if ($fields_selected[0] != '') { + foreach ($fields_selected as $field_selected) { + switch ($field_selected) { + case 'policy': + $result = __('Policy'); + break; + + case 'agent': + $result = __('Agent'); + break; + + case 'data_type': + $result = __('Data type'); + break; + + case 'module_name': + $result = __('Module name'); + break; + + case 'server_type': + $result = __('Server type'); + break; + + case 'interval': + $result = __('Interval'); + break; + + case 'status': + $result = __('Status'); + break; + + case 'graph': + $result = __('Graph'); + break; + + case 'warn': + $result = __('Warn'); + break; + + case 'data': + $result = __('Data'); + break; + + case 'timestamp': + $result = __('Timestamp'); + break; + + case 'to_critical': + $result = __('Last status change'); + break; + } + + $result_selected[$field_selected] = $result; + } } echo '

'.__('Show monitor detail fields').'

'; @@ -115,17 +128,16 @@ $table = new stdClass(); $table->width = '100%'; $table->class = 'databox filters'; -$table->size = array(); -//~ $table->size[0] = '20%'; +$table->size = []; +// ~ $table->size[0] = '20%'; $table->size[1] = '10px'; -//~ $table->size[2] = '20%'; - +// ~ $table->size[2] = '20%'; $table->style[0] = 'text-align:center;'; $table->style[2] = 'text-align:center;'; -$table->data = array(); +$table->data = []; -$fields_available = array(); +$fields_available = []; $fields_available['policy'] = __('Policy'); $fields_available['agent'] = __('Agent'); @@ -140,36 +152,56 @@ $fields_available['data'] = __('Data'); $fields_available['timestamp'] = __('Timestamp'); $fields_available['to_critical'] = __('Last status change'); -//remove fields already selected -foreach ($fields_available as $key=>$available) { - foreach ($result_selected as $selected) { - if ($selected == $available) { - unset($fields_available[$key]); - } - } +// remove fields already selected +foreach ($fields_available as $key => $available) { + foreach ($result_selected as $selected) { + if ($selected == $available) { + unset($fields_available[$key]); + } + } } -$table->data[0][0] = '' . __('Fields available').''; -$table->data[1][0] = html_print_select ($fields_available, 'fields_available[]', true, '', '', 0, true, true, false, '', false, 'width: 300px'); -$table->data[1][1] = '' . - html_print_image('images/darrowright.png', true, - array('id' => 'right', 'title' => __('Add fields to select'))) . - ''; -$table->data[1][1] .= '



' . - html_print_image('images/darrowleft.png', true, - array('id' => 'left', 'title' => __('Delete fields to select'))) . - ''; +$table->data[0][0] = ''.__('Fields available').''; +$table->data[1][0] = html_print_select($fields_available, 'fields_available[]', true, '', '', 0, true, true, false, '', false, 'width: 300px'); +$table->data[1][1] = ''.html_print_image( + 'images/darrowright.png', + true, + [ + 'id' => 'right', + 'title' => __('Add fields to select'), + ] +).''; +$table->data[1][1] .= '



'.html_print_image( + 'images/darrowleft.png', + true, + [ + 'id' => 'left', + 'title' => __('Delete fields to select'), + ] +).''; $table->data[0][1] = ''; -$table->data[0][2] = '' . __('Fields selected') . ''; -$table->data[1][2] = html_print_select($result_selected, - 'fields_selected[]', true, '', '', 0, true, true, false, '', false, 'width: 300px'); +$table->data[0][2] = ''.__('Fields selected').''; +$table->data[1][2] = html_print_select( + $result_selected, + 'fields_selected[]', + true, + '', + '', + 0, + true, + true, + false, + '', + false, + 'width: 300px' +); echo '
'; html_print_table($table); echo '
'; - html_print_submit_button (__('Update'), 'upd_button', false, 'class="sub upd"'); + html_print_submit_button(__('Update'), 'upd_button', false, 'class="sub upd"'); echo ''; echo '
'; ?> @@ -177,64 +209,64 @@ echo ''; diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 69ec49cfce..0ed041d680 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -21,6 +21,21 @@ require_once 'include/functions_menu.php'; $menu_godmode = []; $menu_godmode['class'] = 'godmode'; + +if (check_acl($config['id_user'], 0, 'PM')) { + $sub = []; + $sub['godmode/servers/discovery']['text'] = __('Discover'); + $sub['godmode/servers/discovery']['id'] = 'Discover'; + $sub['godmode/servers/discovery']['subsecs'] = ['godmode/servers/discovery']; + + // Add to menu. + $menu_godmode['discover']['text'] = __('Discovery'); + $menu_godmode['discover']['sec2'] = 'godmode/servers/discovery'; + $menu_godmode['discover']['id'] = 'god-discovery'; + $menu_godmode['discover']['sub'] = $sub; +} + + $sub = []; if (check_acl($config['id_user'], 0, 'AW') || check_acl($config['id_user'], 0, 'AD')) { $sub['godmode/agentes/modificar_agente']['text'] = __('Manage agents'); @@ -200,6 +215,7 @@ if (check_acl($config['id_user'], 0, 'AW') || check_acl($config['id_user'], 0, ' $menu_godmode['gservers']['id'] = 'god-servers'; $sub = []; + if (check_acl($config['id_user'], 0, 'AW')) { $sub['godmode/servers/modificar_server']['text'] = __('Manage servers'); $sub['godmode/servers/modificar_server']['id'] = 'Manage servers'; @@ -269,6 +285,9 @@ if (check_acl($config['id_user'], 0, 'PM')) { $sub2['godmode/setup/setup&section=ehorus']['text'] = __('eHorus'); $sub2['godmode/setup/setup&section=ehorus']['refr'] = 0; + $sub2['godmode/setup/setup&section=notifications']['text'] = __('Notifications'); + $sub2['godmode/setup/setup&section=notifications']['refr'] = 0; + if ($config['activate_gis']) { $sub2['godmode/setup/gis']['text'] = __('Map conections GIS'); } diff --git a/pandora_console/godmode/servers/discovery.php b/pandora_console/godmode/servers/discovery.php new file mode 100755 index 0000000000..41f7fd1ffc --- /dev/null +++ b/pandora_console/godmode/servers/discovery.php @@ -0,0 +1,136 @@ +run(); + if (is_array($result) === true) { + // Redirect control and messages to DiscoveryTasklist. + $classname_selected = 'DiscoveryTaskList'; + $wiz = new $classname_selected($page); + $result = $wiz->run($result['msg'], $result['result']); + } +} + +if ($classname_selected === null) { + // Load classes and print selector. + $wiz_data = []; + foreach ($classes as $classpath) { + $classname = basename($classpath, '.class.php'); + $obj = new $classname(); + + // DiscoveryTaskList must be first button. + if ($classname == 'DiscoveryTaskList') { + array_unshift($wiz_data, $obj->load()); + } else { + $wiz_data[] = $obj->load(); + } + } + + Wizard::printBigButtonsList($wiz_data); +} diff --git a/pandora_console/godmode/servers/manage_recontask_form.php b/pandora_console/godmode/servers/manage_recontask_form.php index c47416afd7..cbbcde8ec7 100644 --- a/pandora_console/godmode/servers/manage_recontask_form.php +++ b/pandora_console/godmode/servers/manage_recontask_form.php @@ -248,9 +248,9 @@ $table->rowclass[17] = 'recon_script'; $table->data[0][0] = ''.__('Task name').''; $table->data[0][1] = html_print_input_text('name', $name, '', 25, 0, true); -// Recon server -$table->data[1][0] = ''.__('Recon server').ui_print_help_tip( - __('You must select a Recon Server for the Task, otherwise the Recon Task will never run'), +// Discovery server +$table->data[1][0] = ''.__('Discovery server').ui_print_help_tip( + __('You must select a Discovery Server to run the Task, otherwise the Recon Task will never run'), true ); diff --git a/pandora_console/godmode/setup/performance.php b/pandora_console/godmode/setup/performance.php index 0bbf28001f..666dd0b21c 100644 --- a/pandora_console/godmode/setup/performance.php +++ b/pandora_console/godmode/setup/performance.php @@ -524,6 +524,18 @@ if ($config['history_db_enabled'] == 1) { ); } +$table->data[] = [ + __('Max. days before delete old messages'), + html_print_input_text( + 'delete_old_messages', + $config['delete_old_messages'], + '', + 5, + 5, + true + ), +]; + $table_other = new stdClass(); $table_other->width = '100%'; $table_other->class = 'databox filters'; diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index 7f88982a14..6ee8577367 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -122,6 +122,12 @@ $buttons['ehorus'] = [ 'text' => ''.html_print_image('images/ehorus/ehorus.png', true, ['title' => __('eHorus')]).'', ]; +// FIXME: Not definitive icon +$buttons['notifications'] = [ + 'active' => false, + 'text' => ''.html_print_image('images/alerts_template.png', true, ['title' => __('Notifications')]).'', +]; + $help_header = ''; if (enterprise_installed()) { $subpage = setup_enterprise_add_subsection_main($section, $buttons, $help_header); @@ -159,6 +165,11 @@ switch ($section) { $buttons['ehorus']['active'] = true; $subpage = ' » '.__('eHorus'); break; + + case 'notifications': + $buttons['notifications']['active'] = true; + $subpage = ' » '.__('Notifications'); + break; } // Header. @@ -199,6 +210,10 @@ switch ($section) { include_once $config['homedir'].'/godmode/setup/setup_ehorus.php'; break; + case 'notifications': + include_once $config['homedir'].'/godmode/setup/setup_notifications.php'; + break; + default: enterprise_hook('setup_enterprise_select_tab', [$section]); break; diff --git a/pandora_console/godmode/setup/setup_notifications.php b/pandora_console/godmode/setup/setup_notifications.php new file mode 100644 index 0000000000..9ee95f78cc --- /dev/null +++ b/pandora_console/godmode/setup/setup_notifications.php @@ -0,0 +1,413 @@ + $res]; + echo json_encode($result); + return; +} + +if (get_parameter('remove_source_on_database', 0)) { + $res = ($is_users) ? notifications_remove_users_from_source($source, $elements) : notifications_remove_group_from_source($source, $elements); + $result = ['result' => $res]; + echo json_encode($result); + return; +} + +if (get_parameter('update_config', 0)) { + $element = (string) get_parameter('element', ''); + $value = (int) get_parameter('value', 0); + + // Update the label value. + ob_clean(); + $res = false; + switch ($element) { + // All users has other action. + case 'all_users': + $res = ($value) ? notifications_add_group_to_source($source, [0]) : notifications_remove_group_from_source($source, [0]); + break; + + default: + $res = (bool) db_process_sql_update( + 'tnotification_source', + [$element => $value], + ['id' => $source] + ); + break; + } + + echo json_encode(['result' => $res]); + return; +} + +if (get_parameter('check_new_notifications', 0)) { + $last_id_ui = (int) get_parameter('last_id', 0); + $counters = notifications_get_counters(); + if ((int) $last_id_ui === (int) $counters['last_id']) { + echo json_encode(['has_new_notifications' => false]); + return; + } + + if (messages_get_count() == 0) { + return; + } + + $messages = messages_get_overview( + 'timestamp', + 'ASC', + false, + true, + 0, + ['id_mensaje' => '>'.$last_id_ui] + ); + if ($messages === false) { + $messages = []; + } + + // If there is new messages, get the info. + echo json_encode( + [ + 'has_new_notifications' => true, + 'new_ball' => base64_encode( + notifications_print_ball( + $counters['notifications'], + $counters['last_id'] + ) + ), + 'new_notifications' => array_map( + function ($elem) { + $elem['full_url'] = messages_get_url($elem['id_mensaje']); + return $elem; + }, + $messages + ), + ] + ); + return; +} + +if (get_parameter('mark_notification_as_read', 0)) { + $message = (int) get_parameter('message', 0); + messages_process_read($message); + // TODO check read. + $url = messages_get_url($message); + // Return false if cannot get the URL. + if ($url === false) { + echo json_encode(['result' => false]); + return; + } + + // If there is new messages, get the info. + echo json_encode( + [ + 'result' => true, + 'url' => $url, + ] + ); + return; +} + +if (get_parameter('get_notifications_dropdown', 0)) { + echo notifications_print_dropdown(); + return; +} + +// Notification table. It is just a wrapper. +$table_content = new StdClass(); +$table_content->data = []; +$table_content->width = '100%'; +$table_content->id = 'notifications-wrapper'; +$table_content->class = 'databox filters'; +$table_content->size['name'] = '30%'; + +// Print each source configuration. +$table_content->data = array_map( + function ($source) { + return notifications_print_global_source_configuration($source); + }, + notifications_get_all_sources() +); + +html_print_table($table_content); + +?> + diff --git a/pandora_console/godmode/snmpconsole/snmp_alert.php b/pandora_console/godmode/snmpconsole/snmp_alert.php index 3fcf9818e3..677a283854 100755 --- a/pandora_console/godmode/snmpconsole/snmp_alert.php +++ b/pandora_console/godmode/snmpconsole/snmp_alert.php @@ -751,7 +751,7 @@ if ($create_alert || $update_alert) { // echo '' . __('Alert filters') . ui_print_help_icon("snmp_alert_filters", true) . ''; // OID - echo ''.''.__('Enterprise String').ui_print_help_tip (__('Matches substrings. End the string with $ for exact matches.'), true).''.''; + echo ''.''.__('Enterprise String').ui_print_help_tip(__('Matches substrings. End the string with $ for exact matches.'), true).''.''; html_print_input_text('oid', $oid, '', 50, 255); echo ''; diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php new file mode 100644 index 0000000000..9f7c416854 --- /dev/null +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -0,0 +1,984 @@ +setBreadcrum([]); + + $this->task = []; + $this->msg = $msg; + $this->icon = $icon; + $this->label = __($label); + $this->page = $page; + $this->url = ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist' + ); + + return $this; + } + + + /** + * Implements run method. + * + * @return mixed Returns null if wizard is ongoing. Result if done. + */ + public function run($message='', $status=null) + { + global $config; + // Load styles. + parent::run(); + + $this->prepareBreadcrum( + [ + [ + 'link' => 'index.php?sec=gservers&sec2=godmode/servers/discovery', + 'label' => 'Discovery', + ], + ] + ); + + $this->printHeader(); + + // Show redirected messages from discovery.php. + if ($status === 0) { + ui_print_success_message($message); + } else if ($status !== null) { + ui_print_error_message($message); + } + + $force_run = (bool) get_parameter('force_run'); + if ($force_run === true) { + return $this->forceConsoleTask(); + } + + $delete_console_task = (bool) get_parameter('delete_console_task'); + if ($delete_console_task === true) { + return $this->deleteConsoleTask(); + } + + $delete = (bool) get_parameter('delete', false); + if ($delete === true) { + return $this->deleteTask(); + } + + if (enterprise_installed()) { + // This check only applies to enterprise users. + // Check if DiscoveryCronTasks is running. Warn user if not. + if ($config['cron_last_run'] == 0 + || (get_system_time() - $config['cron_last_run']) > 3600 + ) { + $message_conf_cron = __('DiscoveryConsoleTasks is not running properly').'. '; + if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { + $message_conf_cron .= __('Discovery relies on a proper setup of cron, the time-based scheduling service'); + $message_conf_cron .= '. '.__('Please, add the following line to your crontab file:'); + $message_conf_cron .= '
* * * * * <user> wget -q -O - --no-check-certificate ';
+                    $message_conf_cron .= str_replace(
+                        ENTERPRISE_DIR.'/meta/',
+                        '',
+                        ui_get_full_url(false)
+                    );
+                    $message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
+                    $message_conf_cron .= '/cron/cron.php >> ';
+                    $message_conf_cron .= $config['homedir'].'/pandora_console.log
'; + } + + if (isset($config['cron_last_run']) === true + && $config['cron_last_run'] > 0 + ) { + $message_conf_cron .= '

'.__('Last execution').': '; + $message_conf_cron .= date('Y/m/d H:i:s', $config['cron_last_run']).'

'; + $message_conf_cron .= '

'; + $message_conf_cron .= __('Please check process is no locked.').'

'; + } + + ui_print_warning_message($message_conf_cron, '', false); + } + } + + $ret = $this->showListConsoleTask(); + $ret2 = $this->showList(); + + if ($ret === false && $ret2 === false) { + include_once $config['homedir'].'/general/firts_task/recon_view.php'; + } + + return $ret; + } + + + /** + * Implements load method. + * + * @return mixed Skeleton for button. + */ + public function load() + { + return [ + 'icon' => $this->icon, + 'label' => $this->label, + 'url' => $this->url, + + ]; + + } + + + /** + * Delete a recon task. + * + * @return void + */ + public function deleteTask() + { + global $config; + + if (! check_acl($config['id_user'], 0, 'PM')) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access recon task viewer' + ); + include 'general/noaccess.php'; + return; + } + + $task = get_parameter('task', null); + + if ($task !== null) { + $result = db_process_sql_delete( + 'trecon_task', + ['id_rt' => $task] + ); + + if ($result == 1) { + return [ + 'result' => 0, + 'msg' => __('Task successfully deleted'), + 'id' => false, + ]; + } + + // Trick to avoid double execution. + header('Location: '.$this->url); + } + + } + + + /** + * Force console task. + * + * @return void + */ + public function forceConsoleTask() + { + global $config; + + if (! check_acl($config['id_user'], 0, 'PM')) { + db_pandora_audit( + '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 !== null) { + cron_task_run($id_console_task, true); + // Trick to avoid double execution. + header('Location: '.$this->url); + } + + } + + + /** + * Delete a Console task. + * + * @return void + */ + public function deleteConsoleTask() + { + global $config; + + if (! check_acl($config['id_user'], 0, 'PM')) { + db_pandora_audit( + '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 !== null) { + $result = db_process_sql_delete( + 'tuser_task_scheduled', + ['id' => $id_console_task] + ); + + if ($result == 1) { + return [ + 'result' => 0, + 'msg' => __('Console Task successfully deleted'), + 'id' => false, + ]; + } + + // Trick to avoid double execution. + header('Location: '.$this->url); + } + + } + + + /** + * Show complete list of running tasks. + * + * @return boolean Success or not. + */ + public function showList() + { + global $config; + + check_login(); + + if (! check_acl($config['id_user'], 0, 'PM')) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access recon task viewer' + ); + include 'general/noaccess.php'; + return false; + } + + // Get all recon servers. + $servers = db_get_all_rows_sql('SELECT * FROM tserver WHERE server_type = 3'); + if ($servers === false) { + $servers = []; + ui_print_error_message(__('Discovery Server is disabled')); + return false; + } else { + $recon_task = db_get_all_rows_sql('SELECT * FROM trecon_task'); + if ($recon_task === false) { + return false; + } else { + include_once $config['homedir'].'/include/functions_graph.php'; + include_once $config['homedir'].'/include/functions_servers.php'; + include_once $config['homedir'].'/include/functions_network_profiles.php'; + + $modules_server = 0; + $total_modules = 0; + $total_modules_data = 0; + + // -------------------------------- + // FORCE A RECON TASK + // -------------------------------- + if (check_acl($config['id_user'], 0, 'PM')) { + if (isset($_GET['force'])) { + $id = (int) get_parameter_get('force', 0); + servers_force_recon_task($id); + header( + 'Location: '.ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist' + ) + ); + } + } + + foreach ($servers as $serverItem) { + $id_server = $serverItem['id_server']; + $server_name = servers_get_name($id_server); + $recon_tasks = db_get_all_rows_field_filter( + 'trecon_task', + 'id_recon_server', + $id_server + ); + + $user_groups = implode(',', array_keys(users_get_groups())); + $defined_tasks = db_get_all_rows_filter( + 'tuser_task_scheduled', + 'id_grupo IN ('.$user_groups.')' + ); + + if (isset($tasks_console) === true + && is_array($tasks_console) === true + ) { + foreach ($tasks_console as $key => $value) { + $value['parameters'] = unserialize( + $value['parameters'] + ); + + $value['type'] = 'Cron'; + array_push($recon_tasks, $value); + } + } + + // Show network tasks for Recon Server. + if ($recon_tasks === false) { + $recon_tasks = []; + } + + $table = new StdClass(); + $table->cellpadding = 4; + $table->cellspacing = 4; + $table->width = '100%'; + $table->class = 'databox data'; + $table->head = []; + $table->data = []; + $table->align = []; + $table->headstyle = []; + for ($i = 0; $i < 9; $i++) { + $table->headstyle[$i] = 'text-align: left;'; + } + + $table->head[0] = __('Force'); + $table->align[0] = 'left'; + + $table->head[1] = __('Task name'); + $table->align[1] = 'left'; + + $table->head[2] = __('Interval'); + $table->align[2] = 'left'; + + $table->head[3] = __('Network'); + $table->align[3] = 'left'; + + $table->head[4] = __('Status'); + $table->align[4] = 'left'; + + $table->head[5] = __('Task type'); + $table->align[5] = 'left'; + + $table->head[6] = __('Progress'); + $table->align[6] = 'left'; + + $table->head[7] = __('Updated at'); + $table->align[7] = 'left'; + + $table->head[8] = __('Operations'); + $table->align[8] = 'left'; + + foreach ($recon_tasks as $task) { + $data = []; + + if ($task['disabled'] == 0) { + $data[0] = ''; + $data[0] .= html_print_image('images/target.png', true, ['title' => __('Force')]); + $data[0] .= ''; + } else if ($task['disabled'] == 2) { + $data[0] = ui_print_help_tip( + __('This task has not been completely defined, please edit it'), + true + ); + } else { + $data[0] = ''; + } + + $data[1] = ''.$task['name'].''; + + if ($task['interval_sweep'] > 0) { + $data[2] = human_time_description_raw( + $task['interval_sweep'] + ); + } else { + $data[2] = __('Manual'); + } + + if ($task['id_recon_script'] == 0) { + $data[3] = $task['subnet']; + } else { + $data[3] = '-'; + } + + if ($task['status'] <= 0) { + $data[4] = __('Done'); + } else { + $data[4] = __('Pending'); + } + + if ($task['id_recon_script'] == 0) { + // Discovery NetScan. + $data[5] = html_print_image( + 'images/network.png', + true, + ['title' => __('Discovery NetScan')] + ).'  '; + $data[5] .= network_profiles_get_name( + $task['id_network_profile'] + ); + } else { + // APP recon task. + $data[5] = html_print_image( + 'images/plugin.png', + true + ).'  '; + $data[5] .= db_get_sql( + sprintf( + 'SELECT name FROM trecon_script WHERE id_recon_script = %d', + $task['id_recon_script'] + ) + ); + } + + if ($task['status'] <= 0 || $task['status'] > 100) { + $data[6] = '-'; + } else { + $data[6] = progress_bar( + $task['status'], + 100, + 20, + __('Progress').':'.$task['status'].'%', + 1 + ); + } + + if ($task['utimestamp'] > 0) { + $data[7] = ui_print_timestamp( + $task['utimestamp'], + true + ); + } else { + $data[7] = __('Not executed yet'); + } + + if (check_acl( + $config['id_user'], + $task['id_group'], + 'PM' + ) + ) { + // Check if is a H&D, Cloud or Application. + $data[8] = ''.html_print_image( + 'images/config.png', + true + ).''; + $data[8] .= ''.html_print_image( + 'images/cross.png', + true + ).''; + } else { + $data[8] = ''; + } + + array_push($table->data, $data); + } + + if (empty($table->data)) { + echo '
'.__('Server').' '.$server_name.' '.__('has no recon tasks assigned').'
'; + } else { + echo '

'.__('Server task').'

'; + html_print_table($table); + } + + unset($table); + } + } + } + + $form = [ + 'form' => [ + 'method' => 'POST', + 'action' => ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery' + ), + ], + 'inputs' => [ + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Go back'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ], + ]; + + $this->printForm($form); + + return true; + } + + + /** + * Show complete list of running tasks. + * + * @return boolean Success or not. + */ + public function showListConsoleTask() + { + global $config; + + check_login(); + + if (! check_acl($config['id_user'], 0, 'PM')) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access recon task viewer' + ); + include 'general/noaccess.php'; + return false; + } + + $read_perms = check_acl( + $config['id_user'], + 0, + 'RR' + ); + $write_perms = check_acl( + $config['id_user'], + 0, + 'RW' + ); + $manage_perms = check_acl( + $config['id_user'], + 0, + 'RM' + ); + $manage_pandora = check_acl( + $config['id_user'], + 0, + 'PM' + ); + + $url = 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist&'; + + $user_groups = implode( + ',', + array_keys(users_get_groups()) + ); + + $defined_tasks = db_get_all_rows_filter( + 'tuser_task_scheduled', + 'id_grupo IN ('.$user_groups.')' + ); + + if (!check_acl($config['id_user'], 0, 'PM')) { + $read_tasks = []; + foreach ($defined_tasks as $task) { + $function_name = db_get_value( + 'function_name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + if (($function_name != 'cron_task_execute_custom_script') + && ($function_name != 'cron_task_do_backup') + ) { + $read_tasks[] = $task; + } + } + + $defined_tasks = $read_tasks; + + if (empty($defined_tasks)) { + $defined_tasks = false; + } + } + + if ($defined_tasks !== false) { + echo '

'.__('Console task').'

'; + + $table = new stdClass(); + $table->class = 'databox data'; + $table->width = '100%'; + $table->data = []; + $table->head = []; + $table->head[0] = ''; + $table->head[1] = __('User'); + $table->head[2] = __('Task'); + $table->head[3] = __('Scheduled'); + $table->head[4] = __('Next execution'); + $table->head[5] = __('Last run'); + $table->head[6] = __('Group'); + $table->head[7] = __('Operations'); + $table->align[7] = 'left'; + + foreach ($defined_tasks as $task) { + $data = []; + + $function_name = db_get_value( + 'function_name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + switch ($function_name) { + case 'cron_task_generate_report': + if ($write_perms || $manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + $args = unserialize($task['args']); + $report = reports_get_report($args[0]); + + // Check ACL in reports_get_report return false. + if ($report === false) { + continue; + } + + $email = $args[1]; + $data[2] .= '
- '.__('Report').": "; + $data[2] .= $report['name'].''; + $data[2] .= '
- '.__('Email').": "; + $data[2] .= ui_print_truncate_text( + $email, + 60, + false + ).''; + break; + + case 'cron_task_generate_report_by_template': + if ($write_perms || $manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + $args = unserialize($task['args']); + + $filter = []; + $filter['id_report'] = $args[0]; + $template = db_get_row_filter( + 'treport_template', + $filter, + false + ); + + // Check ACL in reports_get_report return false. + if ($template === false) { + continue; + } + + $agents_id = $args[1]; + $id_group = $args[2]; + $report_per_agent = $args[0]; + $report_name = $args[3]; + $email = $args[4]; + $data[2] .= '
- '.__('Template').": ".$template['name'].''; + $data[2] .= '
- '.__('Agents').': '.$agents_id.''; + $data[2] .= '
- '.__('Report per agent').': '.$report_per_agent.''; + $data[2] .= '
- '.__('Report name').': '.$report_name.''; + $data[2] .= '
- '.__('Email').": ".$email.''; + break; + + case 'cron_task_execute_custom_script': + if ($manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + $args = unserialize($task['args']); + $data[2] .= '
- '.__('Custom script').': '.$args[0]; + break; + + case 'cron_task_save_report_to_disk': + if ($write_perms || $manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + $args = unserialize($task['args']); + $report = reports_get_report($args[0]); + + // Check ACL in reports_get_report return false. + if ($report === false) { + continue; + } + + $path = $args[1]; + $data[2] .= '
- '.__('Report').": ".$report['name'].''; + $data[2] .= '
- '.__('Path').': '.$path.''; + 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, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value('name', 'tuser_task', 'id', $task['id_user_task']); + $args = unserialize($task['args']); + $report = reports_get_report($args[0]); + + // Check ACL in reports_get_report return false. + if ($report === false) { + continue; + } + + $path = $args[1]; + $data[2] .= '
- '.__('Report').": ".$report['name'].''; + $data[2] .= '
- '.__('Path').': '.$path.''; + break; + + case 'cron_task_do_backup': + if ($manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + $args = unserialize($task['args']); + break; + + default: + // Ignore. + break; + } + + $data[3] = cron_get_scheduled_string($task['scheduled']); + $data[4] = date('Y/m/d H:i:s', $args['first_execution']); + $data[5] = empty($task['last_run']) ? __('Never') : date('Y/m/d H:i:s', $task['last_run']); + + $data[6] = ui_print_group_icon($task['id_grupo'], true); + + if ($function_name == 'cron_task_do_backup' || $function_name == 'cron_task_execute_custom_script') { + if ($manage_pandora) { + $data[7] = ''; + $data[7] .= html_print_image( + 'images/config.png', + true, + ['title' => __('Edit')] + ).''; + } + + if ($manage_pandora) { + $data[7] .= ''; + $data[7] .= html_print_image( + 'images/cross.png', + true, + ['title' => __('Delete')] + ); + $data[7] .= ''; + } + } else { + if ($write_perms || $manage_pandora) { + $data[7] = ''; + $data[7] .= html_print_image( + 'images/config.png', + true, + ['title' => __('Edit')] + ).''; + } + + if ($manage_perms || $manage_pandora) { + $data[7] .= ''; + $data[7] .= html_print_image( + 'images/cross.png', + true, + ['title' => __('Delete')] + ); + $data[7] .= ''; + } + } + + array_push($table->data, $data); + } + + html_print_table($table); + } else { + return false; + } + + return true; + } + + + /** + * Return target url sub-string to edit target task. + * + * @param array $task With all data. + * + * @return string + */ + public function getTargetWiz($task) + { + // TODO: Do not use description. Use recon_script ID instead. + switch ($task['description']) { + case 'Discovery.Application.VMware': + return 'wiz=app&mode=vmware&page=0'; + + case CLOUDWIZARD_AWS_DESCRIPTION: + return 'wiz=cloud&mode=amazonws&page=1'; + + case 'console_task': + return 'wiz=ctask'; + + default: + return 'wiz=hd&mode=netscan'; + } + } + + +} diff --git a/pandora_console/godmode/wizards/HostDevices.class.php b/pandora_console/godmode/wizards/HostDevices.class.php new file mode 100755 index 0000000000..6e31299b9a --- /dev/null +++ b/pandora_console/godmode/wizards/HostDevices.class.php @@ -0,0 +1,1133 @@ +setBreadcrum([]); + + $this->task = []; + $this->msg = $msg; + $this->icon = $icon; + $this->label = $label; + $this->page = $page; + $this->url = ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=hd' + ); + + return $this; + } + + + /** + * Run wizard manager. + * + * @return mixed Returns null if wizard is ongoing. Result if done. + */ + public function run() + { + global $config; + + // Load styles. + parent::run(); + + $mode = get_parameter('mode', null); + + if ($mode === null) { + $buttons = []; + $buttons[] = [ + 'url' => $this->url.'&mode=netscan', + 'icon' => 'images/wizard/netscan.png', + 'label' => __('Net Scan'), + ]; + if (enterprise_installed()) { + $buttons[] = [ + 'url' => $this->url.'&mode=importcsv', + 'icon' => ENTERPRISE_DIR.'/images/wizard/csv.png', + 'label' => __('Import CSV'), + ]; + } + + $this->prepareBreadcrum( + [ + [ + 'link' => ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery' + ), + 'label' => __('Discovery'), + ], + ] + ); + + $this->printHeader(); + + $this->printBigButtonsList($buttons); + return; + } + + if (enterprise_installed()) { + if ($mode == 'importcsv') { + $csv_importer = new CSVImportAgents($this->page, $this->breadcrum); + return $csv_importer->runCSV(); + } + } + + if ($mode == 'netscan') { + return $this->runNetScan(); + } + + return null; + } + + + // Extra methods. + + + /** + * Retrieves and validates information given by user in NetScan wizard. + * + * @return boolean Data OK or not. + */ + public function parseNetScan() + { + if ($this->page == 0) { + // Check if we're updating a task. + $task_id = get_parameter('task', null); + + if (isset($task_id) === true) { + // We're updating this task. + $task = db_get_row( + 'trecon_task', + 'id_rt', + $task_id + ); + + if ($task !== false) { + $this->task = $task; + } + } + + return true; + } + + // Validate response from page 0. No, not a bug, we're always 1 page + // from 'validation' page. + if ($this->page == 1) { + $task_id = get_parameter('task', null); + $taskname = get_parameter('taskname', ''); + $comment = get_parameter('comment', ''); + $server_id = get_parameter('id_recon_server', ''); + $network = get_parameter('network', ''); + $id_group = get_parameter('id_group', ''); + $interval = get_parameter('interval', 0); + + if (isset($task_id) === true) { + // We're updating this task. + $task = db_get_row( + 'trecon_task', + 'id_rt', + $task_id + ); + + if ($task !== false) { + $this->task = $task; + } + } else if (isset($taskname) === true + && isset($network) === true + ) { + // Avoid double creation. + $task = db_get_row_filter( + 'trecon_task', + [ + 'name' => $taskname, + 'subnet' => $network, + ] + ); + + if ($task !== false) { + $this->task = $task; + $this->msg = __('This network scan task has been already defined. Please edit it or create a new one.'); + return false; + } + } + + if ($task_id !== null + && $taskname == null + && $server_id == null + && $id_group == null + && $server == null + && $datacenter == '' + && $user == '' + && $pass == '' + && $encrypt == null + && $interval == 0 + ) { + // Default values, no data received. + // User is accesing directly to this page. + if (users_is_admin() !== true && check_acl( + $config['id_usuario'], + $this->task['id_group'], + 'PM' + ) !== true + ) { + $this->msg = __('You have no access to edit this task.'); + return false; + } + } else { + if (isset($this->task['id_rt']) === false) { + // Disabled 2 Implies wizard non finished. + $this->task['disabled'] = 2; + } + + if ($taskname == '') { + $this->msg = __('You must provide a task name.'); + return false; + } + + if ($server_id == '') { + $this->msg = __('You must select a Discovery Server.'); + return false; + } + + if ($network == '') { + // XXX: Could be improved validating provided network. + $this->msg = __('You must provide a valid network.'); + return false; + } + + if ($id_group == '') { + $this->msg = __('You must select a valid group.'); + return false; + } + + // Assign fields. + $this->task['name'] = $taskname; + $this->task['description'] = $comment; + $this->task['subnet'] = $network; + $this->task['id_recon_server'] = $server_id; + $this->task['id_group'] = $id_group; + $this->task['interval_sweep'] = $interval; + + if (isset($this->task['id_rt']) === false) { + // Create. + $this->task['id_rt'] = db_process_sql_insert( + 'trecon_task', + $this->task + ); + } else { + // Update. + db_process_sql_update( + 'trecon_task', + $this->task, + ['id_rt' => $this->task['id_rt']] + ); + } + } + + return true; + } + + // Validate response from page 1. + if ($this->page == 2) { + $id_rt = get_parameter('task', -1); + + $task = db_get_row( + 'trecon_task', + 'id_rt', + $id_rt + ); + + if ($task !== false) { + $this->task = $task; + } else { + $this->msg = __('Failed to find network scan task.'); + return false; + } + + $id_network_profile = get_parameter('id_network_profile', null); + $autoconf_enabled = get_parameter_switch( + 'autoconfiguration_enabled' + ); + $snmp_enabled = get_parameter_switch('snmp_enabled'); + $os_detect = get_parameter_switch('os_detect'); + $parent_detection = get_parameter_switch('parent_detection'); + $parent_recursion = get_parameter_switch('parent_recursion'); + $vlan_enabled = get_parameter_switch('vlan_enabled'); + $wmi_enabled = get_parameter_switch('wmi_enabled'); + $resolve_names = get_parameter_switch('resolve_names'); + $snmp_version = get_parameter('snmp_version', null); + $community = get_parameter('community', null); + $snmp_context = get_parameter('snmp_context', null); + $snmp_auth_user = get_parameter('snmp_auth_user', null); + $snmp_auth_pass = get_parameter('snmp_auth_pass', null); + $snmp_privacy_method = get_parameter('snmp_privacy_method', null); + $snmp_privacy_pass = get_parameter('snmp_privacy_pass', null); + $snmp_auth_method = get_parameter('snmp_auth_method', null); + $snmp_security_level = get_parameter('snmp_security_level', null); + $auth_strings = get_parameter('auth_strings', null); + + if ($snmp_version == 3) { + $this->task['snmp_community'] = $snmp_context; + } else { + $this->task['snmp_community'] = $community; + } + + $this->task['autoconfiguration_enabled'] = $autoconf_enabled; + $this->task['id_network_profile'] = $id_network_profile; + $this->task['snmp_enabled'] = $snmp_enabled; + $this->task['os_detect'] = $os_detect; + $this->task['parent_detection'] = $parent_detection; + $this->task['parent_recursion'] = $parent_recursion; + $this->task['vlan_enabled'] = $vlan_enabled; + $this->task['wmi_enabled'] = $wmi_enabled; + $this->task['resolve_names'] = $resolve_names; + $this->task['snmp_version'] = $snmp_version; + $this->task['snmp_auth_user'] = $snmp_auth_user; + $this->task['snmp_auth_pass'] = $snmp_auth_pass; + $this->task['snmp_privacy_method'] = $snmp_privacy_method; + $this->task['snmp_privacy_pass'] = $snmp_privacy_pass; + $this->task['snmp_auth_method'] = $snmp_auth_method; + $this->task['snmp_security_level'] = $snmp_security_level; + $this->task['auth_strings'] = $auth_strings; + + if ($this->task['disabled'] == 2) { + // Wizard finished. + $this->task['disabled'] = 0; + } + + // Update. + $res = db_process_sql_update( + 'trecon_task', + $this->task, + ['id_rt' => $this->task['id_rt']] + ); + + return true; + } + + if ($this->page == 3) { + // Wizard ended. Load data and return control to Discovery. + $id_rt = get_parameter('task', -1); + + $task = db_get_row( + 'trecon_task', + 'id_rt', + $id_rt + ); + + if ($task !== false) { + $this->task = $task; + } else { + $this->msg = __('Failed to find network scan task.'); + return false; + } + + return true; + } + + return false; + } + + + /** + * Undocumented function + * + * @return void + */ + public function runNetScan() + { + global $config; + + check_login(); + + if (! check_acl($config['id_user'], 0, 'PM')) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access Agent Management' + ); + include 'general/noaccess.php'; + return; + } + + if ($this->parseNetScan() === false) { + // Error. + ui_print_error_message( + $this->msg + ); + + $form = [ + 'form' => [ + 'method' => 'POST', + 'action' => $this->url.'&mode=netscan&page='.($this->page - 1).'&task='.$this->task['id_rt'], + ], + 'inputs' => [ + [ + 'arguments' => [ + 'type' => 'hidden', + 'name' => 'task', + 'value' => $this->task['id_rt'], + ], + ], + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Go back'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ], + ]; + + // Check ACL. If user is not able to manage target task, + // redirect him to main page. + if (users_is_admin() !== true && check_acl( + $config['id_usuario'], + $this->task['id_group'], + 'PM' + ) !== true + ) { + $form['form']['action'] = $this->url.'&mode=netscan&page='.($this->page - 1); + } + + $this->printForm($form); + return null; + } + + $task_url = ''; + if (isset($this->task['id_rt'])) { + $task_url = '&task='.$this->task['id_rt']; + } + + for ($i = 0; $i < $this->maxPagesNetScan; $i++) { + $breadcrum[] = [ + 'link' => 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=hd&mode=netscan&page='.$i.$task_url, + 'label' => $this->pageLabelsNetScan[$i], + 'selected' => (($i == $this->page) ? 1 : 0), + ]; + } + + if ($this->page < $this->maxPagesNetScan) { + // Avoid to print header out of wizard. + $this->prepareBreadcrum($breadcrum); + $this->printHeader(); + } + + if (isset($this->page) === true + && $this->page != 0 + && isset($this->task['id_rt']) === false + ) { + // Error. + ui_print_error_message( + __('Internal error, please re-run this wizard.') + ); + + $form = [ + 'form' => [ + 'method' => 'POST', + 'action' => $this->url.'&mode=netscan&page=0', + ], + 'inputs' => [ + [ + 'arguments' => [ + 'type' => 'hidden', + 'name' => 'page', + 'value' => 0, + ], + ], + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Go back'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ], + ]; + + $this->printForm($form); + return null; + } + + // -------------------------------. + // Page 0. wizard starts HERE. + // -------------------------------. + if (isset($this->page) === true || $this->page == 0) { + if (isset($this->page) === false + || $this->page == 0 + ) { + $form = []; + + // Input task name. + $form['inputs'][] = [ + 'label' => ''.__('Task name').'', + 'arguments' => [ + 'name' => 'taskname', + 'value' => $this->task['name'], + 'type' => 'text', + 'size' => 25, + ], + ]; + + if (isset($this->task['id_rt']) === true) { + // Propagate id. + $form['inputs'][] = [ + 'arguments' => [ + 'name' => 'task', + 'value' => $this->task['id_rt'], + 'type' => 'hidden', + ], + ]; + } + + // Input task name. + $form['inputs'][] = [ + 'label' => ''.__('Comment').'', + 'arguments' => [ + 'name' => 'comment', + 'value' => $this->task['description'], + 'type' => 'text', + 'size' => 25, + ], + ]; + + // Input Discovery Server. + $form['inputs'][] = [ + 'label' => ''.__('Discovery server').''.ui_print_help_tip( + __('You must select a Discovery Server to run the Task, otherwise the Recon Task will never run'), + true + ), + 'arguments' => [ + 'type' => 'select_from_sql', + 'sql' => sprintf( + 'SELECT id_server, name + FROM tserver + WHERE server_type = %d + ORDER BY name', + SERVER_TYPE_DISCOVERY + ), + 'name' => 'id_recon_server', + 'selected' => $this->task['id_recon_server'], + 'return' => true, + ], + ]; + + // Input Network. + $form['inputs'][] = [ + + 'label' => ''.__('Network').''.ui_print_help_tip( + __('You can specify several networks, separated by commas, for example: 192.168.50.0/24,192.168.60.0/24'), + true + ), + 'arguments' => [ + 'name' => 'network', + 'value' => $this->task['subnet'], + 'type' => 'text', + 'size' => 25, + ], + ]; + + // Input Group. + $form['inputs'][] = [ + 'label' => ''.__('Group').'', + 'arguments' => [ + 'name' => 'id_group', + 'returnAllGroup' => false, + 'privilege' => 'PM', + 'type' => 'select_groups', + 'selected' => $this->task['id_group'], + 'return' => true, + ], + ]; + + // Interval and schedules. + $interv_manual = 0; + if ((int) $this->task['interval_sweep'] == 0) { + $interv_manual = 1; + } + + // Schedule. + $form['inputs'][] = [ + 'label' => ''.__('Interval').''.ui_print_help_tip( + __('Manual interval means that it will be executed only On-demand'), + true + ), + 'arguments' => [ + 'type' => 'select', + 'selected' => $interv_manual, + 'fields' => [ + 0 => __('Defined'), + 1 => __('Manual'), + ], + 'name' => 'interval_manual_defined', + 'return' => true, + ], + 'extra' => ''.html_print_extended_select_for_time( + 'interval', + $this->task['interval_sweep'], + '', + '', + '0', + false, + true, + false, + false + ).ui_print_help_tip( + __('The minimum recomended interval for Recon Task is 5 minutes'), + true + ).'', + ]; + + $str = __('Next'); + + if (isset($this->task['id_rt']) === true) { + $str = __('Update and continue'); + } + + // Submit button. + $form['inputs'][] = [ + 'arguments' => [ + 'name' => 'submit', + 'label' => $str, + 'type' => 'submit', + 'attributes' => 'class="sub next"', + 'return' => true, + ], + ]; + + $task_url = ''; + if (isset($this->task['id_rt'])) { + $task_url = '&task='.$this->task['id_rt']; + } + + $form['form'] = [ + 'method' => 'POST', + 'action' => $this->url.'&mode=netscan&page='.($this->page + 1).$task_url, + ]; + + // Default. + $interval = 600; + $unit = 60; + if (isset($this->task['interval_sweep']) === true) { + $interval = $this->task['interval_sweep']; + $unit = $this->getTimeUnit($interval); + } + + $form['js'] = ' +$("select#interval_manual_defined").change(function() { + if ($("#interval_manual_defined").val() == 1) { + $("#interval_manual_container").hide(); + $("#text-interval_text").val(0); + $("#hidden-interval").val(0); + } + else { + $("#interval_manual_container").show(); + $("#text-interval_text").val(10); + $("#hidden-interval").val('.$interval.'); + $("#interval_units").val('.$unit.'); + } +}).change();'; + + // XXX: Could be improved validating inputs before continue (JS) + // Print NetScan page 0. + $this->printForm($form); + $this->printGoBackButton( + $this->url.'&page='.($this->page - 1).$task_url + ); + } + } + + if ($this->page == 1) { + // Page 1. + $form = []; + // Hidden, id_rt. + $form['inputs'][] = [ + 'arguments' => [ + 'name' => 'task', + 'value' => $this->task['id_rt'], + 'type' => 'hidden', + 'return' => true, + ], + ]; + + // Hidden, page. + $form['inputs'][] = [ + 'arguments' => [ + 'name' => 'page', + 'value' => ($this->page + 1), + 'type' => 'hidden', + 'return' => true, + ], + ]; + + $form['inputs'][] = [ + 'extra' => '

Please, configure task '.io_safe_output($this->task['name']).'

', + ]; + + // Input: Module template. + $form['inputs'][] = [ + 'label' => __('Module template'), + 'arguments' => [ + 'name' => 'id_network_profile', + 'type' => 'select_from_sql', + 'sql' => 'SELECT id_np, name + FROM tnetwork_profile + ORDER BY name', + 'return' => true, + 'selected' => $this->task['id_network_profile'], + 'nothing_value' => 0, + 'nothing' => __('None'), + + ], + ]; + + if (enterprise_installed() === true) { + // Input: Enable auto configuration. + $form['inputs'][] = [ + 'label' => __('Apply autoconfiguration rules').ui_print_help_tip( + __( + 'System is able to auto configure detected host & devices by applying your defined configuration rules.' + ), + true + ), + 'arguments' => [ + 'name' => 'autoconfiguration_enabled', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['autoconfiguration_enabled'])) ? $this->task['autoconfiguration_enabled'] : 0, + + ], + ]; + } + + // Feature configuration. + // Input: SNMP enabled. + $form['inputs'][] = [ + 'label' => __('SNMP enabled'), + 'arguments' => [ + 'name' => 'snmp_enabled', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['snmp_enabled'])) ? $this->task['snmp_enabled'] : 1, + 'onclick' => 'extraSNMP();', + + ], + ]; + + // SNMP CONFIGURATION. + $form['inputs'][] = [ + 'hidden' => 1, + 'block_id' => 'snmp_extra', + 'block_content' => [ + [ + 'label' => __('SNMP version'), + 'arguments' => [ + 'name' => 'snmp_version', + 'fields' => [ + '1' => 'v. 1', + '2c' => 'v. 2c', + '3' => 'v. 3', + ], + 'type' => 'select', + 'script' => 'SNMPExtraShow(this.value)', + 'selected' => $this->task['snmp_version'], + 'return' => true, + ], + ], + ], + ]; + + // SNMP Options pack v1. + $form['inputs'][] = [ + 'hidden' => 1, + 'block_id' => 'snmp_options_basic', + 'block_content' => [ + [ + 'label' => ''.__('SNMP Default community').''.ui_print_help_tip( + __( + 'You can specify several values, separated by commas, for example: public,mysecret,1234' + ), + true + ), + 'arguments' => [ + 'name' => 'community', + 'type' => 'text', + 'value' => $this->task['snmp_community'], + 'size' => 25, + 'return' => true, + + ], + ], + ], + ]; + + // SNMP Options pack v3. + $form['inputs'][] = [ + 'hidden' => 1, + 'block_id' => 'snmp_options_v3', + 'block_content' => [ + [ + 'label' => ''.__('Context').'', + 'arguments' => [ + 'name' => 'snmp_context', + 'type' => 'text', + 'value' => $this->task['snmp_community'], + 'size' => 15, + 'return' => true, + + ], + ], + [ + 'label' => ''.__('Auth user').'', + 'arguments' => [ + 'name' => 'snmp_auth_user', + 'type' => 'text', + 'value' => $this->task['snmp_auth_user'], + 'size' => 15, + 'return' => true, + + ], + ], + [ + 'label' => ''.__('Auth password').''.ui_print_help_tip( + __( + 'The pass length must be eight character minimum.' + ), + true + ), + 'arguments' => [ + 'name' => 'snmp_auth_pass', + 'type' => 'password', + 'value' => $this->task['snmp_auth_pass'], + 'size' => 15, + 'return' => true, + + ], + ], + [ + 'label' => ''.__('Privacy method').'', + 'arguments' => [ + 'name' => 'snmp_privacy_method', + 'type' => 'select', + 'fields' => [ + 'DES' => __('DES'), + 'AES' => __('AES'), + ], + 'selected' => $this->task['snmp_privacy_method'], + 'size' => 15, + 'return' => true, + + ], + ], + [ + 'label' => ''.__('Privacy pass').''.ui_print_help_tip( + __( + 'The pass length must be eight character minimum.' + ), + true + ), + 'arguments' => [ + 'name' => 'snmp_privacy_pass', + 'type' => 'password', + 'value' => $this->task['snmp_privacy_pass'], + 'size' => 15, + 'return' => true, + + ], + ], + [ + 'label' => ''.__('Auth method').'', + 'arguments' => [ + 'name' => 'snmp_auth_method', + 'type' => 'select', + 'fields' => [ + 'MD5' => __('MD5'), + 'SHA' => __('SHA'), + ], + 'selected' => $this->task['snmp_auth_method'], + 'size' => 15, + 'return' => true, + + ], + ], + [ + 'label' => ''.__('Security level').'', + 'arguments' => [ + 'name' => 'snmp_security_level', + 'type' => 'select', + 'fields' => [ + 'noAuthNoPriv' => __('Not auth and not privacy method'), + 'authNoPriv' => __('Auth and not privacy method'), + 'authPriv' => __('Auth and privacy method'), + ], + 'selected' => $this->task['snmp_security_level'], + 'size' => 15, + 'return' => true, + + ], + ], + + ], + ]; + + // Input: WMI enabled. + $form['inputs'][] = [ + 'label' => __('WMI enabled'), + 'arguments' => [ + 'name' => 'wmi_enabled', + 'type' => 'switch', + 'value' => (isset($this->task['wmi_enabled'])) ? $this->task['wmi_enabled'] : 0, + 'return' => true, + 'onclick' => 'toggleWMI();', + + ], + ]; + + // WMI CONFIGURATION. + $form['inputs'][] = [ + 'block_id' => 'wmi_extra', + 'hidden' => 1, + 'block_content' => [ + [ + 'label' => ''.__('WMI Auth. strings').''.ui_print_help_tip( + __( + 'Auth strings must be defined as user%pass, comma separated as many you need.' + ), + true + ), + 'arguments' => [ + 'name' => 'auth_strings', + 'type' => 'text', + 'value' => $this->task['auth_strings'], + 'return' => true, + ], + ], + ], + ]; + + // Input: Enforce os detection. + $form['inputs'][] = [ + 'label' => __('OS detection'), + 'arguments' => [ + 'name' => 'os_detect', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['os_detect'])) ? $this->task['os_detect'] : 1, + + ], + ]; + + // Input: Name resolution. + $form['inputs'][] = [ + 'label' => __('Name resolution'), + 'arguments' => [ + 'name' => 'resolve_names', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['resolve_names'])) ? $this->task['resolve_names'] : 0, + ], + ]; + + // Input: Parent detection. + $form['inputs'][] = [ + 'label' => __('Parent detection'), + 'arguments' => [ + 'name' => 'parent_detection', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['parent_detection'])) ? $this->task['parent_detection'] : 1, + ], + ]; + + // Input: Parent recursion. + $form['inputs'][] = [ + 'label' => __('Parent recursion'), + 'arguments' => [ + 'name' => 'parent_recursion', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['parent_recursion'])) ? $this->task['parent_recursion'] : 1, + ], + ]; + + // Input: VLAN enabled. + $form['inputs'][] = [ + 'label' => __('VLAN enabled'), + 'arguments' => [ + 'name' => 'vlan_enabled', + 'type' => 'switch', + 'return' => true, + 'value' => (isset($this->task['vlan_enabled'])) ? $this->task['vlan_enabled'] : 1, + ], + ]; + + // Submit button. + $form['inputs'][] = [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Finish'), + 'type' => 'submit', + 'attributes' => 'class="sub next"', + 'return' => true, + ], + ]; + + $form['js'] = ' +function SNMPExtraShow(target) { + $("#snmp_options_basic").hide(); + $("#snmp_options_v3").hide(); + if (document.getElementsByName("snmp_enabled")[0].checked) { + $("#snmp_extra").show(); + if (target == 3) { + $("#snmp_options_v3").show(); + } else { + $("#snmp_options_basic").show(); + } + } + +} + +function extraSNMP() { + if (document.getElementsByName("snmp_enabled")[0].checked) { + SNMPExtraShow($("#snmp_version").val()); + $("#snmp_extra").show(); + } else { + // Hide unusable sections + $("#snmp_extra").hide(); + $("#snmp_options_basic").hide(); + $("#snmp_options_v3").hide(); + + // Disable snmp dependant checks + if (document.getElementsByName("parent_recursion")[0].checked) + $("input[name=parent_recursion]").click(); + + if (document.getElementsByName("parent_detection")[0].checked) + $("input[name=parent_detection]").click(); + + if (document.getElementsByName("vlan_enabled")[0].checked) + $("input[name=vlan_enabled]").click(); + + } +} + +function toggleWMI() { + if (document.getElementsByName("wmi_enabled")[0].checked) + $("#wmi_extra").show(); + else + $("#wmi_extra").hide(); +} + +$(function() { + SNMPExtraShow($("#snmp_version").val()); + toggleWMI(); +}); + '; + + $form['form'] = [ + 'method' => 'POST', + 'action' => $this->url.'&mode=netscan&page='.($this->page + 1).'&task='.$this->task['id_rt'], + ]; + + $this->printForm($form); + } + + if ($this->page == 2) { + if ($this->task['id_rt']) { + // 0 - Is OK. + $this->result = 0; + $this->msg = __('Task configured.'); + } else { + // 1 - Is NOT OK. + $this->result = 1; + $this->msg = __('Wizard failed. Cannot configure task.'); + } + + return [ + 'result' => $this->result, + 'id' => $this->task['id_rt'], + 'msg' => $this->msg, + ]; + } + } + + +} diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php new file mode 100644 index 0000000000..c584e6a9b7 --- /dev/null +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -0,0 +1,678 @@ +breadcrum = $str; + } + + + /** + * Getter for breadcrum + * + * @return array Breadcrum. + */ + public function getBreadcrum() + { + return $this->breadcrum; + } + + + /** + * Add an element to breadcrum array. + * + * @param string $breads Elements to add to breadcrum. + * + * @return void + */ + protected function addBreadcrum($breads) + { + if (empty($breads)) { + return; + } + + $this->breadcrum = array_merge($this->breadcrum, $breads); + } + + + /** + * Setter for label + * + * @param string $str Label. + * + * @return void + */ + public function setLabel(string $str) + { + $this->label = $str; + } + + + /** + * Getter for label + * + * @return array Breadcrum. + */ + public function getLabel() + { + return $this->label; + } + + + /** + * Return units associated to target interval (in seconds). + * + * @param integer $interval Target interval. + * + * @return integer Unit. + */ + public function getTimeUnit($interval) + { + $units = [ + 1, + 60, + 3600, + 86400, + 604800, + 2592000, + 31104000, + ]; + + $size = count($units); + for ($i = 0; $i < $size; $i++) { + if ($interval < $units[$i]) { + if (($i - 1) < 0) { + return 1; + } + + return $units[($i - 1)]; + } + } + + return $units[-1]; + } + + + /** + * Builder for breadcrum + * + * @param array $urls Array of urls to be stored in breadcrum. + * @param boolean $add True if breadcrum should be added instead of + * overwrite it. + * + * @return void + */ + public function prepareBreadcrum(array $urls, bool $add=false) + { + $bc = []; + $i = 0; + foreach ($urls as $url) { + if ($url['selected'] == 1) { + $class = 'selected'; + } else { + $class = ''; + } + + $bc[$i] = ''; + $bc[$i] .= '
'.$url['label']; + $bc[$i++] .= '
'; + } + + if ($add === true) { + $this->addBreadcrum($bc); + } else { + $this->setBreadcrum($bc); + } + + } + + + /** + * To be overwritten. + * + * @return void + */ + public function run() + { + ui_require_css_file('wizard'); + } + + + /** + * Checks if environment is ready, + * returns array + * icon: icon to be displayed + * label: label to be displayed + * + * @return array With data. + **/ + public function load() + { + return [ + 'icon' => $this->icon, + 'label' => $this->label, + 'url' => $this->url, + ]; + } + + + /** + * Print breadcrum to follow flow. + * + * @return string Breadcrum HTML code. + */ + public function printBreadcrum() + { + return '

'.implode('', $this->breadcrum).'

'; + } + + + /** + * Prints a header for current wizard. + * + * @param boolean $return Return HTML or print it. + * + * @return string HTML code for header. + */ + public function printHeader(bool $return=false) + { + $output = $this->printBreadcrum(); + if ($return === false) { + echo $output; + } + + return $output; + } + + + /** + * Print input using functions html lib. + * + * @param array $data Input definition. + * + * @return string HTML code for desired input. + */ + public function printInput($data) + { + if (is_array($data) === false) { + return ''; + } + + switch ($data['type']) { + case 'text': + return html_print_input_text( + $data['name'], + $data['value'], + ((isset($data['alt']) === true) ? $data['alt'] : ''), + ((isset($data['size']) === true) ? $data['size'] : 50), + ((isset($data['maxlength']) === true) ? $data['maxlength'] : 255), + ((isset($data['return']) === true) ? $data['return'] : true), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['required']) === true) ? $data['required'] : false), + ((isset($data['function']) === true) ? $data['function'] : ''), + ((isset($data['class']) === true) ? $data['class'] : ''), + ((isset($data['onChange']) === true) ? $data['onChange'] : ''), + ((isset($data['autocomplete']) === true) ? $data['autocomplete'] : '') + ); + + case 'image': + return html_print_input_image( + $data['name'], + $data['src'], + $data['value'], + ((isset($data['style']) === true) ? $data['style'] : ''), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['options']) === true) ? $data['options'] : false) + ); + + case 'text_extended': + return html_print_input_text_extended( + $data['name'], + $data['value'], + $data['id'], + $data['alt'], + $data['size'], + $data['maxlength'], + $data['disabled'], + $data['script'], + $data['attributes'], + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['password']) === true) ? $data['password'] : false), + ((isset($data['function']) === true) ? $data['function'] : '') + ); + + case 'password': + return html_print_input_password( + $data['name'], + $data['value'], + ((isset($data['alt']) === true) ? $data['alt'] : ''), + ((isset($data['size']) === true) ? $data['size'] : 50), + ((isset($data['maxlength']) === true) ? $data['maxlength'] : 255), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['required']) === true) ? $data['required'] : false), + ((isset($data['class']) === true) ? $data['class'] : '') + ); + + case 'text': + return html_print_input_text( + $data['name'], + $data['value'], + ((isset($data['alt']) === true) ? $data['alt'] : ''), + ((isset($data['size']) === true) ? $data['size'] : 50), + ((isset($data['maxlength']) === true) ? $data['maxlength'] : 255), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['required']) === true) ? $data['required'] : false), + ((isset($data['function']) === true) ? $data['function'] : ''), + ((isset($data['class']) === true) ? $data['class'] : ''), + ((isset($data['onChange']) === true) ? $data['onChange'] : ''), + ((isset($data['autocomplete']) === true) ? $data['autocomplete'] : '') + ); + + case 'image': + return html_print_input_image( + $data['name'], + $data['src'], + $data['value'], + ((isset($data['style']) === true) ? $data['style'] : ''), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['options']) === true) ? $data['options'] : false) + ); + + case 'hidden': + return html_print_input_hidden( + $data['name'], + $data['value'], + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['class']) === true) ? $data['class'] : false) + ); + + case 'hidden_extended': + return html_print_input_hidden_extended( + $data['name'], + $data['value'], + $data['id'], + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['class']) === true) ? $data['class'] : false) + ); + + case 'color': + return html_print_input_color( + $data['name'], + $data['value'], + ((isset($data['class']) === true) ? $data['class'] : false), + ((isset($data['return']) === true) ? $data['return'] : false) + ); + + case 'file': + return html_print_input_file( + $data['name'], + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['options']) === true) ? $data['options'] : false) + ); + + case 'select': + return html_print_select( + $data['fields'], + $data['name'], + ((isset($data['selected']) === true) ? $data['selected'] : ''), + ((isset($data['script']) === true) ? $data['script'] : ''), + ((isset($data['nothing']) === true) ? $data['nothing'] : ''), + ((isset($data['nothing_value']) === true) ? $data['nothing_value'] : 0), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['multiple']) === true) ? $data['multiple'] : false), + ((isset($data['sort']) === true) ? $data['sort'] : true), + ((isset($data['class']) === true) ? $data['class'] : ''), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['style']) === true) ? $data['style'] : false), + ((isset($data['option_style']) === true) ? $data['option_style'] : false), + ((isset($data['size']) === true) ? $data['size'] : false), + ((isset($data['modal']) === true) ? $data['modal'] : false), + ((isset($data['message']) === true) ? $data['message'] : ''), + ((isset($data['select_all']) === true) ? $data['select_all'] : false) + ); + + case 'select_from_sql': + return html_print_select_from_sql( + $data['sql'], + $data['name'], + ((isset($data['selected']) === true) ? $data['selected'] : ''), + ((isset($data['script']) === true) ? $data['script'] : ''), + ((isset($data['nothing']) === true) ? $data['nothing'] : ''), + ((isset($data['nothing_value']) === true) ? $data['nothing_value'] : '0'), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['multiple']) === true) ? $data['multiple'] : false), + ((isset($data['sort']) === true) ? $data['sort'] : true), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['style']) === true) ? $data['style'] : false), + ((isset($data['size']) === true) ? $data['size'] : false), + ((isset($data['trucate_size']) === true) ? $data['trucate_size'] : GENERIC_SIZE_TEXT) + ); + + case 'select_groups': + return html_print_select_groups( + ((isset($data['id_user']) === true) ? $data['id_user'] : false), + ((isset($data['privilege']) === true) ? $data['privilege'] : 'AR'), + ((isset($data['returnAllGroup']) === true) ? $data['returnAllGroup'] : true), + $data['name'], + ((isset($data['selected']) === true) ? $data['selected'] : ''), + ((isset($data['script']) === true) ? $data['script'] : ''), + ((isset($data['nothing']) === true) ? $data['nothing'] : ''), + ((isset($data['nothing_value']) === true) ? $data['nothing_value'] : 0), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['multiple']) === true) ? $data['multiple'] : false), + ((isset($data['sort']) === true) ? $data['sort'] : true), + ((isset($data['class']) === true) ? $data['class'] : ''), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['style']) === true) ? $data['style'] : false), + ((isset($data['option_style']) === true) ? $data['option_style'] : false), + ((isset($data['id_group']) === true) ? $data['id_group'] : false), + ((isset($data['keys_field']) === true) ? $data['keys_field'] : 'id_grupo'), + ((isset($data['strict_user']) === true) ? $data['strict_user'] : false), + ((isset($data['delete_groups']) === true) ? $data['delete_groups'] : false), + ((isset($data['include_groups']) === true) ? $data['include_groups'] : false) + ); + + case 'submit': + return '
'.html_print_submit_button( + ((isset($data['label']) === true) ? $data['label'] : 'OK'), + ((isset($data['name']) === true) ? $data['name'] : ''), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['attributes']) === true) ? $data['attributes'] : ''), + ((isset($data['return']) === true) ? $data['return'] : false) + ).'
'; + + case 'checkbox': + return html_print_checkbox( + $data['name'], + $data['value'], + ((isset($data['checked']) === true) ? $data['checked'] : false), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['disabled']) === true) ? $data['disabled'] : false), + ((isset($data['script']) === true) ? $data['script'] : ''), + ((isset($data['disabled_hidden']) === true) ? $data['disabled_hidden'] : false) + ); + + case 'switch': + return html_print_switch($data); + + case 'interval': + return html_print_extended_select_for_time( + $data['name'], + $data['value'], + ((isset($data['script']) === true) ? $data['script'] : ''), + ((isset($data['nothing']) === true) ? $data['nothing'] : ''), + ((isset($data['nothing_value']) === true) ? $data['nothing_value'] : 0), + ((isset($data['size']) === true) ? $data['size'] : false), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['style']) === true) ? $data['selected'] : false), + ((isset($data['unique']) === true) ? $data['unique'] : false) + ); + + case 'textarea': + return html_print_textarea( + $data['name'], + $data['rows'], + $data['columns'], + ((isset($data['value']) === true) ? $data['value'] : ''), + ((isset($data['attributes']) === true) ? $data['attributes'] : ''), + ((isset($data['return']) === true) ? $data['return'] : false), + ((isset($data['class']) === true) ? $data['class'] : '') + ); + + default: + // Ignore. + break; + } + + return ''; + } + + + /** + * Prints a go back button redirecting to main page. + * + * @return void + */ + public function printGoBackButton($url=null) + { + if (isset($url) === false) { + $url = ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery' + ); + } + + $form = [ + 'form' => [ + 'method' => 'POST', + 'action' => $url, + ], + 'inputs' => [ + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Go back'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ], + ]; + + $this->printForm($form); + } + + + /** + * Print a block of inputs. + * + * @param array $input Definition of target block to be printed. + * @param boolean $return Return as string or direct output. + * + * @return string HTML content. + */ + public function printBlock(array $input, bool $return=false) + { + $output = ''; + if ($input['hidden'] == 1) { + $class = ' class="hidden"'; + } else { + $class = ''; + } + + if (is_array($input['block_content']) === true) { + // Print independent block of inputs. + $output .= '
  • '; + $output .= '
      '; + foreach ($input['block_content'] as $input) { + $output .= $this->printBlock($input, $return); + } + + $output .= '
  • '; + } else { + if ($input['arguments']['type'] != 'hidden') { + $output .= '
  • '; + $output .= ''; + $output .= $this->printInput($input['arguments']); + // Allow dynamic content. + $output .= $input['extra']; + $output .= '
  • '; + } else { + $output .= $this->printInput($input['arguments']); + // Allow dynamic content. + $output .= $input['extra']; + } + } + + if ($return === false) { + echo $output; + } + + return $output; + } + + + /** + * Print a form. + * + * @param array $data Definition of target form to be printed. + * @param boolean $return Return as string or direct output. + * + * @return string HTML code. + */ + public function printForm(array $data, bool $return=false) + { + $form = $data['form']; + $inputs = $data['inputs']; + $js = $data['js']; + $cb_function = $data['cb_function']; + $cb_args = $data['cb_args']; + + $output_head = '
    '; + + if ($return === false) { + echo $output_head; + } + + try { + if (isset($cb_function) === true) { + call_user_func_array( + $cb_function, + (isset($cb_args) === true) ? $cb_args : [] + ); + } + } catch (Exception $e) { + error_log('Error executing wizard callback: ', $e->getMessage()); + } + + $output = '
      '; + + foreach ($inputs as $input) { + $output .= $this->printBlock($input, true); + } + + $output .= '
    '; + $output .= '
    '; + $output .= ''; + + if ($return === false) { + echo $output; + } + + return $output_head.$output; + + } + + + /** + * Print a big button element (huge image, big text and link). + * + * @param array $data Element data (link, image...). + * + * @return void Only prints the element. + */ + public static function printBigButtonElement($data) + { + if (isset($data['url']) === false) { + $data['url'] = '#'; + } + + ?> +
  • + +
    + +
    +
    +
    +
  • + '; + array_map('self::printBigButtonElement', $list_data); + echo ''; + } + + +} diff --git a/pandora_console/godmode/wizards/index.php b/pandora_console/godmode/wizards/index.php new file mode 100755 index 0000000000..d825d5121d --- /dev/null +++ b/pandora_console/godmode/wizards/index.php @@ -0,0 +1,7 @@ +load(); diff --git a/pandora_console/images/discovery-100.png b/pandora_console/images/discovery-100.png new file mode 100644 index 0000000000..7ec755e7eb Binary files /dev/null and b/pandora_console/images/discovery-100.png differ diff --git a/pandora_console/images/discovery_green-100.png b/pandora_console/images/discovery_green-100.png new file mode 100644 index 0000000000..bcda80e4dd Binary files /dev/null and b/pandora_console/images/discovery_green-100.png differ diff --git a/pandora_console/images/gm_discovery.menu.png b/pandora_console/images/gm_discovery.menu.png new file mode 100644 index 0000000000..0f396c08c6 Binary files /dev/null and b/pandora_console/images/gm_discovery.menu.png differ diff --git a/pandora_console/images/gm_discovery_green.menu.png b/pandora_console/images/gm_discovery_green.menu.png new file mode 100644 index 0000000000..f4a387c201 Binary files /dev/null and b/pandora_console/images/gm_discovery_green.menu.png differ diff --git a/pandora_console/images/wizard/hostdevices.png b/pandora_console/images/wizard/hostdevices.png new file mode 100644 index 0000000000..bc60d6125c Binary files /dev/null and b/pandora_console/images/wizard/hostdevices.png differ diff --git a/pandora_console/images/wizard/netscan.png b/pandora_console/images/wizard/netscan.png new file mode 100644 index 0000000000..c90f4ddc5d Binary files /dev/null and b/pandora_console/images/wizard/netscan.png differ diff --git a/pandora_console/images/wizard/tasklist.png b/pandora_console/images/wizard/tasklist.png new file mode 100644 index 0000000000..3250311b69 Binary files /dev/null and b/pandora_console/images/wizard/tasklist.png differ diff --git a/pandora_console/images/wizard/verde/hostdevices.png b/pandora_console/images/wizard/verde/hostdevices.png new file mode 100644 index 0000000000..8b8fa022ec Binary files /dev/null and b/pandora_console/images/wizard/verde/hostdevices.png differ diff --git a/pandora_console/images/wizard/verde/tasklist.png b/pandora_console/images/wizard/verde/tasklist.png new file mode 100644 index 0000000000..4c6669e89d Binary files /dev/null and b/pandora_console/images/wizard/verde/tasklist.png differ diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 4867088c1f..af05a8c07f 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -1,16 +1,31 @@ > '; switch ($event_response['type']) { case 'command': - - if ($massive) { echo "
    "; - echo $prompt.sprintf("(Event #$event_id) ".__('Executing command: %s', $command)); + echo $prompt.sprintf( + '(Event #'.$event_id.') '.__( + 'Executing command: %s', + $command + ) + ); echo '

    '; echo "'; @@ -241,7 +259,11 @@ if ($dialogue_event_response) { case 'url': $command = str_replace('localhost', $_SERVER['SERVER_NAME'], $command); - echo ""; + echo ""; + break; + + default: + // Ignore. break; } } @@ -318,10 +340,10 @@ if ($get_extended_event) { $readonly = true; } - // Clean url from events and store in array + // Clean url from events and store in array. $event['clean_tags'] = events_clean_tags($event['tags']); - // If the event is not found, we abort + // If the event is not found, we abort. if (empty($event)) { ui_print_error_message('Event not found'); return false; @@ -340,42 +362,62 @@ if ($get_extended_event) { $event['timestamp_last'] = $timestamp_last; $event['event_rep'] = $event_rep; - // Check ACLs + // Check ACLs. if (is_user_admin($config['id_user'])) { - // Do nothing if you're admin, you get full access + // Do nothing if you're admin, you get full access. + $__ignored_line = 0; } else if ($config['id_user'] == $event['owner_user']) { - // Do nothing if you're the owner user, you get access + // Do nothing if you're the owner user, you get access. + $__ignored_line = 0; } else if ($event['id_grupo'] == 0) { - // If the event has access to all groups, you get access + // If the event has access to all groups, you get access. + $__ignored_line = 0; } else { - // Get your groups + // Get your groups. $groups = users_get_groups($config['id_user'], 'ER'); if (in_array($event['id_grupo'], array_keys($groups))) { - // If the event group is among the groups of the user, you get access + // If event group is among the groups of the user, you get access. + $__ignored_line = 0; } else { - // If all the access types fail, abort + // If all the access types fail, abort. echo 'Access denied'; return false; } } - // Print group_rep in a hidden field to recover it from javascript + // Print group_rep in a hidden field to recover it from javascript. html_print_input_hidden('group_rep', (int) $group_rep); if ($event === false) { return; } - // Tabs + // Tabs. $tabs = "'; - // Get criticity image + // Get criticity image. switch ($event['criticity']) { default: case 0: @@ -418,7 +460,19 @@ if ($get_extended_event) { } if (!$readonly - && ((tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids)) || (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EW', $event['clean_tags'], $childrens_ids))) + && ((tags_checks_event_acl( + $config['id_user'], + $event['id_grupo'], + 'EM', + $event['clean_tags'], + $childrens_ids + )) || (tags_checks_event_acl( + $config['id_user'], + $event['id_grupo'], + 'EW', + $event['clean_tags'], + $childrens_ids + ))) ) { $responses = events_page_responses($event, $childrens_ids); } else { @@ -426,7 +480,7 @@ if ($get_extended_event) { } $console_url = ''; - // If metaconsole switch to node to get details and custom fields + // If metaconsole switch to node to get details and custom fields. if ($meta) { $server = metaconsole_get_connection_by_id($server_id); metaconsole_connect($server); @@ -436,7 +490,12 @@ if ($get_extended_event) { $details = events_page_details($event, $server); - // Juanma (09/05/2014) Fix: Needs to reconnect to node, in previous funct node connection was lost + if (events_has_extended_info($event['id_evento']) === true) { + $related = events_page_related($event, $server); + } + + // Juanma (09/05/2014) Fix: Needs to reconnect to node, in previous funct + // node connection was lost. if ($meta) { $server = metaconsole_get_connection_by_id($server_id); metaconsole_connect($server); @@ -463,7 +522,7 @@ if ($get_extended_event) { $loading = ''; - $out = '
    '.$tabs.$notifications.$loading.$general.$details.$custom_fields.$comments.$responses.$custom_data.html_print_input_hidden('id_event', $event['id_evento']).'
    '; + $out = '
    '.$tabs.$notifications.$loading.$general.$details.$related.$custom_fields.$comments.$responses.$custom_data.html_print_input_hidden('id_event', $event['id_evento']).'
    '; $js = ''; + $js .= '});'; + + if (events_has_extended_info($event['id_evento']) === true) { + $js .= ' + $("#link_related").click(function (){ + $.post ({ + url : "ajax.php", + data : { + page: "include/ajax/events_extended", + get_extended_info: 1, + id_event: '.$event['id_evento'].' + }, + dataType : "html", + success: function (data) { + $("#related_data").html(data); + console.log("vamos puta"); + } + }); + });'; + } + + $js .= ''; echo $out.$js; } @@ -542,6 +628,10 @@ if ($get_events_details) { $img = ui_get_full_url('images/hourglass.png', false, false, false); $title = __('Event in process'); break; + + default: + // Ignore. + break; } $out .= ''; @@ -593,7 +683,8 @@ if ($table_events) { $id_agente = (int) get_parameter('id_agente', 0); $all_events_24h = (int) get_parameter('all_events_24h', 0); - // Fix: for tag functionality groups have to be all user_groups (propagate ACL funct!) + // Fix: for tag functionality groups have to be all user_groups + // (propagate ACL funct!). $groups = users_get_groups($config['id_user']); $tags_condition = tags_get_acl_tags( @@ -611,7 +702,7 @@ if ($table_events) { if ($all_events_24h) { events_print_event_table( - "utimestamp > $date_subtract_day", + 'utimestamp > '.$date_subtract_day, 200, '100%', false, @@ -620,7 +711,7 @@ if ($table_events) { ); } else { events_print_event_table( - "estado <> 1 $tags_condition", + 'estado <> 1 '.$tags_condition, 200, '100%', false, diff --git a/pandora_console/include/ajax/events_extended.php b/pandora_console/include/ajax/events_extended.php new file mode 100644 index 0000000000..4993014ddf --- /dev/null +++ b/pandora_console/include/ajax/events_extended.php @@ -0,0 +1,104 @@ +width = '100%'; + $table->data = []; + $table->head = []; + $table->style[0] = 'min-width:120px; text-align: left;'; + $table->style[1] = 'text-align: left;'; + $table->cellspacing = 2; + $table->cellpadding = 2; + $table->class = 'alternate rounded_cells'; + + $output = []; + $output[] = ''.__('Timestamp').''; + $output[] = ''.__('Description').''; + $table->data[] = $output; + + foreach ($extended_info as $data) { + $output = []; + $output[] = date('Y/m/d H:i:s', $data['utimestamp']); + $output[] = io_safe_output($data['description']); + $table->data[] = $output; + } + + html_print_table($table); +} diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php new file mode 100644 index 0000000000..64643b4c58 --- /dev/null +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -0,0 +1,2152 @@ +verbose = $verbose; + + if ($source === false) { + $this->enabled = false; + $this->sourceId = null; + + $this->targetGroups = null; + $this->targetUsers = null; + } else { + $this->enabled = (bool) $source['enabled']; + $this->sourceId = $source['id']; + + // Assign targets. + $targets = get_notification_source_targets($this->sourceId); + $this->targetGroups = $targets['groups']; + $this->targetUsers = $targets['users']; + $this->targetUpdated = true; + } + + return $this; + } + + + /** + * Warn a message. + * + * @param string $msg Message. + * + * @return void + */ + public function warn(string $msg) + { + if ($this->verbose === true) { + echo date('M j G:i:s').' ConsoleSupervisor: '.$msg."\n"; + } + } + + + /** + * Manage scheduled tasks (basic). + * + * @return void + */ + public function runBasic() + { + global $config; + + /* + * PHP configuration warnings: + * NOTIF.PHP.SAFE_MODE + * NOTIF.PHP.INPUT_TIME + * NOTIF.PHP.EXECUTION_TIME + * NOTIF.PHP.UPLOAD_MAX_FILESIZE + * NOTIF.PHP.MEMORY_LIMIT + * NOTIF.PHP.DISABLE_FUNCTIONS + * NOTIF.PHP.PHANTOMJS + * NOTIF.PHP.VERSION + */ + + $this->checkPHPSettings(); + + /* + * Check license. + * NOTIF.LICENSE.EXPIRATION + */ + + $this->checkLicense(); + + /* + * Check component statuses (servers down - frozen). + * NOTIF.SERVER.STATUS.ID_SERVER + */ + + $this->checkPandoraServers(); + + /* + * Check at least 1 server running in master mode. + * NOTIF.SERVER.MASTER + */ + + $this->checkPandoraServerMasterAvailable(); + + /* + * Check if CRON is running. + * NOTIF.CRON.CONFIGURED + */ + + if (enterprise_installed()) { + $this->checkCronRunning(); + } + + } + + + /** + * Manage scheduled tasks. + * + * @return void + */ + public function run() + { + global $config; + + if ($this->enabled === false) { + // Feature not enabled. + return; + } + + if ($this->sourceId === null) { + // Source not detected. + return; + } + + if ($this->verbose === true) { + if (enterprise_hook('cron_supervisor_lock') === false) { + // Cannot continue. Locked. + exit; + } + } + + // Enterprise support. + if (file_exists($config['homedir'].'/'.ENTERPRISE_DIR.'/load_enterprise.php')) { + include_once $config['homedir'].'/'.ENTERPRISE_DIR.'/load_enterprise.php'; + } + + // Automatic checks launched by supervisor. + $this->warn('running.'); + + /* + * Check license. + * NOTIF.LICENSE.EXPIRATION + */ + + $this->checkLicense(); + + /* + * Check number of files in attachment: + * NOTIF.FILES.ATTACHMENT + */ + + $this->checkAttachment(); + + /* + * Files in data_in: + * NOTIF.FILES.DATAIN (>1000) + * NOTIF.FILES.DATAIN.BADXML (>150) + */ + + $this->checkDataIn(); + + /* + * Check module queues not growing: + * NOTIF.SERVER.QUEUE.ID_SERVER + */ + + $this->checkServers(); + + /* + * Check component statuses (servers down - frozen). + * NOTIF.SERVER.STATUS.ID_SERVER + */ + + $this->checkPandoraServers(); + + /* + * Check at least 1 server running in master mode. + * NOTIF.SERVER.MASTER + */ + + $this->checkPandoraServerMasterAvailable(); + + /* + * PHP configuration warnings: + * NOTIF.PHP.SAFE_MODE + * NOTIF.PHP.INPUT_TIME + * NOTIF.PHP.EXECUTION_TIME + * NOTIF.PHP.UPLOAD_MAX_FILESIZE + * NOTIF.PHP.MEMORY_LIMIT + * NOTIF.PHP.DISABLE_FUNCTIONS + * NOTIF.PHP.PHANTOMJS + * NOTIF.PHP.VERSION + */ + + $this->checkPHPSettings(); + + /* + * Check connection with historical DB (if enabled). + * NOTIF.HISTORYDB + */ + + $this->checkPandoraHistoryDB(); + + /* + * Check pandoradb running in main DB. + * Check pandoradb running in historical DB. + * NOTIF.PANDORADB + * NOTIF.PANDORADB.HISTORICAL + */ + + $this->checkPandoraDBMaintenance(); + + /* + * Check historical DB MR version. + * NOTIF.HISTORYDB.MR + */ + + $this->checkPandoraHistoryDBMR(); + + /* + * Check external components. + * NOTIF.EXT.ELASTICSEARCH + * NOTIF.EXT.LOGSTASH + * + */ + + $this->checkExternalComponents(); + + /* + * Check Metaconsole synchronization issues. + * NOTIF.METACONSOLE.DB_CONNECTION + */ + + $this->checkMetaconsole(); + + /* + * Check incoming scheduled downtimes (< 15d). + * NOTIF.DOWNTIME + */ + + $this->checkDowntimes(); + + /* + * Check if instance is registered. + * NOTIF.UPDATEMANAGER.REGISTRATION + */ + + $this->checkUpdateManagerRegistration(); + + /* + * Check if event storm protection is activated. + * NOTIF.MISC.EVENTSTORMPROTECTION + */ + + $this->checkEventStormProtection(); + + /* + * Check if develop_bypass is enabled. + * NOTIF.MISC.DEVELOPBYPASS + */ + + $this->checkDevelopBypass(); + + /* + * Check if fontpath exists. + * NOTIF.MISC.FONTPATH + */ + + $this->checkFont(); + + /* + * Check if default user and password exists. + * NOTIF.SECURITY.DEFAULT_PASSWORD + */ + + $this->checkDefaultPassword(); + + /* + * Check if there's an active subscription. + * NOTIF.NEWSLETTER.SUBSCRIPTION + */ + + $this->checkNewsletterSubscription(); + + /* + * Check if there're new updates. + * NOTIF.UPDATEMANAGER.OPENSETUP + * NOTIF.UPDATEMANAGER.UPDATE + */ + + $this->checkUpdates(); + + /* + * Check if there're new minor updates available. + * NOTIF.UPDATEMANAGER.MINOR + */ + + $this->checkMinorRelease(); + + if (enterprise_installed()) { + // Release the lock. + enterprise_hook('cron_supervisor_release_lock'); + } + + /* + * Check if CRON is running. + * NOTIF.CRON.CONFIGURED + */ + + if (enterprise_installed()) { + $this->checkCronRunning(); + } + + } + + + /** + * Update targets for given notification using object targets. + * + * @param array $notification Current notification. + * @param boolean $update Only update db targets, no email. + * + * @return void + */ + public function updateTargets( + array $notification, + bool $update=false + ) { + $notification_id = $notification['id_mensaje']; + $blacklist = []; + + if (is_array($this->targetUsers) === true + && count($this->targetUsers) > 0 + ) { + // Process user targets. + $insertion_string = ''; + $users_sql = 'INSERT INTO tnotification_user(id_mensaje,id_user)'; + foreach ($this->targetUsers as $user) { + $insertion_string .= sprintf( + '(%d,"%s")', + $notification_id, + $user['id_user'] + ); + $insertion_string .= ','; + + if ($update === false) { + // Send mail. + if (isset($user['also_mail']) && $user['also_mail'] == 1) { + enterprise_hook( + 'send_email_user', + [ + $user['id_user'], + io_safe_output($notification['mensaje']).'

    '.$notification['url'], + io_safe_output($notification['subject']), + ] + ); + array_push($blacklist, $user['id_user']); + } + } + } + + $insertion_string = substr($insertion_string, 0, -1); + db_process_sql($users_sql.' VALUES '.$insertion_string); + } + + if (is_array($this->targetGroups) === true + && count($this->targetGroups) > 0 + ) { + // Process group targets. + $insertion_string = ''; + $groups_sql = 'INSERT INTO tnotification_group(id_mensaje,id_group)'; + foreach ($this->targetGroups as $group) { + $insertion_string .= sprintf( + '(%d,"%s")', + $notification_id, + $group['id_group'] + ); + $insertion_string .= ','; + + if ($update === false) { + // Send mail. + if (isset($group['also_mail']) && $group['also_mail'] == 1) { + enterprise_hook( + 'send_email_group', + [ + $group['id_group'], + io_safe_output($notification['mensaje']).'

    '.$notification['url'], + io_safe_output($notification['subject']), + null, + $blacklist, + ] + ); + } + } + } + + $insertion_string = substr($insertion_string, 0, -1); + + db_process_sql($groups_sql.' VALUES '.$insertion_string); + } + + } + + + /** + * Generates notifications for target users and groups. + * + * @param array $data Message to be delivered: + * - boolean status (false: notify, true: do not notify) + * - string title + * - string message + * - string url. + * @param integer $source_id Target source_id, by default $this->sourceId. + * @param integer $max_age Maximum age for generated notification. + * + * @return void + */ + public function notify( + array $data, + int $source_id=0, + int $max_age=86400 + ) { + // Uses 'check failed' logic. + if (is_array($data) === false) { + // Skip. + return; + } + + if ($this->targetUpdated === false) { + $targets = get_notification_source_targets($this->sourceId); + $this->targetGroups = $targets['groups']; + $this->targetUsers = $targets['users']; + $this->targetUpdated = false; + } + + if ($source_id === 0) { + $source_id = $this->sourceId; + // Assign targets. + $targets = get_notification_source_targets($source_id); + $this->targetGroups = $targets['groups']; + $this->targetUsers = $targets['users']; + $this->targetUpdated = false; + } + + switch ($data['type']) { + case 'NOTIF.LICENSE.EXPIRATION': + case 'NOTIF.FILES.ATTACHMENT': + case 'NOTIF.FILES.DATAIN': + case 'NOTIF.FILES.DATAIN.BADXML': + case 'NOTIF.PHP.SAFE_MODE': + case 'NOTIF.PHP.INPUT_TIME': + case 'NOTIF.PHP.EXECUTION_TIME': + case 'NOTIF.PHP.UPLOAD_MAX_FILESIZE': + case 'NOTIF.PHP.MEMORY_LIMIT': + case 'NOTIF.PHP.DISABLE_FUNCTIONS': + case 'NOTIF.PHP.PHANTOMJS': + case 'NOTIF.PHP.VERSION': + case 'NOTIF.HISTORYDB': + case 'NOTIF.PANDORADB': + case 'NOTIF.PANDORADB.HISTORICAL': + case 'NOTIF.HISTORYDB.MR': + case 'NOTIF.EXT.ELASTICSEARCH': + case 'NOTIF.EXT.LOGSTASH': + case 'NOTIF.METACONSOLE.DB_CONNECTION': + case 'NOTIF.DOWNTIME': + case 'NOTIF.UPDATEMANAGER.REGISTRATION': + case 'NOTIF.MISC.EVENTSTORMPROTECTION': + case 'NOTIF.MISC.DEVELOPBYPASS': + case 'NOTIF.MISC.FONTPATH': + case 'NOTIF.SECURITY.DEFAULT_PASSWORD': + case 'NOTIF.NEWSLETTER.SUBSCRIPTION': + case 'NOTIF.UPDATEMANAGER.OPENSETUP': + case 'NOTIF.UPDATEMANAGER.UPDATE': + case 'NOTIF.UPDATEMANAGER.MINOR': + case 'NOTIF.CRON.CONFIGURED': + default: + // NOTIF.SERVER.STATUS. + // NOTIF.SERVER.STATUS.ID_SERVER. + // NOTIF.SERVER.QUEUE.ID_SERVER. + // NOTIF.SERVER.MASTER. + // NOTIF.SERVER.STATUS.ID_SERVER. + if (preg_match('/^NOTIF.SERVER/', $data['type']) === true) { + // Component notifications require be inmediate. + $max_age = 0; + } + + // Else ignored. + break; + } + + // Get previous notification. + $prev = db_get_row( + 'tmensajes', + 'subtype', + $data['type'] + ); + + if ($prev !== false + && (time() - $prev['timestamp']) > $max_age + ) { + // Clean previous notification. + $this->cleanNotifications($data['type']); + } else if ($prev !== false) { + // Avoid creation. Previous notification is still valid. + // Update message with latest information. + $r = db_process_sql_update( + 'tmensajes', + [ + 'mensaje' => io_safe_input($data['message']), + 'subject' => io_safe_input($data['title']), + ], + ['id_mensaje' => $prev['id_mensaje']] + ); + $this->updateTargets($prev, true); + return; + } + + if (isset($data['type']) === false) { + $data['type'] = ''; + } + + // Create notification. + $notification = []; + $notification['timestamp'] = time(); + $notification['id_source'] = $source_id; + $notification['mensaje'] = io_safe_input($data['message']); + $notification['subject'] = io_safe_input($data['title']); + $notification['subtype'] = $data['type']; + $notification['url'] = io_safe_input($data['url']); + + $id = db_process_sql_insert('tmensajes', $notification); + + if ($id === false) { + // Failed to generate notification. + $this->warn('Failed to generate notification'); + return; + } + + // Update reference to update targets. + $notification['id_mensaje'] = $id; + + $this->updateTargets($notification); + + } + + + /** + * Deletes useless notifications. + * + * @param string $subtype Subtype to be deleted. + * + * @return mixed False in case of error or invalid values passed. + * Affected rows otherwise + */ + public function cleanNotifications(string $subtype) + { + $not_count = db_get_value_sql( + sprintf( + 'SELECT count(*) as n + FROM tmensajes + WHERE subtype like "%s"', + $subtype + ) + ); + + if ($not_count > 0) { + return db_process_sql_delete( + 'tmensajes', + sprintf('subtype like "%s"', $subtype) + ); + } + + return true; + } + + + /** + * Check license status and validity. + * + * @return boolean Return true if license is valid, false if not. + */ + public function checkLicense() + { + global $config; + + $license = enterprise_hook('license_get_info'); + if ($license === ENTERPRISE_NOT_HOOK) { + return false; + } + + $days_to_expiry = ((strtotime($license['expiry_date']) - time()) / (60 * 60 * 24)); + + if (($days_to_expiry <= 15) && ($days_to_expiry > 0)) { + // Warn user if license is going to expire in 15 days or less. + $this->notify( + [ + 'type' => 'NOTIF.LICENSE_EXPIRATION', + 'title' => __('License is going to expire.'), + 'message' => __( + 'Your license is going to expire in %d days. Please contact sales.', + $days_to_expiry + ), + 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/license', + ] + ); + } else if ($days_to_expiry < 0) { + // Warn user, license has expired. + $this->notify( + [ + 'type' => 'NOTIF.LICENSE.EXPIRATION', + 'title' => __('License is expired.'), + 'message' => __('Your license has expired. Please contact sales.'), + 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/license', + ] + ); + return false; + } else { + $this->cleanNotifications('NOTIF.LICENSE.EXPIRATION'); + } + + return true; + + } + + + /** + * Count files in target path. + * + * @param string $path Path to be checked. + * @param string $regex Regular expression to find files. + * @param integer $max_files Maximum number of files to find. + * + * @return integer Number of files in target path. + */ + public function countFiles( + string $path='', + string $regex='', + int $max_files=500 + ) { + if (empty($path) === true) { + return -1; + } + + $nitems = 0; + + // Count files up to max_files. + $dir = opendir($path); + + if ($dir !== false) { + // Used instead of glob to avoid check directories with + // more than 1M files. + while (false !== ($file = readdir($dir)) && $nitems <= $max_files) { + if ($file != '.' && $file != '..') { + if (empty($regex) === false) { + if (preg_match($regex, $file) === 1) { + $nitems++; + continue; + } + } else { + $nitems++; + } + } + } + + closedir($dir); + } + + return $nitems; + } + + + /** + * Check excesive files in attachment directory. + * + * @return void + */ + public function checkAttachment() + { + global $config; + + if (is_writable($config['attachment_store']) !== true) { + $this->notify( + [ + 'type' => 'NOTIF.WRITABLE.ATTACHMENT', + 'title' => __('Attachment directory is not writable.'), + 'message' => __( + 'Directory %s is not writable. Please configure proper permissions.', + $config['attachment_store'] + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', + ] + ); + return; + } else { + $this->cleanNotifications('NOTIF.WRITABLE.ATTACHMENT'); + } + + $filecount = $this->countFiles( + $config['attachment_store'], + '', + $config['num_files_attachment'] + ); + if ($filecount > $config['num_files_attachment']) { + $this->notify( + [ + 'type' => 'NOTIF.FILES.ATTACHMENT', + 'title' => __('There are too much files in attachment directory.'), + 'message' => __( + 'There are more than %d files in attachment, you should consider cleaning up your attachment directory manually.', + $config['num_files_attachment'] + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', + ] + ); + } else { + $this->cleanNotifications('NOTIF.FILES.ATTACHMENT'); + } + + } + + + /** + * Check excesive files in data_in directory. + * + * @return void + */ + public function checkDataIn() + { + global $config; + + if (enterprise_installed() + && isset($config['license_nms']) + && $config['license_nms'] != 1 + ) { + if (is_readable($config['remote_config']) !== true) { + $this->notify( + [ + 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG', + 'title' => __('Remote configuration directory is not readable.'), + 'message' => __( + 'Remote configuration directory %s is not readable. Please configure it.', + $config['remote_config'] + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', + ] + ); + return; + } else { + $this->cleanNotifications( + 'NOTIF.PERMISSIONS.REMOTE_CONFIG' + ); + } + + if (is_writable($config['remote_config'].'/conf') !== true) { + $this->notify( + [ + 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG.CONF', + 'title' => __('Remote configuration directory is not writable.'), + 'message' => __( + 'Remote configuration directory %s is not writable. Please configure it.', + $config['remote_config'].'/conf' + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', + ] + ); + } else { + $this->cleanNotifications( + 'NOTIF.PERMISSIONS.REMOTE_CONFIG.CONF' + ); + } + + if (is_writable($config['remote_config'].'/collections') !== true) { + $this->notify( + [ + 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG.COLLECTIONS', + 'title' => __('Remote collections directory is not writable.'), + 'message' => __( + 'Collections directory %s is not writable. Please configure it.', + $config['remote_config'].'/collections' + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', + ] + ); + } else { + $this->cleanNotifications( + 'NOTIF.PERMISSIONS.REMOTE_CONFIG.COLLECTIONS' + ); + } + + if (is_writable($config['remote_config'].'/md5') !== true) { + $this->notify( + [ + 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG.MD5', + 'title' => __('Remote md5 directory is not writable.'), + 'message' => __( + 'MD5 directory %s is not writable. Please configure it.', + $config['remote_config'].'/md5' + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', + ] + ); + } else { + $this->cleanNotifications( + 'NOTIF.PERMISSIONS.REMOTE_CONFIG.MD5' + ); + } + } else { + $this->cleanNotifications('NOTIF.PERMISSIONS.REMOTE_CONF%'); + } + + $MAX_FILES_DATA_IN = 1000; + $MAX_BADXML_FILES_DATA_IN = 150; + + $filecount = $this->countFiles( + $config['remote_config'], + '', + $MAX_FILES_DATA_IN + ); + // If cannot open directory, count is '-1', skip. + if ($filecount > $MAX_FILES_DATA_IN) { + $this->notify( + [ + 'type' => 'NOTIF.FILES.DATAIN', + 'title' => __('There are too much files in spool').'.', + 'message' => __( + 'There are more than %d files in %s, you should consider checking DataServer performance', + $MAX_FILES_DATA_IN, + $config['remote_config'] + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', + ] + ); + } else { + $this->cleanNotifications('NOTIF.FILES.DATAIN'); + } + + $filecount = $this->countFiles( + $config['remote_config'], + '/^.*BADXML$/', + $MAX_BADXML_FILES_DATA_IN + ); + // If cannot open directory, count is '-1', skip. + if ($filecount > $MAX_BADXML_FILES_DATA_IN) { + $this->notify( + [ + 'type' => 'NOTIF.FILES.DATAIN.BADXML', + 'title' => __('There are too much BADXML files in spool.'), + 'message' => __( + 'There are more than %d files in %s, you should consider checking software agents.', + $MAX_BADXML_FILES_DATA_IN, + $config['remote_config'] + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', + ] + ); + } else { + $this->cleanNotifications('NOTIF.FILES.DATAIN.BADXML'); + } + } + + + /** + * Check growing queues in servers. + * + * @return void + */ + public function checkServers() + { + global $config; + + $idx_file = $config['attachment_store'].'/.cron.supervisor.servers.idx'; + + $MAX_QUEUE = 1500; + $MAX_GROWN = 50; + + $queue_state = []; + $previous = []; + $new = []; + + if (file_exists($idx_file) === true) { + // Read previous values from file. + $previous = json_decode(file_get_contents($idx_file), true); + } + + // DataServer queue status. + $queue_state = db_get_all_rows_sql( + 'SELECT id_server,name,server_type,queued_modules,status + FROM tserver ORDER BY 1' + ); + + $time = time(); + if (is_array($queue_state) === true) { + foreach ($queue_state as $queue) { + $key = $queue['id_server']; + $type = $queue['server_type']; + $new_data[$key] = $queue['queued_modules']; + + // Compare queue increments in a not over 900 seconds. + if (empty($previous[$key]['modules']) + || ($time - $previous[$key]['utime']) > 900 + ) { + $previous[$key]['modules'] = 0; + } + + $modules_queued = ($queue['queued_modules'] - $previous[$key]['modules']); + + // 50 Modules queued since last check. Or more than 1500 queued. + if ($modules_queued > $MAX_GROWN + || $queue['queued_modules'] > $MAX_QUEUE + ) { + $msg = 'Queue has grown %d modules. Total %d'; + if ($modules_queued <= 0) { + $msg = 'Queue is decreasing in %d modules. But there are %d queued.'; + $modules_queued *= -1; + } + + $this->notify( + [ + 'type' => 'NOTIF.SERVER.QUEUE.'.$key, + 'title' => __( + '%s (%s) performance is being lacked.', + servers_get_server_string_name($type), + $queue['name'] + ), + 'message' => __( + $msg, + $modules_queued, + $queue['queued_modules'] + ), + 'url' => 'index.php?sec=gservers&sec2=godmode/servers/modificar_server&refr=60', + ] + ); + } else { + $this->cleanNotifications('NOTIF.SERVER.QUEUE.'.$key); + } + + $new[$key]['modules'] = $queue['queued_modules']; + $new[$key]['utime'] = $time; + } + + // Update file content. + file_put_contents($idx_file, json_encode($new)); + } else { + // No queue data, ignore. + unlink($idx_file); + + // Clean notifications. + $this->cleanNotifications('NOTIF.SERVER.QUEUE.%'); + } + } + + + /** + * Check Pandora component statuses. + * + * @return void + */ + public function checkPandoraServers() + { + $servers = db_get_all_rows_sql( + 'SELECT + id_server, + name, + server_type, + status, + unix_timestamp() - unix_timestamp(keepalive) as downtime + FROM tserver + WHERE + unix_timestamp() - unix_timestamp(keepalive) > server_keepalive + OR status = 0' + ); + + if ($servers === false) { + $nservers = db_get_value_sql( + 'SELECT count(*) as nservers + FROM tserver' + ); + if ($nservers == 0) { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_en:Configuration'; + if ($config['language'] == 'es') { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_es:Configuracion'; + } + + $this->notify( + [ + 'type' => 'NOTIF.SERVER.STATUS', + 'title' => __('No servers available.'), + 'message' => __('There are no servers registered in this console, please check installation guide.'), + 'url' => $url, + ] + ); + } + + // At this point there's no servers with issues. + $this->cleanNotifications('NOTIF.SERVER.STATUS%'); + return; + } + + foreach ($servers as $server) { + if ($server['status'] == 1) { + // Fatal error. Component has die. + $msg = __( + '%s (%s) crashed.', + servers_get_server_string_name($server['server_type']), + $server['name'] + ); + + $description = __( + '%s (%s) has died, please check log files', + servers_get_server_string_name($server['server_type']), + $server['name'] + ); + } else { + // Non-fatal error. Controlated exit. Component is not running. + $msg = __( + '%s (%s) is stopped.', + servers_get_server_string_name($server['server_type']), + $server['name'] + ); + $description = __( + '%s (%s) is stopped, please check configuration file or remove this server from server list.', + servers_get_server_string_name($server['server_type']), + $server['name'] + ); + } + + $this->notify( + [ + 'type' => 'NOTIF.SERVER.STATUS.'.$server['id_server'], + 'title' => $msg, + 'message' => $description, + 'url' => 'index.php?sec=gservers&sec2=godmode/servers/modificar_server&refr=60', + ] + ); + } + } + + + /** + * Checks if there's at last one server running in master mode. + * + * @return void + */ + public function checkPandoraServerMasterAvailable() + { + $n_masters = db_get_value_sql( + 'SELECT + count(*) as n + FROM tserver + WHERE + unix_timestamp() - unix_timestamp(keepalive) <= server_keepalive + AND master > 0 + AND status = 1' + ); + + if ($n_masters === false) { + // Failed to retrieve server list. + return; + } + + if ($n_masters <= 0) { + // No server running in master. + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_en:Configuration#master'; + if ($config['language'] == 'es') { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_es:Configuracion#master'; + } + + $this->notify( + [ + 'type' => 'NOTIF.SERVER.MASTER', + 'title' => __('No master servers found.'), + 'message' => __('You should define at last one server to run as master, please check documentation.'), + 'url' => $url, + ] + ); + } else { + $this->cleanNotifications('NOTIF.SERVER.MASTER%'); + } + + } + + + /** + * Checks PHP settings to be correct. Generates system notifications if not. + * + * @return void + */ + public function checkPHPSettings() + { + global $config; + + $PHPupload_max_filesize = config_return_in_bytes( + ini_get('upload_max_filesize') + ); + + // PHP configuration. + $PHPmax_input_time = ini_get('max_input_time'); + $PHPmemory_limit = config_return_in_bytes(ini_get('memory_limit')); + $PHPmax_execution_time = ini_get('max_execution_time'); + $PHPsafe_mode = ini_get('safe_mode'); + $PHPdisable_functions = ini_get('disable_functions'); + $PHPupload_max_filesize_min = config_return_in_bytes('800M'); + $PHPmemory_limit_min = config_return_in_bytes('500M'); + + // PhantomJS status. + $result_ejecution = exec($config['phantomjs_bin'].'/phantomjs --version'); + + // PHP version checks. + $php_version = phpversion(); + $php_version_array = explode('.', $php_version); + + if ($PHPsafe_mode === '1') { + $this->notify( + [ + 'type' => 'NOTIF.PHP.SAFE_MODE', + 'title' => __('PHP safe mode is enabled. Some features may not properly work.'), + 'message' => __('To disable, change it on your PHP configuration file (php.ini) and put safe_mode = Off (Dont forget restart apache process after changes)'), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.SAFE_MODE'); + } + + if ($PHPmax_input_time !== '-1') { + $this->notify( + [ + 'type' => 'NOTIF.PHP.INPUT_TIME', + 'title' => sprintf( + __("Not recommended '%s' value in PHP configuration"), + 'max_input_time' + ), + 'message' => sprintf( + __('Recommended value is %s'), + '-1 ('.__('Unlimited').')' + ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.INPUT_TIME'); + } + + if ($PHPmax_execution_time !== '0') { + $this->notify( + [ + 'type' => 'NOTIF.PHP.EXECUTION_TIME', + 'title' => sprintf( + __("Not recommended '%s' value in PHP configuration"), + 'max_execution_time' + ), + 'message' => sprintf( + __('Recommended value is: %s'), + '0 ('.__('Unlimited').')' + ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.EXECUTION_TIME'); + } + + if ($PHPupload_max_filesize < $PHPupload_max_filesize_min) { + $this->notify( + [ + 'type' => 'NOTIF.PHP.UPLOAD_MAX_FILESIZE', + 'title' => sprintf( + __("Not recommended '%s' value in PHP configuration"), + 'upload_max_filesize' + ), + 'message' => sprintf( + __('Recommended value is: %s'), + sprintf(__('%s or greater'), '800M') + ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.UPLOAD_MAX_FILESIZE'); + } + + if ($PHPmemory_limit < $PHPmemory_limit_min && $PHPmemory_limit !== '-1') { + $this->notify( + [ + 'type' => 'NOTIF.PHP.MEMORY_LIMIT', + 'title' => sprintf( + __("Not recommended '%s' value in PHP configuration"), + 'memory_limit' + ), + 'message' => sprintf( + __('Recommended value is: %s'), + sprintf(__('%s or greater'), '500M') + ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator'), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.MEMORY_LIMIT'); + } + + if (preg_match('/system/', $PHPdisable_functions) || preg_match('/exec/', $PHPdisable_functions)) { + $this->notify( + [ + 'type' => 'NOTIF.PHP.DISABLE_FUNCTIONS', + 'title' => __('Problems with disable functions in PHP.INI'), + 'message' => __('Variable disable_functions containts functions system() or exec(), in PHP configuration file (php.ini)').'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.DISABLE_FUNCTIONS'); + } + + if (!isset($result_ejecution) || $result_ejecution == '') { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_en:Configuration#Phantomjs'; + if ($config['language'] == 'es') { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_es:Configuracion#Phantomjs'; + } + + $this->notify( + [ + 'type' => 'NOTIF.PHP.PHANTOMJS', + 'title' => __('phantomjs is not installed'), + 'message' => __('To be able to create images of the graphs for PDFs, please install the phantom.js extension. For that, it is necessary to follow these steps:'), + 'url' => $url, + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.PHANTOMJS'); + } + + if ($php_version_array[0] < 7) { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_en:_PHP_7'; + if ($config['language'] == 'es') { + $url = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_es:Instalaci%C3%B3n_y_actualizaci%C3%B3n_PHP_7'; + } + + $this->notify( + [ + 'type' => 'NOTIF.PHP.VERSION', + 'title' => __('PHP UPDATE REQUIRED'), + 'message' => __('For a correct operation of PandoraFMS, PHP must be updated to version 7.0 or higher.').'
    '.__('Otherwise, functionalities will be lost.').'
    '."
    1. ".__('Report download in PDF format').'
    2. '."
    3. ".__('Emails Sending').'
    4. '.__('Metaconsole Collections').'
    5. ...
    ', + 'url' => $url, + ] + ); + } else { + $this->cleanNotifications('NOTIF.PHP.VERSION'); + } + } + + + /** + * Checks if history DB is available. + * + * @return void + */ + public function checkPandoraHistoryDB() + { + global $config; + + if (isset($config['history_db_enabled']) + && $config['history_db_enabled'] == 1 + ) { + if (! isset($config['history_db_connection']) + || $config['history_db_connection'] === false + ) { + ob_start(); + $config['history_db_connection'] = db_connect( + $config['history_db_host'], + $config['history_db_name'], + $config['history_db_user'], + io_output_password($config['history_db_pass']), + $config['history_db_port'], + false + ); + ob_get_clean(); + } + + if ($config['history_db_connection'] === false) { + $this->notify( + [ + 'type' => 'NOTIF.HISTORYDB', + 'title' => __('Historical database not available'), + 'message' => __('Historical database is enabled. But not available using given configuration. Please check it.'), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=hist_db', + ] + ); + } else { + $this->cleanNotifications('NOTIF.HISTORYDB'); + } + } else { + $this->cleanNotifications('NOTIF.HISTORYDB'); + } + } + + + /** + * Check if pandora_db is running in all available DB instances. + * Generating notifications. + * + * @return void + */ + public function checkPandoraDBMaintenance() + { + global $config; + + // Main DB db_maintenance value. + $db_maintance = db_get_value( + 'value', + 'tconfig', + 'token', + 'db_maintance' + ); + + // If never was executed, it means we are in the first Pandora FMS execution. Set current timestamp. + if (empty($db_maintance)) { + config_update_value('db_maintance', date('U')); + } + + $last_maintance = (date('U') - $db_maintance); + + // Limit 48h. + if ($last_maintance > 172800) { + $this->notify( + [ + 'type' => 'NOTIF.PANDORADB', + 'title' => __('Database maintance problem'), + 'message' => __( + 'Your database is not maintained correctly. It seems that more than 48hrs have passed without proper maintenance. Please review documents of %s on how to perform this maintenance process (DB Tool) and enable it as soon as possible.', + io_safe_output(get_product_name()) + ), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', + ] + ); + } else { + $this->cleanNotifications('NOTIF.PANDORADB'); + } + + if (isset($config['history_db_enabled']) + && $config['history_db_enabled'] == 1 + ) { + // History DB db_maintenance value. + $db_maintenance = db_get_value( + 'value', + 'tconfig', + 'token', + 'db_maintenance', + true + ); + + // History db connection is supossed to be enabled since we use + // db_get_value, wich initializes target db connection. + if (empty($db_maintance)) { + $sql = sprintf( + 'UPDATE tconfig SET `value`=%d WHERE `token`="%s"', + date('U'), + 'db_maintenance' + ); + $affected_rows = db_process_sql( + $sql, + $rettype = 'affected_rows', + $dbconnection = $config['history_db_connection'] + ); + + if ($affected_rows == 0) { + // Failed to update. Maybe the row does not exist? + $sql = sprintf( + 'INSERT INTO tconfig(`token`,`value`) VALUES("%s",%d)', + 'db_maintenance', + date('U') + ); + + $affected_rows = db_process_sql( + $sql, + $rettype = 'affected_rows', + $dbconnection = $config['history_db_connection'] + ); + } + } + + $last_maintance = (date('U') - $db_maintance); + + // Limit 48h. + if ($last_maintance > 172800) { + $this->notify( + [ + 'type' => 'NOTIF.PANDORADB.HISTORY', + 'title' => __( + 'Historical database maintance problem.' + ), + 'message' => __('Your historical database is not being maintained correctly. It seems that more than 48hrs have passed without proper maintenance. Please review documents of %s on how to perform this maintenance process (DB Tool) and enable it as soon as possible.', get_product_name()), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', + ] + ); + } else { + // Historical db working fine. + $this->cleanNotifications('NOTIF.PANDORADB.HISTORY'); + } + } else { + // Disabled historical db. + $this->cleanNotifications('NOTIF.PANDORADB.HISTORY'); + } + } + + + /** + * Check MR package applied in historical DB + * + * @return void + */ + public function checkPandoraHistoryDBMR() + { + global $config; + + if (isset($config['history_db_enabled']) + && $config['history_db_enabled'] == 1 + ) { + $mrh_version = db_get_value( + 'value', + 'tconfig', + 'token', + 'MR', + true + ); + if ($mrh_version != $config['MR']) { + $this->notify( + [ + 'type' => 'NOTIF.HISTORYDB.MR', + 'title' => __('Historical database MR missmatch'), + 'message' => __('Your historical database is not using the same schema of main DB. This could produce anomalyes while storing historical data.'), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=hist_db', + ] + ); + } else { + // MR version OK. + $this->cleanNotifications('NOTIF.HISTORYDB.MR'); + } + } else { + // Disabled historical db. + $this->cleanNotifications('NOTIF.HISTORYDB.MR'); + } + } + + + /** + * Check if elasticsearch is available. + * + * @return void + */ + public function checkExternalComponents() + { + global $config; + + // Cannot check logstash, configuration is only available from server. + // Cannot check selenium, configuration is only available from server. + if (isset($config['log_collector']) + && $config['log_collector'] == 1 + ) { + $elasticsearch = @fsockopen( + $config['elasticsearch_ip'], + $config['elasticsearch_port'], + $errno, + $errstr, + 5 + ); + + if ($elasticsearch === false) { + $this->notify( + [ + 'type' => 'NOTIF.EXT.ELASTICSEARCH', + 'title' => __('Log collector cannot connect to ElasticSearch'), + 'message' => __('ElasticSearch is not available using current configuration. Please check it.'), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=log', + ] + ); + } else { + fclose($elasticsearch); + $this->cleanNotifications('NOTIF.EXT.ELASTICSEARCH'); + } + } else { + $this->cleanNotifications('NOTIF.EXT.ELASTICSEARCH'); + } + + } + + + /** + * Checks if metaconsole DB connection is ready. + * + * @return void + */ + public function checkMetaconsole() + { + global $config; + + $check_ok = true; + + if (license_free() + && is_metaconsole() === false + && isset($config['node_metaconsole']) + && $config['node_metaconsole'] == 1 + ) { + // Check if node is successfully registered in MC. + $server_name = db_get_value( + 'distinct(name)', + 'tserver', + 'server_type', + 1 + ); + + $mc_db_conn = enterprise_hook( + 'metaconsole_load_external_db', + [ + [ + 'dbhost' => $config['replication_dbhost'], + 'dbuser' => $config['replication_dbuser'], + 'dbpass' => io_output_password( + $config['replication_dbpass'] + ), + 'dbname' => $config['replication_dbname'], + ], + ] + ); + + if ($mc_db_conn === NOERR) { + $check_ok = true; + } else { + $check_ok = false; + } + + // Restore the default connection. + enterprise_hook('metaconsole_restore_db'); + } + + if ($check_ok === true) { + $this->cleanNotifications('NOTIF.METACONSOLE.DB_CONNECTION'); + } else { + $this->notify( + [ + 'type' => 'NOTIF.METACONSOLE.DB_CONNECTION', + 'title' => __('Metaconsole DB is not available.'), + 'message' => __('Cannot connect with Metaconsole DB using stored configuration. Please check it.'), + 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=enterprise', + ] + ); + } + } + + + /** + * Check if there are any incoming scheduled downtime in less than 15d. + * + * @return void + */ + public function checkDowntimes() + { + // 15 Days. + $THRESHOLD_SECONDS = (15 * 3600 * 24); + + // Check first if any planned runtime is running. + $currently_running = (int) db_get_value_sql( + 'SELECT count(*) as "n" FROM tplanned_downtime + WHERE executed = 1' + ); + + if ($currently_running > 0) { + $this->notify( + [ + 'type' => 'NOTIF.DOWNTIME', + 'title' => __('Scheduled downtime running.'), + 'message' => __('A scheduled downtime is running. Some monitorization data won\'t be available while downtime is taking place.'), + 'url' => 'index.php?sec=gagente&sec2=godmode/agentes/planned_downtime.list', + ] + ); + return; + } else { + // Retrieve downtimes. + $downtimes = db_get_all_rows_sql( + 'SELECT * FROM tplanned_downtime + WHERE + (type_execution="once" AND date_from > now()) + OR type_execution!="once" ORDER BY `id` DESC' + ); + + // Initialize searchers. + $next_downtime_begin = PHP_INT_MAX; + $now = time(); + + if ($downtimes === false) { + $this->cleanNotifications('NOTIF.DOWNTIME'); + return; + } + + $weekdays = [ + 'monday', + 'tuesday', + 'wednesday', + 'thursday', + 'friday', + 'saturday', + 'sunday', + ]; + + foreach ($downtimes as $dt) { + if ($dt['type_execution'] == 'once' + && ($dt['date_from'] - $now) < $THRESHOLD_SECONDS + ) { + if ($next_downtime_begin > $dt['date_from']) { + // Store datetime for next downtime. + $next_downtime_begin = $dt['date_from']; + $next_downtime_end = $dt['date_to']; + } + } else if ($dt['type_periodicity'] == 'monthly') { + $schd_time_begin = explode( + ':', + $dt['periodically_time_from'] + ); + $schd_time_end = explode( + ':', + $dt['periodically_time_to'] + ); + + $begin = mktime( + // Hour. + $schd_time_begin[0], + // Minute. + $schd_time_begin[1], + // Second. + $schd_time_begin[2], + // Month. + date('n', $now), + // Day. + $dt['periodically_day_from'], + // Year. + date('Y', $now) + ); + + $end = mktime( + // Hour. + $schd_time_end[0], + // Minute. + $schd_time_end[1], + // Second. + $schd_time_end[2], + // Month. + date('n', $now), + // Day. + $dt['periodically_day_to'], + // Year. + date('Y', $now) + ); + + if ($next_downtime_begin > $begin) { + $next_downtime_begin = $begin; + $next_downtime_end = $end; + } + } else if ($dt['type_periodicity'] == 'weekly') { + // Always applies. + $current_week_day = date('N', $now); + + $schd_time_begin = explode( + ':', + $dt['periodically_time_from'] + ); + $schd_time_end = explode( + ':', + $dt['periodically_time_to'] + ); + + $i = 0; + $max = 7; + while ($dt[$weekdays[(($current_week_day + $i) % 7)]] != 1 + && $max-- >= 0 + ) { + // Calculate day of the week matching downtime + // definition. + $i++; + } + + if ($max < 0) { + // No days set. + continue; + } + + // Calculate utimestamp. + $begin = mktime( + // Hour. + $schd_time_begin[0], + // Minute. + $schd_time_begin[1], + // Second. + $schd_time_begin[2], + // Month. + date('n', $now), + // Day. + (date('j', $now) + $i + 1), + // Year. + date('Y', $now) + ); + + $end = mktime( + // Hour. + $schd_time_end[0], + // Minute. + $schd_time_end[1], + // Second. + $schd_time_end[2], + // Month. + date('n', $now), + // Day. + (date('j', $now) + $i + 1), + // Year. + date('Y', $now) + ); + + if ($next_downtime_begin > $begin) { + $next_downtime_begin = $begin; + $next_downtime_end = $end; + } + } + } + + if ($next_downtime_begin != PHP_INT_MAX) { + $this->notify( + [ + 'type' => 'NOTIF.DOWNTIME', + 'title' => __('Downtime scheduled soon.'), + 'message' => __( + 'A scheduled downtime is going to be executed from %s to %s. Some monitorization data won\'t be available while downtime is taking place.', + date('M j, G:i:s ', $next_downtime_begin), + date('M j, G:i:s ', $next_downtime_end) + ), + 'url' => 'index.php?sec=gagente&sec2=godmode/agentes/planned_downtime.list', + ] + ); + return; + } else { + $this->cleanNotifications('NOTIF.DOWNTIME'); + } + } + } + + + /** + * Check if current instance of Pandora FMS is registered in Update Manager. + * + * @return void + */ + public function checkUpdateManagerRegistration() + { + global $config; + $login = get_parameter('login', false); + + if (license_free() === true + && users_is_admin($config['id_user']) === true + ) { + $login = get_parameter('login', false); + // Registration advice. + if ((isset($config['instance_registered']) === true + || ($config['instance_registered'] != 1)) && ($login === false) + ) { + $this->notify( + [ + 'type' => 'NOTIF.UPDATEMANAGER.REGISTRATION', + 'title' => __('This instance is not registered in the Update manager'), + 'message' => __('Click here to start the registration process'), + 'url' => 'javascript: force_run_register();', + ] + ); + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.REGISTRATION'); + } + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.REGISTRATION'); + } + } + + + /** + * Check if instance is subscribed to newsletter. + * + * @return void + */ + public function checkNewsletterSubscription() + { + global $config; + $login = get_parameter('login', false); + + // Newsletter advice. + $newsletter = db_get_value( + 'middlename', + 'tusuario', + 'id_user', + $config['id_user'] + ); + if (license_free() === true + && $newsletter != 1 + && $login === false + ) { + $this->notify( + [ + 'type' => 'NOTIF.NEWSLETTER.SUBSCRIPTION', + 'title' => __('Not subscribed to the newsletter'), + 'message' => __('Click here to start the newsletter subscription process'), + 'url' => 'javascript: force_run_newsletter();', + ] + ); + } else { + $this->cleanNotifications('NOTIF.NEWSLETTER.SUBSCRIPTION'); + } + } + + + /** + * Check if user 'admin' is enabled and using default password. + * + * @return void + */ + public function checkDefaultPassword() + { + global $config; + // Check default password for "admin". + $admin_with_default_pass = db_get_value_sql( + 'SELECT count(*) FROM tusuario + WHERE + id_user="admin" + AND password="1da7ee7d45b96d0e1f45ee4ee23da560" + AND is_admin=1 + and disabled!=1' + ); + + if ($admin_with_default_pass > 0) { + $this->notify( + [ + 'type' => 'NOTIF.SECURITY.DEFAULT_PASSWORD', + 'title' => __('Default password for "Admin" user has not been changed.'), + 'message' => __('Please change the default password because is a common vulnerability reported.'), + 'url' => 'index.php?sec=gusuarios&sec2=godmode/users/user_list', + ] + ); + } else { + $this->cleanNotifications('NOTIF.SECURITY.DEFAULT_PASSWORD'); + } + } + + + /** + * Undocumented function + * + * @return void + */ + public function checkFont() + { + global $config; + + if (($config['fontpath'] == '') + || (file_exists($config['fontpath']) === false) + ) { + $this->notify( + [ + 'type' => 'NOTIF.MISC.FONTPATH', + 'title' => __('Default font doesnt exist'), + 'message' => __('Your defined font doesnt exist or is not defined. Please check font parameters in your config'), + 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=vis', + ] + ); + } else { + $this->cleanNotifications('NOTIF.MISC.FONTPATH'); + } + } + + + /** + * Checks if develop_bypass is enabbled. + * + * @return void + */ + public function checkDevelopBypass() + { + global $develop_bypass; + + if ($develop_bypass == 1) { + $this->notify( + [ + 'type' => 'NOTIF.MISC.DEVELOPBYPASS', + 'title' => __('Developer mode is enabled'), + 'message' => __( + 'Your %s has the "develop_bypass" mode enabled. This is a developer mode and should be disabled in a production system. This value is written in the main index.php file', + get_product_name() + ), + 'url' => 'index.php', + ] + ); + } else { + $this->cleanNotifications('NOTIF.MISC.DEVELOPBYPASS'); + } + } + + + /** + * Check if event storm protection is enabled. + * + * @return void + */ + public function checkEventStormProtection() + { + global $config; + if ($config['event_storm_protection']) { + $this->notify( + [ + 'type' => 'NOTIF.MISC.EVENTSTORMPROTECTION', + 'title' => __('Event storm protection is activated.'), + 'message' => __('You need to restart server after altering this configuration setting. No events will be generated during this mode.'), + 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=general', + ] + ); + } else { + $this->cleanNotifications('NOTIF.MISC.EVENTSTORMPROTECTION'); + } + } + + + /** + * Check if there're new updates available. + * + * @return void + */ + public function checkUpdates() + { + global $config; + + if (isset($_SESSION['new_update'])) { + if (!empty($_SESSION['return_installation_open'])) { + if (!$_SESSION['return_installation_open']['return']) { + foreach ($_SESSION['return_installation_open']['text'] as $message) { + $this->notify( + [ + 'type' => 'NOTIF.UPDATEMANAGER.OPENSETUP', + 'title' => __('Error, first setup "Open update".'), + 'message' => $message, + 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=general', + ] + ); + } + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.OPENSETUP'); + } + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.OPENSETUP'); + } + + if ($_SESSION['new_update'] == 'new') { + $this->notify( + [ + 'type' => 'NOTIF.UPDATEMANAGER.UPDATE', + 'title' => __( + 'New %s Console update', + get_product_name() + ), + 'message' => __('There is a new update available. Please go to Administration:Setup:Update Manager for more details.'), + 'url' => 'index.php?sec=gsetup&sec2=godmode/update_manager/update_manager&tab=online', + ] + ); + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.UPDATE'); + } + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.OPENSETUP'); + $this->cleanNotifications('NOTIF.UPDATEMANAGER.UPDATE'); + } + } + + + /** + * Check if there're minor updates available. + * + * @return void + */ + public function checkMinorRelease() + { + global $config; + + $check_minor_release_available = db_check_minor_relase_available(); + + if ($check_minor_release_available) { + $url = 'http://wiki.pandorafms.com/index.php?title=Pandora:Documentation_en:Anexo_Upgrade#Version_7.0NG_.28_Rolling_Release_.29'; + if ($config['language'] == 'es') { + $url = 'http://wiki.pandorafms.com/index.php?title=Pandora:Documentation_es:Actualizacion#Versi.C3.B3n_7.0NG_.28_Rolling_Release_.29'; + } + + $this->notify( + [ + 'type' => 'NOTIF.UPDATEMANAGER.MINOR', + 'title' => __('Minor release/s available'), + 'message' => __( + 'There are one or more minor releases waiting for update. .About minor release update.', + $url + ), + 'url' => $url, + ] + ); + } else { + $this->cleanNotifications('NOTIF.UPDATEMANAGER.MINOR'); + } + + } + + + /** + * Check if CRON utility has been configured. + * + * @return void + */ + public function checkCronRunning() + { + global $config; + + // Check if DiscoveryCronTasks is running. Warn user if not. + if ($config['cron_last_run'] == 0 + || (get_system_time() - $config['cron_last_run']) > 3600 + ) { + $message_conf_cron = __('DiscoveryConsoleTasks is not running properly'); + if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { + $message_conf_cron .= __('Discovery relies on a proper setup of cron, the time-based scheduling service'); + $message_conf_cron .= '. '.__('Please, add the following line to your crontab file:'); + $message_conf_cron .= '
    * * * * * <user> wget -q -O - --no-check-certificate ';
    +                $message_conf_cron .= str_replace(
    +                    ENTERPRISE_DIR.'/meta/',
    +                    '',
    +                    ui_get_full_url(false)
    +                );
    +                $message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
    +                $message_conf_cron .= '/cron/cron.php >> ';
    +                $message_conf_cron .= $config['homedir'].'/pandora_console.log
    '; + } + + if (isset($config['cron_last_run']) === true) { + $message_conf_cron .= __('Last execution').': '; + $message_conf_cron .= date('Y/m/d H:i:s', $config['cron_last_run']); + $message_conf_cron .= __('Please check process is no locked.'); + } + + $this->notify( + [ + 'type' => 'NOTIF.CRON.CONFIGURED', + 'title' => __('DiscoveryConsoleTasks is not configured.'), + 'message' => __($message_conf_cron), + 'url' => 'index.php?extension_in_menu=gservers&sec=extensions&sec2=enterprise/extensions/cron', + ] + ); + } else { + $this->cleanNotifications('NOTIF.CRON.CONFIGURED'); + } + + } + + +} diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 42306dbfc1..81ddb9f336 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 = 'PC190225'; +$build_version = 'PC190226'; $pandora_version = 'v7.0NG.731'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index ce7b91735c..b472f98ad8 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -1,47 +1,57 @@ $value) { + $negative = false; if (is_numeric($field)) { // User provide the exact operation to do $query .= $value; @@ -718,6 +719,11 @@ function mysql_db_format_array_where_clause_sql($values, $join='AND', $prefix=fa continue; } + if ($field[0] == '!') { + $negative = true; + $field = substr($field, 1); + } + if ($field[0] != '`') { // If the field is as ., don't scape. if (strstr($field, '.') === false) { @@ -732,7 +738,8 @@ function mysql_db_format_array_where_clause_sql($values, $join='AND', $prefix=fa } else if (is_float($value) || is_double($value)) { $query .= sprintf('%s = %f', $field, $value); } else if (is_array($value)) { - $query .= sprintf('%s IN ("%s")', $field, implode('", "', $value)); + $not = $negative ? ' NOT ' : ''; + $query .= sprintf('%s %sIN ("%s")', $field, $not, implode('", "', $value)); } else { if ($value === '') { // Search empty string diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index 6f13388fc0..e1861e70a3 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -852,6 +852,28 @@ function get_parameter_checkbox($name, $default='') } +/** + * Transforms a swicth data (on - non present) to a int value. + * + * @param string $name Variable, switch name. + * @param string $default Default value. + * + * @return integer Value, 1 on, 0 off. + */ +function get_parameter_switch($name, $default='') +{ + $data = get_parameter($name, null); + + if ($data === null) { + return 0; + } else if ($data == 'on') { + return 1; + } + + return 0; +} + + function get_cookie($name, $default='') { if (isset($_COOKIE[$name])) { diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 714005f821..475ef2db79 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -1,26 +1,39 @@ 0) { @@ -1154,7 +1166,7 @@ function config_update_config() } } - // Delete interval value if is required + // Delete interval value if is required. $interval_to_delete = (float) get_parameter('interval_to_delete'); if ($interval_to_delete > 0) { $interval_values_array = explode(',', $interval_values); @@ -1176,7 +1188,7 @@ function config_update_config() $error_update[] = __('Custom report info'); } - // Juanma (06/05/2014) New feature: Custom front page for reports + // Juanma (06/05/2014) New feature: Custom front page for reports. if (!config_update_value('custom_report_front', get_parameter('custom_report_front'))) { $error_update[] = __('Custom report front'); } @@ -1337,7 +1349,15 @@ function config_update_config() $error_update[] = __('eHorus id custom field'); } break; + + default: + // Ignore. + break; } + + default: + // Ignore. + break; } if (count($error_update) > 0) { @@ -1359,7 +1379,9 @@ function config_update_config() /** - * Process config variables + * Process config variables. + * + * @return void */ function config_process_config() { @@ -1377,7 +1399,7 @@ function config_process_config() $is_windows = true; } - // Compatibility fix + // Compatibility fix. foreach ($configs as $c) { $config[$c['token']] = $c['value']; } @@ -1434,18 +1456,18 @@ function config_process_config() if (!isset($config['prominent_time'])) { // Prominent time tells us what to show prominently when a timestamp is - // displayed. The comparation (... days ago) or the timestamp (full date) + // displayed. The comparation (... days ago) or the timestamp (full date). config_update_value('prominent_time', 'comparation'); } if (!isset($config['timesource'])) { - // Timesource says where time comes from (system or mysql) + // Timesource says where time comes from (system or mysql). config_update_value('timesource', 'system'); } if (!isset($config['https'])) { // Sets whether or not we want to enforce https. We don't want to go to a - // potentially unexisting config by default + // potentially unexisting config by default. config_update_value('https', false); } @@ -1454,7 +1476,7 @@ function config_process_config() } if (!isset($config['cert_path'])) { - // Sets name and path of ssl path for use in application + // Sets name and path of ssl path for use in application. config_update_value('cert_path', '/etc/ssl/certs/pandorafms.pem'); } @@ -1466,7 +1488,7 @@ function config_process_config() config_update_value('status_images_set', 'default'); } - // Load user session + // Load user session. if (isset($_SESSION['id_usuario'])) { $config['id_user'] = $_SESSION['id_usuario']; } @@ -1517,12 +1539,12 @@ function config_process_config() } } - if (!isset($config['max_graph_container'])) { - config_update_value('max_graph_container', 10); + if (!isset($config['delete_old_messages'])) { + config_update_value('delete_old_messages', 21); } - if (!isset($config['max_execution_event_response'])) { - config_update_value('max_execution_event_response', 10); + if (!isset($config['max_graph_container'])) { + config_update_value('max_graph_container', 10); } if (!isset($config['max_macro_fields'])) { @@ -1669,13 +1691,10 @@ function config_process_config() config_update_value('limit_parameters_massive', (ini_get('max_input_vars') / 2)); } - if (!isset($config['unique_ip'])) { - config_update_value('unique_ip', 0); - } - /* - *Parse the ACL IP list for access API + * Parse the ACL IP list for access API */ + $temp_list_ACL_IPs_for_API = []; if (isset($config['list_ACL_IPs_for_API'])) { if (!empty($config['list_ACL_IPs_for_API'])) { @@ -1691,8 +1710,7 @@ function config_process_config() // the first time make a conenction and disable itself // Not Managed here ! // if (!isset ($config["autoupdate"])) { - // config_update_value ('autoupdate', true); - // } + // config_update_value ('autoupdate', true);. include_once $config['homedir'].'/include/auth/mysql.php'; include_once $config['homedir'].'/include/functions_io.php'; @@ -2287,7 +2305,7 @@ function config_process_config() } if (defined('METACONSOLE')) { - // Customizable sections (Metaconsole) + // Customizable sections (Metaconsole). enterprise_include_once('include/functions_enterprise.php'); $customizable_sections = enterprise_hook('enterprise_get_customizable_sections'); @@ -2309,15 +2327,15 @@ function config_process_config() ) { $isFunctionSkins = enterprise_include_once('include/functions_skins.php'); if ($isFunctionSkins !== ENTERPRISE_NOT_HOOK) { - // Try to update user table in order to refresh skin inmediatly + // Try to update user table in order to refresh skin inmediatly. $is_user_updating = get_parameter('sec2', ''); if ($is_user_updating == 'operation/users/user_edit') { $id = get_parameter_get('id', $config['id_user']); - // ID given as parameter + // ID given as parameter. $user_info = get_user_info($id); - // If current user is editing himself or if the user has UM (User Management) rights on any groups the user is part of AND the authorization scheme allows for users/admins to update info + // If current user is editing himself or if the user has UM (User Management) rights on any groups the user is part of AND the authorization scheme allows for users/admins to update info. if (($config['id_user'] == $id || check_acl($config['id_user'], users_get_groups($id), 'UM')) && $config['user_can_update_info']) { $view_mode = false; } else { @@ -2331,7 +2349,7 @@ function config_process_config() } if (!is_metaconsole()) { - // Skins are available only in console mode + // Skins are available only in console mode. if (isset($config['id_user'])) { $relative_path = enterprise_hook('skins_set_image_skin_path', [$config['id_user']]); } else { @@ -2461,12 +2479,12 @@ function config_process_config() config_update_value('render_proc_fail', __('Fail')); } - // Daniel maya 02/06/2016 Display menu with click --INI + // Daniel maya 02/06/2016 Display menu with click --INI. if (!isset($config['click_display'])) { config_update_value('click_display', 1); } - // Daniel maya 02/06/2016 Display menu with click --END + // Daniel maya 02/06/2016 Display menu with click --END. if (isset($config['enterprise_installed']) && $config['enterprise_installed'] == 1) { if (!isset($config['service_label_font_size'])) { config_update_value('service_label_font_size', 20); @@ -2493,7 +2511,7 @@ function config_process_config() config_update_value('custom_report_info', 1); } - // Juanma (06/05/2014) New feature: Custom front page for reports + // Juanma (06/05/2014) New feature: Custom front page for reports. if (!isset($config['custom_report_front'])) { config_update_value('custom_report_front', 0); } @@ -2603,7 +2621,7 @@ function config_process_config() config_update_value('instance_registered', 0); } - // eHorus + // Ehorus. if (!isset($config['ehorus_enabled'])) { config_update_value('ehorus_enabled', 0); } @@ -2638,285 +2656,77 @@ function config_process_config() } } - // Finally, check if any value was overwritten in a form + // Finally, check if any value was overwritten in a form. config_update_config(); } +/** + * Start supervisor. + * + * @return void + */ function config_check() { global $config; - // At this first version I'm passing errors using session variables, because the error management - // is done by an AJAX request. Better solutions could be implemented in the future :-) - if (license_free() && users_is_admin($config['id_user'])) { - $login = get_parameter('login', false); - // Registration advice - if ((!isset($config['instance_registered']) || ($config['instance_registered'] != 1)) && ($login === false)) { - set_pandora_error_for_header( - __('Click here to start the registration process'), - __('This instance is not registered in the Update manager') - ); - } + include_once __DIR__.'/class/ConsoleSupervisor.php'; - // Newsletter advice - $newsletter = db_get_value('middlename', 'tusuario', 'id_user', $config['id_user']); - if ($newsletter != 1 && $login === false) { - set_pandora_error_for_header( - __('Click here to start the newsletter subscription process'), - __('Not subscribed to the newsletter') - ); - } + // Enterprise customers launch supervisor using discovery task. + if (enterprise_installed() === false) { + $supervisor = new ConsoleSupervisor(false); + $supervisor->run(); + } else if ($config['cron_last_run'] == 0 + || (get_system_time() - $config['cron_last_run']) > 3600 + ) { + $supervisor = new ConsoleSupervisor(false); + $supervisor->runBasic(); } - // Check default password for "admin" - $is_admin = db_get_value('is_admin', 'tusuario', 'id_user', $config['id_user']); - if ($is_admin) { - $hashpass = db_get_sql( - "SELECT password - FROM tusuario WHERE id_user = 'admin'" - ); - if ($hashpass == '1da7ee7d45b96d0e1f45ee4ee23da560') { - set_pandora_error_for_header( - __('Default password for "Admin" user has not been changed.'), - __('Please change the default password because is a common vulnerability reported.') - ); - } - } - - if (isset($config['license_expired'])) { - set_pandora_error_for_header( - __('You can not get updates until you renew the license.'), - __('This license has expired.') - ); - } - - if (!is_writable('attachment')) { - set_pandora_error_for_header( - __('Please check that the web server has write rights on the {HOMEDIR}/attachment directory'), - __('Attachment directory is not writable by HTTP Server') - ); - } - - // Get remote file dir. - $remote_config = io_safe_output( - db_get_value_filter( - 'value', - 'tconfig', - ['token' => 'remote_config'] - ) - ); - - if (enterprise_installed()) { - if (!is_readable($remote_config)) { - set_pandora_error_for_header( - __('Remote configuration directory is not readble for the console').' - '.$remote_config - ); - } - - $remote_config_conf = $remote_config.'/conf'; - if (!is_writable($remote_config_conf)) { - set_pandora_error_for_header( - __('Remote configuration directory is not writtable for the console').' - '.$remote_config.'/conf' - ); - } - - $remote_config_col = $remote_config.'/collections'; - if (!is_writable($remote_config_col)) { - set_pandora_error_for_header( - __('Remote configuration directory is not writtable for the console').' - '.$remote_config.'/collections' - ); - } - } - - // Check attachment directory (too much files?) - $filecount = count(glob($config['homedir'].'/attachment/*')); - // N temporal files of trash should be enough for most people. - if ($filecount > $config['num_files_attachment']) { - set_pandora_error_for_header( - __('There are too much files in attachment directory. This is not fatal, but you should consider cleaning up your attachment directory manually')." ( $filecount ".__('files').' )', - __('Too much files in your tempora/attachment directory') - ); - } - - // Check database maintance - $db_maintance = db_get_value_filter( - 'value', - 'tconfig', - ['token' => 'db_maintance'] - ); - - // If never was executed, it means we are in the first Pandora FMS execution. Set current timestamp - if (empty($db_maintance)) { - config_update_value('db_maintance', date('U')); - } - - $last_maintance = (date('U') - $db_maintance); - - // ~ about 50 hr - if ($last_maintance > 190000) { - set_pandora_error_for_header( - __('Your database is not maintained correctly. It seems that more than 48hrs have passed without proper maintenance. Please review documents of %s on how to perform this maintenance process (DB Tool) and enable it as soon as possible.', get_product_name()), - __('Database maintance problem') - ); - } - - $fontpath = io_safe_output(db_get_value_filter('value', 'tconfig', ['token' => 'fontpath'])); - if (($fontpath == '') or (!file_exists($fontpath))) { - set_pandora_error_for_header( - __('Your defined font doesnt exist or is not defined. Please check font parameters in your config'), - __('Default font doesnt exist') - ); - } - - if ($config['event_storm_protection']) { - set_pandora_error_for_header( - __('You need to restart server after altering this configuration setting.'), - __('Event storm protection is activated. No events will be generated during this mode.') - ); - } - - global $develop_bypass; - - if ($develop_bypass == 1) { - set_pandora_error_for_header( - __('Your %s has the "develop_bypass" mode enabled. This is a developer mode and should be disabled in a production system. This value is written in the main index.php file', get_product_name()), - __('Developer mode is enabled') - ); - } - - if (isset($_SESSION['new_update'])) { - if (!empty($_SESSION['return_installation_open'])) { - if (!$_SESSION['return_installation_open']['return']) { - foreach ($_SESSION['return_installation_open']['text'] as $message) { - set_pandora_error_for_header( - $message, - __('Error first setup Open update') - ); - } - } - } - - if ($_SESSION['new_update'] == 'new') { - set_pandora_error_for_header( - __('There is a new update available. Please go to Administration:Setup:Update Manager for more details.'), - __('New %s Console update', get_product_name()) - ); - } - } - - // PHP configuration values - $PHPupload_max_filesize = config_return_in_bytes(ini_get('upload_max_filesize')); - $PHPmax_input_time = ini_get('max_input_time'); - $PHPmemory_limit = config_return_in_bytes(ini_get('memory_limit')); - $PHPmax_execution_time = ini_get('max_execution_time'); - $PHPsafe_mode = ini_get('safe_mode'); - $PHPdisable_functions = ini_get('disable_functions'); - - if ($PHPsafe_mode === '1') { - set_pandora_error_for_header( - __('To disable, change it on your PHP configuration file (php.ini) and put safe_mode = Off (Dont forget restart apache process after changes)'), - sprintf(__('PHP safe mode is enabled. Some features may not properly work.')) - ); - } - - if ($PHPmax_input_time !== '-1') { - set_pandora_error_for_header( - sprintf(__('Recommended value is %s'), '-1 ('.__('Unlimited').')').'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - sprintf(__("Not recommended '%s' value in PHP configuration"), 'max_input_time') - ); - } - - if ($PHPmax_execution_time !== '0') { - set_pandora_error_for_header( - sprintf(__('Recommended value is: %s'), '0 ('.__('Unlimited').')').'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - sprintf(__("Not recommended '%s' value in PHP configuration"), 'max_execution_time') - ); - } - - $PHPupload_max_filesize_min = config_return_in_bytes('800M'); - - if ($PHPupload_max_filesize < $PHPupload_max_filesize_min) { - set_pandora_error_for_header( - sprintf(__('Recommended value is: %s'), sprintf(__('%s or greater'), '800M')).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - sprintf(__("Not recommended '%s' value in PHP configuration"), 'upload_max_filesize') - ); - } - - $PHPmemory_limit_min = config_return_in_bytes('500M'); - - if ($PHPmemory_limit < $PHPmemory_limit_min && $PHPmemory_limit !== '-1') { - set_pandora_error_for_header( - sprintf(__('Recommended value is: %s'), sprintf(__('%s or greater'), '500M')).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator'), - sprintf(__("Not recommended '%s' value in PHP configuration"), 'memory_limit') - ); - } - - if (preg_match('/system/', $PHPdisable_functions) or preg_match('/exec/', $PHPdisable_functions)) { - set_pandora_error_for_header( - __('Variable disable_functions containts functions system() or exec(), in PHP configuration file (php.ini)').'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - __('Problems with disable functions in PHP.INI') - ); - } - - $result_ejecution = exec('"'.io_safe_output($config['phantomjs_bin']).'/phantomjs" --version'); - if (!isset($result_ejecution) || $result_ejecution == '') { - if ($config['language'] == 'es') { - set_pandora_error_for_header( - __('To be able to create images of the graphs for PDFs, please install the phantom.js extension. For that, it is necessary to follow these steps:').'Click here', - __('phantomjs is not installed') - ); - } else { - set_pandora_error_for_header( - __('To be able to create images of the graphs for PDFs, please install the phantom.js extension. For that, it is necessary to follow these steps:').'Click here', - __('phantomjs is not installed') - ); - } - } - - $php_version = phpversion(); - $php_version_array = explode('.', $php_version); - if ($php_version_array[0] < 7) { - if ($config['language'] == 'es') { - $url_help = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_es:Instalaci%C3%B3n_y_actualizaci%C3%B3n_PHP_7'; - } else { - $url_help = 'https://wiki.pandorafms.com/index.php?title=Pandora:Documentation_en:_PHP_7'; - } - - set_pandora_error_for_header( - __('For a correct operation of PandoraFMS, PHP must be updated to version 7.0 or higher.').'
    '.__('Otherwise, functionalities will be lost.').'
    '."
    1. ".__('Report download in PDF format').'
    2. '."
    3. ".__('Emails Sending').'
    4. '."
    5. ".__('Metaconsole Collections').'
    6. '."
    7. ".'...'.'
    8. '.'
    '.''.__('Access Help').'', - __('PHP UPDATE REQUIRED') - ); - } } +/** + * Return in bytes + * + * @param string $val Value to convert. + * + * @return integer + */ function config_return_in_bytes($val) { $val = trim($val); $last = strtolower($val[(strlen($val) - 1)]); switch ($last) { - // The 'G' modifier is available since PHP 5.1.0 + // The 'G' modifier is available since PHP 5.1.0. case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; + default: + // Ignore. + break; } return $val; } +/** + * Undocumented function + * + * @return void + */ function config_user_set_custom_config() { global $config; $userinfo = get_user_info($config['id_user']); - // Refresh the last_connect info in the user table - // if last update was more than 5 minutes ago + // Refresh the last_connect info in the user table. + // if last update was more than 5 minutes ago. if ($userinfo['last_connect'] < (time() - SECONDS_1MINUTE)) { update_user($config['id_user'], ['last_connect' => time()]); } @@ -2925,7 +2735,7 @@ function config_user_set_custom_config() $config['block_size'] = $userinfo['block_size']; } - // Each user could have it's own timezone) + // Each user could have it's own timezone). if (isset($userinfo['timezone'])) { if ($userinfo['timezone'] != '') { date_default_timezone_set($userinfo['timezone']); @@ -2938,6 +2748,11 @@ function config_user_set_custom_config() } +/** + * Undocumented function + * + * @return void + */ function config_prepare_session() { global $config; @@ -2950,10 +2765,10 @@ function config_prepare_session() } if ($user_sesion_time == 0) { - // Change the session timeout value to session_timeout minutes // 8*60*60 = 8 hours + // Change the session timeout value to session_timeout minutes // 8*60*60 = 8 hours. $sessionCookieExpireTime = $config['session_timeout']; } else { - // Change the session timeout value to session_timeout minutes // 8*60*60 = 8 hours + // Change the session timeout value to session_timeout minutes // 8*60*60 = 8 hours. $sessionCookieExpireTime = $user_sesion_time; } @@ -2963,7 +2778,7 @@ function config_prepare_session() $sessionCookieExpireTime *= 60; } - // Reset the expiration time upon page load //session_name() is default name of session PHPSESSID + // Reset the expiration time upon page load //session_name() is default name of session PHPSESSID. if (isset($_COOKIE[session_name()])) { setcookie(session_name(), $_COOKIE[session_name()], (time() + $sessionCookieExpireTime), '/'); } diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index f67204d5ba..e56a3d4a52 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -15,17 +15,23 @@ global $config; require_once $config['homedir'].'/include/functions_db.php'; -// Update the execution interval of the given module +// Update the execution interval of the given module. function cron_update_module_interval($module_id, $cron) { - // Check for a valid cron + // Check for a valid cron. if (!cron_check_syntax($cron)) { return; } if ($cron == '* * * * *') { - $module_interval = db_get_value_filter('module_interval', 'tagente_modulo', ['id_agente_modulo' => $module_id]); - return db_process_sql('UPDATE tagente_estado SET current_interval = '.$module_interval.' WHERE id_agente_modulo = '.(int) $module_id); + $module_interval = db_get_value_filter( + 'module_interval', + 'tagente_modulo', + ['id_agente_modulo' => $module_id] + ); + return db_process_sql( + 'UPDATE tagente_estado SET current_interval = '.$module_interval.' WHERE id_agente_modulo = '.(int) $module_id + ); } else { return db_process_sql( 'UPDATE tagente_estado SET current_interval = '.cron_next_execution($cron, $module_interval, $module_id).' WHERE id_agente_modulo = '.(int) $module_id @@ -38,7 +44,7 @@ function cron_update_module_interval($module_id, $cron) // Get the number of seconds left to the next execution of the given cron entry. function cron_next_execution($cron, $module_interval, $module_id) { - // Get day of the week and month from cron config + // Get day of the week and month from cron config. $cron_array = explode(' ', $cron); $minute = $cron_array[0]; $hour = $cron_array[1]; @@ -46,21 +52,34 @@ function cron_next_execution($cron, $module_interval, $module_id) $month = $cron_array[3]; $wday = $cron_array[4]; - // Get last execution time - $last_execution = db_get_value('utimestamp', 'tagente_estado', 'id_agente_modulo', $module_id); + // Get last execution time. + $last_execution = db_get_value( + 'utimestamp', + 'tagente_estado', + 'id_agente_modulo', + $module_id + ); $cur_time = ($last_execution !== false) ? $last_execution : time(); - // Any day of the way + // Any day of the way. if ($wday == '*') { - $nex_time = cron_next_execution_date($cron, $cur_time, $module_interval); + $nex_time = cron_next_execution_date( + $cron, + $cur_time, + $module_interval + ); return ($nex_time - $cur_time); } - // A specific day of the week + // A specific day of the week. $count = 0; $nex_time = $cur_time; do { - $nex_time = cron_next_execution_date($cron, $nex_time, $module_interval); + $nex_time = cron_next_execution_date( + $cron, + $nex_time, + $module_interval + ); $nex_time_wd = $nex_time; $array_nex = explode(' ', date('m w', $nex_time_wd)); @@ -68,12 +87,12 @@ function cron_next_execution($cron, $module_interval, $module_id) $nex_wday = $array_nex[1]; do { - // Check the day of the week + // Check the day of the week. if ($nex_wday == $wday) { return ($nex_time_wd - $cur_time); } - // Move to the next day of the month + // Move to the next day of the month. $nex_time_wd += SECONDS_1DAY; $array_nex_w = explode(' ', date('m w', $nex_time_wd)); @@ -84,7 +103,7 @@ function cron_next_execution($cron, $module_interval, $module_id) $count++; } while ($count < SECONDS_1MINUTE); - // Something went wrong, default to 5 minutes + // Something went wrong, default to 5 minutes. return SECONDS_5MINUTES; } @@ -92,11 +111,11 @@ function cron_next_execution($cron, $module_interval, $module_id) // Get the next execution date for the given cron entry in seconds since epoch. function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) { - // Get cron configuration + // Get cron configuration. $cron_array = explode(' ', $cron); // REMARKS: Months start from 1 in php (different to server) - // Get current time + // Get current time. if ($cur_time === false) { $cur_time = time(); } @@ -107,7 +126,7 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) return $nex_time; } - // Update minutes + // Update minutes. $min_s = cron_get_interval($cron_array[0]); $nex_time_array[0] = ($min_s['down'] == '*') ? 0 : $min_s['down']; @@ -118,22 +137,22 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) } } - // Check if next hour is in cron + // Check if next hour is in cron. $nex_time_array[1]++; $nex_time = cron_valid_date($nex_time_array); if ($nex_time === false) { - // Update the month day if overflow + // Update the month day if overflow. $nex_time_array[1] = 0; $nex_time_array[2]++; $nex_time = cron_valid_date($nex_time_array); if ($nex_time === false) { - // Update the month if overflow + // Update the month if overflow. $nex_time_array[2] = 1; $nex_time_array[3]++; $nex_time = cron_valid_date($nex_time_array); if ($nex_time === false) { - // Update the year if overflow + // Update the year if overflow. $nex_time_array[3] = 1; $nex_time_array[4]++; $nex_time = cron_valid_date($nex_time_array); @@ -141,16 +160,16 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) } } - // Check the hour + // Check the hour. if (cron_is_in_cron($cron_array, $nex_time_array) && $nex_time) { return $nex_time; } - // Update the hour if fails + // Update the hour if fails. $hour_s = cron_get_interval($cron_array[1]); $nex_time_array[1] = ($hour_s['down'] == '*') ? 0 : $hour_s['down']; - // When an overflow is passed check the hour update again + // When an overflow is passed check the hour update again. $nex_time = cron_valid_date($nex_time_array); if ($nex_time >= $cur_time) { if (cron_is_in_cron($cron_array, $nex_time_array) && $nex_time) { @@ -158,32 +177,32 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) } } - // Check if next day is in cron + // Check if next day is in cron. $nex_time_array[2]++; $nex_time = cron_valid_date($nex_time_array); if ($nex_time === false) { - // Update the month if overflow + // Update the month if overflow. $nex_time_array[2] = 1; $nex_time_array[3]++; $nex_time = cron_valid_date($nex_time_array); if ($nex_time === false) { - // Update the year if overflow + // Update the year if overflow. $nex_time_array[3] = 1; $nex_time_array[4]++; $nex_time = cron_valid_date($nex_time_array); } } - // Check the day + // Check the day. if (cron_is_in_cron($cron_array, $nex_time_array) && $nex_time) { return $nex_time; } - // Update the day if fails + // Update the day if fails. $mday_s = cron_get_interval($cron_array[2]); $nex_time_array[2] = ($mday_s['down'] == '*') ? 1 : $mday_s['down']; - // When an overflow is passed check the hour update in the next execution + // When an overflow is passed check the hour update in the next execution. $nex_time = cron_valid_date($nex_time_array); if ($nex_time >= $cur_time) { if (cron_is_in_cron($cron_array, $nex_time_array) && $nex_time) { @@ -191,26 +210,26 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) } } - // Check if next month is in cron + // Check if next month is in cron. $nex_time_array[3]++; $nex_time = cron_valid_date($nex_time_array); if ($nex_time === false) { - // Update the year if overflow + // Update the year if overflow. $nex_time_array[3] = 1; $nex_time_array[4]++; $nex_time = cron_valid_date($nex_time_array); } - // Check the month + // Check the month. if (cron_is_in_cron($cron_array, $nex_time_array) && $nex_time) { return $nex_time; } - // Update the month if fails + // Update the month if fails. $mon_s = cron_get_interval($cron_array[3]); $nex_time_array[3] = ($mon_s['down'] == '*') ? 1 : $mon_s['down']; - // When an overflow is passed check the hour update in the next execution + // When an overflow is passed check the hour update in the next execution. $nex_time = cron_valid_date($nex_time_array); if ($nex_time >= $cur_time) { if (cron_is_in_cron($cron_array, $nex_time_array) && $nex_time) { @@ -218,7 +237,7 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) } } - // Update the year + // Update the year. $nex_time_array[4]++; $nex_time = cron_valid_date($nex_time_array); @@ -226,10 +245,10 @@ function cron_next_execution_date($cron, $cur_time=false, $module_interval=300) } -// Get an array with the cron interval +// Get an array with the cron interval. function cron_get_interval($element) { - // Not a range + // Not a range. if (!preg_match('/(\d+)\-(\d+)/', $element, $capture)) { return [ 'down' => $element, @@ -250,12 +269,12 @@ function cron_is_in_cron($elems_cron, $elems_curr_time) $elem_cron = array_shift($elems_cron); $elem_curr_time = array_shift($elems_curr_time); - // If there is no elements means that is in cron + // If there is no elements means that is in cron. if ($elem_cron === null || $elem_curr_time === null) { return true; } - // Go to last element if current is a wild card + // Go to last element if current is a wild card. if ($elem_cron != '*') { $elem_s = cron_get_interval($elem_cron); // Check if there is no a range @@ -263,7 +282,7 @@ function cron_is_in_cron($elems_cron, $elems_curr_time) return false; } - // Check if there is on the range + // Check if there is on the range. if ($elem_s['up'] !== false) { if ($elem_s['down'] < $elem_s['up']) { if ($elem_curr_time < $elem_s['down'] || $elem_curr_time > $elem_s['up']) { @@ -283,14 +302,365 @@ function cron_is_in_cron($elems_cron, $elems_curr_time) function cron_valid_date($da) { - $st = sprintf('%04d:%02d:%02d %02d:%02d:00', $da[4], $da[3], $da[2], $da[1], $da[0]); + $st = sprintf( + '%04d:%02d:%02d %02d:%02d:00', + $da[4], + $da[3], + $da[2], + $da[1], + $da[0] + ); $time = strtotime($st); return $time; } -// Check if cron is properly constructed +// Check if cron is properly constructed. function cron_check_syntax($cron) { - return preg_match('/^[\d|\*].* .*[\d|\*].* .*[\d|\*].* .*[\d|\*].* .*[\d|\*]$/', $cron); + return preg_match( + '/^[\d|\*].* .*[\d|\*].* .*[\d|\*].* .*[\d|\*].* .*[\d|\*]$/', + $cron + ); +} + + +function cron_list_table() +{ + global $config; + + $read_perms = check_acl($config['id_user'], 0, 'RR'); + $write_perms = check_acl($config['id_user'], 0, 'RW'); + $manage_perms = check_acl($config['id_user'], 0, 'RM'); + $manage_pandora = check_acl($config['id_user'], 0, 'PM'); + + $url = 'index.php?extension_in_menu=gservers&sec=extensions&sec2=enterprise/extensions/cron&'; + + $user_groups = implode( + ',', + array_keys(users_get_groups()) + ); + + $defined_tasks = db_get_all_rows_filter( + 'tuser_task_scheduled', + 'id_grupo IN ('.$user_groups.')' + ); + + if (!check_acl($config['id_user'], 0, 'PM')) { + $read_tasks = []; + foreach ($defined_tasks as $task) { + $function_name = db_get_value( + 'function_name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + if (($function_name != 'cron_task_execute_custom_script') + && ($function_name != 'cron_task_do_backup') + ) { + $read_tasks[] = $task; + } + } + + $defined_tasks = $read_tasks; + + if (empty($defined_tasks)) { + $defined_tasks = false; + } + } + + if ($defined_tasks !== false) { + echo '

    '.__('Scheduled jobs').'

    '; + + $table = new stdClass(); + $table->class = 'databox data'; + $table->width = '100%'; + $table->data = []; + $table->head = []; + $table->head[0] = ''; + $table->head[1] = __('User'); + $table->head[2] = __('Task'); + $table->head[3] = __('Scheduled'); + $table->head[4] = __('Next execution'); + $table->head[5] = __('Last run'); + $table->head[6] = __('Group'); + $table->head[7] = __('Actions'); + $table->align[7] = 'left'; + + foreach ($defined_tasks as $task) { + $data = []; + + $function_name = db_get_value( + 'function_name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + switch ($function_name) { + case 'cron_task_generate_report': + if ($write_perms || $manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + $args = unserialize($task['args']); + $report = reports_get_report($args[0]); + + // Check ACL in reports_get_report return false. + if ($report === false) { + continue; + } + + $email = $args[1]; + $data[2] .= '
    - '.__('Report').": "; + $data[2] .= $report['name'].''; + $data[2] .= '
    - '.__('Email').": "; + $data[2] .= ui_print_truncate_text($email, 60, false).''; + break; + + case 'cron_task_generate_report_by_template': + if ($write_perms || $manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + $args = unserialize($task['args']); + + $filter = []; + $filter['id_report'] = $args[0]; + $template = db_get_row_filter( + 'treport_template', + $filter, + false + ); + + // Check ACL in reports_get_report return false. + if ($template === false) { + continue; + } + + $agents_id = $args[1]; + $id_group = $args[2]; + $report_per_agent = $args[0]; + $report_name = $args[3]; + $email = $args[4]; + $data[2] .= '
    - '.__('Template').": ".$template['name'].''; + $data[2] .= '
    - '.__('Agents').': '.$agents_id.''; + $data[2] .= '
    - '.__('Report per agent').': '.$report_per_agent.''; + $data[2] .= '
    - '.__('Report name').': '.$report_name.''; + $data[2] .= '
    - '.__('Email').": ".$email.''; + break; + + case 'cron_task_execute_custom_script': + if ($manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + $args = unserialize($task['args']); + $data[2] .= '
    - '.__('Custom script').': '.$args[0]; + break; + + case 'cron_task_save_report_to_disk': + if ($write_perms || $manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + + $args = unserialize($task['args']); + $report = reports_get_report($args[0]); + + // Check ACL in reports_get_report return false. + if ($report === false) { + continue; + } + + $path = $args[1]; + $data[2] .= '
    - '.__('Report').": ".$report['name'].''; + $data[2] .= '
    - '.__('Path').': '.$path.''; + 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, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value('name', 'tuser_task', 'id', $task['id_user_task']); + $args = unserialize($task['args']); + $report = reports_get_report($args[0]); + + // Check ACL in reports_get_report return false. + if ($report === false) { + continue; + } + + $path = $args[1]; + $data[2] .= '
    - '.__('Report').": ".$report['name'].''; + $data[2] .= '
    - '.__('Path').': '.$path.''; + break; + + case 'cron_task_do_backup': + if ($manage_pandora) { + $data[0] = ''; + $data[0] .= html_print_image( + 'images/target.png', + true, + ['title' => __('Force run')] + ); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = $task['id_usuario']; + $data[2] = db_get_value( + 'name', + 'tuser_task', + 'id', + $task['id_user_task'] + ); + $args = unserialize($task['args']); + break; + + default: + // Ignore. + break; + } + + $data[3] = cron_get_scheduled_string($task['scheduled']); + $data[4] = date('Y/m/d H:i:s', $args['first_execution']); + $data[5] = empty($task['last_run']) ? __('Never') : date('Y/m/d H:i:s', $task['last_run']); + + $data[6] = ui_print_group_icon($task['id_grupo'], true); + + if ($function_name == 'cron_task_do_backup' || $function_name == 'cron_task_execute_custom_script') { + if ($manage_pandora) { + $data[7] = ''; + $data[7] .= html_print_image( + 'images/config.png', + true, + ['title' => __('Edit')] + ); + $data[7] .= ''; + } + + if ($manage_pandora) { + $data[7] .= ''; + $data[7] .= html_print_image( + 'images/cross.png', + true, + ['title' => __('Delete')] + ); + $data[7] .= ''; + } + } else { + if ($write_perms || $manage_pandora) { + $data[7] = ''; + $data[7] .= html_print_image( + 'images/config.png', + true, + ['title' => __('Edit')] + ); + $data[7] .= ''; + } + + if ($manage_perms || $manage_pandora) { + $data[7] .= ''; + $data[7] .= html_print_image( + 'images/cross.png', + true, + ['title' => __('Delete')] + ); + $data[7] .= ''; + } + } + + array_push($table->data, $data); + } + + html_print_table($table); + } } diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 476f0f158a..15570de763 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -1,17 +1,32 @@ - * Both are similars: - * db_get_all_rows_filter ('table', array ('disabled', 0)); - * db_get_all_rows_filter ('table', 'disabled = 0'); + * @param mixed $filter Filters elements. It can be an indexed array + * (keys would be the field name and value the expected + * value, and would be joined with an AND operator) or a + * string, including any SQL clause (without the WHERE + * keyword). Example: + * + * Both are similars: + * db_get_all_rows_filter ('table', ['disabled', 0]); + * db_get_all_rows_filter ('table', 'disabled = 0'); + * Both are similars: + * db_get_all_rows_filter ( + * 'table', + * [ + * 'disabled' => 0, + * 'history_data' => 0 + * ], + * 'name', + * 'OR' + * ); + * db_get_all_rows_filter ( + * 'table', + * 'disabled = 0 OR history_data = 0', 'name' + * ); + * . + * @param mixed $fields Fields of the table to retrieve. Can be an array or a + * coma separated string. All fields are retrieved by + * default. * - * Both are similars: - * db_get_all_rows_filter ('table', array ('disabled' => 0, 'history_data' => 0), 'name', 'OR'); - * db_get_all_rows_filter ('table', 'disabled = 0 OR history_data = 0', 'name'); - * - * @param mixed Fields of the table to retrieve. Can be an array or a coma - * separated string. All fields are retrieved by default - * - * @return mixed False in case of error or invalid values passed. Affected rows otherwise + * @return mixed False in case of error or invalid values passed. + * Affected rows otherwise */ function events_get_events($filter=false, $fields=false) { @@ -93,10 +120,13 @@ function events_get_events($filter=false, $fields=false) /** * Get the event with the id pass as parameter. * - * @param integer $id Event id - * @param mixed $fields The fields to show or by default all with false. + * @param integer $id Event id. + * @param mixed $fields The fields to show or by default all with false. + * @param boolean $meta Metaconsole environment or not. + * @param boolean $history Retrieve also historical data. * - * @return mixed False in case of error or invalid values passed. Event row otherwise + * @return mixed False in case of error or invalid values passed. + * Event row otherwise. */ function events_get_event($id, $fields=false, $meta=false, $history=false) { @@ -123,6 +153,20 @@ function events_get_event($id, $fields=false, $meta=false, $history=false) } +/** + * Retrieve all events ungrouped. + * + * @param string $sql_post Sql_post. + * @param integer $offset Offset. + * @param integer $pagination Pagination. + * @param boolean $meta Meta. + * @param boolean $history History. + * @param boolean $total Total. + * @param boolean $history_db History_db. + * @param string $order Order. + * + * @return mixed Array of events or false. + */ function events_get_events_no_grouped( $sql_post, $offset=0, @@ -137,7 +181,7 @@ function events_get_events_no_grouped( $table = events_get_events_table($meta, $history); - $sql = "SELECT * FROM $table te WHERE 1=1 ".$sql_post; + $sql = 'SELECT * FROM '.$table.' te WHERE 1=1 '.$sql_post; $events = db_get_all_rows_sql($sql, $history_db); @@ -145,6 +189,21 @@ function events_get_events_no_grouped( } +/** + * Return all events matching sql_post grouped. + * + * @param [type] $sql_post Sql_post. + * @param integer $offset Offset. + * @param integer $pagination Pagination. + * @param boolean $meta Meta. + * @param boolean $history History. + * @param boolean $total Total. + * @param boolean $history_db History_db. + * @param string $order Order. + * @param string $sort_field Sort_field. + * + * @return mixed Array of events or false. + */ function events_get_events_grouped( $sql_post, $offset=0, @@ -203,6 +262,15 @@ function events_get_events_grouped( } +/** + * Return count of events grouped. + * + * @param string $sql_post Sql_post. + * @param boolean $meta Meta. + * @param boolean $history History. + * + * @return integer Number of events or false if failed. + */ function events_get_total_events_grouped($sql_post, $meta=false, $history=false) { return events_get_events_grouped($sql_post, 0, 0, $meta, $history, true); @@ -215,9 +283,9 @@ function events_get_total_events_grouped($sql_post, $meta=false, $history=false) * An event is similar then the event text (evento) and the id_agentmodule are * the same. * - * @param int Event id to get similar events. - * @param bool Metaconsole mode flag - * @param bool History mode flag + * @param integer $id Event id to get similar events. + * @param boolean $meta Metaconsole mode flag. + * @param boolean $history History mode flag. * * @return array A list of events ids. */ @@ -227,7 +295,14 @@ function events_get_similar_ids($id, $meta=false, $history=false) $ids = []; if ($meta) { - $event = events_meta_get_event($id, ['evento', 'id_agentmodule'], $history); + $event = events_meta_get_event( + $id, + [ + 'evento', + 'id_agentmodule', + ], + $history + ); } else { $event = events_get_event($id, ['evento', 'id_agentmodule']); } @@ -259,26 +334,33 @@ function events_get_similar_ids($id, $meta=false, $history=false) /** * Delete events in a transresponse * - * @param mixed Event ID or array of events - * @param bool Whether to delete similar events too. - * @param bool Metaconsole mode flag - * @param bool History mode flag + * @param mixed $id_event Event ID or array of events. + * @param boolean $similar Whether to delete similar events too. + * @param boolean $meta Metaconsole mode flag. + * @param boolean $history History mode flag. * * @return boolean Whether or not it was successful */ -function events_delete_event($id_event, $similar=true, $meta=false, $history=false) -{ +function events_delete_event( + $id_event, + $similar=true, + $meta=false, + $history=false +) { global $config; $table_event = events_get_events_table($meta, $history); - // Cleans up the selection for all unwanted values also casts any single values as an array + // Cleans up the selection for all unwanted values also casts any single values as an array. $id_event = (array) safe_int($id_event, 1); - // We must delete all events like the selected + // We must delete all events like the selected. if ($similar) { foreach ($id_event as $id) { - $id_event = array_merge($id_event, events_get_similar_ids($id, $meta, $history)); + $id_event = array_merge( + $id_event, + events_get_similar_ids($id, $meta, $history) + ); } $id_event = array_unique($id_event); @@ -294,7 +376,7 @@ function events_delete_event($id_event, $similar=true, $meta=false, $history=fal } if (check_acl($config['id_user'], $event_group, 'EM') == 0) { - // Check ACL + // Check ACL. db_pandora_audit('ACL Violation', 'Attempted deleting event #'.$event); $errors++; } else { @@ -304,7 +386,7 @@ function events_delete_event($id_event, $similar=true, $meta=false, $history=fal $errors++; } else { db_pandora_audit('Event deleted', 'Deleted event #'.$event); - // ACL didn't fail nor did return + // ACL didn't fail nor did return. continue; } } @@ -321,25 +403,29 @@ function events_delete_event($id_event, $similar=true, $meta=false, $history=fal /** - * Change the status of one or various events + * Change the status of one or multiple events. * - * @param mixed Event ID or array of events - * @param int new status of the event - * @param bool metaconsole mode flag - * @param bool history mode flag + * @param mixed $id_event Event ID or array of events. + * @param integer $new_status New status of the event. + * @param boolean $meta Metaconsole mode flag. + * @param boolean $history History mode flag. * * @return boolean Whether or not it was successful */ -function events_change_status($id_event, $new_status, $meta=false, $history=false) -{ +function events_change_status( + $id_event, + $new_status, + $meta=false, + $history=false +) { global $config; $event_table = events_get_events_table($meta, $history); - // Cleans up the selection for all unwanted values also casts any single values as an array + // Cleans up the selection for all unwanted values also casts any single values as an array. $id_event = (array) safe_int($id_event, 1); - // Update ack info if the new status is validated + // Update ack info if the new status is validated. if ($new_status == EVENT_STATUS_VALIDATED) { $ack_utimestamp = time(); $ack_user = $config['id_user']; @@ -409,14 +495,20 @@ function events_change_status($id_event, $new_status, $meta=false, $history=fals return false; } - events_comment($id_event, '', "Change status to $status_string", $meta, $history); + events_comment( + $id_event, + '', + 'Change status to '.$status_string, + $meta, + $history + ); if ($meta && !empty($alerts)) { $server = metaconsole_get_connection_by_id($server_id); metaconsole_connect($server); } - // Put the alerts in standby or not depends the new status + // Put the alerts in standby or not depends the new status. foreach ($alerts as $alert) { switch ($new_status) { case EVENT_NEW: @@ -427,6 +519,10 @@ function events_change_status($id_event, $new_status, $meta=false, $history=fals case EVENT_PROCESS: alerts_agent_module_standby($alert, 1); break; + + default: + // Ignore. + break; } } @@ -439,23 +535,31 @@ function events_change_status($id_event, $new_status, $meta=false, $history=fals /** - * Change the owner of an event if the event hasn't owner + * Change the owner of an event if the event hasn't owner. * - * @param mixed Event ID or array of events - * @param string id_user of the new owner. If is false, the current owner will be setted - * @param bool flag to force the change or not (not force is change only when it hasn't owner) - * @param bool metaconsole mode flag - * @param bool history mode flag + * @param mixed $id_event Event ID or array of events. + * @param string $new_owner Id_user of the new owner. If is false, the current + * owner will be setted. + * @param boolean $force Flag to force the change or not (not force is + * change only when it hasn't owner). + * @param boolean $meta Metaconsole mode flag. + * @param boolean $history History mode flag. * - * @return boolean Whether or not it was successful + * @return boolean Whether or not it was successful. */ -function events_change_owner($id_event, $new_owner=false, $force=false, $meta=false, $history=false) -{ +function events_change_owner( + $id_event, + $new_owner=false, + $force=false, + $meta=false, + $history=false +) { global $config; $event_table = events_get_events_table($meta, $history); - // Cleans up the selection for all unwanted values also casts any single values as an array + // Cleans up the selection for all unwanted values also casts any single + // values as an array. $id_event = (array) safe_int($id_event, 1); foreach ($id_event as $k => $id) { @@ -476,20 +580,27 @@ function events_change_owner($id_event, $new_owner=false, $force=false, $meta=fa } // If no new_owner is provided, the current user will be the owner - // ** Comment this lines because if possible selected None owner in owner event. TIQUET: #2250*** + // * #2250: Comment this lines because if possible selected None owner. // if (empty($new_owner)) { // $new_owner = $config['id_user']; // } - // Only generate comment when is forced (sometimes is changed the owner when comment) + // Only generate comment when is forced (sometimes is owner changes when + // comment). if ($force) { - events_comment($id_event, '', "Change owner to $new_owner", $meta, $history); + events_comment( + $id_event, + '', + 'Change owner to '.$new_owner, + $meta, + $history + ); } $values = ['owner_user' => $new_owner]; $where = ['id_evento' => $id_event]; - // If not force, add to where if owner_user = '' + // If not force, add to where if owner_user = ''. if (!$force) { $where['owner_user'] = ''; } @@ -510,6 +621,14 @@ function events_change_owner($id_event, $new_owner=false, $force=false, $meta=fa } +/** + * Returns proper event table based on environment. + * + * @param boolean $meta Metaconsole environment or not. + * @param boolean $history Historical data or not. + * + * @return string Table name. + */ function events_get_events_table($meta, $history) { if ($meta) { @@ -529,21 +648,30 @@ function events_get_events_table($meta, $history) /** * Comment events in a transresponse * - * @param mixed Event ID or array of events - * @param string comment to be registered - * @param string action performed with the comment. Bu default just Added comment - * @param bool Flag of metaconsole mode - * @param bool Flag of history mode + * @param mixed $id_event Event ID or array of events. + * @param string $comment Comment to be registered. + * @param string $action Action performed with comment. By default just add + * a comment. + * @param boolean $meta Flag of metaconsole mode. + * @param boolean $history Flag of history mode. + * @param boolean $similars Similars. * * @return boolean Whether or not it was successful */ -function events_comment($id_event, $comment='', $action='Added comment', $meta=false, $history=false, $similars=true) -{ +function events_comment( + $id_event, + $comment='', + $action='Added comment', + $meta=false, + $history=false, + $similars=true +) { global $config; $event_table = events_get_events_table($meta, $history); - // Cleans up the selection for all unwanted values also casts any single values as an array + // Cleans up the selection for all unwanted values also casts any single + // values as an array. $id_event = (array) safe_int($id_event, 1); foreach ($id_event as $k => $id) { @@ -564,25 +692,30 @@ function events_comment($id_event, $comment='', $action='Added comment', $meta=f return false; } - // If the event hasn't owner, assign the user as owner + // If the event hasn't owner, assign the user as owner. events_change_owner($id_event); - // Get the current event comments + // Get the current event comments. $first_event = $id_event; if (is_array($id_event)) { $first_event = reset($id_event); } - $event_comments = db_get_value('user_comment', $event_table, 'id_evento', $first_event); + $event_comments = db_get_value( + 'user_comment', + $event_table, + 'id_evento', + $first_event + ); $event_comments_array = []; if ($event_comments == '') { $comments_format = 'new'; } else { - // If comments are not stored in json, the format is old + // If comments are not stored in json, the format is old. $event_comments_array = json_decode($event_comments); - if (is_null($event_comments_array)) { + if (empty($event_comments_array)) { $comments_format = 'old'; } else { $comments_format = 'new'; @@ -600,12 +733,17 @@ function events_comment($id_event, $comment='', $action='Added comment', $meta=f $event_comments = io_json_mb_encode($event_comments_array); - // Update comment - $ret = db_process_sql_update($event_table, ['user_comment' => $event_comments], ['id_evento' => implode(',', $id_event)]); + // Update comment. + $ret = db_process_sql_update( + $event_table, + ['user_comment' => $event_comments], + ['id_evento' => implode(',', $id_event)] + ); break; case 'old': - // Give old ugly format to comment. TODO: Change this method for aux table or json + // Give old ugly format to comment. TODO: Change this method for + // aux table or json. $comment = str_replace(["\r\n", "\r", "\n"], '
    ', $comment); if ($comment != '') { @@ -614,30 +752,26 @@ function events_comment($id_event, $comment='', $action='Added comment', $meta=f $commentbox = ''; } - // Don't translate 'by' word because if various users with different languages - // make comments in the same console will be a mess - $comment = '-- '.$action.' by '.$config['id_user'].' '.'['.date($config['date_format']).'] --
    '.$commentbox.'
    '; + // Don't translate 'by' word because if multiple users with + // different languages make comments in the same console + // will be a mess. + $comment = '-- '.$action.' by '.$config['id_user'].' ['.date($config['date_format']).'] --
    '.$commentbox.'
    '; - // Update comment - switch ($config['dbtype']) { - // Oldstyle SQL to avoid innecesary PHP foreach - case 'mysql': - $sql_validation = "UPDATE $event_table - SET user_comment = concat('".$comment."', user_comment) - WHERE id_evento in (".implode(',', $id_event).')'; + // Update comment. + $sql_validation = sprintf( + 'UPDATE %s + SET user_comment = concat("%s", user_comment) + WHERE id_evento in (%s)', + $event_table, + $comment, + implode(',', $id_event) + ); - $ret = db_process_sql($sql_validation); - break; + $ret = db_process_sql($sql_validation); + break; - case 'postgresql': - case 'oracle': - $sql_validation = "UPDATE $event_table - SET user_comment='".$comment."' || user_comment) - WHERE id_evento in (".implode(',', $id_event).')'; - - $ret = db_process_sql($sql_validation); - break; - } + default: + // Ignore. break; } @@ -652,13 +786,18 @@ function events_comment($id_event, $comment='', $action='Added comment', $meta=f /** * Get group id of an event. * - * @param integer $id_event Event id + * @param integer $id_event Event id. * * @return integer Group id of the given event. */ function events_get_group($id_event) { - return (int) db_get_value('id_grupo', 'tevento', 'id_evento', (int) $id_event); + return (int) db_get_value( + 'id_grupo', + 'tevento', + 'id_evento', + (int) $id_event + ); } @@ -671,24 +810,37 @@ function events_get_group($id_event) */ function events_get_description($id_event) { - return (string) db_get_value('evento', 'tevento', 'id_evento', (int) $id_event); + return (string) db_get_value( + 'evento', + 'tevento', + 'id_evento', + (int) $id_event + ); } /** * Insert a event in the event log system. * - * @param integer $event - * @param integer $id_group - * @param integer $id_agent - * @param integer $status - * @param string $id_user - * @param string $event_type - * @param integer $priority - * @param integer $id_agent_module - * @param integer $id_aam + * @param integer $event Event. + * @param integer $id_group Id_group. + * @param integer $id_agent Id_agent. + * @param integer $status Status. + * @param string $id_user Id_user. + * @param string $event_type Event_type. + * @param integer $priority Priority. + * @param integer $id_agent_module Id_agent_module. + * @param integer $id_aam Id_aam. + * @param string $critical_instructions Critical_instructions. + * @param string $warning_instructions Warning_instructions. + * @param string $unknown_instructions Unknown_instructions. + * @param boolean $source Source. + * @param string $tags Tags. + * @param string $custom_data Custom_data. + * @param integer $server_id Server_id. + * @param string $id_extra Id_extra. * - * @return integer event id + * @return integer Event id. */ function events_create_event( $event, @@ -719,206 +871,64 @@ function events_create_event( if (defined('METACONSOLE')) { $table_events = 'tmetaconsole_event'; - switch ($config['dbtype']) { - case 'mysql': - $sql = sprintf( - ' - INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, - timestamp, estado, utimestamp, id_usuario, - event_type, criticity, id_agentmodule, id_alert_am, - critical_instructions, warning_instructions, - unknown_instructions, source, tags, custom_data, - server_id, id_extra, data, module_status) - VALUES (%d, %d, "%s", NOW(), %d, UNIX_TIMESTAMP(NOW()), - "%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s", - "%s", "%s", %d, "%s", %d, %d)', - $id_agent, - $id_group, - $event, - $status, - $id_user, - $event_type, - $priority, - $id_agent_module, - $id_aam, - $critical_instructions, - $warning_instructions, - $unknown_instructions, - $source, - $tags, - $custom_data, - $server_id, - $id_extra, - $data, - $module_status - ); - break; - - case 'postgresql': - $sql = sprintf( - ' - INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, - timestamp, estado, utimestamp, id_usuario, - event_type, criticity, id_agentmodule, id_alert_am, - critical_instructions, warning_instructions, - unknown_instructions, source, tags, custom_data, - server_id, id_extra, data, module_status) - VALUES (%d, %d, "%s", NOW(), %d, - ceil(date_part(\'epoch\', CURRENT_TIMESTAMP)), "%s", - "%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s", - "%s", %d, "%s", %d, %d)', - $id_agent, - $id_group, - $event, - $status, - $id_user, - $event_type, - $priority, - $id_agent_module, - $id_aam, - $critical_instructions, - $warning_instructions, - $unknown_instructions, - $source, - $tags, - $custom_data, - $server_id, - $id_extra, - $data, - $module_status - ); - break; - - case 'oracle': - $sql = sprintf( - ' - INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, - timestamp, estado, utimestamp, id_usuario, - event_type, criticity, id_agentmodule, id_alert_am, - critical_instructions, warning_instructions, - unknown_instructions, source, tags, custom_data, - server_id, id_extra, data, module_status) - VALUES (%d, %d, "%s", CURRENT_TIMESTAMP, %d, UNIX_TIMESTAMP, - "%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s", - "%s", "%s", %d, "%s", %d, %d)', - $id_agent, - $id_group, - $event, - $status, - $id_user, - $event_type, - $priority, - $id_agent_module, - $id_aam, - $critical_instructions, - $warning_instructions, - $unknown_instructions, - $source, - $tags, - $custom_data, - $server_id, - $id_extra, - $data, - $module_status - ); - break; - } + $sql = sprintf( + 'INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, + timestamp, estado, utimestamp, id_usuario, + event_type, criticity, id_agentmodule, id_alert_am, + critical_instructions, warning_instructions, + unknown_instructions, source, tags, custom_data, + server_id, id_extra, data, module_status) + VALUES (%d, %d, "%s", NOW(), %d, UNIX_TIMESTAMP(NOW()), + "%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s", + "%s", "%s", %d, "%s", %d, %d)', + $id_agent, + $id_group, + $event, + $status, + $id_user, + $event_type, + $priority, + $id_agent_module, + $id_aam, + $critical_instructions, + $warning_instructions, + $unknown_instructions, + $source, + $tags, + $custom_data, + $server_id, + $id_extra, + $data, + $module_status + ); } else { - switch ($config['dbtype']) { - case 'mysql': - $sql = sprintf( - ' - INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, - timestamp, estado, utimestamp, id_usuario, - event_type, criticity, id_agentmodule, id_alert_am, - critical_instructions, warning_instructions, - unknown_instructions, source, tags, custom_data, id_extra, data, module_status) - VALUES (%d, %d, "%s", NOW(), %d, UNIX_TIMESTAMP(NOW()), - "%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s", "%s", "%s", %d, %d)', - $id_agent, - $id_group, - $event, - $status, - $id_user, - $event_type, - $priority, - $id_agent_module, - $id_aam, - $critical_instructions, - $warning_instructions, - $unknown_instructions, - $source, - $tags, - $custom_data, - $id_extra, - $data, - $module_status - ); - break; - - case 'postgresql': - $sql = sprintf( - ' - INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, - timestamp, estado, utimestamp, id_usuario, - event_type, criticity, id_agentmodule, id_alert_am, - critical_instructions, warning_instructions, - unknown_instructions, source, tags, custom_data, id_extra, data, module_status) - VALUES (%d, %d, "%s", NOW(), %d, - ceil(date_part(\'epoch\', CURRENT_TIMESTAMP)), "%s", - "%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s", "%s", "%s", %d, %d)', - $id_agent, - $id_group, - $event, - $status, - $id_user, - $event_type, - $priority, - $id_agent_module, - $id_aam, - $critical_instructions, - $warning_instructions, - $unknown_instructions, - $source, - $tags, - $custom_data, - $id_extra, - $data, - $module_status - ); - break; - - case 'oracle': - $sql = sprintf( - ' - INSERT INTO '.$table_events." (id_agente, id_grupo, evento, - timestamp, estado, utimestamp, id_usuario, - event_type, criticity, id_agentmodule, id_alert_am, - critical_instructions, warning_instructions, - unknown_instructions, source, tags, custom_data, id_extra, data, module_status) - VALUES (%d, %d, '%s', CURRENT_TIMESTAMP, %d, UNIX_TIMESTAMP, - '%s', '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)", - $id_agent, - $id_group, - $event, - $status, - $id_user, - $event_type, - $priority, - $id_agent_module, - $id_aam, - $critical_instructions, - $warning_instructions, - $unknown_instructions, - $source, - $tags, - $custom_data, - $id_extra, - $data, - $module_status - ); - break; - } + $sql = sprintf( + 'INSERT INTO '.$table_events.' (id_agente, id_grupo, evento, + timestamp, estado, utimestamp, id_usuario, + event_type, criticity, id_agentmodule, id_alert_am, + critical_instructions, warning_instructions, + unknown_instructions, source, tags, custom_data, id_extra, data, module_status) + VALUES (%d, %d, "%s", NOW(), %d, UNIX_TIMESTAMP(NOW()), + "%s", "%s", %d, %d, %d, "%s", "%s", "%s", "%s", "%s", "%s", "%s", %d, %d)', + $id_agent, + $id_group, + $event, + $status, + $id_user, + $event_type, + $priority, + $id_agent_module, + $id_aam, + $critical_instructions, + $warning_instructions, + $unknown_instructions, + $source, + $tags, + $custom_data, + $id_extra, + $data, + $module_status + ); } return (int) db_process_sql($sql, 'insert_id'); @@ -926,24 +936,32 @@ function events_create_event( /** - * Prints a small event table + * Prints a small event table. * - * @param string $filter SQL WHERE clause - * @param integer $limit How many events to show - * @param integer $width How wide the table should be - * @param boolean $return Prints out HTML if false - * @param int agent id if is the table of one agent. 0 otherwise + * @param string $filter SQL WHERE clause. + * @param integer $limit How many events to show. + * @param integer $width How wide the table should be. + * @param boolean $return Prints out HTML if false. + * @param integer $agent_id Agent id if is the table of one agent. + * 0 otherwise. + * @param boolean $tactical_view Be shown in tactical view or not. * - * @return string HTML with table element + * @return string HTML with table element. */ -function events_print_event_table($filter='', $limit=10, $width=440, $return=false, $agent_id=0, $tactical_view=false) -{ +function events_print_event_table( + $filter='', + $limit=10, + $width=440, + $return=false, + $agent_id=0, + $tactical_view=false +) { global $config; if ($agent_id == 0) { $agent_condition = ''; } else { - $agent_condition = " id_agente = $agent_id AND "; + $agent_condition = ' id_agente = '.$agent_id.' AND '; } if ($filter == '') { @@ -991,7 +1009,9 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal $table->cellclass = []; $table->data = []; $table->align = []; - $table->style[0] = $table->style[1] = $table->style[2] = 'width:25px;'; + $table->style[0] = 'width:25px;'; + $table->style[1] = 'width:25px;'; + $table->style[2] = 'width:25px;'; if ($agent_id == 0) { $table->style[3] = 'word-break: break-all;'; } @@ -1026,7 +1046,7 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal } foreach ($result as $event) { - // Copy all groups of the agent and append the event group + // Copy all groups of the agent and append the event group. $check_events = $all_groups; $check_events[] = $event['id_grupo']; if (! check_acl_one_of_groups($config['id_user'], $check_events, 'ER')) { @@ -1035,7 +1055,7 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal $data = []; - // Colored box + // Colored box. switch ($event['estado']) { case 0: $img = 'images/star.png'; @@ -1051,6 +1071,10 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal $img = 'images/hourglass.png'; $title = __('Event in process'); break; + + default: + // Ignore. + break; } $data[0] = html_print_image( @@ -1095,20 +1119,25 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal ] ); - // Event type + // Event type. $data[2] = events_print_type_img($event['event_type'], true); - // Event text - $data[3] = ui_print_string_substr(strip_tags(io_safe_output($event['evento'])), 75, true, '7.5'); + // Event text. + $data[3] = ui_print_string_substr( + strip_tags(io_safe_output($event['evento'])), + 75, + true, + '7.5' + ); if ($agent_id == 0) { if ($event['id_agente'] > 0) { - // Agent name - // Get class name, for the link color... + // Agent name. + // Get class name, for the link color, etc. $myclass = get_priority_class($event['criticity']); - $data[4] = "".agents_get_alias($event['id_agente']).''; - // for System or SNMP generated alerts + $data[4] = "".agents_get_alias($event['id_agente']).''; + // For System or SNMP generated alerts. } else if ($event['event_type'] == 'system') { $data[4] = __('System'); } else { @@ -1116,13 +1145,21 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal } } - // Timestamp + // Timestamp. $data[5] = ui_print_timestamp($event['timestamp'], true, ['style' => 'font-size: 7.5pt; letter-spacing: 0.3pt;']); $class = get_priority_class($event['criticity']); - $cell_classes[3] = $cell_classes[4] = $cell_classes[5] = $class; + $cell_classes[3] = $class; + $cell_classes[4] = $class; + $cell_classes[5] = $class; + array_push($table->cellclass, $cell_classes); - // array_push ($table->rowclass, get_priority_class ($event["criticity"])); + + /* + Commented out (old). + // array_push ($table->rowclass, get_priority_class ($event["criticity"])); + */ + array_push($table->data, $data); } @@ -1162,16 +1199,19 @@ function events_print_event_table($filter='', $limit=10, $width=440, $return=fal /** - * Prints the event type image + * Prints the event type image. * - * @param string $type Event type from SQL - * @param boolean $return Whether to return or print + * @param string $type Event type from SQL. + * @param boolean $return Whether to return or print. * @param boolean $only_url Flag to return only url of image, by default false. * - * @return string HTML with img + * @return string HTML with img. */ -function events_print_type_img($type, $return=false, $only_url=false) -{ +function events_print_type_img( + $type, + $return=false, + $only_url=false +) { global $config; $output = ''; @@ -1189,13 +1229,13 @@ function events_print_type_img($type, $return=false, $only_url=false) case 'going_down_critical': case 'going_up_critical': - // This is to be backwards compatible + // This is to be backwards compatible. $icon = 'module_critical.png'; break; case 'going_up_normal': case 'going_down_normal': - // This is to be backwards compatible + // This is to be backwards compatible. $icon = 'module_ok.png'; break; @@ -1235,7 +1275,7 @@ function events_print_type_img($type, $return=false, $only_url=false) } if ($only_url) { - $output = $urlImage.'/'.'images/'.$icon; + $output = $urlImage.'/images/'.$icon; } else { $output .= html_print_image( 'images/'.$icon, @@ -1255,8 +1295,8 @@ function events_print_type_img($type, $return=false, $only_url=false) /** * Prints the event type description * - * @param string $type Event type from SQL - * @param boolean $return Whether to return or print + * @param string $type Event type from SQL. + * @param boolean $return Whether to return or print. * * @return string HTML with img */ @@ -1283,13 +1323,13 @@ function events_print_type_description($type, $return=false) case 'going_down_critical': case 'going_up_critical': - // This is to be backwards compatible + // This is to be backwards compatible. $output .= __('Going up to critical state'); break; case 'going_up_normal': case 'going_down_normal': - // This is to be backwards compatible + // This is to be backwards compatible. $output .= __('Going up to normal state'); break; @@ -1306,7 +1346,7 @@ function events_print_type_description($type, $return=false) break; case 'recon_host_detected'; - $output .= __('Recon server detected a new host'); + $output .= __('Discovery server detected a new host'); break; case 'new_agent'; @@ -1344,9 +1384,15 @@ function events_print_type_description($type, $return=false) * * The returned events will be in the time interval ($date - $period, $date] * - * @param mixed $id_group Group id to get events for. - * @param integer $period Period of time in seconds to get events. - * @param integer $date Beginning date to get events. + * @param mixed $begin Begin. + * @param mixed $result Result. + * @param mixed $id_group Group id to get events for. + * @param integer $period Period in seconds to get events. + * @param integer $date Beginning date to get events. + * @param boolean $filter_event_validated Filter_event_validated. + * @param boolean $filter_event_critical Filter_event_critical. + * @param boolean $filter_event_warning Filter_event_warning. + * @param boolean $filter_event_no_validated Filter_event_no_validated. * * @return array An array with all the events happened. */ @@ -1366,7 +1412,7 @@ function events_get_group_events_steps( $id_group = groups_safe_acl($config['id_user'], $id_group, 'ER'); if (empty($id_group)) { - // An empty array means the user doesn't have access + // An empty array means the user doesn't have access. return false; } @@ -1420,9 +1466,20 @@ function events_get_group_events_steps( * * The returned events will be in the time interval ($date - $period, $date] * - * @param integer $id_agent Agent id to get events. - * @param integer $period Period of time in seconds to get events. - * @param integer $date Beginning date to get events. + * @param integer $id_agent Agent id to get events. + * @param integer $period Period in seconds to get events. + * @param integer $date Beginning date to get events. + * @param boolean $history History. + * @param boolean $show_summary_group Show_summary_group. + * @param boolean $filter_event_severity Filter_event_severity. + * @param boolean $filter_event_type Filter_event_type. + * @param boolean $filter_event_status Filter_event_status. + * @param boolean $filter_event_filter_search Filter_event_filter_search. + * @param boolean $id_group Id_group. + * @param boolean $events_group Events_group. + * @param boolean $id_agent_module Id_agent_module. + * @param boolean $events_module Events_module. + * @param boolean $id_server Id_server. * * @return array An array with all the events happened. */ @@ -1456,7 +1513,7 @@ function events_get_agent( $id_group = groups_safe_acl($config['id_user'], $id_group, 'ER'); if (empty($id_group)) { - // An empty array means the user doesn't have access + // An empty array means the user doesn't have access. return false; } } @@ -1485,6 +1542,7 @@ function events_get_agent( break; default: + // Ignore. break; } } @@ -1505,12 +1563,16 @@ function events_get_agent( case 3: $filter_event_status[$key] = ('0, 2'); default: + // Ignore. break; } } if (!$status_all) { - $sql_where .= ' AND estado IN ('.implode(', ', $filter_event_status).')'; + $sql_where .= ' AND estado IN ('.implode( + ', ', + $filter_event_status + ).')'; } } @@ -1519,10 +1581,10 @@ function events_get_agent( $type = []; foreach ($filter_event_type as $event_type) { if ($event_type != '') { - // If normal, warning, could be several (going_up_warning, going_down_warning... too complex - // for the user so for him is presented only "warning, critical and normal" + // If normal, warning, could be several (going_up_warning, going_down_warning... too complex. + // Shown to user only "warning, critical and normal". if ($event_type == 'warning' || $event_type == 'critical' || $event_type == 'normal') { - $type[] = " event_type LIKE '%$event_type%' "; + $type[] = " event_type LIKE '%".$event_type."%' "; } else if ($event_type == 'not_normal') { $type[] = " (event_type LIKE '%warning%' OR event_type LIKE '%critical%' OR event_type LIKE '%unknown%') "; } else if ($event_type != 'all') { @@ -1535,7 +1597,7 @@ function events_get_agent( } if (!empty($filter_event_filter_search)) { - $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%"'.' OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; + $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%" OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; } if ($events_group) { @@ -1729,6 +1791,8 @@ function events_get_severity_types($severity_id) /** * Return all descriptions of event status. * + * @param boolean $report Show in report or not. + * * @return array Status description array. */ function events_get_all_status($report=false) @@ -1781,6 +1845,10 @@ function events_get_status($status_id) case 3: $status_desc = __('Only not validated'); break; + + default: + // Ignore. + break; } return $status_desc; @@ -1800,10 +1868,10 @@ function events_check_event_filter_group($id_filter) $id_group = db_get_value('id_group_filter', 'tevent_filter', 'id_filter', $id_filter); $own_info = get_user_info($config['id_user']); - // Get group list that user has access + // Get group list that user has access. $groups_user = users_get_groups($config['id_user'], 'EW', $own_info['is_admin'], true); - // Permissions in any group allow to edit "All group" filters + // Permissions in any group allow to edit "All group" filters. if ($id_group == 0 && !empty($groups_user)) { return true; } @@ -1824,9 +1892,9 @@ function events_check_event_filter_group($id_filter) /** * Get a event filter. * - * @param int Filter id to be fetched. - * @param array Extra filter. - * @param array Fields to be fetched. + * @param integer $id_filter Filter id to be fetched. + * @param array $filter Extra filter. + * @param array $fields Fields to be fetched. * * @return array A event filter matching id and filter or false. */ @@ -1848,7 +1916,9 @@ function events_get_event_filter($id_filter, $filter=false, $fields=false) /** * Get a event filters in select format. * - * @param boolean If event filters are used for manage/view operations (non admin users can see group ALL for manage) # Fix + * @param boolean $manage If event filters are used for manage/view operations + * (non admin users can see group ALL for manage) # Fix. + * * @return array A event filter matching id and filter or false. */ function events_get_event_filter_select($manage=true) @@ -1895,13 +1965,20 @@ function events_get_event_filter_select($manage=true) } -// Events pages functions to load modal window with advanced view of an event. -// Called from include/ajax/events.php +/** + * Events pages functions to load modal window with advanced view of an event. + * Called from include/ajax/events.php. + * + * @param mixed $event Event. + * @param array $childrens_ids Children_ids. + * + * @return string HTML. + */ function events_page_responses($event, $childrens_ids=[]) { global $config; // - // Responses + // Responses. // $table_responses->cellspacing = 2; $table_responses->cellpadding = 2; @@ -1914,26 +1991,43 @@ function events_page_responses($event, $childrens_ids=[]) $table_responses->class = 'alternate rounded_cells'; if (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids)) { - // Owner + // Owner. $data = []; $data[0] = __('Change owner'); - // Owner change can be done to users that belong to the event group with ER permission + // Owner change can be done to users that belong to the event group + // with ER permission. $profiles_view_events = db_get_all_rows_filter('tperfil', ['event_view' => '1'], 'id_perfil'); foreach ($profiles_view_events as $k => $v) { $profiles_view_events[$k] = reset($v); } - // Juanma (05/05/2014) Fix : Propagate ACL hell! - $_user_groups = array_keys(users_get_groups($config['id_user'], 'ER', users_can_manage_group_all())); - $strict_user = db_get_value('strict_acl', 'tusuario', 'id_user', $config['id_user']); + // Juanma (05/05/2014) Fix : Propagate ACL. + $_user_groups = array_keys( + users_get_groups($config['id_user'], 'ER', users_can_manage_group_all()) + ); + $strict_user = db_get_value( + 'strict_acl', + 'tusuario', + 'id_user', + $config['id_user'] + ); if ($strict_user) { - $user_name = db_get_value('fullname', 'tusuario', 'id_user', $config['id_user']); + $user_name = db_get_value( + 'fullname', + 'tusuario', + 'id_user', + $config['id_user'] + ); $users = []; $users[0]['id_user'] = $config['id_user']; $users[0]['fullname'] = $user_name; } else { - $users = groups_get_users($_user_groups, ['id_perfil' => $profiles_view_events], true); + $users = groups_get_users( + $_user_groups, + ['id_perfil' => $profiles_view_events], + true + ); } foreach ($users as $u) { @@ -1943,24 +2037,52 @@ function events_page_responses($event, $childrens_ids=[]) if ($event['owner_user'] == '') { $owner_name = __('None'); } else { - $owner_name = db_get_value('fullname', 'tusuario', 'id_user', $event['owner_user']); + $owner_name = db_get_value( + 'fullname', + 'tusuario', + 'id_user', + $event['owner_user'] + ); $owners[$event['owner_user']] = $owner_name; } - $data[1] = html_print_select($owners, 'id_owner', $event['owner_user'], '', __('None'), -1, true); - $data[1] .= html_print_button(__('Update'), 'owner_button', false, 'event_change_owner();', 'class="sub next"', true); + $data[1] = html_print_select( + $owners, + 'id_owner', + $event['owner_user'], + '', + __('None'), + -1, + true + ); + $data[1] .= html_print_button( + __('Update'), + 'owner_button', + false, + 'event_change_owner();', + 'class="sub next"', + true + ); $table_responses->data[] = $data; } - // Status + // Status. $data = []; $data[0] = __('Change status'); $status_blocked = false; - if (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids)) { - // If the user has manager acls, the status can be changed to all possibilities always + if (tags_checks_event_acl( + $config['id_user'], + $event['id_grupo'], + 'EM', + $event['clean_tags'], + $childrens_ids + ) + ) { + // If the user has manager acls, the status can be changed to all + // possibilities always. $status = [ 0 => __('New'), 2 => __('In process'), @@ -1969,7 +2091,8 @@ function events_page_responses($event, $childrens_ids=[]) } else { switch ($event['estado']) { case 0: - // If the user hasnt manager acls and the event is new. The status can be changed + // If the user hasnt manager acls and the event is new. + // The status can be changed. $status = [ 2 => __('In process'), 1 => __('Validated'), @@ -1977,48 +2100,99 @@ function events_page_responses($event, $childrens_ids=[]) break; case 1: - // If the user hasnt manager acls and the event is validated. The status cannot be changed + // If the user hasnt manager acls and the event is validated. + // The status cannot be changed. $status = [1 => __('Validated')]; $status_blocked = true; break; case 2: - // If the user hasnt manager acls and the event is in process. The status only can be changed to validated + // If the user hasnt manager acls and the event is in process. + // The status only can be changed to validated. $status = [1 => __('Validated')]; break; + + default: + // Ignored. + break; } } - // The change status option will be enabled only when is possible change the status - $data[1] = html_print_select($status, 'estado', $event['estado'], '', '', 0, true, false, false, '', $status_blocked); + // The change status option will be enabled only when is possible change + // the status. + $data[1] = html_print_select( + $status, + 'estado', + $event['estado'], + '', + '', + 0, + true, + false, + false, + '', + $status_blocked + ); if (!$status_blocked) { - $data[1] .= html_print_button(__('Update'), 'status_button', false, 'event_change_status(\''.$event['similar_ids'].'\');', 'class="sub next"', true); + $data[1] .= html_print_button( + __('Update'), + 'status_button', + false, + 'event_change_status(\''.$event['similar_ids'].'\');', + 'class="sub next"', + true + ); } $table_responses->data[] = $data; - // Comments + // Comments. $data = []; $data[0] = __('Comment'); - $data[1] = html_print_button(__('Add comment'), 'comment_button', false, '$(\'#link_comments\').trigger(\'click\');', 'class="sub next"', true); + $data[1] = html_print_button( + __('Add comment'), + 'comment_button', + false, + '$(\'#link_comments\').trigger(\'click\');', + 'class="sub next"', + true + ); $table_responses->data[] = $data; - if (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids)) { - // Delete + if (tags_checks_event_acl( + $config['id_user'], + $event['id_grupo'], + 'EM', + $event['clean_tags'], + $childrens_ids + ) + ) { + // Delete. $data = []; $data[0] = __('Delete event'); $data[1] = '
    '; - $data[1] .= html_print_button(__('Delete event'), 'delete_button', false, 'if(!confirm(\''.__('Are you sure?').'\')) { return false; } this.form.submit();', 'class="sub cancel"', true); + $data[1] .= html_print_button( + __('Delete event'), + 'delete_button', + false, + 'if(!confirm(\''.__('Are you sure?').'\')) { return false; } this.form.submit();', + 'class="sub cancel"', + true + ); $data[1] .= html_print_input_hidden('delete', 1, true); - $data[1] .= html_print_input_hidden('validate_ids', $event['id_evento'], true); + $data[1] .= html_print_input_hidden( + 'validate_ids', + $event['id_evento'], + true + ); $data[1] .= ''; $table_responses->data[] = $data; } - // Custom responses + // Custom responses. $data = []; $data[0] = __('Custom responses'); @@ -2054,7 +2228,14 @@ function events_page_responses($event, $childrens_ids=[]) $server_id = 0; } - $data[1] .= html_print_button(__('Execute'), 'custom_response_button', false, 'execute_response('.$event['id_evento'].','.$server_id.')', "class='sub next'", true); + $data[1] .= html_print_button( + __('Execute'), + 'custom_response_button', + false, + 'execute_response('.$event['id_evento'].','.$server_id.')', + "class='sub next'", + true + ); } $table_responses->data[] = $data; @@ -2091,29 +2272,35 @@ function events_page_responses($event, $childrens_ids=[]) /** * Replace macros in the target of a response and return it. - * If server_id > 0, it's a metaconsole query. + * If server_id > 0, is a metaconsole query. * - * @param integer $event_id Event identifier. - * @param integer $response_id Event response identifier. - * @param integer $server_id Node identifier (for metaconsole). - * @param boolean $history Use the history database or not. + * @param integer $event_id Event_id. + * @param integer $response_id Response_id. + * @param integer $server_id Server_id. + * @param boolean $history History. * - * @return string The response text with the macros applied. + * @return string Target. */ function events_get_response_target( - int $event_id, - int $response_id, - int $server_id=0, - bool $history=false + $event_id, + $response_id, + $server_id, + $history=false ) { global $config; - // If server_id > 0, it's a metaconsole query. - $meta = $server_id > 0; + $event_response = db_get_row('tevent_response', 'id', $response_id); + + if ($server_id > 0) { + $meta = true; + } else { + $meta = false; + } + $event_table = events_get_events_table($meta, $history); + $event = db_get_row($event_table, 'id_evento', $event_id); - $event_response = db_get_row('tevent_response', 'id', $response_id); $target = io_safe_output($event_response['target']); // Substitute each macro. @@ -2130,7 +2317,7 @@ function events_get_response_target( } $ip = db_get_value_filter('direccion', $agente_table_name, $filter); - // If agent has not an IP, display N/A. + // If agent has not an ip, display N/A. if ($ip === false) { $ip = __('N/A'); } @@ -2201,7 +2388,11 @@ function events_get_response_target( } if (strpos($target, '_event_utimestamp_') !== false) { - $target = str_replace('_event_utimestamp_', $event['utimestamp'], $target); + $target = str_replace( + '_event_utimestamp_', + $event['utimestamp'], + $target + ); } if (strpos($target, '_event_date_') !== false) { @@ -2290,7 +2481,12 @@ function events_get_response_target( } if (strpos($target, '_group_custom_id_') !== false) { - $group_custom_id = db_get_value($dbh, 'SELECT custom_id FROM tgrupo WHERE id_grupo=?', $event['id_grupo']); + $group_custom_id = db_get_value_sql( + sprintf( + 'SELECT custom_id FROM tgrupo WHERE id_grupo=%s', + $event['id_grupo'] + ) + ); $event_st = events_display_status($event['estado']); $target = str_replace('_group_custom_id_', $group_custom_id, $target); } @@ -2303,21 +2499,23 @@ function events_get_response_target( } } - // This will replace the macro with the current logged user. - if (strpos($target, '_current_user_') !== false) { - $target = str_replace('_current_user_', $config['id_user'], $target); - } - return $target; } +/** + * Generates 'custom field' page for event viewer. + * + * @param array $event Event to be displayed. + * + * @return string HTML. + */ function events_page_custom_fields($event) { global $config; // - // Custom fields + // Custom fields. // $table->cellspacing = 2; $table->cellpadding = 2; @@ -2358,7 +2556,7 @@ function events_page_custom_fields($event) } foreach ($fields as $field) { - // Owner + // Owner. $data = []; $data[0] = $field['name']; @@ -2383,15 +2581,82 @@ function events_page_custom_fields($event) } +/** + * Retrieves extended information of given event. + * + * @param integer $id_evento Target event. + * + * @return mixed array Of extended events or false if error. + */ +function events_get_extended_events(int $id_evento) +{ + return db_get_all_rows_sql( + sprintf( + 'SELECT * FROM tevent_extended + WHERE id_evento=%d ORDER BY utimestamp DESC', + $id_evento + ) + ); + +} + + +/** + * Return if event has extended info or not. + * + * @param integer $id_event Target event. + * + * @return boolean Has extended info or not + */ +function events_has_extended_info(int $id_event) +{ + return (bool) db_get_value_sql( + sprintf( + 'SELECT count(*) as "n" FROM ( + SELECT * + FROM tevent_extended WHERE id_evento=%d LIMIT 1) t', + $id_event + ) + ); +} + + +/** + * Generates the 'related' page in event view. + * + * @param array $event To be displayed. + * @param string $server Server (if in metaconsole environment). + * + * @return string HTML to be displayed. + */ +function events_page_related($event, $server='') +{ + $html = ''; + + return $html; +} + + +/** + * Generates the 'details' page in event view. + * + * @param array $event To be displayed. + * @param string $server Server (if in metaconsole environment). + * + * @return string HTML to be displayed. + */ function events_page_details($event, $server='') { global $img_sev; global $config; - // If server is provided, get the hash parameters + // If server is provided, get the hash parameters. if (!empty($server) && defined('METACONSOLE')) { $hashdata = metaconsole_get_server_hashdata($server); - $hashstring = '&'.'loginhash=auto&'.'loginhash_data='.$hashdata.'&'.'loginhash_user='.str_rot13($config['id_user']); + $hashstring = '&loginhash=auto&loginhash_data='.$hashdata.'&loginhash_user='.str_rot13($config['id_user']); $serverstring = $server['server_url'].'/'; if (metaconsole_connect($server) !== NOERR) { @@ -2403,7 +2668,7 @@ function events_page_details($event, $server='') } // - // Details + // Details. // $table_details->width = '100%'; $table_details->data = []; @@ -2414,15 +2679,20 @@ function events_page_details($event, $server='') $table_details->style[1] = 'text-align: left; height: 23px;'; $table_details->class = 'alternate rounded_cells'; - switch ($event['event_type']) { + /* + * Useless switch. + + switch ($event['event_type']) { case 'going_unknown': case 'going_up_warning': case 'going_down_warning': case 'going_up_critical': case 'going_down_critical': - + default: + // Ignore. break; - } + } + */ if ($event['id_agente'] != 0) { $agent = db_get_row('tagente', 'id_agente', $event['id_agente']); @@ -2430,7 +2700,6 @@ function events_page_details($event, $server='') $agent = []; } - $data = []; $data[0] = __('Agent details'); $data[1] = empty($agent) ? ''.__('N/A').'' : ''; $table_details->data[] = $data; @@ -2439,9 +2708,24 @@ function events_page_details($event, $server='') $data = []; $data[0] = '
    '.__('Name').'
    '; if (can_user_access_node()) { - $data[1] = ui_print_agent_name($event['id_agente'], true, 'agent_medium', '', false, $serverstring, $hashstring, $agent['alias']); + $data[1] = ui_print_agent_name( + $event['id_agente'], + true, + 'agent_medium', + '', + false, + $serverstring, + $hashstring, + $agent['alias'] + ); } else { - $data[1] = ui_print_truncate_text($agent['alias'], 'agent_medium', true, true, true); + $data[1] = ui_print_truncate_text( + $agent['alias'], + 'agent_medium', + true, + true, + true + ); } $table_details->data[] = $data; @@ -2462,22 +2746,35 @@ function events_page_details($event, $server='') $data = []; $data[0] = '
    '.__('Last contact').'
    '; - $data[1] = $agent['ultimo_contacto'] == '1970-01-01 00:00:00' ? ''.__('N/A').'' : date_w_fixed_tz($agent['ultimo_contacto']); + $data[1] = ($agent['ultimo_contacto'] == '1970-01-01 00:00:00') ? ''.__('N/A').'' : date_w_fixed_tz($agent['ultimo_contacto']); $table_details->data[] = $data; $data = []; $data[0] = '
    '.__('Last remote contact').'
    '; - $data[1] = $agent['ultimo_contacto_remoto'] == '1970-01-01 00:00:00' ? ''.__('N/A').'' : date_w_fixed_tz($agent['ultimo_contacto_remoto']); + $data[1] = ($agent['ultimo_contacto_remoto'] == '1970-01-01 00:00:00') ? ''.__('N/A').'' : date_w_fixed_tz($agent['ultimo_contacto_remoto']); $table_details->data[] = $data; $data = []; $data[0] = '
    '.__('Custom fields').'
    '; - $data[1] = html_print_button(__('View custom fields'), 'custom_button', false, '$(\'#link_custom_fields\').trigger(\'click\');', 'class="sub next"', true); + $data[1] = html_print_button( + __('View custom fields'), + 'custom_button', + false, + '$(\'#link_custom_fields\').trigger(\'click\');', + 'class="sub next"', + true + ); $table_details->data[] = $data; } if ($event['id_agentmodule'] != 0) { - $module = db_get_row_filter('tagente_modulo', ['id_agente_modulo' => $event['id_agentmodule'], 'delete_pending' => 0]); + $module = db_get_row_filter( + 'tagente_modulo', + [ + 'id_agente_modulo' => $event['id_agentmodule'], + 'delete_pending' => 0, + ] + ); } else { $module = []; } @@ -2488,20 +2785,25 @@ function events_page_details($event, $server='') $table_details->data[] = $data; if (!empty($module)) { - // Module name + // Module name. $data = []; $data[0] = '
    '.__('Name').'
    '; $data[1] = $module['nombre']; $table_details->data[] = $data; - // Module group + // Module group. $data = []; $data[0] = '
    '.__('Module group').'
    '; $id_module_group = $module['id_module_group']; if ($id_module_group == 0) { $data[1] = __('No assigned'); } else { - $module_group = db_get_value('name', 'tmodule_group', 'id_mg', $id_module_group); + $module_group = db_get_value( + 'name', + 'tmodule_group', + 'id_mg', + $id_module_group + ); $data[1] = ''; $data[1] .= $module_group; $data[1] .= ''; @@ -2509,12 +2811,21 @@ function events_page_details($event, $server='') $table_details->data[] = $data; - // ACL + // ACL. $acl_graph = false; - $strict_user = (bool) db_get_value('strict_acl', 'tusuario', 'id_user', $config['id_user']); + $strict_user = (bool) db_get_value( + 'strict_acl', + 'tusuario', + 'id_user', + $config['id_user'] + ); if (!empty($agent['id_grupo'])) { - $acl_graph = check_acl($config['id_user'], $agent['id_grupo'], 'RR'); + $acl_graph = check_acl( + $config['id_user'], + $agent['id_grupo'], + 'RR' + ); } if ($acl_graph) { @@ -2527,9 +2838,16 @@ function events_page_details($event, $server='') } $graph_type = return_graphtype($module_type); - $url = ui_get_full_url('operation/agentes/stat_win.php', false, false, false); - $handle = dechex(crc32($module['id_agente_modulo'].$module['nombre'])); - $win_handle = "day_$handle"; + $url = ui_get_full_url( + 'operation/agentes/stat_win.php', + false, + false, + false + ); + $handle = dechex( + crc32($module['id_agente_modulo'].$module['nombre']) + ); + $win_handle = 'day_'.$handle; $graph_params = [ 'type' => $graph_type, @@ -2540,13 +2858,13 @@ function events_page_details($event, $server='') ]; if (defined('METACONSOLE')) { - // Set the server id + // Set the server id. $graph_params['server'] = $server['id']; } $graph_params_str = http_build_query($graph_params); - $link = "winopeng('$url?$graph_params_str','$win_handle')"; + $link = "winopeng('".$url.'?'.$graph_params_str."','".$win_handle."')"; $data[1] = ''; $data[1] .= html_print_image('images/chart_curve.png', true); @@ -2557,7 +2875,7 @@ function events_page_details($event, $server='') $data = []; $data[0] = __('Alert details'); - $data[1] = $event['id_alert_am'] == 0 ? ''.__('N/A').'' : ''; + $data[1] = ($event['id_alert_am'] == 0) ? ''.__('N/A').'' : ''; $table_details->data[] = $data; if ($event['id_alert_am'] != 0) { @@ -2648,12 +2966,19 @@ function events_page_details($event, $server='') } +/** + * Generates content for 'custom data' page in event viewer. + * + * @param array $event Event. + * + * @return string HTML. + */ function events_page_custom_data($event) { global $config; // - // Custom data + // Custom data. // if ($event['custom_data'] == '') { return ''; @@ -2685,14 +3010,26 @@ function events_page_custom_data($event) } -// Get the event name from tevento and display it in console +/** + * Get the event name from tevento and display it in console. + * + * @param string $db_name Target event name. + * + * @return string Event name. + */ function events_display_name($db_name='') { return io_safe_output(str_replace(' ', '
    ', $db_name)); } -// Get the image and status value of event +/** + * Get the image and status value of event. + * + * @param integer $status Status. + * + * @return string Image path. + */ function events_display_status($status) { switch ($status) { @@ -2713,15 +3050,26 @@ function events_display_status($status) 'img' => 'images/hourglass.png', 'title' => __('Event in process'), ]; + + default: + // Ignore. + break; } } -// Get the instruction of an event -// $event_type: Type of event -// $inst: Array with unknown warning and critical instructions -// $italic: Display N/A between italic html marks if instruction is not found -function events_display_instructions($event_type='', $inst, $italic=true) +/** + * Get the instruction of an event. + * + * @param string $event_type Type of event. + * @param array $inst Array with unknown warning and critical + * instructions. + * @param boolean $italic Display N/A between italic html marks if + * instruction is not found. + * + * @return string Safe output. + */ +function events_display_instructions($event_type='', $inst=[], $italic=true) { switch ($event_type) { case 'going_unknown': @@ -2758,23 +3106,39 @@ function events_display_instructions($event_type='', $inst, $italic=true) return str_replace("\n", '
    ', io_safe_output($inst['unknown_instructions'])); } break; + + default: + // Ignore. + break; } - $na_return = $italic ? ''.__('N/A').'' : __('N/A'); + $na_return = ($italic === true) ? ''.__('N/A').'' : __('N/A'); + return $na_return; } +/** + * Generates 'general' page for events viewer. + * + * @param array $event Event. + * + * @return string HTML. + */ function events_page_general($event) { global $img_sev; global $config; - // $group_rep = $event['similar_ids'] == -1 ? 1 : count(explode(',',$event['similar_ids'])); + /* + Commented out (old) + // $group_rep = $event['similar_ids'] == -1 ? 1 : count(explode(',',$event['similar_ids'])); + */ + global $group_rep; // - // General + // General. // $table_general->cellspacing = 2; $table_general->cellpadding = 2; @@ -2825,7 +3189,10 @@ function events_page_general($event) $data = []; $data[0] = __('Type'); - $data[1] = events_print_type_img($event['event_type'], true).' '.events_print_type_description($event['event_type'], true); + $data[1] = events_print_type_img( + $event['event_type'], + true + ).' '.events_print_type_description($event['event_type'], true); $table_general->data[] = $data; $data = []; @@ -2859,7 +3226,7 @@ function events_page_general($event) $data[1] .= ' '.$event_criticity; $table_general->data[] = $data; - // Get Status + // Get Status. $event_st = events_display_status($event['estado']); $data = []; @@ -2867,7 +3234,7 @@ function events_page_general($event) $data[1] = html_print_image($event_st['img'], true).' '.$event_st['title']; $table_general->data[] = $data; - // If event is validated, show who and when acknowleded it + // If event is validated, show who and when acknowleded it. $data = []; $data[0] = __('Acknowledged by'); @@ -2924,10 +3291,18 @@ function events_page_general($event) } +/** + * Generate 'comments' page for event viewer. + * + * @param array $event Event. + * @param array $childrens_ids Children ids. + * + * @return string HTML. + */ function events_page_comments($event, $childrens_ids=[]) { // - // Comments + // Comments. // global $config; @@ -2941,13 +3316,13 @@ function events_page_comments($event, $childrens_ids=[]) $event_comments = $event['user_comment']; $event_comments = str_replace(["\n", ' '], '
    ', $event_comments); - // If comments are not stored in json, the format is old + // If comments are not stored in json, the format is old. $event_comments_array = json_decode($event_comments, true); - // Show the comments more recent first + // Show the comments more recent first. $event_comments_array = array_reverse($event_comments_array); - if (is_null($event_comments_array)) { + if (empty($event_comments_array)) { $comments_format = 'old'; } else { $comments_format = 'new'; @@ -2974,7 +3349,7 @@ function events_page_comments($event, $childrens_ids=[]) case 'old': $comments_array = explode('
    ', $event_comments); - // Split comments and put in table + // Split comments and put in table. $col = 0; $data = []; @@ -2990,6 +3365,10 @@ function events_page_comments($event, $childrens_ids=[]) case 1: $row_text = preg_replace("/[\r\n|\r|\n]/", '
    ', io_safe_output(strip_tags($c))); break; + + default: + // Ignore. + break; } $data[$col] = $row_text; @@ -3011,14 +3390,33 @@ function events_page_comments($event, $childrens_ids=[]) $table_comments->data[] = $data; } break; + + default: + // Ignore. + break; } - if (((tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids)) || (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EW', $event['clean_tags'], $childrens_ids))) && $config['show_events_in_local'] == false || $config['event_replication'] == false) { + if (((tags_checks_event_acl( + $config['id_user'], + $event['id_grupo'], + 'EM', + $event['clean_tags'], + $childrens_ids + )) || (tags_checks_event_acl( + $config['id_user'], + $event['id_grupo'], + 'EW', + $event['clean_tags'], + $childrens_ids + ))) && $config['show_events_in_local'] == false || $config['event_replication'] == false + ) { $comments_form = '
    '.html_print_textarea('comment', 3, 10, '', 'style="min-height: 15px; width: 100%; disabled"', true); $comments_form .= '
    '.html_print_button(__('Add comment'), 'comment_button', false, 'event_comment();', 'class="sub next"', true).'

    '; } else { - $comments_form = ui_print_message(__('If event replication is ongoing, it won\'t be possible to enter comments here. This option is only to allow local pandora users to see comments, but not to operate with them. The operation, when event replication is enabled, must be done only in the Metaconsole.')); + $comments_form = ui_print_message( + __('If event replication is ongoing, it won\'t be possible to enter comments here. This option is only to allow local pandora users to see comments, but not to operate with them. The operation, when event replication is enabled, must be done only in the Metaconsole.') + ); } $comments = '
    '.$comments_form.html_print_table($table_comments, true).'
    '; @@ -3027,6 +3425,13 @@ function events_page_comments($event, $childrens_ids=[]) } +/** + * Retrieve event tags (cleaned). + * + * @param string $tags Tags. + * + * @return array of Tags. + */ function events_clean_tags($tags) { if (empty($tags)) { @@ -3043,9 +3448,14 @@ function events_clean_tags($tags) * * The returned events will be in the time interval ($date - $period, $date] * - * @param mixed $id_group Group id to get events for. - * @param integer $period Period of time in seconds to get events. - * @param integer $date Beginning date to get events. + * @param mixed $id_group Group id to get events for. + * @param integer $period Period in seconds to get events. + * @param integer $date Beginning date to get events. + * @param boolean $filter_event_severity Filter_event_severity. + * @param boolean $filter_event_type Filter_event_type. + * @param boolean $filter_event_status Filter_event_status. + * @param boolean $filter_event_filter_search Filter_event_filter_search. + * @param boolean $dbmeta Dbmeta. * * @return array An array with all the events happened. */ @@ -3061,7 +3471,7 @@ function events_get_count_events_by_agent( ) { global $config; - // date + // Date. if (!is_numeric($date)) { $date = time_w_fixed_tz($date); } @@ -3070,11 +3480,11 @@ function events_get_count_events_by_agent( $date = get_system_time(); } - // group + // Group. $id_group = groups_safe_acl($config['id_user'], $id_group, 'AR'); if (empty($id_group)) { - // An empty array means the user doesn't have access + // An empty array means the user doesn't have access. return false; } @@ -3102,6 +3512,7 @@ function events_get_count_events_by_agent( break; default: + // Ignore. break; } } @@ -3122,6 +3533,7 @@ function events_get_count_events_by_agent( case 3: $filter_event_status[$key] = ('0, 2'); default: + // Ignore. break; } } @@ -3136,10 +3548,10 @@ function events_get_count_events_by_agent( $type = []; foreach ($filter_event_type as $event_type) { if ($event_type != '') { - // If normal, warning, could be several (going_up_warning, going_down_warning... too complex - // for the user so for him is presented only "warning, critical and normal" + // If normal, warning, could be several (going_up_warning, going_down_warning... too complex. + // Shown to user only "warning, critical and normal". if ($event_type == 'warning' || $event_type == 'critical' || $event_type == 'normal') { - $type[] = " event_type LIKE '%$event_type%' "; + $type[] = " event_type LIKE '%".$event_type."%' "; } else if ($event_type == 'not_normal') { $type[] = " (event_type LIKE '%warning%' OR event_type LIKE '%critical%' OR event_type LIKE '%unknown%') "; } else if ($event_type != 'all') { @@ -3152,7 +3564,7 @@ function events_get_count_events_by_agent( } if (!empty($filter_event_filter_search)) { - $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%"'.' OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; + $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%" OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; } $tagente = 'tagente'; @@ -3205,9 +3617,14 @@ function events_get_count_events_by_agent( * * The returned events will be in the time interval ($date - $period, $date] * - * @param mixed $id_group Group id to get events for. - * @param integer $period Period of time in seconds to get events. - * @param integer $date Beginning date to get events. + * @param array $filter Use target filter. + * @param integer $period Period in seconds to get events. + * @param integer $date Beginning date to get events. + * @param boolean $filter_event_severity Filter_event_severity. + * @param boolean $filter_event_type Filter_event_type. + * @param boolean $filter_event_status Filter_event_status. + * @param boolean $filter_event_filter_search Filter_event_filter_search. + * @param boolean $dbmeta Dbmeta. * * @return array An array with all the events happened. */ @@ -3222,13 +3639,13 @@ function events_get_count_events_validated_by_user( $dbmeta=false ) { global $config; - // group + // Group. $sql_filter = ' AND 1=1 '; if (isset($filter['id_group'])) { $id_group = groups_safe_acl($config['id_user'], $filter['id_group'], 'AR'); if (empty($id_group)) { - // An empty array means the user doesn't have access + // An empty array means the user doesn't have access. return false; } @@ -3243,7 +3660,7 @@ function events_get_count_events_validated_by_user( $sql_filter .= sprintf(' AND id_agentmodule = %d ', $filter['id_agentmodule']); } - // date + // Date. if (!is_numeric($date)) { $date = time_w_fixed_tz($date); } @@ -3276,6 +3693,7 @@ function events_get_count_events_validated_by_user( break; default: + // Ignore. break; } } @@ -3296,6 +3714,7 @@ function events_get_count_events_validated_by_user( case 3: $filter_event_status[$key] = ('0, 2'); default: + // Ignore. break; } } @@ -3310,10 +3729,10 @@ function events_get_count_events_validated_by_user( $type = []; foreach ($filter_event_type as $event_type) { if ($event_type != '') { - // If normal, warning, could be several (going_up_warning, going_down_warning... too complex - // for the user so for him is presented only "warning, critical and normal" + // If normal, warning, could be several (going_up_warning, going_down_warning... too complex. + // Shown to user only "warning, critical and normal". if ($event_type == 'warning' || $event_type == 'critical' || $event_type == 'normal') { - $type[] = " event_type LIKE '%$event_type%' "; + $type[] = " event_type LIKE '%".$event_type."%' "; } else if ($event_type == 'not_normal') { $type[] = " (event_type LIKE '%warning%' OR event_type LIKE '%critical%' OR event_type LIKE '%unknown%') "; } else if ($event_type != 'all') { @@ -3326,7 +3745,7 @@ function events_get_count_events_validated_by_user( } if (!empty($filter_event_filter_search)) { - $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%"'.' OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; + $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%" OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; } $tevento = 'tevento'; @@ -3375,9 +3794,14 @@ function events_get_count_events_validated_by_user( * * The returned events will be in the time interval ($date - $period, $date] * - * @param mixed $id_group Group id to get events for. - * @param integer $period Period of time in seconds to get events. - * @param integer $date Beginning date to get events. + * @param mixed $filter Target filter. + * @param integer $period Period in seconds to get events. + * @param integer $date Beginning date to get events. + * @param boolean $filter_event_severity Filter_event_severity. + * @param boolean $filter_event_type Filter_event_type. + * @param boolean $filter_event_status Filter_event_status. + * @param boolean $filter_event_filter_search Filter_event_filter_search. + * @param boolean $dbmeta Dbmeta. * * @return array An array with all the events happened. */ @@ -3398,7 +3822,7 @@ function events_get_count_events_by_criticity( $id_group = groups_safe_acl($config['id_user'], $filter['id_group'], 'AR'); if (empty($id_group)) { - // An empty array means the user doesn't have access + // An empty array means the user doesn't have access. return false; } @@ -3445,6 +3869,7 @@ function events_get_count_events_by_criticity( break; default: + // Ignore. break; } } @@ -3464,7 +3889,10 @@ function events_get_count_events_by_criticity( case 3: $filter_event_status[$key] = ('0, 2'); + break; + default: + // Ignored. break; } } @@ -3479,10 +3907,10 @@ function events_get_count_events_by_criticity( $type = []; foreach ($filter_event_type as $event_type) { if ($event_type != '') { - // If normal, warning, could be several (going_up_warning, going_down_warning... too complex - // for the user so for him is presented only "warning, critical and normal" + // If normal, warning, could be several (going_up_warning, going_down_warning... too complex. + // Shown to user only "warning, critical and normal". if ($event_type == 'warning' || $event_type == 'critical' || $event_type == 'normal') { - $type[] = " event_type LIKE '%$event_type%' "; + $type[] = " event_type LIKE '%".$event_type."%' "; } else if ($event_type == 'not_normal') { $type[] = " (event_type LIKE '%warning%' OR event_type LIKE '%critical%' OR event_type LIKE '%unknown%') "; } else if ($event_type != 'all') { @@ -3495,7 +3923,7 @@ function events_get_count_events_by_criticity( } if (!empty($filter_event_filter_search)) { - $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%"'.' OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; + $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%" OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; } $tevento = 'tevento'; @@ -3537,9 +3965,14 @@ function events_get_count_events_by_criticity( * * The returned events will be in the time interval ($date - $period, $date] * - * @param mixed $id_group Group id to get events for. - * @param integer $period Period of time in seconds to get events. - * @param integer $date Beginning date to get events. + * @param mixed $filter Target filter. + * @param integer $period Period in seconds to get events. + * @param integer $date Beginning date to get events. + * @param boolean $filter_event_severity Filter_event_severity. + * @param boolean $filter_event_type Filter_event_type. + * @param boolean $filter_event_status Filter_event_status. + * @param boolean $filter_event_filter_search Filter_event_filter_search. + * @param boolean $dbmeta Dbmeta. * * @return array An array with all the events happened. */ @@ -3555,30 +3988,43 @@ function events_get_count_events_validated( ) { global $config; - // group + // Group. $sql_filter = ' 1=1 '; if (isset($filter['id_group'])) { - $id_group = groups_safe_acl($config['id_user'], $filter['id_group'], 'AR'); + $id_group = groups_safe_acl( + $config['id_user'], + $filter['id_group'], + 'AR' + ); if (empty($id_group)) { - // An empty array means the user doesn't have access + // An empty array means the user doesn't have access. return false; } - $sql_filter .= sprintf(' AND id_grupo IN (%s) ', implode(',', $id_group)); + $sql_filter .= sprintf( + ' AND id_grupo IN (%s) ', + implode(',', $id_group) + ); } - // agent + // Agent. if (!empty($filter['id_agent'])) { - $sql_filter .= sprintf(' AND id_agente = %d ', $filter['id_agent']); + $sql_filter .= sprintf( + ' AND id_agente = %d ', + $filter['id_agent'] + ); } - // module + // Module. if (!empty($filter['id_agentmodule'])) { - $sql_filter .= sprintf(' AND id_agentmodule = %d ', $filter['id_agentmodule']); + $sql_filter .= sprintf( + ' AND id_agentmodule = %d ', + $filter['id_agentmodule'] + ); } - // date + // Date. if (!is_numeric($date)) { $date = time_w_fixed_tz($date); } @@ -3631,6 +4077,7 @@ function events_get_count_events_validated( break; default: + // Ingore. break; } } @@ -3650,7 +4097,10 @@ function events_get_count_events_validated( case 3: $filter_event_status[$key] = ('0, 2'); + break; + default: + // Ignore. break; } } @@ -3665,10 +4115,10 @@ function events_get_count_events_validated( $type = []; foreach ($filter_event_type as $event_type) { if ($event_type != '') { - // If normal, warning, could be several (going_up_warning, going_down_warning... too complex - // for the user so for him is presented only "warning, critical and normal" + // If normal, warning, could be several (going_up_warning, going_down_warning... too complex. + // Shown to user only "warning, critical and normal". if ($event_type == 'warning' || $event_type == 'critical' || $event_type == 'normal') { - $type[] = " event_type LIKE '%$event_type%' "; + $type[] = " event_type LIKE '%".$event_type."%' "; } else if ($event_type == 'not_normal') { $type[] = " (event_type LIKE '%warning%' OR event_type LIKE '%critical%' OR event_type LIKE '%unknown%') "; } else if ($event_type != 'all') { @@ -3681,7 +4131,7 @@ function events_get_count_events_validated( } if (!empty($filter_event_filter_search)) { - $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%"'.' OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; + $sql_where .= ' AND (evento LIKE "%'.io_safe_input($filter_event_filter_search).'%" OR id_evento LIKE "%'.io_safe_input($filter_event_filter_search).'%")'; } $tevento = 'tevento'; @@ -3721,6 +4171,14 @@ function events_get_count_events_validated( } +/** + * Check event tags. + * + * @param array $event_data Event. + * @param array $acltags Acl tags. + * + * @return boolean True or false. + */ function events_checks_event_tags($event_data, $acltags) { global $config; @@ -3749,6 +4207,18 @@ function events_checks_event_tags($event_data, $acltags) } +/** + * Retrieves events grouped by agent. + * + * @param string $sql_post Sql_post. + * @param integer $offset Offset. + * @param integer $pagination Pagination. + * @param boolean $meta Meta. + * @param boolean $history History. + * @param boolean $total Total. + * + * @return array Data. + */ function events_get_events_grouped_by_agent( $sql_post, $offset=0, @@ -3771,23 +4241,23 @@ function events_get_events_grouped_by_agent( $event_lj = events_get_secondary_groups_left_join($table); if ($total) { - $sql = "SELECT COUNT(*) FROM (select id_agente from $table $event_lj WHERE 1=1 - $sql_post GROUP BY id_agente, event_type$groupby_extra ORDER BY id_agente ) AS t"; + $sql = 'SELECT COUNT(*) FROM (select id_agente from '.$table.' '.$event_lj.' WHERE 1=1 + '.$sql_post.' GROUP BY id_agente, event_type'.$groupby_extra.' ORDER BY id_agente ) AS t'; } else { - $sql = "select id_agente, count(*) as total$fields_extra from $table te $event_lj - WHERE id_agente > 0 $sql_post GROUP BY id_agente$groupby_extra ORDER BY id_agente LIMIT $offset,$pagination"; + $sql = 'select id_agente, count(*) as total'.$fields_extra.' from '.$table.' te '.$event_lj.' + WHERE id_agente > 0 '.$sql_post.' GROUP BY id_agente'.$groupby_extra.' ORDER BY id_agente LIMIT '.$offset.','.$pagination; } $result = []; - // Extract the events by filter (or not) from db + // Extract the events by filter (or not) from db. $events = db_get_all_rows_sql($sql); $result = []; if ($events) { foreach ($events as $event) { if ($meta) { - $sql = "select event_type from $table te $event_lj - WHERE agent_name = '".$event['agent_name']."' $sql_post ORDER BY utimestamp DESC "; + $sql = 'SELECT event_type FROM '.$table.' te '.$event_lj." + WHERE agent_name = '".$event['agent_name']."' ".$sql_post.' ORDER BY utimestamp DESC '; $resultado = db_get_row_sql($sql); $id_agente = $event['agent_name']; @@ -3798,8 +4268,8 @@ function events_get_events_grouped_by_agent( 'event_type' => $resultado['event_type'], ]; } else { - $sql = "SELECT event_type FROM $table te $event_lj - WHERE id_agente = ".$event['id_agente']." $sql_post ORDER BY utimestamp DESC "; + $sql = 'SELECT event_type FROM '.$table.' te '.$event_lj.' + WHERE id_agente = '.$event['id_agente'].' '.$sql_post.' ORDER BY utimestamp DESC '; $resultado = db_get_row_sql($sql); $id_agente = $event['id_agente']; @@ -3816,6 +4286,28 @@ function events_get_events_grouped_by_agent( } +/** + * Return SQL query to group events by agents. + * + * @param mixed $id_agent Id_agent. + * @param integer $server_id Server_id. + * @param string $event_type Event_type. + * @param integer $severity Severity. + * @param integer $status Status. + * @param string $search Search. + * @param integer $id_agent_module Id_agent_module. + * @param integer $event_view_hr Event_view_hr. + * @param boolean $id_user_ack Id_user_ack. + * @param array $tag_with Tag_with. + * @param array $tag_without Tag_without. + * @param boolean $filter_only_alert Filter_only_alert. + * @param string $date_from Date_from. + * @param string $date_to Date_to. + * @param boolean $id_user Id_user. + * @param boolean $server_id_search Server_id_search. + * + * @return string SQL. + */ function events_sql_events_grouped_agents( $id_agent, $server_id=-1, @@ -3853,17 +4345,21 @@ function events_sql_events_grouped_agents( case 3: $sql_post .= ' AND (estado = 0 OR estado = 2)'; break; + + default: + // Ignore. + break; } if ($search != '') { - $sql_post .= " AND (evento LIKE '%".io_safe_input($search)."%' OR id_evento LIKE '%$search%')"; + $sql_post .= " AND (evento LIKE '%".io_safe_input($search)."%' OR id_evento LIKE '%".$search."%')"; } if ($event_type != '') { // If normal, warning, could be several (going_up_warning, going_down_warning... too complex - // for the user so for him is presented only "warning, critical and normal" + // Shown to user only "warning, critical and normal". if ($event_type == 'warning' || $event_type == 'critical' || $event_type == 'normal') { - $sql_post .= " AND event_type LIKE '%$event_type%' "; + $sql_post .= " AND event_type LIKE '%".$event_type."%' "; } else if ($event_type == 'not_normal') { $sql_post .= " AND (event_type LIKE '%warning%' OR event_type LIKE '%critical%' OR event_type LIKE '%unknown%') "; } else if ($event_type != 'all') { @@ -3890,23 +4386,25 @@ function events_sql_events_grouped_agents( break; default: - $sql_post .= " AND criticity = $severity"; + $sql_post .= ' AND criticity = '.$severity; break; } } - // In metaconsole mode the agent search is performed by name + // In metaconsole mode the agent search is performed by name. if ($meta) { if ($id_agent != __('All')) { - $sql_post .= " AND agent_name LIKE '%$id_agent%'"; + $sql_post .= " AND agent_name LIKE '%".$id_agent."%'"; } } else { switch ($id_agent) { case 0: + // Ignore. + $__invalid_value = 1; break; case -1: - // Agent doesnt exist. No results will returned + // Agent doesnt exist. No results will returned. $sql_post .= ' AND 1 = 0'; break; @@ -3916,14 +4414,13 @@ function events_sql_events_grouped_agents( } } - if ($meta) { - // There is another filter. - } else { + // There is another filter for if ($meta). + if (!$meta) { if (!empty($text_module)) { $sql_post .= " AND id_agentmodule IN ( SELECT id_agente_modulo FROM tagente_modulo - WHERE nombre = '$text_module' + WHERE nombre = '".$text_module."' )"; } } @@ -3957,7 +4454,7 @@ function events_sql_events_grouped_agents( } } - // Search by tag + // Search by tag. if (!empty($tag_with) && (io_safe_output($tag_with) != '[]') && (io_safe_output($tag_with) != '["0"]')) { $sql_post .= ' AND ( '; $first = true; @@ -3990,7 +4487,7 @@ function events_sql_events_grouped_agents( $sql_post .= ' ) '; } - // Filter/Only alerts + // Filter/Only alerts. if (isset($filter_only_alert)) { if ($filter_only_alert == 0) { $sql_post .= " AND event_type NOT LIKE '%alert%'"; @@ -3999,7 +4496,7 @@ function events_sql_events_grouped_agents( } } - // Tags ACLS + // Tags ACLS. if ($id_group > 0 && in_array($id_group, array_keys($groups))) { $group_array = (array) $id_group; } else { @@ -4017,12 +4514,12 @@ function events_sql_events_grouped_agents( [], true ); - // FORCE CHECK SQL "(TAG = tag1 AND id_grupo = 1)" + // FORCE CHECK SQL "(TAG = tag1 AND id_grupo = 1)". if (($tags_acls_condition != ERR_WRONG_PARAMETERS) && ($tags_acls_condition != ERR_ACL) && ($tags_acls_condition != -110000)) { $sql_post .= $tags_acls_condition; } - // Metaconsole fitlers + // Metaconsole filters. if ($meta) { if ($server_id_search) { $sql_post .= ' AND server_id = '.$server_id_search; @@ -4056,29 +4553,40 @@ function events_sql_events_grouped_agents( } +/** + * Retrieve list of events grouped by agents. + * + * @param string $sql SQL. + * + * @return string HTML. + */ function events_list_events_grouped_agents($sql) { global $config; $table = events_get_events_table(is_metaconsole(), $history); - $sql = "select * from $table - LEFT JOIN tagent_secondary_group - ON tagent_secondary_group.id_agent = tevento.id_agente - WHERE $sql"; + $sql = sprintf( + 'SELECT * FROM %s + LEFT JOIN tagent_secondary_group + ON tagent_secondary_group.id_agent = tevento.id_agente + WHERE %s', + $table, + $sql + ); $result = db_get_all_rows_sql($sql); $group_rep = 0; $meta = is_metaconsole(); - // fields that the user has selected to show + // Fields that the user has selected to show. if ($meta) { $show_fields = events_meta_get_custom_fields_user(); } else { $show_fields = explode(',', $config['event_fields']); } - // headers + // Headers. $i = 0; $table = new stdClass(); if (!isset($table->width)) { @@ -4239,7 +4747,7 @@ function events_list_events_grouped_agents($sql) } if ($meta) { - // Get info of the all servers to use it on hash auth + // Get info of the all servers to use it on hash auth. $servers_url_hash = metaconsole_get_servers_url_hash(); $servers = metaconsole_get_servers(); } @@ -4248,7 +4756,7 @@ function events_list_events_grouped_agents($sql) $show_validate_button = false; $idx = 0; - // Arrange data. We already did ACL's in the query + // Arrange data. We already did ACL's in the query. foreach ($result as $event) { $data = []; @@ -4258,16 +4766,16 @@ function events_list_events_grouped_agents($sql) $event['server_name'] = $servers[$event['server_id']]['server_name']; } - // Clean url from events and store in array + // Clean url from events and store in array. $event['clean_tags'] = events_clean_tags($event['tags']); - // First pass along the class of this row + // First pass along the class of this row. $myclass = get_priority_class($event['criticity']); - // print status + // Print status. $estado = $event['estado']; - // Colored box + // Colored box. switch ($estado) { case EVENT_NEW: $img_st = 'images/star.png'; @@ -4283,6 +4791,10 @@ function events_list_events_grouped_agents($sql) $img_st = 'images/hourglass.png'; $title_st = __('Event in process'); break; + + default: + // Ignore. + break; } $i = 0; @@ -4290,7 +4802,7 @@ function events_list_events_grouped_agents($sql) $data[$i] = '#'.$event['id_evento']; $table->cellstyle[count($table->data)][$i] = 'background: #F3F3F3; color: #111 !important;'; - // Pass grouped values in hidden fields to use it from modal window + // Pass grouped values in hidden fields to use it from modal window. if ($group_rep) { $similar_ids = $event['similar_ids']; $timestamp_first = $event['timestamp_rep_min']; @@ -4301,17 +4813,17 @@ function events_list_events_grouped_agents($sql) $timestamp_last = $event['utimestamp']; } - // Store group data to show in extended view + // Store group data to show in extended view. $data[$i] .= html_print_input_hidden('similar_ids_'.$event['id_evento'], $similar_ids, true); $data[$i] .= html_print_input_hidden('timestamp_first_'.$event['id_evento'], $timestamp_first, true); $data[$i] .= html_print_input_hidden('timestamp_last_'.$event['id_evento'], $timestamp_last, true); $data[$i] .= html_print_input_hidden('childrens_ids', json_encode($childrens_ids), true); - // Store server id if is metaconsole. 0 otherwise + // Store server id if is metaconsole. 0 otherwise. if ($meta) { $server_id = $event['server_id']; - // If meta activated, propagate the id of the event on node (source id) + // If meta activated, propagate the id of the event on node (source id). $data[$i] .= html_print_input_hidden('source_id_'.$event['id_evento'], $event['id_source_event'], true); $table->cellclass[count($table->data)][$i] = $myclass; } else { @@ -4325,7 +4837,7 @@ function events_list_events_grouped_agents($sql) } $data[$i] .= html_print_input_hidden('event_rep_'.$event['id_evento'], $event['event_rep'], true); - // Store concat comments to show in extended view + // Store concat comments to show in extended view. $data[$i] .= html_print_input_hidden('user_comment_'.$event['id_evento'], base64_encode($event['user_comment']), true); $i++; @@ -4396,7 +4908,7 @@ function events_list_events_grouped_agents($sql) } if (in_array('evento', $show_fields)) { - // Event description + // Event description. $data[$i] = ''; if ($allow_action) { $data[$i] .= '
    '; @@ -4416,7 +4928,7 @@ function events_list_events_grouped_agents($sql) $data[$i] = ''; if ($event['id_agente'] > 0) { - // Agent name + // Agent name. if ($meta) { $agent_link = ''; if (can_user_access_node()) { @@ -4437,7 +4949,7 @@ function events_list_events_grouped_agents($sql) } if (in_array('timestamp', $show_fields)) { - // Time + // Time. $data[$i] = ''; if ($group_rep == 1) { $data[$i] .= ui_print_timestamp($event['timestamp_rep'], true); @@ -4640,6 +5152,10 @@ function events_list_events_grouped_agents($sql) $data[$i] = html_print_image('images/page_white_text.png', true, ['title' => str_replace("\n", '
    ', io_safe_output($event['unknown_instructions']))]); } break; + + default: + // Ignore. + break; } if (!isset($data[$i])) { @@ -4669,11 +5185,11 @@ function events_list_events_grouped_agents($sql) } if ($i != 0 && $allow_action) { - // Actions + // Actions. $data[$i] = ''; if (!$readonly) { - // Validate event + // Validate event. if (($event['estado'] != 1) && (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EW', $event['clean_tags'], $childrens_ids))) { $show_validate_button = true; $data[$i] .= '
    '; @@ -4685,7 +5201,7 @@ function events_list_events_grouped_agents($sql) $data[$i] .= ''; } - // Delete event + // Delete event. if ((tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids) == 1)) { if ($event['estado'] != 2) { $show_delete_button = true; @@ -4724,11 +5240,11 @@ function events_list_events_grouped_agents($sql) if (!$readonly) { if (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EM', $event['clean_tags'], $childrens_ids) == 1) { - // Checkbox - // Class 'candeleted' must be the fist class to be parsed from javascript. Dont change + // Checkbox. + // Class 'candeleted' must be the fist class to be parsed from javascript. Dont change. $data[$i] = html_print_checkbox_extended('validate_ids[]', $event['id_evento'], false, false, false, 'class="candeleted chk_val"', true); } else if (tags_checks_event_acl($config['id_user'], $event['id_grupo'], 'EW', $event['clean_tags'], $childrens_ids) == 1) { - // Checkbox + // Checkbox. $data[$i] = html_print_checkbox_extended('validate_ids[]', $event['id_evento'], false, false, false, 'class="chk_val"', true); } else if (isset($table->header[$i]) || true) { $data[$i] = ''; @@ -4747,6 +5263,15 @@ function events_list_events_grouped_agents($sql) } +/** + * Retrieves SQL for custom order. + * + * @param string $sort_field Field. + * @param string $sort Order. + * @param integer $group_rep Group field. + * + * @return string SQL. + */ function events_get_sql_order($sort_field='timestamp', $sort='DESC', $group_rep=0) { $sort_field_translated = $sort_field; @@ -4794,18 +5319,22 @@ function events_get_sql_order($sort_field='timestamp', $sort='DESC', $group_rep= case 'extra_id': $sort_field_translated = 'id_extra'; break; + + default: + // Ignore. + break; } $dir = ($sort == 'up') ? 'ASC' : 'DESC'; - return "ORDER BY $sort_field_translated $dir"; + return 'ORDER BY '.$sort_field_translated.' '.$dir; } /** - * SQL left join of event queries to handle secondary groups + * SQL left join of event queries to handle secondary groups. * - * @param string Table to see if is metaconsole or not + * @param string $table Table to use based on environment. * * @return string With the query. */ diff --git a/pandora_console/include/functions_extensions.php b/pandora_console/include/functions_extensions.php index 095af6494c..8efb4c8f36 100755 --- a/pandora_console/include/functions_extensions.php +++ b/pandora_console/include/functions_extensions.php @@ -178,7 +178,8 @@ function extensions_get_extensions($enterprise=false, $rel_path='') function extensions_is_enabled_extension($name) { global $config; - return isset($config['extensions'][$name]); + return isset($config['extensions'][$name]) + || isset($config['extensions'][$name.'.php']); } diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index cbdada69b9..71049d7804 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -549,12 +549,6 @@ function grafico_modulo_sparse($params) return false; } - if (!isset($params['agent_module_id'])) { - return false; - } else { - $agent_module_id = $params['agent_module_id']; - } - if (!isset($params['period'])) { return false; } @@ -710,6 +704,12 @@ function grafico_modulo_sparse($params) $params['projection'] = false; } + if (!isset($params['agent_module_id'])) { + return graph_nodata_image($params['width'], $params['height']); + } else { + $agent_module_id = $params['agent_module_id']; + } + // XXXX Configurable $params['grid_color'] = '#C1C1C1'; $params['legend_color'] = '#636363'; @@ -1318,6 +1318,10 @@ function graphic_combined_module( $array_data = []; foreach ($module_list as $key => $agent_module_id) { + if ((bool) $agent_module_id === false) { + continue; + } + if (is_metaconsole() && $params_combined['type_report'] == 'automatic_graph') { $server = metaconsole_get_connection_by_id($agent_module_id['server']); if (metaconsole_connect($server) != NOERR) { @@ -1394,6 +1398,15 @@ function graphic_combined_module( } } + if (empty($array_data)) { + if ($params_combined['return']) { + return graph_nodata_image($width, $height); + } + + echo graph_nodata_image($width, $height); + return false; + } + if ($params_combined['projection']) { // If projection doesn't have data then don't draw graph if ($output_projection != null) { diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index cb100db256..6d461350e9 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -1822,35 +1822,35 @@ function html_get_predefined_table($model='transparent', $columns=4) * Print a nicely formatted table. Code taken from moodle. * * @param object Object with several properties: - * $table->head - An array of heading names. - * $table->head_colspan - An array of colspans of each head column. - * $table->headstyle - An array of styles of each head column. - * $table->align - An array of column alignments - * $table->valign - An array of column alignments - * $table->size - An array of column sizes - * $table->wrap - An array of "nowrap"s or nothing - * $table->style - An array of personalized style for each column. - * $table->rowid - An array of personalized ids of each row. - * $table->rowstyle - An array of personalized style of each row. - * $table->rowclass - An array of personalized classes of each row (odd-evens classes will be ignored). - * $table->colspan - An array of colspans of each column. - * $table->rowspan - An array of rowspans of each column. - * $table->data[] - An array of arrays containing the data. - * $table->width - A percentage of the page - * $table->border - Border of the table. - * $table->tablealign - Align the whole table (float left or right) - * $table->cellpadding - Padding on each cell - * $table->cellspacing - Spacing between cells - * $table->cellstyle - Style of a cell - * $table->cellclass - Class of a cell - * $table->class - CSS table class - * $table->id - Table ID (useful in JavaScript) - * $table->headclass[] - An array of classes for each heading - * $table->title - Title of the table is a single string that will be on top of the table in the head spanning the whole table - * $table->titlestyle - Title style - * $table->titleclass - Title class - * $table->styleTable - Table style - * $table->caption - Table title + * $table->head - An array of heading names. + * $table->head_colspan - An array of colspans of each head column. + * $table->headstyle - An array of styles of each head column. + * $table->align - An array of column alignments + * $table->valign - An array of column alignments + * $table->size - An array of column sizes + * $table->wrap - An array of "nowrap"s or nothing + * $table->style - An array of personalized style for each column. + * $table->rowid - An array of personalized ids of each row. + * $table->rowstyle - An array of personalized style of each row. + * $table->rowclass - An array of personalized classes of each row (odd-evens classes will be ignored). + * $table->colspan - An array of colspans of each column. + * $table->rowspan - An array of rowspans of each column. + * $table->data[] - An array of arrays containing the data. + * $table->width - A percentage of the page + * $table->border - Border of the table. + * $table->tablealign - Align the whole table (float left or right) + * $table->cellpadding - Padding on each cell + * $table->cellspacing - Spacing between cells + * $table->cellstyle - Style of a cell + * $table->cellclass - Class of a cell + * $table->class - CSS table class + * $table->id - Table ID (useful in JavaScript) + * $table->headclass[] - An array of classes for each heading + * $table->title - Title of the table is a single string that will be on top of the table in the head spanning the whole table + * $table->titlestyle - Title style + * $table->titleclass - Title class + * $table->styleTable - Table style + * $table->caption - Table title * @param bool Whether to return an output string or echo now * * @return string HTML code if return parameter is true. @@ -2257,7 +2257,7 @@ function html_print_checkbox_extended($name, $value, $checked, $disabled, $scrip if ($id == '') { $output .= ' id="checkbox-'.$id_aux.'"'; } else { - $output .= ' id='.$id; + $output .= ' '.$id.'"'; } if ($script != '') { diff --git a/pandora_console/include/functions_messages.php b/pandora_console/include/functions_messages.php index 60f2d71172..5374fb7b1e 100644 --- a/pandora_console/include/functions_messages.php +++ b/pandora_console/include/functions_messages.php @@ -1,55 +1,150 @@ $usuario_origen, + 'subject' => $subject, + 'mensaje' => $mensaje, + 'id_source' => get_notification_source_id('message'), + 'timestamp' => get_system_time(), + ] + ); + + // Update URL + // Update targets. + if ($message_id !== false) { + $ret = message_set_targets( + $message_id, + $target_users, + $target_groups + ); + if ($ret === false) { + // Failed to deliver messages. Erase message and show error. + db_process_sql_delete( + 'tmensajes', + ['id_mensaje' => $message_id] + ); + return false; + } } - $values = []; - $values['id_usuario_origen'] = $usuario_origen; - $values['id_usuario_destino'] = $usuario_destino; - $values['subject'] = $subject; - $values['mensaje'] = $mensaje; - $values['timestamp'] = get_system_time(); - - $return = db_process_sql_insert('tmensajes', $values); - if ($return === false) { return false; } else { @@ -58,108 +153,133 @@ function messages_create_message($usuario_origen, $usuario_destino, $subject, $m } -/** - * Creates private messages to be forwarded to groups - * - * @param string The sender of the message - * @param string The receivers (group) of the message - * @param string Subject of the message (much like E-Mail) - * @param string The actual message. This message will be cleaned by io_safe_input - * (html is allowed but loose html chars will be translated) - * - * @return boolean true when delivered, false in case of error - */ -function messages_create_group($usuario_origen, $dest_group, $subject, $mensaje) -{ - $users = users_get_info(); - $group_users = groups_get_users($dest_group); - - if (! array_key_exists($usuario_origen, $users)) { - // Users don't exist in the system - return false; - } else if (empty($group_users)) { - // There are no users in the group, so it hasn't failed although it hasn't done anything. - return true; - } - - // array unique - foreach ($group_users as $user) { - foreach ($user as $key => $us) { - if ($key == 'id_user') { - $group_user[$us] = $us; - } - } - } - - foreach ($group_user as $user) { - $return = messages_create_message($usuario_origen, get_user_id($user), $subject, $mensaje); - if ($return === false) { - // Error sending message - return false; - } - } - - return true; -} - - /** * Deletes a private message * - * @param integer $id_message + * @param integer $id_message Message to be deleted. * * @return boolean true when deleted, false in case of error */ -function messages_delete_message($id_message) +function messages_delete_message(int $id_message) { global $config; - $where = [ - // 'id_usuario_destino' => $config["id_user"], - 'id_mensaje' => $id_message, - ]; - return (bool) db_process_sql_delete('tmensajes', $where); + // Check if user has grants to access the message. + if (check_notification_readable($id_message) === false) { + return false; + } + + $utimestamp = time(); + + $ret = db_process_sql_update( + 'tnotification_user', + ['utimestamp_erased' => $utimestamp], + [ + 'id_mensaje' => $id_message, + 'id_user' => $config['id_user'], + ] + ); + + if ($ret === 0) { + // No previous updates. + // Message available to user due group assignment. + $ret = db_process_sql_insert( + 'tnotification_user', + [ + 'id_mensaje' => $id_message, + 'id_user' => $config['id_user'], + 'utimestamp_erased' => $utimestamp, + ] + ); + + // Quick fix. Insertions returns 0. + if ($ret !== false) { + $ret = 1; + } + } + + return (bool) $ret; } /** * Marks a private message as read/unread * - * @param integer $message_id The message to modify - * @param boolean $read To set unread pass 0, false or empty value + * @param integer $message_id The message to modify. + * @param boolean $read To set unread pass 0, false or empty value. * * @return boolean true when marked, false in case of error */ -function messages_process_read($message_id, $read=true) -{ - if (empty($read)) { - $read = 0; - } else { - $read = 1; +function messages_process_read( + int $message_id, + bool $read=true +) { + global $config; + // Check if user has grants to read the message. + if (check_notification_readable($message_id) === false) { + return false; } - return (bool) db_process_sql_update('tmensajes', ['estado' => $read], ['id_mensaje' => $message_id]); + if (empty($read)) { + // Mark as unread. + $utimestamp = null; + } else { + // Mark as read. + $utimestamp = time(); + } + + $ret = db_process_sql_update( + 'tnotification_user', + ['utimestamp_read' => $utimestamp], + [ + 'id_mensaje' => $message_id, + 'id_user' => $config['id_user'], + 'utimestamp_read' => null, + ] + ); + + if ($ret === 0) { + // No previous updates. + // Message available to user due group assignment. + $ret = db_process_sql_insert( + 'tnotification_user', + [ + 'id_mensaje' => $message_id, + 'id_user' => $config['id_user'], + 'utimestamp_read' => $utimestamp, + ] + ); + } + + return (bool) $ret; } /** * Gets a private message * - * This function abstracts the database backend so it can simply be replaced with another system + * This function abstracts the database backend so it can simply be + * replaced with another system * - * @param integer $message_id + * @param integer $message_id Message to be retrieved. * * @return mixed False if it doesn't exist or a filled array otherwise */ -function messages_get_message($message_id) +function messages_get_message(int $message_id) { global $config; + // Check if user has grants to read the message. + if (check_notification_readable($message_id) === false) { + return false; + } + $sql = sprintf( - "SELECT id_usuario_origen, id_usuario_destino, subject, mensaje, timestamp - FROM tmensajes - WHERE id_usuario_destino='%s' AND id_mensaje=%d", - $config['id_user'], + 'SELECT *, nu.utimestamp_read > 0 as "read" + FROM tmensajes tm + LEFT JOIN tnotification_user nu + ON nu.id_mensaje = tm.id_mensaje + WHERE tm.id_mensaje=%d', $message_id ); $row = db_get_row_sql($sql); @@ -168,6 +288,8 @@ function messages_get_message($message_id) return false; } + $row['id_usuario_destino'] = $config['id_user']; + return $row; } @@ -175,20 +297,21 @@ function messages_get_message($message_id) /** * Gets a sent message * - * This function abstracts the database backend so it can simply be replaced with another system + * This function abstracts the database backend so it can simply be + * replaced with another system * - * @param integer $message_id + * @param integer $message_id Message to be retrieved. * * @return mixed False if it doesn't exist or a filled array otherwise */ -function messages_get_message_sent($message_id) +function messages_get_message_sent(int $message_id) { global $config; $sql = sprintf( - "SELECT id_usuario_origen, id_usuario_destino, subject, mensaje, timestamp - FROM tmensajes - WHERE id_usuario_origen='%s' AND id_mensaje=%d", + "SELECT id_usuario_origen, subject, mensaje, timestamp + FROM tmensajes + WHERE id_usuario_origen='%s' AND id_mensaje=%d", $config['id_user'], $message_id ); @@ -198,6 +321,16 @@ function messages_get_message_sent($message_id) return false; } + $targets = get_notification_targets($message_id); + + $row['id_usuario_destino'] = implode( + ',', + $targets['users'] + ).','.implode( + ',', + $targets['groups'] + ); + return $row; } @@ -205,29 +338,77 @@ function messages_get_message_sent($message_id) /** * Counts private messages * - * @param string $user - * @param boolean $incl_read Whether or not to include read messages + * @param string $user Target user. + * @param boolean $incl_read Whether or not to include read messages. + * @param boolean $ignore_source Ignore source. * * @return integer The number of messages this user has */ -function messages_get_count($user=false, $incl_read=false) -{ +function messages_get_count( + string $user='', + bool $incl_read=false, + bool $ignore_source=false +) { if (empty($user)) { global $config; $user = $config['id_user']; } - if (empty($incl_read)) { - $filter = 'AND estado = 0'; + if (!empty($incl_read)) { + // Do not filter. + $read = ' 1=1 '; } else { - $filter = ''; + // Retrieve only unread messages. + $read = ' t.read is null'; + } + + if ($ignore_source === true) { + $source_select = ''; + $source_sql = ''; + $source_extra = ''; + } else { + $source_select = ',IF(ns.user_editable,nsu.enabled,ns.enabled) as enabled'; + + // Row in tnotification_source_user could exist or not. + $source_sql = sprintf( + 'INNER JOIN ( + tnotification_source ns + LEFT JOIN tnotification_source_user nsu + ON ns.id=nsu.id_source + AND nsu.id_user="%s") + ON tm.id_source=ns.id', + $user + ); + $source_extra = 'AND (t.enabled=1 OR t.enabled is null)'; } $sql = sprintf( - "SELECT COUNT(*) - FROM tmensajes WHERE id_usuario_destino='%s' %s", + 'SELECT count(*) as "n" FROM ( + SELECT + tm.*, + utimestamp_read > 0 as "read" + %s + FROM tmensajes tm + %s + LEFT JOIN tnotification_user nu + ON tm.id_mensaje=nu.id_mensaje + AND nu.id_user="%s" + LEFT JOIN (tnotification_group ng + INNER JOIN tusuario_perfil up + ON ng.id_group=up.id_grupo + AND up.id_grupo=ng.id_group) + ON tm.id_mensaje=ng.id_mensaje + WHERE utimestamp_erased is null + AND (nu.id_user="%s" OR up.id_usuario="%s" OR ng.id_group=0) + ) t + WHERE %s %s', + $source_select, + $source_sql, $user, - $filter + $user, + $user, + $read, + $source_extra ); return (int) db_get_sql($sql); @@ -235,13 +416,13 @@ function messages_get_count($user=false, $incl_read=false) /** - * Counts sended messages + * Counts messages sent. * - * @param string $user + * @param string $user Target user. * * @return integer The number of messages this user has sent */ -function messages_get_count_sent($user=false) +function messages_get_count_sent(string $user='') { if (empty($user)) { global $config; @@ -250,7 +431,7 @@ function messages_get_count_sent($user=false) $sql = sprintf( "SELECT COUNT(*) - FROM tmensajes WHERE id_usuario_origen='%s'", + FROM tmensajes WHERE id_usuario_origen='%s'", $user ); @@ -261,20 +442,34 @@ function messages_get_count_sent($user=false) /** * Get message overview in array * - * @param string $order How to order them valid: - * (status (default), subject, timestamp, sender) - * @param string $order_dir Direction of order (ASC = Ascending, DESC = Descending) + * @param string $order How to order them valid: + * (status (default), subject, timestamp, sender). + * @param string $order_dir Direction of order + * (ASC = Ascending, DESC = Descending). + * @param boolean $incl_read Include read messages in return. + * @param boolean $incl_source_info Include source info. + * @param integer $limit Maximum number of result in the query. + * @param array $other_filter Add a filter on main query. * * @return integer The number of messages this user has */ -function messages_get_overview($order='status', $order_dir='ASC') -{ +function messages_get_overview( + string $order='status', + string $order_dir='ASC', + bool $incl_read=true, + bool $incl_source_info=false, + int $limit=0, + array $other_filter=[] +) { global $config; switch ($order) { - case 'timestamp': - case 'sender': - case 'subject': + case 'timestamp':{ + } + case 'sender':{ + } + case 'subject':{ + } break; case 'status': @@ -287,21 +482,59 @@ function messages_get_overview($order='status', $order_dir='ASC') $order .= ' DESC'; } - $result = []; - $return = db_get_all_rows_field_filter('tmensajes', 'id_usuario_destino', $config['id_user'], $order); - - if ($return === false) { - return $result; + if (!empty($incl_read)) { + // Do not filter. + $read = ''; + } else { + // Retrieve only unread messages. + $read = 'where t.read is null'; } - foreach ($return as $message) { - $result[$message['id_mensaje']]['sender'] = $message['id_usuario_origen']; - $result[$message['id_mensaje']]['subject'] = $message['subject']; - $result[$message['id_mensaje']]['timestamp'] = $message['timestamp']; - $result[$message['id_mensaje']]['status'] = $message['estado']; + $source_fields = ''; + $source_join = ''; + if ($incl_source_info) { + $source_fields = ', tns.*'; + $source_join = 'INNER JOIN tnotification_source tns + ON tns.id=tm.id_source + INNER JOIN tnotification_source_user nsu + ON nsu.id_source=tns.id + AND nsu.enabled = 1 + OR tns.enabled = 1'; } - return $result; + // Using distinct because could be double assignment due group/user. + $sql = sprintf( + 'SELECT * FROM ( + SELECT DISTINCT tm.*, utimestamp_read > 0 as "read" %s + FROM tmensajes tm + LEFT JOIN tnotification_user nu + ON tm.id_mensaje=nu.id_mensaje + AND nu.id_user="%s" + LEFT JOIN (tnotification_group ng + INNER JOIN tusuario_perfil up + ON ng.id_group=up.id_grupo + AND up.id_grupo=ng.id_group + ) ON tm.id_mensaje=ng.id_mensaje + %s + WHERE utimestamp_erased is null + AND (nu.id_user="%s" OR up.id_usuario="%s" OR ng.id_group=0) + ) t + %s + %s + ORDER BY %s + %s', + $source_fields, + $config['id_user'], + $source_join, + $config['id_user'], + $config['id_user'], + $read, + db_format_array_where_clause_sql($other_filter, 'AND', ' AND '), + $order, + ($limit !== 0) ? ' LIMIT '.$limit : '' + ); + + return db_get_all_rows_sql($sql); } @@ -309,19 +542,25 @@ function messages_get_overview($order='status', $order_dir='ASC') * Get sent message overview in array * * @param string $order How to order them valid: - * (status (default), subject, timestamp, sender) - * @param string $order_dir Direction of order (ASC = Ascending, DESC = Descending) + * (status (default), subject, timestamp, sender). + * @param string $order_dir Direction of order + * (ASC = Ascending, DESC = Descending). * * @return integer The number of messages this user has */ -function messages_get_overview_sent($order='timestamp', $order_dir='ASC') -{ +function messages_get_overview_sent( + string $order='timestamp', + string $order_dir='ASC' +) { global $config; switch ($order) { - case 'timestamp': - case 'sender': - case 'subject': + case 'timestamp':{ + } + case 'sender':{ + } + case 'subject':{ + } break; case 'status': @@ -334,19 +573,35 @@ function messages_get_overview_sent($order='timestamp', $order_dir='ASC') $order .= ' DESC'; } - $result = []; - $return = db_get_all_rows_field_filter('tmensajes', 'id_usuario_origen', $config['id_user'], $order); - - if ($return === false) { - return $result; - } - - foreach ($return as $message) { - $result[$message['id_mensaje']]['dest'] = $message['id_usuario_destino']; - $result[$message['id_mensaje']]['subject'] = $message['subject']; - $result[$message['id_mensaje']]['timestamp'] = $message['timestamp']; - $result[$message['id_mensaje']]['status'] = $message['estado']; - } - - return $result; + return db_get_all_rows_field_filter( + 'tmensajes', + 'id_usuario_origen', + $config['id_user'], + $order + ); +} + + +/** + * Get the URL of a message. If field in db is null, it returs a link to + * messages view. + * + * @param integer $message_id Message id to get URL. + * + * @return mixed False if fails. A string with URL otherwise. + */ +function messages_get_url($message_id) +{ + $messages = messages_get_message($message_id); + if ($messages === false) { + return false; + } + + // Return URL stored if is set in database. + if (isset($messages['url'])) { + return $messages['url']; + } + + // Return the message direction. + return ui_get_full_url('index.php?sec=message_list&sec2=operation/messages/message_edit&read_message=1&id_message='.$message_id); } diff --git a/pandora_console/include/functions_notifications.php b/pandora_console/include/functions_notifications.php new file mode 100644 index 0000000000..26dcc248c5 --- /dev/null +++ b/pandora_console/include/functions_notifications.php @@ -0,0 +1,999 @@ + [], + 'groups' => [], + ]; + + if (empty($id_message)) { + return $targets; + } + + $ret = db_get_all_rows_sql( + sprintf( + 'SELECT id_user + FROM tnotification_user nu + WHERE nu.id_mensaje = %d', + $id_message + ) + ); + + if (is_array($ret)) { + foreach ($ret as $row) { + array_push( + $targets['users'], + get_user_fullname($row['id_user']) + ); + } + } + + $ret = db_get_all_rows_sql( + sprintf( + 'SELECT COALESCE(tg.nombre,ng.id_group) as "id_group" + FROM tnotification_group ng + LEFT JOIN tgrupo tg + ON tg.id_grupo=ng.id_group + WHERE ng.id_mensaje = %d', + $id_message + ) + ); + + if (is_array($ret)) { + foreach ($ret as $row) { + if ($row['id_group'] == '0') { + $row['id_group'] = ''.__('All').''; + } + + array_push($targets['groups'], $row['id_group']); + } + } + + return $targets; +} + + +/** + * Check if current user has grants to read this notification + * + * @param integer $id_message Target message. + * + * @return boolean true, read available. False if not. + */ +function check_notification_readable(int $id_message) +{ + global $config; + + if (empty($id_message)) { + return false; + } + + // Using distinct to avoid double response on group messages read by user. + $sql = sprintf( + 'SELECT DISTINCT tm.*, utimestamp_read > 0 as "read" + FROM tmensajes tm + LEFT JOIN tnotification_user nu + ON tm.id_mensaje=nu.id_mensaje + AND nu.id_user="%s" + AND tm.id_mensaje=%d + LEFT JOIN (tnotification_group ng + INNER JOIN tusuario_perfil up + ON ng.id_group=up.id_grupo + AND up.id_grupo=ng.id_group + ) ON tm.id_mensaje=ng.id_mensaje + WHERE utimestamp_erased is null + AND (nu.id_user="%s" OR up.id_usuario="%s" OR ng.id_group=0)', + $config['id_user'], + $id_message, + $config['id_user'], + $config['id_user'] + ); + + return (bool) db_get_value_sql($sql); +} + + +/** + * Returns the target users and groups assigned to be notified on + * desired source. + * + * @param integer $id_source Source identificator. + * + * @return array [users] and [groups] with the targets. + */ +function get_notification_source_targets(int $id_source) +{ + $ret = []; + + $users = db_get_all_rows_sql( + sprintf( + 'SELECT + id_user, + IF(ns.user_editable = 1,nsu.also_mail,ns.also_mail) AS also_mail + FROM tnotification_source_user nsu + INNER JOIN tnotification_source ns + ON ns.id=nsu.id_source + WHERE ns.id = %d + AND ((ns.enabled is NULL OR ns.enabled != 0) + OR (nsu.enabled is NULL OR nsu.enabled != 0))', + $id_source + ) + ); + + if ($users !== false) { + $i = 0; + foreach ($users as $user) { + $ret['users'][$i]['id_user'] = $user['id_user']; + $ret['users'][$i++]['also_mail'] = $user['also_mail']; + } + } + + $groups = db_get_all_rows_sql( + sprintf( + 'SELECT id_group,ns.also_mail + FROM tnotification_source_group nsg + INNER JOIN tnotification_source ns + ON ns.id=nsg.id_source + WHERE ns.id = %d + AND (ns.enabled is NULL OR ns.enabled != 0)', + $id_source + ) + ); + + if ($groups !== false) { + $i = 0; + foreach ($groups as $group) { + $ret['groups'][$i]['id_group'] = $group['id_group']; + $ret['groups'][$i++]['also_mail'] = $group['also_mail']; + } + } + + return $ret; +} + + +/** + * Return all info from tnotification_source + * + * @param array $filter Filter to table tnotification_source. + * + * @return array with sources info + */ +function notifications_get_all_sources($filter=[]) +{ + return db_get_all_rows_filter('tnotification_source', $filter); +} + + +/** + * Return the user sources to be inserted into a select + * + * @param integer $source_id Source database identificator. + * + * @return array with the user id in keys and user id in value too + */ +function notifications_get_user_sources_for_select($source_id) +{ + $users = notifications_get_user_sources( + ['id_source' => $source_id], + ['id_user'] + ); + + return index_array($users, 'id_user', 'id_user'); +} + + +/** + * Get the user sources + * + * @param array $filter Filter of sql query. + * @param array $fields Fields to get of query. + * + * @return array Array with user sources data. + */ +function notifications_get_user_sources($filter=[], $fields=[]) +{ + $users = db_get_all_rows_filter( + 'tnotification_source_user', + $filter, + $fields + ); + // If fails or no one is selected, return empty array. + if ($users === false) { + return []; + } + + return $users; +} + + +/** + * Return the groups sources to be inserted into a select + * + * @param integer $source_id Source database identificator. + * + * @return array with the group id in keys and group name in value + */ +function notifications_get_group_sources_for_select($source_id) +{ + $groups = notifications_get_group_sources( + ['id_source' => $source_id], + ['id_group'] + ); + return index_array($groups, 'id_group', 'name'); +} + + +/** + * Get the group sources + * + * @param array $filter Filter of sql query. + * @param array $fields Fields retrieved. + * + * @return array With the group info + */ +function notifications_get_group_sources($filter=[], $fields=[]) +{ + // Get only the tnotifications_source_group fields in addition to group name. + if (empty($fields)) { + $fields[] = 'tnsg.*'; + } + + $fields = array_map( + function ($field) { + if (!preg_match('/^tnsg./', $field)) { + $field = 'tnsg.'.$field; + } + + return $field; + }, + $fields + ); + + // Get groups. + $groups = db_get_all_rows_filter( + 'tnotification_source_group tnsg + LEFT JOIN tgrupo tg ON tnsg.id_group = tg.id_grupo', + $filter, + array_merge($fields, ['IFNULL(tg.nombre, "All") AS name']) + ); + + // If fails or no one is selected, return empty array. + if ($groups === false) { + return []; + } + + return $groups; +} + + +/** + * Delete a set of groups from notification source + * + * @param integer $source_id Source id. + * @param array $groups Id of groups to be deleted. + * + * @return boolean True if success. False otherwise. + */ +function notifications_remove_group_from_source($source_id, $groups) +{ + // Source id is mandatory. + if (!isset($source_id)) { + return false; + } + + // Delete from database. + return db_process_sql_delete( + 'tnotification_source_group', + [ + 'id_group' => $groups, + 'id_source' => $source_id, + ] + ) !== false; +} + + +/** + * Delete a set of users from notification source + * + * @param integer $source_id Source id. + * @param array $users Id of users to be deleted. + * + * @return boolean True if success. False otherwise. + */ +function notifications_remove_users_from_source($source_id, $users) +{ + // Source id is mandatory. + if (!isset($source_id)) { + return false; + } + + // Delete from database. + return db_process_sql_delete( + 'tnotification_source_user', + [ + 'id_user' => $users, + 'id_source' => $source_id, + ] + ) !== false; +} + + +/** + * Insert a set of groups to notification source + * + * @param integer $source_id Source id. + * @param array $groups Id of groups to be deleted. + * + * @return boolean True if success. False otherwise. + */ +function notifications_add_group_to_source($source_id, $groups) +{ + // Source id is mandatory. + if (!isset($source_id)) { + return false; + } + + // Insert into database all groups passed. + $res = true; + foreach ($groups as $group) { + if (!isset($group)) { + continue; + } + + $res = $res && db_process_sql_insert( + 'tnotification_source_group', + [ + 'id_group' => $group, + 'id_source' => $source_id, + ] + ) !== false; + } + + return $res; +} + + +/** + * Insert a set of users to notification source + * + * @param integer $source_id Source id. + * @param array $users Id of users to be deleted. + * + * @return boolean True if success. False otherwise. + */ +function notifications_add_users_to_source($source_id, $users) +{ + // Source id is mandatory. + if (!isset($source_id)) { + return false; + } + + // Insert into database all groups passed. + $res = true; + $also_mail = db_get_value( + 'also_mail', + 'tnotification_source', + 'id', + $source_id + ); + foreach ($users as $user) { + if (empty($user)) { + continue; + } + + $res = $res && db_process_sql_insert( + 'tnotification_source_user', + [ + 'id_user' => $user, + 'id_source' => $source_id, + 'enabled' => 1, + 'also_mail' => (int) $also_mail, + ] + ) !== false; + } + + return $res; +} + + +/** + * Get the groups that not own to a source and, for that reason, they can be + * added to the source. + * + * @param integer $source_id Source id. + * + * @return array Indexed by id group all selectable groups. + */ +function notifications_get_group_source_not_configured($source_id) +{ + $groups_selected = notifications_get_group_sources_for_select($source_id); + $all_groups = users_get_groups_for_select(false, 'AR', false, true, $groups_selected); + return array_diff($all_groups, $groups_selected); +} + + +/** + * Get the users that not own to a source and, for that reason, they can be + * added to the source. + * + * @param integer $source_id Source id. + * + * @return array Indexed by id user, all selectable users. + */ +function notifications_get_user_source_not_configured($source_id) +{ + $users_selected = array_keys(notifications_get_user_sources_for_select($source_id)); + $users = get_users( + 'id_user', + ['!id_user' => $users_selected], + ['id_user'] + ); + return index_array($users, 'id_user', 'id_user'); +} + + +/** + * Build a data struct to handle the value of a label + * + * @param mixed $status Status value. + * @param mixed $enabled Enabled value. + * + * @return array with status (1|0) and enabled (1|0) + */ +function notifications_build_user_enable_return($status, $enabled) +{ + return [ + 'status' => ((bool) $status === true) ? 1 : 0, + 'enabled' => ((bool) $enabled === true) ? 1 : 0, + ]; +} + + +/** + * Get user label (enabled, also_mail...) status. + * + * @param integer $source Id of notification source. + * @param string $user User id. + * @param string $label Label id (enabled, also_email...). + * + * @return array Return of notifications_build_user_enable_return. + */ +function notifications_get_user_label_status($source, $user, $label) +{ + // If not enabled, it cannot be modificable. + if (!$source['enabled']) { + return notifications_build_user_enable_return(false, false); + } + + // See at first for direct reference. + $user_source = notifications_get_user_sources( + [ + 'id_source' => $source['id'], + 'id_user' => $user, + ] + ); + if (!empty($user_source)) { + return notifications_build_user_enable_return( + isset($user_source[0][$label]) ? $user_source[0][$label] : false, + $source['user_editable'] + ); + } + + $common_groups = array_intersect( + array_keys(users_get_groups($user)), + array_keys( + notifications_get_group_sources_for_select($source['id']) + ) + ); + // No group found, return no permissions. + $value = empty($common_groups) ? false : $source[$label]; + return notifications_build_user_enable_return( + $value, + false + ); +} + + +/** + * Set the status to a single label on config of users notifications. + * + * @param integer $source Id of notification source. + * @param string $user User id. + * @param string $label Label id (enabled, also_email...). + * @param mixed $value Numeric value: 1 or 0. + * + * @return boolean True if success. + */ +function notifications_set_user_label_status($source, $user, $label, $value) +{ + $source_info = notifications_get_all_sources(['id' => $source]); + if (!isset($source_info[0]) + || !$source_info[0]['enabled'] + || !$source_info[0]['user_editable'] + ) { + return false; + } + + return (bool) db_process_sql_update( + 'tnotification_source_user', + [$label => $value], + [ + 'id_user' => $user, + 'id_source' => $source, + ] + ); +} + + +/** + * Get the counters of notification. Usefull to print the header notification + * ball. + * + * @return array With the fields: + * 'notifications' => Total new notifications, + * 'last_id' => Id of last read value. Usefull to make comparisons. + */ +function notifications_get_counters() +{ + $num_notifications = 0; + $last_id = 0; + $last_message = messages_get_overview( + 'timestamp', + 'DESC', + false, + false, + 1 + ); + if (!empty($last_message)) { + $num_notifications = messages_get_count(); + $last_id = $last_message[0]['id_mensaje']; + } + + return [ + 'notifications' => $num_notifications, + 'last_id' => $last_id, + ]; +} + + +// ///////////////////////////////////////////////////////////////////////////// +// UI FUNCTIONS +// ///////////////////////////////////////////////////////////////////////////// + + +/** + * Print the notification ball to see unread messages. + * + * @param integer $num_notifications Number of messages shown + * in notification ball. + * @param integer $last_id Id of last message shown + * in the notification ball. + * + * @return string with HTML code of notification ball. + */ +function notifications_print_ball($num_notifications, $last_id) +{ + $no_notifications = (int) $num_notifications === 0; + $class_status = ($no_notifications) ? 'notification-ball-no-messages' : 'notification-ball-new-messages'; + return sprintf( + '
    + %s +
    ', + ($no_notifications) ? '' : 'onclick="addNotifications(event)"', + $class_status, + $last_id, + $num_notifications + ); +} + + +/** + * Print notification configuration global + * + * @param array $source Notification source data. + * + * @return string with HTML of source configuration + */ +function notifications_print_global_source_configuration($source) +{ + // Get some values to generate the title. + $switch_values = [ + 'name' => 'enable-'.$source['id'], + 'value' => $source['enabled'], + 'id' => 'nt-'.$source['id'].'-enabled', + 'class' => 'elem-clickable', + ]; + + // Search if group all is set and handle that situation. + $source_groups = notifications_get_group_sources_for_select($source['id']); + $is_group_all = isset($source_groups['0']); + if ($is_group_all) { + unset($source_groups['0']); + } + + // Generate the title. + $html_title = "
    "; + $html_title .= html_print_switch($switch_values); + $html_title .= '

    '.$source['description'].'

    '; + $html_title .= '
    '; + + // Generate the html for title. + $html_selectors = "
    "; + $html_selectors .= notifications_print_source_select_box( + notifications_get_user_sources_for_select($source['id']), + 'users', + $source['id'] + ); + $html_selectors .= notifications_print_source_select_box( + $source_groups, + 'groups', + $source['id'] + ); + $html_selectors .= '
    '; + // Generate the checkboxes and time select. + $html_checkboxes = "
    "; + $html_checkboxes .= ' '; + $html_checkboxes .= html_print_checkbox_extended('all-'.$source['id'], 1, $is_group_all, false, '', 'class= "elem-clickable"', true, 'id="nt-'.$source['id'].'-all_users"'); + $html_checkboxes .= __('Notify all users'); + $html_checkboxes .= '
    '; + $html_checkboxes .= html_print_checkbox_extended('mail-'.$source['id'], 1, $source['also_mail'], false, '', 'class= "elem-clickable"', true, 'id="nt-'.$source['id'].'-also_mail"'); + $html_checkboxes .= __('Also email users with notification content'); + $html_checkboxes .= '
    '; + $html_checkboxes .= html_print_checkbox_extended('user-'.$source['id'], 1, $source['user_editable'], false, '', 'class= "elem-clickable"', true, 'id="nt-'.$source['id'].'-user_editable"'); + $html_checkboxes .= __('Users can modify notification preferences'); + $html_checkboxes .= ' '; + $html_checkboxes .= '
    '; + + // Generate the select with the time. + $html_select_pospone = __('Users can postpone notifications up to'); + // FIXMEit should not be disabled. + $html_select_pospone .= html_print_select( + [ + SECONDS_5MINUTES => __('5 minutes'), + SECONDS_15MINUTES => __('15 minutes'), + SECONDS_12HOURS => __('12 hours'), + SECONDS_1DAY => __('1 day'), + SECONDS_1WEEK => __('1 week'), + SECONDS_15DAYS => __('15 days'), + SECONDS_1MONTH => __('1 month'), + NOTIFICATIONS_POSTPONE_FOREVER => __('forever'), + ], + 'nt-'.$source['id'].'-max_postpone_time', + $source['max_postpone_time'], + '', + '', + 0, + true, + false, + true, + 'elem-changeable', + true + ); + + // Return all html. + return $html_title.$html_selectors.$html_checkboxes.$html_select_pospone; +} + + +/** + * Print select boxes of notified users or groups + * + * @param array $info_selec All info required for build the selector. + * @param string $id One of users|groups. + * @param string $source_id Id of source. + * + * @return string HTML with the generated selector + */ +function notifications_print_source_select_box( + $info_selec, + $id, + $source_id +) { + $title = ($id === 'users') ? __('Notified users') : __('Notified groups'); + $add_title = ($id === 'users') ? __('Add users') : __('Add groups'); + $delete_title = ($id === 'users') ? __('Delete users') : __('Delete groups'); + + // Generate the HTML. + return sprintf( + " +
    +
    +

    %s

    + %s +
    +
    + %s + %s +
    +
    + ", + $title, + // Put a true if empty sources to avoid to sow the 'None' value. + html_print_select( + empty($info_selec) ? true : $info_selec, + 'multi-'.$id.'-'.$source_id.'[]', + 0, + false, + '', + '', + true, + true + ), + html_print_image( + 'images/input_add.png', + true, + [ + 'title' => $add_title, + 'onclick' => sprintf( + "add_source_dialog('%s', '%s')", + $id, + $source_id + ), + ] + ), + html_print_image( + 'images/input_delete.png', + true, + [ + 'title' => $delete_title, + 'onclick' => sprintf( + "remove_source_elements('%s', '%s')", + $id, + $source_id + ), + ] + ) + ); +} + + +/** + * Print the select with right and left arrows to select new sources + * (groups or users). + * + * @param array $info_selec Array with source info. + * @param string $users One of users|groups. + * @param source $source_id Source id. + * + * @return string HTML with the select code. + */ +function notifications_print_two_ways_select($info_selec, $users, $source_id) +{ + return sprintf( + " +
    + %s +
    + %s + %s +
    + %s +
    + %s + ", + html_print_select( + empty($info_selec) ? true : $info_selec, + 'all-multi-'.$users.'-'.$source_id.'[]', + 0, + false, + '', + '', + true, + true, + true, + '' + ), + html_print_image( + 'images/darrowright.png', + true, + [ + 'title' => __('Add elements'), + 'onclick' => sprintf( + "notifications_modify_two_ways_element('%s', '%s', 'add')", + $users, + $source_id + ), + ] + ), + html_print_image( + 'images/darrowleft.png', + true, + [ + 'title' => __('Remove elements'), + 'onclick' => sprintf( + "notifications_modify_two_ways_element('%s', '%s', 'remove')", + $users, + $source_id + ), + ] + ), + html_print_select( + true, + 'selected-multi-'.$users.'-'.$source_id.'[]', + 0, + false, + '', + '', + true, + true, + true, + '' + ), + html_print_button( + __('Add'), + 'Add', + false, + sprintf( + "notifications_add_source_element_to_database('%s', '%s')", + $users, + $source_id + ), + "class='sub add'", + true + ) + ); +} + + +/** + * Print a label status represented by a switch + * + * @param integer $source Source id. + * @param string $user User id. + * @param string $label Label (enabled, also_mail...). + * + * @return string With HTML code + */ +function notifications_print_user_switch($source, $user, $label) +{ + $status = notifications_get_user_label_status($source, $user, $label); + return html_print_switch( + [ + 'name' => $label, + 'value' => $status['status'], + 'disabled' => !$status['enabled'], + 'class' => 'notifications-user-label_individual', + 'id' => 'notifications-user-'.$source['id'].'-label-'.$label, + ] + ); +} + + +/** + * Generates the dropdown notifications menu. + * + * @return string HTML with dropdown menu. + */ +function notifications_print_dropdown() +{ + $mess = messages_get_overview('status', 'DESC', false, true); + if ($mess === false) { + $mess = []; + } + + return sprintf( + "
    +
    + %s +
    +
    +
    +
    + ", + array_reduce( + $mess, + function ($carry, $message) { + return $carry.notifications_print_dropdown_element($message); + }, + '' + ) + ); +} + + +/** + * Print a single notification box + * + * @param array $message_info Info of printed message. + * + * @return string HTML code of single message + */ +function notifications_print_dropdown_element($message_info) +{ + return sprintf( + " + %s +
    +

    + %s +

    +

    + %s +

    +
    +
    ", + $message_info['id_mensaje'], + messages_get_url($message_info['id_mensaje']), + html_print_image('images/'.$message_info['icon'], true), + $message_info['subject'], + str_replace([io_safe_input('
    ')], ' ', $message_info['mensaje']) + ); +} diff --git a/pandora_console/include/functions_servers.php b/pandora_console/include/functions_servers.php index 3081e076b6..ba6659ddc1 100644 --- a/pandora_console/include/functions_servers.php +++ b/pandora_console/include/functions_servers.php @@ -1,22 +1,33 @@ __('Recon server')]); + case SERVER_TYPE_DISCOVERY: + $server['img'] = html_print_image('images/recon.png', true, ['title' => __('Discovery server')]); $server['type'] = 'recon'; $id_modulo = 0; break; @@ -589,11 +600,11 @@ function servers_get_info($id_server=-1) $server['lag'] = 0; $server['module_lag'] = 0; } - // Recon server - else if ($server['server_type'] == SERVER_TYPE_RECON) { + // Discovery server + else if ($server['server_type'] == SERVER_TYPE_DISCOVERY) { $server['name'] = ''.$server['name'].''; - // Total jobs running on this recon server + // Total jobs running on this Discovery server $server['modules'] = db_get_sql( 'SELECT COUNT(id_rt) FROM trecon_task @@ -921,3 +932,64 @@ function servers_get_status($id_server) $serverinfo = servers_get_info($id_server); return $serverinfo[$id_server]; } + + +/** + * Return server name based on identifier. + * + * @param integer $server Server identifier. + * + * @return string Server name + */ +function servers_get_server_string_name(int $server) +{ + switch ($server) { + case SERVER_TYPE_DATA: + return __('Data server'); + + case SERVER_TYPE_NETWORK: + return __('Network server'); + + case SERVER_TYPE_SNMP: + return __('SNMP server'); + + case SERVER_TYPE_ENTERPRISE_ICMP: + return __('Enterprise ICMP server'); + + case SERVER_TYPE_ENTERPRISE_SNMP: + return __('Enterprise SNMP server'); + + case SERVER_TYPE_PLUGIN: + return __('Plugin server'); + + case SERVER_TYPE_PREDICTION: + return __('Prediction Server'); + + case SERVER_TYPE_WMI: + return __('WMI server'); + + case SERVER_TYPE_WEB: + return __('Web server'); + + case SERVER_TYPE_EXPORT: + return __('Export server'); + + case SERVER_TYPE_INVENTORY: + return __('Inventory server'); + + case SERVER_TYPE_EVENT: + return __('Event server'); + + case SERVER_TYPE_DISCOVERY: + return __('Discovery server'); + + case SERVER_TYPE_SYSLOG: + return __('Syslog server'); + + case SERVER_TYPE_WUX: + return __('WUX server'); + + default: + return __('N/A'); + } +} diff --git a/pandora_console/include/functions_snmp_browser.php b/pandora_console/include/functions_snmp_browser.php index 57bc416c76..4920816c89 100644 --- a/pandora_console/include/functions_snmp_browser.php +++ b/pandora_console/include/functions_snmp_browser.php @@ -27,7 +27,7 @@ $nfdump_date_format = 'Y/m/d.H:i:s'; * @param id string Level ID. Do not set, used for recursion. * @param depth string Branch depth. Do not set, used for recursion. */ -function snmp_browser_print_tree($tree, $id=0, $depth=0, $last=0, $last_array=[]) +function snmp_browser_print_tree($tree, $id=0, $depth=0, $last=0, $last_array=[], $sufix=false, $checked=[]) { static $url = false; @@ -52,13 +52,13 @@ function snmp_browser_print_tree($tree, $id=0, $depth=0, $last=0, $last_array=[] } foreach ($tree['__LEAVES__'] as $level => $sub_level) { - // Id used to expand leafs + // Id used to expand leafs. $sub_id = time().rand(0, getrandmax()); - // Display the branch + // Display the branch. echo "
  • "; - // Indent sub branches + // Indent sub branches. for ($i = 1; $i <= $depth; $i++) { if ($last_array[$i] == 1) { echo ''; @@ -67,7 +67,7 @@ function snmp_browser_print_tree($tree, $id=0, $depth=0, $last=0, $last_array=[] } } - // Branch + // Branch. if (! empty($sub_level['__LEAVES__'])) { echo ""; if ($depth == 0 && $count == 0) { @@ -84,7 +84,7 @@ function snmp_browser_print_tree($tree, $id=0, $depth=0, $last=0, $last_array=[] echo ''; } - // Leave + // Leave. else { if ($depth == 0 && $count == 0) { if ($count == $total) { @@ -106,15 +106,18 @@ function snmp_browser_print_tree($tree, $id=0, $depth=0, $last=0, $last_array=[] echo ''; } - echo html_print_checkbox("create_$sub_id", 0, false, true, false, '').' '.$level.''; + $checkbox_name_sufix = ($sufix === true) ? '_'.$level : ''; + $checkbox_name = 'create_'.$sub_id.$checkbox_name_sufix; + $status = (!empty($checked) && isset($checked[$level])); + echo html_print_checkbox($checkbox_name, 0, $status, true, false, '').' '.$level.''; if (isset($sub_level['__VALUE__'])) { echo ''; } echo '
  • '; - // Recursively print sub levels - snmp_browser_print_tree($sub_level, $sub_id, ($depth + 1), ($count == $total ? 1 : 0), $last_array); + // Recursively print sub levels. + snmp_browser_print_tree($sub_level, $sub_id, ($depth + 1), ($count == $total ? 1 : 0), $last_array, $sufix, $checked); $count++; } @@ -838,7 +841,7 @@ function snmp_browser_print_container($return=false, $width='100%', $height='500 if ($(this).is(':checked') ) { $('input[name*=create_network_component]').show(); var id_input = $(this).attr("id"); - id_input = id_input.split("checkbox-create_"); + id_input = id_input.match("checkbox-create_([0-9]+)"); var checks = $('#ul_'+id_input[1]).find('input').map(function(){ if(this.id.indexOf('checkbox-create_')!=-1){ return this.id; @@ -851,7 +854,7 @@ function snmp_browser_print_container($return=false, $width='100%', $height='500 } else { var id_input = $(this).attr("id"); - id_input = id_input.split("checkbox-create_"); + id_input = id_input.match("checkbox-create_([0-9]+)"); var checks = $('#ul_'+id_input[1]).find('input').map(function(){ if(this.id.indexOf('checkbox-create_')!=-1){ return this.id; diff --git a/pandora_console/include/graphs/flot/pandora.flot.js b/pandora_console/include/graphs/flot/pandora.flot.js index 3561581f49..dd6fb0645e 100644 --- a/pandora_console/include/graphs/flot/pandora.flot.js +++ b/pandora_console/include/graphs/flot/pandora.flot.js @@ -857,11 +857,11 @@ function pandoraFlotSlicebar( var font_size = parseInt(font_size); if (font != undefined) - var font = font - .split("/") - .pop() - .split(".") - .shift(); + var font = font + .split("/") + .pop() + .split(".") + .shift(); // Check possible adapt_keys on classes check_adaptions(graph_id); diff --git a/pandora_console/include/help/en/help_reconscript_definition.php b/pandora_console/include/help/en/help_reconscript_definition.php index 3259b34dd2..f7562acbfc 100644 --- a/pandora_console/include/help/en/help_reconscript_definition.php +++ b/pandora_console/include/help/en/help_reconscript_definition.php @@ -7,7 +7,7 @@

    The "ReconScripts" allows to work with more flexible capabilities. The recon scripts are developped in an individual way with completely specific targets, such as the network plugins or the agent plugins. Each ReconScript is different and has one purpose.

    -

    Its basic idea consist on "detect" things in the system it recognizes and automatically log in one monitoring (network, plugin or wmi) so in a completely customized way we could automatically log in requests in an Oracle database, new virtual host in a VmWare that is managed with VirtualCenter or we also can detect new requests in an WebLogic application Server. It is possible to do an script or application that does the task that are wanted and schedule its execution through the Recon Server.

    +

    Its basic idea consist on "detect" things in the system it recognizes and automatically log in one monitoring (network, plugin or wmi) so in a completely customized way we could automatically log in requests in an Oracle database, new virtual host in a VmWare that is managed with VirtualCenter or we also can detect new requests in an WebLogic application Server. It is possible to do an script or application that does the task that are wanted and schedule its execution through the Discovery Server.

    A field with importance is:

    diff --git a/pandora_console/include/help/en/help_recontask.php b/pandora_console/include/help/en/help_recontask.php index 0223d66e5b..b56a0a85c6 100644 --- a/pandora_console/include/help/en/help_recontask.php +++ b/pandora_console/include/help/en/help_recontask.php @@ -11,9 +11,9 @@ If you choose to edit or create a new task of network recon, then you should fil Name of the discovery task. It's only a descriptive value to could distinguish the task in case it would have several of them with different values of filter or template.

    -Recon server
    +Discovery server
    -Recon Server assigned to the task. If you have several Recon Servers, then you have to select here which of them you want to do the recon task.

    +Discovery Server assigned to the task. If you have several Discovery Servers, then you have to select here which of them you want to do the recon task.

    Mode
    diff --git a/pandora_console/include/help/ja/help_recontask.php b/pandora_console/include/help/ja/help_recontask.php index 790c2cdb48..182b249653 100644 --- a/pandora_console/include/help/ja/help_recontask.php +++ b/pandora_console/include/help/ja/help_recontask.php @@ -12,7 +12,7 @@ 検出タスクの名前です。フィルターやテンプレートとは異なり、タスクを区別しやすい説明を入れるだけです。

    -自動検出サーバ(Recon server)
    +自動検出サーバ(Discovery server)
    タスクを割り当てる自動検出サーバです。複数の自動検出サーバがある場合は、自動検出タスクをどのサーバで実行するかを選択します。

    diff --git a/pandora_console/include/styles/discovery.css b/pandora_console/include/styles/discovery.css new file mode 100644 index 0000000000..36711a8474 --- /dev/null +++ b/pandora_console/include/styles/discovery.css @@ -0,0 +1,113 @@ +/* + * Discovery css global + */ + +li.discovery { + display: inline-block; + float: left; + width: 250px; + height: 120px; + margin: 15px; + padding-bottom: 50px; +} + +li.discovery > a { + text-decoration: none; + color: #333; +} +li.discovery > a:hover { + color: #000; +} + +li.discovery img { + height: 90px; +} + +li.discovery > a label { + cursor: pointer; +} + +div.data_container { + width: 100%; + height: 100%; + text-align: center; + padding-top: 30px; + padding-bottom: 30px; +} + +div.data_container:hover { + box-shadow: 2px 2px 10px #ddd; +} + +/* + * TODO: This may be at hostdevices.css + */ +.texto { + height: auto; + text-align: center; +} +h1.wizard { + padding: 0; + margin: 0; + margin-top: -1.25em; +} +h1.wizard a { + margin-left: -20px; +} +h1.wizard a:hover { + color: #fff; +} +#text_wizard { + font-weight: bolder; + text-decoration: none; + font-size: 24px; +} +div.arrow_box { + display: inline-block; + position: relative; + background: #ccc; + color: #888; + padding: 1.3em; + margin-left: 20px; + margin-bottom: 10px; + padding-left: 3em; +} + +.arrow_box:before { + top: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + z-index: 1; +} +.arrow_box.selected { + background: #424242; + color: #ccc; +} + +.arrow_box:after { + left: 0%; + border-left-color: white; + border-width: 20px; + margin-top: -20px; +} + +div.arrow_box:before { + left: 100%; + border-left-color: #ccc; + border-width: 20px; + margin-top: -20px; +} +.arrow_box.selected:before { + border-left-color: #424242; +} + +.arrow_box.selected:hover { + color: #fff; +} +.arrow_box:hover { + color: #000; +} diff --git a/pandora_console/include/styles/hostdevices.css b/pandora_console/include/styles/hostdevices.css new file mode 100644 index 0000000000..461327705e --- /dev/null +++ b/pandora_console/include/styles/hostdevices.css @@ -0,0 +1,3 @@ +/* + * TODO: This may be at hostdevices.css + */ diff --git a/pandora_console/include/styles/menu.css b/pandora_console/include/styles/menu.css index a30978b3a8..001e9a7c32 100644 --- a/pandora_console/include/styles/menu.css +++ b/pandora_console/include/styles/menu.css @@ -167,6 +167,9 @@ li:hover ul { } /* Godmode images */ +#icon_god-discovery { + background: url(../../images/gm_discovery.menu.png) no-repeat 50% 50%; +} #icon_god-resources { background: url(../../images/gm_resources.menu.png) no-repeat 50% 50%; } diff --git a/pandora_console/include/styles/message_edit.css b/pandora_console/include/styles/message_edit.css new file mode 100644 index 0000000000..f4b2294580 --- /dev/null +++ b/pandora_console/include/styles/message_edit.css @@ -0,0 +1,49 @@ +/* Chat containers */ +.container { + border: 2px solid #dedede; + background-color: #f1f1f1; + border-radius: 5px; + padding: 10px; + margin: 10px 0; +} + +/* Darker chat container */ +.darker { + border-color: #ccc; + background-color: #ddd; +} + +/* Clear floats */ +.container::after { + content: ""; + clear: both; + display: table; +} + +/* Style images */ +.container img { + float: left; + max-width: 60px; + width: 100%; + margin-right: 20px; + border-radius: 50%; +} + +/* Style the right image */ +.container img.right { + float: right; + margin-left: 20px; + margin-right: 0; +} + +/* Style time text */ +.time-right { + float: right; + color: #aaa; +} + +/* Style time text */ +.time-left { + float: left; + color: #999; +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 51c7ab8fc5..a194b45a35 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -917,6 +917,13 @@ input.group_item_min[disabled] { background: #fefefe url(../../images/group_green.disabled.png) no-repeat center !important; } +input.color_cloud_min { + background: #fefefe url(../../images/color_cloud_item.png) no-repeat center !important; +} +input.color_cloud_min[disabled] { + background: #fefefe url(../../images/color_cloud_item.disabled.png) no-repeat + center !important; +} div#cont { position: fixed; @@ -1496,14 +1503,12 @@ table.databox { } .databox > thead > tr > th, -.databox > tbody > tr > th { +.databox > tbody > tr > th, +.databox > thead > tr > th a { padding: 9px 7px; font-weight: normal; color: #fff; } -.databox > td { - #border-bottom: 1px solid #e2e2e2; -} .databox > th * { color: #fff; @@ -4250,255 +4255,191 @@ div#dialog_messages table th:last-child { text-align: right; } -/* --- JQUERY-UI --- */ -.ui-button-text-only .ui-button-text { - font-family: "nunito", sans-serif; - font-size: 9pt; - color: #82b92e; +/* + * --------------------------------------------------------------------- + * - Notifications + * --------------------------------------------------------------------- + */ + +.notification-ball { + border: white solid 2px; + border-radius: 50px; + width: 18px; + height: 18px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; } -.ui-datepicker .ui-datepicker-title *, -.ui-datepicker th * { - color: white; -} -.ui-datepicker .ui-datepicker-title select, -.ui-datepicker .ui-datepicker-title option { - color: #111 !important; -} -.ui-dialog .ui-dialog-titlebar { - display: inherit; - text-align: center; - padding: 0.4em 1em; - height: 30px; - position: relative; - background-color: #82b92e !important; -} -.ui-dialog .ui-dialog-title { - font-family: "Nunito", sans-serif; - margin: 0.1em 0 !important; - white-space: nowrap !important; - width: 100% !important; - overflow: hidden !important; - text-overflow: ellipsis !important; - font-size: 11pt; - position: relative; - top: 5px; - float: none !important; -} -.ui-dialog .ui-dialog-titlebar-close { - position: absolute !important; - right: 1em !important; - width: 21px !important; - margin: 0px 0 0 0 !important; - padding: 1px !important; - height: 20px !important; - bottom: 30% !important; - top: 20% !important; -} -.ui-dialog .ui-dialog-content { - position: relative !important; - border: 0; - padding: 0.5em 1em !important; - background: none !important; - overflow: auto !important; - margin-bottom: 1em; -} -.ui-dialog .ui-dialog-buttonpane { - text-align: left; - border-width: 1px 0 0 0; - background-image: none; - margin-top: 0.5em; - padding: 0.3em 1em 0.5em 0.4em; -} -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { - float: right; -} -.ui-dialog .ui-dialog-buttonpane button { - margin: 0.5em 1em 0.5em 0 !important; - cursor: pointer !important; - background: white !important; - background-color: white !important; - border: 1px solid #82b92e !important; - min-height: 35px !important; - width: 90px !important; -} -.ui-widget-content { - background: #ffffff url(include/styles/images/ui-bg_flat_75_ffffff_40x100.png) - 50% 50% repeat-x; -} -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - margin-top: 3px; - border: 1px solid #d3d3d3 !important; - border-bottom: 0 !important; - background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% - repeat-x !important; - font-weight: normal !important; - color: #555555 !important; -} -.ui-corner-all, -.ui-corner-top, -.ui-corner-left, -.ui-corner-tl { - border-top-left-radius: 0 !important; -} -.ui-corner-all, -.ui-corner-top, -.ui-corner-right, -.ui-corner-tr { - border-top-right-radius: 0 !important; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-left, -.ui-corner-bl { - border-bottom-left-radius: 0 !important; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - border-bottom-right-radius: 0 !important; -} -#ui-datepicker-div { - border-color: #b1b1b1; - background: #ffffff; -} -.ui-widget-header { - background: #b1b1b1 !important; - color: #ffffff !important; -} -.ui-datepicker-calendar th { - background-color: #3f3f3f; -} -.ui-dialog .ui-widget-header { + +.notification-ball-no-messages { background-color: #82b92e; + cursor: pointer; } -.ui_tpicker_hour, -.ui_tpicker_minute, -.ui_tpicker_second, -.ui-slider-handle { - border: 1px solid #aaaaaa !important; -} -.ui-timepicker-div dd { - margin: 0px 15px 0px 15px; -} -.ui-timepicker-div .ui-datepicker-title { - color: white; -} -.ui-datepicker-buttonpane button { - border-color: #b1b1b1 !important; -} -.ui-datepicker-buttonpane .ui-datepicker-current { - margin-left: 0.2em !important; -} -.ui-dialog .ui-widget-content { - border: 0px !important; -} -.ui-dialog { - box-shadow: 5px 5px 19px #4e4e4e; - border: 0px !important; - padding: 0 !important; -} -.ui-dialog-titlebar { - border: 0px !important; -} -.ui-dialog-titlebar .ui-icon-closethick, -.ui-dialog-titlebar .ui-state-default, -.ui-dialog-titlebar .ui-state-hover, -.ui-dialog-titlebar button { - background: transparent; - border: 0px; +.notification-ball-new-messages { + background-color: #fc4444; } -.ui-dialog-title { - color: #ffffff; - font-size: 9pt; +#notification-wrapper { + background: white; + border: #a5a5a5 solid 1px; + z-index: 900000; + position: absolute; + width: 400px; + margin-top: -5px; + border-radius: 5px; } -.ui-widget input, -.ui-widget select, -.ui-widget textarea, -.ui-widget button { - font-family: Verdana, Arial, sans-serif !important; +#notification-wrapper::before { + content: ""; + display: block; + position: absolute; + width: 0px; + height: 0; + border-color: transparent; + border-width: 12px; + border-style: solid; + bottom: 100%; + left: 78%; + left: calc(78% - 2px); + margin-left: -12px; + border-bottom-color: white; +} +#notification-wrapper-inner { + max-height: 400px; + overflow: auto; +} +#notification-wrapper-shadow { + height: 100%; + width: 100%; + background: #111; + position: fixed; + z-index: 9009; + top: 0; + opacity: 0.3; +} +.notification-item { + background: whitesmoke; + height: 100px; + margin: 7px; + border: #e4e4e4 solid 1px; + display: flex; + flex-flow: row nowrap; + align-items: center; + padding: 5px; +} +.notification-item:hover { + border: #ccc solid 1px; +} +.notification-item > * { + padding-left: 15px; + pointer-events: none; } -a.ui-button:active, -.ui-button:active, -.ui-button.ui-state-active:hover, -.ui-state-focus .ui-widget-content, -.ui-state-focus .ui-widget-header, -.ui-state-focus .ui-button:hover, -.ui-button:focus { - background: transparent !important; - border: none !important; +.notification-item:hover { + text-decoration: none; } -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-widget-header .ui-state-hover { - border: 1px solid #999999 !important; - border-bottom: 0 !important; - background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% - repeat-x !important; +.notification-info { + width: 87%; + display: flex; + flex-flow: column nowrap; + overflow: hidden; + max-height: 83px; + line-height: 1.4em; +} +.notification-item img { + max-width: 100%; + max-height: 100%; +} +.notification-title { + margin: 0; +} +.notification-subtitle { + margin: 0; + color: #373737; } -.ui-state-active, -.ui-widget-content .ui-state-active, -.ui-widget-header .ui-state-active { - border: 1px solid #aaaaaa !important; - border-bottom: 0 !important; - background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% - repeat-x !important; - font-weight: normal !important; - color: #212121 !important; -} -.ui-state-active a, -.ui-state-active a:link, -.ui-state-active a:visited { - color: #212121 !important; +.global-config-notification-title { + display: flex; + flex-direction: row; + align-items: center; } -ul.ui-front { - z-index: 1000000 !important; - padding-right: 0px !important; +.global-config-notification-title h2 { + margin-left: 10px; } -ul.ui-front li { - padding: 3px !important; +.global-config-notification-checkboxes :first-child { + font-weight: bold; } -ul.ui-front li:hover { - background-color: #e1e3e1 !important; +.global-config-notification-selectors { + display: flex; + flex-direction: row; + margin-bottom: 10px; } -ul.ui-front li a.ui-menu-item-wrapper { - background: transparent !important; - border: none !important; +.global-config-notification-selectors h4 { + margin: 0; } -ul.ui-front li a.ui-menu-item-wrapper span { - padding-left: 5px !important; +.global-config-notification-single-selector, +.global_config_notifications_dialog_add select { + display: flex; + width: 100%; + padding: 0 10px; } -ul.ui-front li a.ui-menu-item-wrapper:hover { - text-decoration: none !important; +.global-config-notification-single-selector :first-child, +.global-config-notification-single-selector :first-child select { + width: 99%; } -/* --- END - JQUERY-UI --- */ -.toogle_switch { +.global-config-notification-single-selector :last-child, +.global_config_notifications_dialog_add_wrapper { + flex-direction: column; + display: flex; + justify-content: flex-end; +} + +.global_config_notifications_dialog_add { + display: flex; + flex-direction: row; + margin: 8px; +} + +.global_config_notifications_two_ways_form_arrows { + display: flex; + flex-flow: column; + justify-content: center; + margin: 0 5px; +} + +.global_config_notifications_two_ways_form_arrows img { + margin: 15px 0; +} + +/* jQuery dialog */ +.no-close .ui-dialog-titlebar-close { + display: none; +} +/* jQuery dialog */ + +/* --- SWITCH --- */ +.p-switch { position: relative; display: inline-block; width: 30px; height: 17px; } -.toogle_switch input { +.p-switch input { opacity: 0; width: 0; height: 0; } -.slider { +.p-slider { position: absolute; cursor: pointer; top: 0; @@ -4511,7 +4452,7 @@ ul.ui-front li a.ui-menu-item-wrapper:hover { border-radius: 34px; } -.slider:before { +.p-slider:before { position: absolute; content: ""; height: 13px; @@ -4524,22 +4465,105 @@ ul.ui-front li a.ui-menu-item-wrapper:hover { border-radius: 50%; } -input:checked + .slider { +input:checked + .p-slider { background-color: #82b92e; } -input:focus + .slider { +input:focus + .p-slider { box-shadow: 0 0 1px #82b92e; } -input:checked + .slider:before { +input:checked + .p-slider:before { -webkit-transform: translateX(13px); -ms-transform: translateX(13px); transform: translateX(13px); } -/* jQuery dialog */ -.no-close .ui-dialog-titlebar-close { - display: none; +/* --- END SWITCH --- */ + +/* --- TOAST --- */ +#notifications-toasts-wrapper { + position: fixed; + right: 20px; + top: 70px; + width: 270px; + height: 100%; + z-index: 6; + pointer-events: none; } -/* --- END - JQUERY-UI --- */ + +.snackbar { + max-width: 270px; + background-color: #333; + color: #fff; + text-align: center; + /* border-radius: 2px; */ + padding: 16px; + margin: 10px; + border-radius: 4px; + visibility: hidden; + pointer-events: all; +} + +.snackbar.show { + visibility: visible; + -webkit-animation: fadein 0.5s, fadeout 0.5s 7.5s; + animation: fadein 0.5s, fadeout 0.5s 7.5s; +} + +.snackbar p, +.snackbar h3 { + text-align: left; + margin: 0; + pointer-events: none; +} +.snackbar h3 { + color: white; + margin-bottom: 10px; +} + +@-webkit-keyframes fadein { + from { + bottom: 0; + opacity: 0; + } + to { + bottom: 30px; + opacity: 1; + } +} + +@keyframes fadein { + from { + bottom: 0; + opacity: 0; + } + to { + bottom: 30px; + opacity: 1; + } +} + +@-webkit-keyframes fadeout { + from { + bottom: 30px; + opacity: 1; + } + to { + bottom: 0; + opacity: 0; + } +} + +@keyframes fadeout { + from { + bottom: 30px; + opacity: 1; + } + to { + bottom: 0; + opacity: 0; + } +} + +/* --- END TOAST --- */ diff --git a/pandora_console/include/styles/wizard.css b/pandora_console/include/styles/wizard.css new file mode 100644 index 0000000000..869ea85f2c --- /dev/null +++ b/pandora_console/include/styles/wizard.css @@ -0,0 +1,25 @@ +/* + * Discovery > Wizard css global style + */ + +ul.wizard { +} + +ul.wizard li { + padding: 10px; +} + +ul.wizard li > label:not(.p-switch) { + width: 250px; + vertical-align: top; + display: inline-block; +} + +ul.wizard li > textarea { + width: 250px; + display: inline-block; +} + +.hidden { + display: none; +} diff --git a/pandora_console/install.php b/pandora_console/install.php new file mode 100644 index 0000000000..996fff9dcc --- /dev/null +++ b/pandora_console/install.php @@ -0,0 +1,1105 @@ + + + + + Pandora FMS - Installation Wizard + + + + + + + + + + + + + + + +
    + +
    + + + +
    '; +} + +function check_include($ext, $label) +{ + echo ''; +} + + +function check_exists($file, $label) +{ + echo ''; +} + + +function check_generic($ok, $label) +{ + echo "'; + echo ''; + return 1; + } else { + echo " "; + echo ''; + echo ''; + return 0; + } +} + + +function check_writable($fullpath, $label) +{ + echo "'; + echo ''; + return 0; + } else { + echo " "; + echo ''; + echo ''; + return 1; + } + } else { + echo " "; + echo ''; + echo ''; + return 1; + } +} + + +function check_variable($var, $value, $label, $mode) +{ + echo ''; +} + + +function parse_mysql_dump($url) +{ + if (file_exists($url)) { + $file_content = file($url); + $query = ''; + foreach ($file_content as $sql_line) { + if (trim($sql_line) != '' && strpos($sql_line, '-- ') === false) { + $query .= $sql_line; + if (preg_match("/;[\040]*\$/", $sql_line)) { + if (!$result = mysql_query($query)) { + echo mysql_error(); + // Uncomment for debug + echo "
    $query
    "; + return 0; + } + + $query = ''; + } + } + } + + return 1; + } else { + return 0; + } +} + + +function parse_mysqli_dump($connection, $url) +{ + if (file_exists($url)) { + $file_content = file($url); + $query = ''; + foreach ($file_content as $sql_line) { + if (trim($sql_line) != '' && strpos($sql_line, '-- ') === false) { + $query .= $sql_line; + if (preg_match("/;[\040]*\$/", $sql_line)) { + if (!$result = mysqli_query($connection, $query)) { + echo mysqli_error(); + // Uncomment for debug + echo "
    $query
    "; + return 0; + } + + $query = ''; + } + } + } + + return 1; + } else { + return 0; + } +} + + +function random_name($size) +{ + $temp = ''; + for ($a = 0; $a < $size; $a++) { + $temp = $temp.chr(rand(122, 97)); + } + + return $temp; +} + + +function print_logo_status($step, $step_total) +{ + global $banner; + + $header = " +
    +
    +
    + $banner +
    +
    "; + $header .= " +
    + Install step $step of $step_total +
    "; + + return $header; +} + + +// +// This function adjusts path settings in pandora db for FreeBSD. +// +// All packages and configuration files except operating system's base files +// are installed under /usr/local in FreeBSD. So, path settings in pandora db +// for some programs should be changed from the Linux default. +// +function adjust_paths_for_freebsd($engine, $connection=false) +{ + $adjust_sql = [ + "update trecon_script set script = REPLACE(script,'/usr/share','/usr/local/share');", + "update tconfig set value = REPLACE(value,'/usr/bin','/usr/local/bin') where token='netflow_daemon' OR token='netflow_nfdump' OR token='netflow_nfexpire';", + "update talert_commands set command = REPLACE(command,'/usr/bin','/usr/local/bin');", + "update talert_commands set command = REPLACE(command,'/usr/share', '/usr/local/share');", + "update tplugin set execute = REPLACE(execute,'/usr/share','/usr/local/share');", + "update tevent_response set target = REPLACE(target,'/usr/share','/usr/local/share');", + "insert into tconfig (token, value) VALUES ('graphviz_bin_dir', '/usr/local/bin');", + ]; + + for ($i = 0; $i < count($adjust_sql); $i++) { + switch ($engine) { + case 'mysql': + $result = mysql_query($adjust_sql[$i]); + break; + + case 'mysqli': + $result = mysqli_query($connection, $adjust_sql[$i]); + break; + + case 'oracle': + // Delete the last semicolon from current query + $query = substr($adjust_sql[$i], 0, (strlen($adjust_sql[$i]) - 1)); + $sql = oci_parse($connection, $query); + $result = oci_execute($sql); + break; + + case 'pgsql': + pg_send_query($connection, $adjust_sql[$i]); + $result = pg_get_result($connection); + break; + } + + if (!$result) { + return 0; + } + } + + return 1; +} + + +function install_step1() +{ + global $banner; + + echo " +
    +
    + ".print_logo_status(1, 6)." +
    +

    Welcome to Pandora FMS installation Wizard

    +

    This wizard helps you to quick install Pandora FMS console and main database in your system.

    +

    In four steps, this installer will check all dependencies and will create your configuration, ready to use.

    +

    For more information, please refer to documentation.
    + Pandora FMS Development Team

    + "; + if (file_exists('include/config.php')) { + echo "
    Warning: You already have a config.php file. + Configuration and database would be overwritten if you continued.
    "; + } + + echo '
    '; + echo '
    '; + echo " $label "; + echo ''; + if (!extension_loaded($ext)) { + echo ""; + return 1; + } else { + echo ""; + return 0; + } + + echo '
    '; + echo " $label "; + echo ''; + if (!include $ext) { + echo ""; + return 1; + } else { + echo ""; + return 0; + } + + echo '
    '; + echo " $label "; + echo ''; + if (!file_exists($file)) { + echo " "; + return 1; + } else { + echo " "; + return 0; + } + + echo '
    "; + if ($ok == 0) { + echo " "; + echo ''; + echo " $label "; + echo '
    '; + echo " $label "; + echo '
    "; + if (file_exists($fullpath)) { + if (is_writable($fullpath)) { + echo " "; + echo ''; + echo " $label "; + echo '
    '; + echo " $label "; + echo '
    '; + echo " $label "; + echo '
    '; + echo " $label "; + echo ''; + if ($mode == 1) { + if ($var >= $value) { + echo " "; + return 0; + } else { + echo " "; + return 1; + } + } else if ($var == $value) { + echo " "; + return 0; + } else { + echo " "; + return 1; + } + + echo '
    '; + $writable = check_writable('include', 'Checking if ./include is writable'); + if (file_exists('include/config.php')) { + $writable += check_writable('include/config.php', 'Checking if include/config.php is writable'); + } + + echo '
    '; + + echo "
    Warning: This installer will overwrite and destroy + your existing Pandora FMS configuration and Database. Before continue, + please be sure that you have no valuable Pandora FMS data in your Database.
    +
    "; + + echo "
    Upgrade: + If you want to upgrade from Pandora FMS 4.x to 5.0 version, please use the migration tool inside /extras directory in this setup. +
    "; + + echo '
    '; + + if ($writable == 0) { + echo "
    "; + echo ""; + echo '
    '; + } else { + echo "
    ERROR:You need to setup permissions to be able to write in ./include directory
    "; + } + + echo ''; + + echo "
    "; + echo " + +
    + Pandora FMS is an OpenSource Software project registered at + SourceForge +
    + "; +} + + +function install_step1_licence() +{ + echo " +
    +
    + ".print_logo_status(2, 6)." +
    +

    GPL2 Licence terms agreement

    +

    Pandora FMS is an OpenSource software project licensed under the GPL2 licence. Pandora FMS includes, as well, another software also licensed under LGPL and BSD licenses. Before continue, you must accept the licence terms.. +

    For more information, please refer to our website at http://pandorafms.org and contact us if you have any kind of question about the usage of Pandora FMS

    +

    If you dont accept the licence terms, please, close your browser and delete Pandora FMS files.

    + "; + + if (!file_exists('COPYING')) { + echo "
    Licence file 'COPYING' is not present in your distribution. This means you have some 'partial' Pandora FMS distribution. We cannot continue without accepting the licence file."; + echo '
    '; + } else { + echo "
    "; + echo "'; + echo '

    '; + echo "

    "; + } + + echo '
    '; + + echo "
    +
    +
    + Pandora FMS is an OpenSource Software project registered at + SourceForge +
    +
    "; +} + + +function install_step2() +{ + echo " +
    +
    + ".print_logo_status(3, 6)." +
    "; + echo '

    Checking software dependencies

    '; + echo ''; + $res = 0; + $res += check_variable(phpversion(), '7.0', 'PHP version >= 7.0', 1); + $res += check_extension('gd', 'PHP GD extension'); + $res += check_extension('ldap', 'PHP LDAP extension'); + $res += check_extension('snmp', 'PHP SNMP extension'); + $res += check_extension('session', 'PHP session extension'); + $res += check_extension('gettext', 'PHP gettext extension'); + $res += check_extension('mbstring', 'PHP Multibyte String'); + $res += check_extension('zip', 'PHP Zip'); + $res += check_extension('zlib', 'PHP Zlib extension'); + $res += check_extension('json', 'PHP json extension'); + $res += check_extension('curl', 'CURL (Client URL Library)'); + $res += check_extension('filter', 'PHP filter extension'); + $res += check_extension('calendar', 'PHP calendar extension'); + if (PHP_OS == 'FreeBSD') { + $res += check_exists('/usr/local/bin/twopi', 'Graphviz Binary'); + } else if (PHP_OS == 'NetBSD') { + $res += check_exists('/usr/pkg/bin/twopi', 'Graphviz Binary'); + } else if (substr(PHP_OS, 0, 3) == 'WIN') { + $res += check_exists("..\\..\\..\\Graphviz\\bin\\twopi.exe", 'Graphviz Binary'); + } else { + $res += check_exists('/usr/bin/twopi', 'Graphviz Binary'); + } + + echo ''; + check_extension('mysqli', 'PHP MySQL(mysqli) extension'); + echo '
    '; + echo "DB Engines"; + echo ''; + echo '
    '; + + if ($res > 0) { + echo " +
    You have some incomplete + dependencies. Please correct them or this installer + will not be able to finish your installation. +
    +
    + Remember, if you install any PHP module to comply + with these dependences, you need to restart + your HTTP/Apache server after it to use the new + modules. +
    +
    + Ignore it. +
    "; + } else { + echo "
    "; + echo " + "; + echo '
    '; + } + + echo '
    '; + echo "
    "; + echo " +
    +
    +
    +
    + Pandora FMS is an OpenSource Software project registered at + SourceForge +
    + "; +} + + +function install_step3() +{ + $options = ''; + if (extension_loaded('mysql')) { + $options .= ""; + } + + if (extension_loaded('mysqli')) { + $options .= ""; + } + + $error = false; + if (empty($options)) { + $error = true; + } + + echo " +
    +
    + ".print_logo_status(4, 6)." +
    +

    Environment and database setup

    +

    + This wizard will create your Pandora FMS database, + and populate it with all the data needed to run for the first time. +

    +

    + You need a privileged user to create database schema, this is usually root user. + Information about root user will not be used or stored anymore. +

    +

    + You can also deploy the scheme into an existing Database. + In this case you need a privileged Database user and password of that instance. +

    +

    + Now, please, complete all details to configure your database and environment setup. +

    +
    + Warning: This installer will overwrite and destroy your existing + Pandora FMS configuration and Database. Before continue, + please be sure that you have no valuable Pandora FMS data in your Database. +

    +
    "; + + if (extension_loaded('oci8')) { + echo "
    For Oracle installation an existing Database with a privileged user is needed.
    "; + } + + if (!$error) { + echo ""; + } + + echo ""; + echo '"; + + // the field dbgrant is only shown when the DB host is different from 127.0.0.1 or localhost + echo " + + "; + + echo " "; + + echo ""; + echo '
    '; + echo 'DB Engine
    '; + + if ($error) { + echo " +
    + Warning: You haven't a any DB engine with PHP. Please check the previous step to DB engine dependencies. +
    "; + } else { + echo "'; + + echo '
    '; + echo ' Installation in
    '; + echo "'; + } + + echo "
    DB User with privileges
    + + +
    DB Password for this user
    + + +
    DB Hostname
    + + +
    DB Name (pandora by default)
    + + +
    Drop Database if exists
    + +
    Full path to HTTP publication directory
    + For example /var/www/pandora_console/ +
    + + +
    '; + echo "URL path to Pandora FMS Console
    + For example '/pandora_console' +
    + +
    + "; + + if (!$error) { + echo "
    "; + echo " + "; + echo '
    '; + ?> + + '; + + echo ''; + + echo "
    "; + echo "
    +
    + Pandora FMS is an OpenSource Software project registered at + SourceForge +
    +
    "; +} + + +function install_step4() +{ + $pandora_config = 'include/config.php'; + + if ((! isset($_POST['user'])) || (! isset($_POST['dbname'])) || (! isset($_POST['host'])) + || (! isset($_POST['pass'])) || (!isset($_POST['engine'])) || (! isset($_POST['db_action'])) + ) { + $dbpassword = ''; + $dbuser = ''; + $dbhost = ''; + $dbname = ''; + $engine = ''; + $dbaction = ''; + $dbgrant = ''; + } else { + $engine = $_POST['engine']; + $dbpassword = $_POST['pass']; + $dbuser = $_POST['user']; + $dbhost = $_POST['host']; + $dbaction = $_POST['db_action']; + if (isset($_POST['dbgrant']) && $_POST['dbgrant'] != '') { + $dbgrant = $_POST['dbgrant']; + } else { + $dbgrant = $_SERVER['SERVER_ADDR']; + } + + if (isset($_POST['drop'])) { + $dbdrop = $_POST['drop']; + } else { + $dbdrop = 0; + } + + $dbname = $_POST['dbname']; + if (isset($_POST['url'])) { + $url = $_POST['url']; + } else { + $url = 'http://localhost'; + } + + if (isset($_POST['path'])) { + $path = $_POST['path']; + $path = str_replace('\\', '/', $path); + // Windows compatibility + } else { + $path = '/var/www'; + } + } + + $everything_ok = 0; + $step1 = 0; + $step2 = 0; + $step3 = 0; + $step4 = 0; + $step5 = 0; + $step6 = 0; + $step7 = 0; + + echo " +
    +
    + ".print_logo_status(5, 6)." +
    +

    Creating database and default configuration file

    + "; + switch ($engine) { + case 'mysql': + if (! mysql_connect($dbhost, $dbuser, $dbpassword)) { + check_generic(0, 'Connection with Database'); + } else { + check_generic(1, 'Connection with Database'); + + // Drop database if needed and don't want to install over an existing DB + if ($dbdrop == 1) { + mysql_query("DROP DATABASE IF EXISTS `$dbname`"); + } + + // Create schema + if ($dbaction == 'db_new' || $dbdrop == 1) { + $step1 = mysql_query("CREATE DATABASE `$dbname`"); + check_generic($step1, "Creating database '$dbname'"); + } else { + $step1 = 1; + } + + if ($step1 == 1) { + $step2 = mysql_select_db($dbname); + check_generic($step2, "Opening database '$dbname'"); + + $step3 = parse_mysql_dump('pandoradb.sql'); + check_generic($step3, 'Creating schema'); + + $step4 = parse_mysql_dump('pandoradb_data.sql'); + check_generic($step4, 'Populating database'); + if (PHP_OS == 'FreeBSD') { + $step_freebsd = adjust_paths_for_freebsd($engine); + check_generic($step_freebsd, 'Adjusting paths in database for FreeBSD'); + } + + $random_password = random_name(8); + $host = $dbhost; + // set default granted origin to the origin of the queries + if (($dbhost != 'localhost') && ($dbhost != '127.0.0.1')) { + $host = $dbgrant; + // if the granted origin is different from local machine, set the valid origin + } + + $step5 = mysql_query( + "GRANT ALL PRIVILEGES ON `$dbname`.* to pandora@$host + IDENTIFIED BY '".$random_password."'" + ); + mysql_query('FLUSH PRIVILEGES'); + check_generic($step5, "Established privileges for user pandora. A new random password has been generated: $random_password
    Please write it down, you will need to setup your Pandora FMS server, editing the /etc/pandora/pandora_server.conf file
    "); + + $step6 = is_writable('include'); + check_generic($step6, "Write permissions to save config file in './include'"); + + $cfgin = fopen('include/config.inc.php', 'r'); + $cfgout = fopen($pandora_config, 'w'); + $config_contents = fread($cfgin, filesize('include/config.inc.php')); + $dbtype = 'mysql'; + $config_new = ''; + $step7 = fputs($cfgout, $config_new); + $step7 = ($step7 + fputs($cfgout, $config_contents)); + if ($step7 > 0) { + $step7 = 1; + } + + fclose($cfgin); + fclose($cfgout); + chmod($pandora_config, 0600); + check_generic($step7, "Created new config file at '".$pandora_config."'"); + } + } + + if (($step7 + $step6 + $step5 + $step4 + $step3 + $step2 + $step1) == 7) { + $everything_ok = 1; + } + break; + + case 'mysqli': + $connection = mysqli_connect($dbhost, $dbuser, $dbpassword); + if (mysqli_connect_error() > 0) { + check_generic(0, 'Connection with Database'); + } else { + check_generic(1, 'Connection with Database'); + + // Drop database if needed and don't want to install over an existing DB + if ($dbdrop == 1) { + mysqli_query($connection, "DROP DATABASE IF EXISTS `$dbname`"); + } + + // Create schema + if ($dbaction == 'db_new' || $dbdrop == 1) { + $step1 = mysqli_query($connection, "CREATE DATABASE `$dbname`"); + check_generic($step1, "Creating database '$dbname'"); + } else { + $step1 = 1; + } + + if ($step1 == 1) { + $step2 = mysqli_select_db($connection, $dbname); + check_generic($step2, "Opening database '$dbname'"); + + $step3 = parse_mysqli_dump($connection, 'pandoradb.sql'); + check_generic($step3, 'Creating schema'); + + $step4 = parse_mysqli_dump($connection, 'pandoradb_data.sql'); + check_generic($step4, 'Populating database'); + if (PHP_OS == 'FreeBSD') { + $step_freebsd = adjust_paths_for_freebsd($engine, $connection); + check_generic($step_freebsd, 'Adjusting paths in database for FreeBSD'); + } + + $random_password = random_name(8); + $host = $dbhost; + // set default granted origin to the origin of the queries + if (($dbhost != 'localhost') && ($dbhost != '127.0.0.1')) { + $host = $dbgrant; + // if the granted origin is different from local machine, set the valid origin + } + + $step5 = mysqli_query( + $connection, + "GRANT ALL PRIVILEGES ON `$dbname`.* to pandora@$host + IDENTIFIED BY '".$random_password."'" + ); + mysqli_query($connection, 'FLUSH PRIVILEGES'); + check_generic($step5, "Established privileges for user pandora. A new random password has been generated: $random_password
    Please write it down, you will need to setup your Pandora FMS server, editing the /etc/pandora/pandora_server.conf file
    "); + + $step6 = is_writable('include'); + check_generic($step6, "Write permissions to save config file in './include'"); + + $cfgin = fopen('include/config.inc.php', 'r'); + $cfgout = fopen($pandora_config, 'w'); + $config_contents = fread($cfgin, filesize('include/config.inc.php')); + $dbtype = 'mysql'; + $config_new = ''; + $step7 = fputs($cfgout, $config_new); + $step7 = ($step7 + fputs($cfgout, $config_contents)); + if ($step7 > 0) { + $step7 = 1; + } + + fclose($cfgin); + fclose($cfgout); + chmod($pandora_config, 0600); + check_generic($step7, "Created new config file at '".$pandora_config."'"); + } + } + + if (($step7 + $step6 + $step5 + $step4 + $step3 + $step2 + $step1) == 7) { + $everything_ok = 1; + } + break; + } + + echo '
    '; + + if ($everything_ok == 1) { + echo "
    "; + echo " + "; + echo '
    '; + } else { + $info = "
    There were some problems. + Installation was not completed. +

    Please correct failures before trying again. + All database "; + if ($engine == 'oracle') { + $info .= 'objects '; + } else { + $info .= 'schemes '; + } + + $info .= 'created in this step have been dropped.

    +
    '; + echo $info; + + switch ($engine) { + case 'mysql': + if (mysql_error() != '') { + echo "
    ERROR: ".mysql_error().'.
    '; + } + + if ($step1 == 1) { + mysql_query("DROP DATABASE $dbname"); + } + break; + + case 'mysqli': + if (mysqli_error($connection) != '') { + echo "
    ERROR: ".mysqli_error($connection).'.
    '; + } + + if ($step1 == 1) { + mysqli_query($connection, "DROP DATABASE $dbname"); + } + break; + } + + echo '
    '; + } + + echo '
    '; + echo "
    "; + echo " +
    +
    + Pandora FMS is an Open Source Software project registered at + SourceForge +
    +
    "; +} + + +function install_step5() +{ + echo " +
    +
    + ".print_logo_status(6, 6)." +
    +

    Installation complete

    +

    For security, you now must manually delete this installer + ('install.php') file before trying to access to your Pandora FMS console. +

    You should also install Pandora FMS Servers before trying to monitor anything; + please read documentation on how to install it.

    +

    Default user is 'admin' with password 'pandora', + please change it both as soon as possible.

    +

    Don't forget to check http://pandorafms.com + for updates. +

    Select if you want to rename 'install.php'.

    +
    + + +
    +


    . +

    +
    "; + + echo "
    +
    + Pandora FMS is an OpenSource Software project registered at + SourceForge +
    +
    "; +} diff --git a/pandora_console/operation/agentes/status_monitor.php b/pandora_console/operation/agentes/status_monitor.php index b0a3762d72..0dd536ac7f 100644 --- a/pandora_console/operation/agentes/status_monitor.php +++ b/pandora_console/operation/agentes/status_monitor.php @@ -37,35 +37,37 @@ enterprise_include_once('include/functions_metaconsole.php'); $isFunctionPolicies = enterprise_include_once('include/functions_policies.php'); if (! defined('METACONSOLE')) { - $section = (string) get_parameter ("section", "view"); + $section = (string) get_parameter('section', 'view'); - $buttons['fields'] = array('active' => false, - 'text' => '' . - html_print_image("images/custom_columns.png", true, array("title" => __('Custom fields'))) . '', - 'operation' => true); + $buttons['fields'] = [ + 'active' => false, + 'text' => ''.html_print_image('images/custom_columns.png', true, ['title' => __('Custom fields')]).'', + 'operation' => true, + ]; - $buttons['view'] = array('active' => false, - 'text' => '' . - html_print_image("images/list.png", true, array("title" => __('View'))) . '', - 'operation' => true); + $buttons['view'] = [ + 'active' => false, + 'text' => ''.html_print_image('images/list.png', true, ['title' => __('View')]).'', + 'operation' => true, + ]; switch ($section) { case 'fields': $buttons['fields']['active'] = true; - $subpage = ' - ' . __('Custom fields'); - break; + $subpage = ' - '.__('Custom fields'); + break; + default: $buttons['view']['active'] = true; - break; + break; } - ui_print_page_header (__("Monitor detail") . $subpage, "", false, "", true, $buttons); - - if ($section == 'fields') { - require_once($config["homedir"] . '/godmode/agentes/status_monitor_custom_fields.php'); - exit(); - } + ui_print_page_header(__('Monitor detail').$subpage, '', false, '', true, $buttons); + if ($section == 'fields') { + include_once $config['homedir'].'/godmode/agentes/status_monitor_custom_fields.php'; + exit(); + } } else { ui_meta_print_header(__('Monitor view')); } @@ -1058,587 +1060,594 @@ if (($config['dbtype'] == 'oracle') && ($result !== false)) { // Start Build List Result // if (!empty($result)) { - $table = new StdClass(); - $table->cellpadding = 0; - $table->cellspacing = 0; - $table->width = '100%'; - $table->class = 'databox data'; - $table->head = array (); - $table->data = array (); - $table->size = array (); - $table->align = array (); + $table = new StdClass(); + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->width = '100%'; + $table->class = 'databox data'; + $table->head = []; + $table->data = []; + $table->size = []; + $table->align = []; - $show_fields = explode (',', $config['status_monitor_fields']); + $show_fields = explode(',', $config['status_monitor_fields']); - if (in_array('policy', $show_fields)) { - if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) - $table->head[0] = '' . __('P.') . ''; - } + if (in_array('policy', $show_fields)) { + if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) { + $table->head[0] = ''.__('P.').''; + } + } - if (in_array('agent', $show_fields) || is_metaconsole()) { - $table->head[1] = __('Agent'); - $table->head[1] .=' ' . html_print_image('images/sort_up.png', true, array('style' => $selectAgentNameUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectAgentNameDown, 'alt' => 'down')) . ''; - } + if (in_array('agent', $show_fields) || is_metaconsole()) { + $table->head[1] = __('Agent'); + $table->head[1] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectAgentNameUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectAgentNameDown, 'alt' => 'down']).''; + } - if (in_array('data_type', $show_fields) || is_metaconsole()) { - $table->head[2] = __('Data Type'); - $table->head[2] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectTypeUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectTypeDown, 'alt' => 'down')) . ''; + if (in_array('data_type', $show_fields) || is_metaconsole()) { + $table->head[2] = __('Data Type'); + $table->head[2] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectTypeUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectTypeDown, 'alt' => 'down']).''; - $table->align[2] = 'left'; - } + $table->align[2] = 'left'; + } - if (in_array('module_name', $show_fields) || is_metaconsole()) { - $table->head[3] = __('Module name'); - $table->head[3] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectModuleNameUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectModuleNameDown, 'alt' => 'down')) . ''; - } + if (in_array('module_name', $show_fields) || is_metaconsole()) { + $table->head[3] = __('Module name'); + $table->head[3] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectModuleNameUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectModuleNameDown, 'alt' => 'down']).''; + } - if (in_array('server_type', $show_fields) || is_metaconsole()) { - $table->head[4] = __('Server type'); - $table->head[4] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectModuleNameUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectModuleNameDown, 'alt' => 'down')) . ''; - } + if (in_array('server_type', $show_fields) || is_metaconsole()) { + $table->head[4] = __('Server type'); + $table->head[4] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectModuleNameUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectModuleNameDown, 'alt' => 'down']).''; + } - if (in_array('interval', $show_fields) || is_metaconsole()) { - $table->head[5] = __('Interval'); - $table->head[5] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectIntervalUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectIntervalDown, 'alt' => 'down')) . ''; - $table->align[5] = 'left'; - } + if (in_array('interval', $show_fields) || is_metaconsole()) { + $table->head[5] = __('Interval'); + $table->head[5] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectIntervalUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectIntervalDown, 'alt' => 'down']).''; + $table->align[5] = 'left'; + } - if (in_array('status', $show_fields) || is_metaconsole()) { - $table->head[6] = __('Status'); - $table->head[6] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectStatusUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectStatusDown, 'alt' => 'down')) . ''; + if (in_array('status', $show_fields) || is_metaconsole()) { + $table->head[6] = __('Status'); + $table->head[6] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectStatusUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectStatusDown, 'alt' => 'down']).''; - $table->align[6] = 'left'; - } + $table->align[6] = 'left'; + } - if (in_array('graph', $show_fields) || is_metaconsole()) { - $table->head[7] = __('Graph'); - $table->align[7] = 'left'; - } + if (in_array('graph', $show_fields) || is_metaconsole()) { + $table->head[7] = __('Graph'); + $table->align[7] = 'left'; + } - if (in_array('warn', $show_fields) || is_metaconsole()) { - $table->head[8] = __('Warn'); - $table->align[8] = 'left'; - } + if (in_array('warn', $show_fields) || is_metaconsole()) { + $table->head[8] = __('Warn'); + $table->align[8] = 'left'; + } - if (in_array('data', $show_fields) || is_metaconsole()) { - $table->head[9] = __('Data'); - $table->align[9] = 'left'; - if ( is_metaconsole() ) { - $table->head[9] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectStatusUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectStatusDown, 'alt' => 'down')) . ''; - } - } + if (in_array('data', $show_fields) || is_metaconsole()) { + $table->head[9] = __('Data'); + $table->align[9] = 'left'; + if (is_metaconsole()) { + $table->head[9] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectStatusUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectStatusDown, 'alt' => 'down']).''; + } + } - if (in_array('timestamp', $show_fields) || is_metaconsole()) { - $table->head[10] = __('Timestamp'); - $table->head[10] .= ' ' . html_print_image('images/sort_up.png', true, array('style' => $selectTimestampUp, 'alt' => 'up')) . '' . - '' . html_print_image('images/sort_down.png', true, array('style' => $selectTimestampDown, 'alt' => 'down')) . ''; - $table->align[10] = 'left'; - } + if (in_array('timestamp', $show_fields) || is_metaconsole()) { + $table->head[10] = __('Timestamp'); + $table->head[10] .= ' '.html_print_image('images/sort_up.png', true, ['style' => $selectTimestampUp, 'alt' => 'up']).''.''.html_print_image('images/sort_down.png', true, ['style' => $selectTimestampDown, 'alt' => 'down']).''; + $table->align[10] = 'left'; + } - if (in_array('to_critical', $show_fields)) { - $table->head[11] = __('Last status change'); - } + if (in_array('to_critical', $show_fields)) { + $table->head[11] = __('Last status change'); + } - $id_type_web_content_string = db_get_value('id_tipo', 'ttipo_modulo', - 'nombre', 'web_content_string'); + $id_type_web_content_string = db_get_value( + 'id_tipo', + 'ttipo_modulo', + 'nombre', + 'web_content_string' + ); - foreach ($result as $row) { + foreach ($result as $row) { + // Avoid unset, null and false value + if (empty($row['server_name'])) { + $row['server_name'] = ''; + } - //Avoid unset, null and false value - if (empty($row['server_name'])) - $row['server_name'] = ""; + $is_web_content_string = (bool) db_get_value_filter( + 'id_agente_modulo', + 'tagente_modulo', + [ + 'id_agente_modulo' => $row['id_agente_modulo'], + 'id_tipo_modulo' => $id_type_web_content_string, + ] + ); - $is_web_content_string = (bool)db_get_value_filter('id_agente_modulo', - 'tagente_modulo', - array('id_agente_modulo' => $row['id_agente_modulo'], - 'id_tipo_modulo' => $id_type_web_content_string)); + // Fixed the goliat sends the strings from web + // without HTML entities + if ($is_web_content_string) { + $row['datos'] = io_safe_input($row['datos']); + } - //Fixed the goliat sends the strings from web - //without HTML entities - if ($is_web_content_string) { - $row['datos'] = io_safe_input($row['datos']); - } + // Fixed the data from Selenium Plugin + if ($row['datos'] != strip_tags($row['datos'])) { + $row['datos'] = io_safe_input($row['datos']); + } - //Fixed the data from Selenium Plugin - if ($row['datos'] != strip_tags($row['datos'])) { - $row['datos'] = io_safe_input($row['datos']); - } + $data = []; - $data = array (); + if (in_array('policy', $show_fields) || is_metaconsole()) { + if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) { + if (is_metaconsole()) { + $node = metaconsole_get_connection_by_id($row['server_id']); + if (metaconsole_load_external_db($node) !== NOERR) { + // Restore the default connection. + metaconsole_restore_db(); + $errors++; + break; + } + } - if (in_array('policy', $show_fields) || is_metaconsole()) { - if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) { - if(is_metaconsole()){ - $node = metaconsole_get_connection_by_id($row['server_id']); - if (metaconsole_load_external_db($node) !== NOERR) { - // Restore the default connection. - metaconsole_restore_db(); - $errors++; - break; - } - } + $policyInfo = policies_info_module_policy($row['id_agente_modulo']); - $policyInfo = policies_info_module_policy($row['id_agente_modulo']); + if ($policyInfo === false) { + $data[0] = ''; + } else { + $linked = policies_is_module_linked($row['id_agente_modulo']); - if ($policyInfo === false) - $data[0] = ''; - else { - $linked = policies_is_module_linked($row['id_agente_modulo']); + $adopt = false; + if (policies_is_module_adopt($row['id_agente_modulo'])) { + $adopt = true; + } - $adopt = false; - if (policies_is_module_adopt($row['id_agente_modulo'])) { - $adopt = true; - } + if ($linked) { + if ($adopt) { + $img = 'images/policies_brick.png'; + $title = __('(Adopt) ').$policyInfo['name_policy']; + } else { + $img = 'images/policies.png'; + $title = $policyInfo['name_policy']; + } + } else { + if ($adopt) { + $img = 'images/policies_not_brick.png'; + $title = __('(Unlinked) (Adopt) ').$policyInfo['name_policy']; + } else { + $img = 'images/unlinkpolicy.png'; + $title = __('(Unlinked) ').$policyInfo['name_policy']; + } + } - if ($linked) { - if ($adopt) { - $img = 'images/policies_brick.png'; - $title = __('(Adopt) ') . $policyInfo['name_policy']; - } - else { - $img = 'images/policies.png'; - $title = $policyInfo['name_policy']; - } - } - else { - if ($adopt) { - $img = 'images/policies_not_brick.png'; - $title = __('(Unlinked) (Adopt) ') . $policyInfo['name_policy']; - } - else { - $img = 'images/unlinkpolicy.png'; - $title = __('(Unlinked) ') . $policyInfo['name_policy']; - } - } - if(is_metaconsole()){ - $data[0] = '' . - html_print_image($img,true, array('title' => $title)) . - ''; - } - else{ - $data[0] = '' . - html_print_image($img,true, array('title' => $title)) . - ''; - } - } + if (is_metaconsole()) { + $data[0] = ''.html_print_image($img, true, ['title' => $title]).''; + } else { + $data[0] = ''.html_print_image($img, true, ['title' => $title]).''; + } + } - if(is_metaconsole()){ - metaconsole_restore_db(); - } - } - } + if (is_metaconsole()) { + metaconsole_restore_db(); + } + } + } - if (in_array('agent', $show_fields) || is_metaconsole()) { - $agent_alias = !empty($row['agent_alias']) ? $row['agent_alias'] : $row['agent_name']; + if (in_array('agent', $show_fields) || is_metaconsole()) { + $agent_alias = !empty($row['agent_alias']) ? $row['agent_alias'] : $row['agent_name']; - // TODO: Calculate hash access before to use it more simply like other sections. I.E. Events view - if (defined('METACONSOLE')) { - $agent_link = ''; - $agent_alias = ui_print_truncate_text($agent_alias, - 'agent_small', false, true, false, '[…]', - 'font-size:7.5pt;'); - if (can_user_access_node ()) { - $data[1] = $agent_link . '' . $agent_alias . ''; - } - else { - $data[1] = $agent_alias; - } - } - else { - $data[1] = ''; - $data[1] .= ui_print_truncate_text($agent_alias, 'agent_medium', false, true, false, '[…]', 'font-size:7.5pt;'); - $data[1] .= ''; - } - } - - if (in_array('data_type', $show_fields) || is_metaconsole()) { - $data[2] = html_print_image('images/' . modules_show_icon_type ($row['module_type']), true); - $agent_groups = is_metaconsole() - ? $row['groups_in_server'] - : agents_get_all_groups_agent($row['id_agent'], $row['id_group']); - if (check_acl_one_of_groups ($config['id_user'], $agent_groups, 'AW')) { - $show_edit_icon = true; - if (defined('METACONSOLE')) { - if (!can_user_access_node ()) { - $show_edit_icon = false; - } - - $url_edit_module = $row['server_url'] . 'index.php?' . - 'sec=gagente&' . - 'sec2=godmode/agentes/configurar_agente&' . - 'id_agente=' . $row['id_agent'] . '&' . - 'tab=module&' . - 'id_agent_module=' . $row['id_agente_modulo'] . '&' . - 'edit_module=1' . - '&loginhash=auto&loginhash_data=' . $row['hashdata'] . '&loginhash_user=' . str_rot13($row['user']); - } - else { - $url_edit_module = 'index.php?' . - 'sec=gagente&' . - 'sec2=godmode/agentes/configurar_agente&' . - 'id_agente=' . $row['id_agent'] . '&' . - 'tab=module&' . - 'id_agent_module=' . $row['id_agente_modulo'] . '&' . - 'edit_module=1'; - } - - if ($show_edit_icon) { - $data[2] .= '' . - html_print_image('images/config.png', true, - array('alt' => '0', 'border' => '', 'title' => __('Edit'))) . - ''; - } - } - } - - if (in_array('module_name', $show_fields) || is_metaconsole()) { - $data[3] = ui_print_truncate_text($row['module_name'], 'agent_small', false, true, true); - if ($row['extended_info'] != '') { - $data[3] .= ui_print_help_tip ($row['extended_info'], true, '/images/default_list.png'); - } - if ($row['tags'] != '') { - $data[3] .= html_print_image('/images/tag_red.png', true, - array( - 'title' => $row['tags'], - 'style' => 'width: 20px; margin-left: 3px;')); - } - } + // TODO: Calculate hash access before to use it more simply like other sections. I.E. Events view + if (defined('METACONSOLE')) { + $agent_link = ''; + $agent_alias = ui_print_truncate_text( + $agent_alias, + 'agent_small', + false, + true, + false, + '[…]', + 'font-size:7.5pt;' + ); + if (can_user_access_node()) { + $data[1] = $agent_link.''.$agent_alias.''; + } else { + $data[1] = $agent_alias; + } + } else { + $data[1] = ''; + $data[1] .= ui_print_truncate_text($agent_alias, 'agent_medium', false, true, false, '[…]', 'font-size:7.5pt;'); + $data[1] .= ''; + } + } - if (in_array('server_type', $show_fields) || is_metaconsole()) - $data[4] = servers_show_type ($row['id_modulo']); - - - if (in_array('interval', $show_fields) || is_metaconsole()) { - $data[5] = ($row['module_interval'] == 0) ? - human_time_description_raw($row['agent_interval']) - : - human_time_description_raw($row['module_interval']); - } - - if (in_array('status', $show_fields) || is_metaconsole()) { - if ($row['utimestamp'] == 0 && (($row['module_type'] < 21 || - $row['module_type'] > 23) && $row['module_type'] != 100)) { - $data[6] = ui_print_status_image(STATUS_MODULE_NO_DATA, - __('NOT INIT'), true); - } - elseif ($row['estado'] == 0) { - if (is_numeric($row['datos'])) { - $data[6] = ui_print_status_image(STATUS_MODULE_OK, - __('NORMAL') . ': ' . remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), true); - } - else { - $data[6] = ui_print_status_image(STATUS_MODULE_OK, - __('NORMAL') . ': ' . $row['datos'], true); - } - } - elseif ($row['estado'] == 1) { - if (is_numeric($row['datos'])) { - $data[6] = ui_print_status_image(STATUS_MODULE_CRITICAL, - __('CRITICAL') . ': ' . remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), true); - } - else { - $data[6] = ui_print_status_image(STATUS_MODULE_CRITICAL, - __('CRITICAL') . ': ' . $row['datos'], true); - } - } - elseif ($row['estado'] == 2) { - if (is_numeric($row['datos'])) { - $data[6] = ui_print_status_image(STATUS_MODULE_WARNING, - __('WARNING') . ': ' . remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), true); - } - else { - $data[6] = ui_print_status_image(STATUS_MODULE_WARNING, - __('WARNING') . ': ' . $row['datos'], true); - } - } - else { - $last_status = modules_get_agentmodule_last_status( - $row['id_agente_modulo']); - switch($last_status) { - case 0: - if (is_numeric($row['datos'])) { - $data[6] = ui_print_status_image(STATUS_MODULE_UNKNOWN, - __('UNKNOWN') . ' - ' . __('Last status') . " " . - __('NORMAL') . ': ' . remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), true); - } - else { - $data[6] = ui_print_status_image(STATUS_MODULE_UNKNOWN, - __('UNKNOWN') . ' - ' . __('Last status') . " " . - __('NORMAL') . ': ' . $row['datos'], true); - } - break; - case 1: - if (is_numeric($row['datos'])) { - $data[6] = ui_print_status_image(STATUS_MODULE_UNKNOWN, - __('UNKNOWN') . ' - ' . __('Last status') ." " . - __('CRITICAL') . ': ' . remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), true); - } - else { - $data[6] = ui_print_status_image(STATUS_MODULE_UNKNOWN, - __('UNKNOWN') . ' - ' . __('Last status') ." " . - __('CRITICAL') . ': ' . $row['datos'], true); - } - break; - case 2: - if (is_numeric($row['datos'])) { - $data[6] = ui_print_status_image(STATUS_MODULE_UNKNOWN, - __('UNKNOWN') . ' - ' . __('Last status') . " " . - __('WARNING') . ': ' . remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), true); - } - else { - $data[6] = ui_print_status_image(STATUS_MODULE_UNKNOWN, - __('UNKNOWN') . ' - ' . __('Last status') . " " . - __('WARNING') . ': ' . $row['datos'], true); - } - break; - } - } - } + if (in_array('data_type', $show_fields) || is_metaconsole()) { + $data[2] = html_print_image('images/'.modules_show_icon_type($row['module_type']), true); + $agent_groups = is_metaconsole() ? $row['groups_in_server'] : agents_get_all_groups_agent($row['id_agent'], $row['id_group']); + if (check_acl_one_of_groups($config['id_user'], $agent_groups, 'AW')) { + $show_edit_icon = true; + if (defined('METACONSOLE')) { + if (!can_user_access_node()) { + $show_edit_icon = false; + } - if (in_array('graph', $show_fields) || is_metaconsole()) { - $data[7] = ""; - - $acl_graphs = false; - - // Avoid the check on the metaconsole. Too slow to show/hide an icon depending on the permissions - if (!is_metaconsole()) { - $acl_graphs = check_acl($config['id_user'], $row['id_group'], 'RR'); - } - else { - $acl_graphs = true; - } - - if ($row['history_data'] == 1 && $acl_graphs) { - $graph_type = return_graphtype ($row['module_type']); - - $url = ui_get_full_url('operation/agentes/stat_win.php', false, false, false); - $handle = dechex(crc32($row['id_agente_modulo'].$row['module_name'])); - $win_handle = 'day_'.$handle; - - $graph_params = array( - 'type' => $graph_type, - 'period' => SECONDS_1DAY, - 'id' => $row['id_agente_modulo'], - 'label' => base64_encode($row['module_name']), - 'refresh' => SECONDS_10MINUTES - ); - - if (is_metaconsole() && isset($row['server_id'])) { - // Set the server id - $graph_params['server'] = $row['server_id']; - } - - $graph_params_str = http_build_query($graph_params); - - $link = 'winopeng(\''.$url.'?'.$graph_params_str.'\',\''.$win_handle.'\')'; + $url_edit_module = $row['server_url'].'index.php?'.'sec=gagente&'.'sec2=godmode/agentes/configurar_agente&'.'id_agente='.$row['id_agent'].'&'.'tab=module&'.'id_agent_module='.$row['id_agente_modulo'].'&'.'edit_module=1'.'&loginhash=auto&loginhash_data='.$row['hashdata'].'&loginhash_user='.str_rot13($row['user']); + } else { + $url_edit_module = 'index.php?'.'sec=gagente&'.'sec2=godmode/agentes/configurar_agente&'.'id_agente='.$row['id_agent'].'&'.'tab=module&'.'id_agent_module='.$row['id_agente_modulo'].'&'.'edit_module=1'; + } - $data[7] = get_module_realtime_link_graph($row); + if ($show_edit_icon) { + $data[2] .= ''.html_print_image( + 'images/config.png', + true, + [ + 'alt' => '0', + 'border' => '', + 'title' => __('Edit'), + ] + ).''; + } + } + } - if(!is_snapshot_data($row['datos'])){ - $data[7] .= '' . html_print_image('images/chart_curve.png', true, array('border' => '0', 'alt' => '')) . ''; - } - $data[7] .= '' . - html_print_image ('images/binary.png', true, - array ('border' => '0', 'alt' => '')) . ''; - - $data[7] .= '' . - $row['module_name'] . - ''; - } - } + if (in_array('module_name', $show_fields) || is_metaconsole()) { + $data[3] = ui_print_truncate_text($row['module_name'], 'agent_small', false, true, true); + if ($row['extended_info'] != '') { + $data[3] .= ui_print_help_tip($row['extended_info'], true, '/images/default_list.png'); + } - if (in_array('warn', $show_fields) || is_metaconsole()) { + if ($row['tags'] != '') { + $data[3] .= html_print_image( + '/images/tag_red.png', + true, + [ + 'title' => $row['tags'], + 'style' => 'width: 20px; margin-left: 3px;', + ] + ); + } + } - $data[8] = ui_print_module_warn_value($row['max_warning'], - $row['min_warning'], $row['str_warning'], $row['max_critical'], - $row['min_critical'], $row['str_critical']); + if (in_array('server_type', $show_fields) || is_metaconsole()) { + $data[4] = servers_show_type($row['id_modulo']); + } - if (is_numeric($row['datos']) && !modules_is_string_type($row['module_type'])) { - if ( $config['render_proc'] ) { - switch($row['module_type']) { - case 2: - case 6: - case 9: - case 18: - case 21: - case 31: - if ( $row['datos'] >= 1 ) - $salida = $config['render_proc_ok']; - else - $salida = $config['render_proc_fail']; - break; - default: - switch($row['module_type']) { - case 15: - $value = db_get_value('snmp_oid', 'tagente_modulo', 'id_agente_modulo', $row['id_agente_modulo']); - if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') - $salida = human_milliseconds_to_string($row['datos']); - else - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); - break; - default: - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); - break; - } - break; - } - } - else { - switch($row['module_type']) { - case 15: - $value = db_get_value('snmp_oid', 'tagente_modulo', 'id_agente_modulo', $row['id_agente_modulo']); - if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') - $salida = human_milliseconds_to_string($row['datos']); - else - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); - break; - default: - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); - break; - } - } - - // Show units ONLY in numeric data types - if (isset($row['unit'])) { - $data_macro = modules_get_unit_macro($row['datos'],$row['unit']); - if($data_macro) { - $salida = $data_macro; - } else { - $salida .= ' ' . '' . io_safe_output($row['unit']) . ''; - if(strlen($salida) > $config['agent_size_text_small']) { - $salida = ui_print_truncate_text($salida, 'agent_small', true, true, false, '[…]', 'font-size:7.5pt;'); - //clean tag - $text_aux = explode(' $row['id_agente_modulo'], - 'interval' => $row['current_interval'], - 'module_name' => $row['module_name'], - 'id_node' => $row['server_id'] - )); - $salida = ui_get_snapshot_image($link, $is_snapshot) . '  '; - } else { - $sub_string = substr(io_safe_output($row['datos']), 0, 12); - if ($module_value == $sub_string) { - if ($module_value == 0 && !$sub_string) { - $salida = 0; - } - else { - $data_macro = modules_get_unit_macro($row['datos'],$row['unit']); - if($data_macro) { - $salida = $data_macro; - } else { - $salida = $row['datos']; - } - } - } - else { - //Fixed the goliat sends the strings from web - //without HTML entities - if ($is_web_content_string) { - $sub_string = substr($row['datos'], 0, 12); - } - else { - //Fixed the data from Selenium Plugin - if ($module_value != strip_tags($module_value)) { - $module_value = io_safe_input($module_value); - $sub_string = substr($row['datos'], 0, 12); - } - else { - $sub_string = substr(io_safe_output($row['datos']),0, 12); - } - } - - if ($module_value == $sub_string) { - $salida = $module_value; - } - else { - $salida = "" . - $module_value . - "" . - "" . - '' . - $sub_string . ' ' . - "" . - html_print_image('images/rosette.png', true) . ''; - } - } - } - } - } + if (in_array('status', $show_fields) || is_metaconsole()) { + if ($row['utimestamp'] == 0 && (($row['module_type'] < 21 + || $row['module_type'] > 23) && $row['module_type'] != 100) + ) { + $data[6] = ui_print_status_image( + STATUS_MODULE_NO_DATA, + __('NOT INIT'), + true + ); + } else if ($row['estado'] == 0) { + if (is_numeric($row['datos'])) { + $data[6] = ui_print_status_image( + STATUS_MODULE_OK, + __('NORMAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + true + ); + } else { + $data[6] = ui_print_status_image( + STATUS_MODULE_OK, + __('NORMAL').': '.$row['datos'], + true + ); + } + } else if ($row['estado'] == 1) { + if (is_numeric($row['datos'])) { + $data[6] = ui_print_status_image( + STATUS_MODULE_CRITICAL, + __('CRITICAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + true + ); + } else { + $data[6] = ui_print_status_image( + STATUS_MODULE_CRITICAL, + __('CRITICAL').': '.$row['datos'], + true + ); + } + } else if ($row['estado'] == 2) { + if (is_numeric($row['datos'])) { + $data[6] = ui_print_status_image( + STATUS_MODULE_WARNING, + __('WARNING').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + true + ); + } else { + $data[6] = ui_print_status_image( + STATUS_MODULE_WARNING, + __('WARNING').': '.$row['datos'], + true + ); + } + } else { + $last_status = modules_get_agentmodule_last_status( + $row['id_agente_modulo'] + ); + switch ($last_status) { + case 0: + if (is_numeric($row['datos'])) { + $data[6] = ui_print_status_image( + STATUS_MODULE_UNKNOWN, + __('UNKNOWN').' - '.__('Last status').' '.__('NORMAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + true + ); + } else { + $data[6] = ui_print_status_image( + STATUS_MODULE_UNKNOWN, + __('UNKNOWN').' - '.__('Last status').' '.__('NORMAL').': '.$row['datos'], + true + ); + } + break; - if (in_array('data', $show_fields) || is_metaconsole()) - $data[9] = $salida; - - if (in_array('timestamp', $show_fields) || is_metaconsole()) { - if ($row['module_interval'] > 0) - $interval = $row['module_interval']; - else - $interval = $row['agent_interval']; - - if ($row['estado'] == 3) { - $option = array ('html_attr' => 'class="redb"','style' => 'font-size:7pt;'); - } - else { - $option = array ('style' => 'font-size:7pt;'); - } - $data[10] = ui_print_timestamp ($row['utimestamp'], true, $option); - } + case 1: + if (is_numeric($row['datos'])) { + $data[6] = ui_print_status_image( + STATUS_MODULE_UNKNOWN, + __('UNKNOWN').' - '.__('Last status').' '.__('CRITICAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + true + ); + } else { + $data[6] = ui_print_status_image( + STATUS_MODULE_UNKNOWN, + __('UNKNOWN').' - '.__('Last status').' '.__('CRITICAL').': '.$row['datos'], + true + ); + } + break; - if (in_array('to_critical', $show_fields)) { + case 2: + if (is_numeric($row['datos'])) { + $data[6] = ui_print_status_image( + STATUS_MODULE_UNKNOWN, + __('UNKNOWN').' - '.__('Last status').' '.__('WARNING').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + true + ); + } else { + $data[6] = ui_print_status_image( + STATUS_MODULE_UNKNOWN, + __('UNKNOWN').' - '.__('Last status').' '.__('WARNING').': '.$row['datos'], + true + ); + } + break; + } + } + } - $change_status_timestamp = db_get_sql ('SELECT utimestamp FROM tevento WHERE id_agentmodule=' . $row['id_agente_modulo'] . ' ORDER BY utimestamp DESC'); - $data[11] = ui_print_timestamp ($change_status_timestamp, true, $option); - } - - array_push ($table->data, $data); - } + if (in_array('graph', $show_fields) || is_metaconsole()) { + $data[7] = ''; + + $acl_graphs = false; + + // Avoid the check on the metaconsole. Too slow to show/hide an icon depending on the permissions + if (!is_metaconsole()) { + $acl_graphs = check_acl($config['id_user'], $row['id_group'], 'RR'); + } else { + $acl_graphs = true; + } + + if ($row['history_data'] == 1 && $acl_graphs) { + $graph_type = return_graphtype($row['module_type']); + + $url = ui_get_full_url('operation/agentes/stat_win.php', false, false, false); + $handle = dechex(crc32($row['id_agente_modulo'].$row['module_name'])); + $win_handle = 'day_'.$handle; + + $graph_params = [ + 'type' => $graph_type, + 'period' => SECONDS_1DAY, + 'id' => $row['id_agente_modulo'], + 'label' => base64_encode($row['module_name']), + 'refresh' => SECONDS_10MINUTES, + ]; + + if (is_metaconsole() && isset($row['server_id'])) { + // Set the server id + $graph_params['server'] = $row['server_id']; + } + + $graph_params_str = http_build_query($graph_params); + + $link = 'winopeng(\''.$url.'?'.$graph_params_str.'\',\''.$win_handle.'\')'; + + $data[7] = get_module_realtime_link_graph($row); + + if (!is_snapshot_data($row['datos'])) { + $data[7] .= ''.html_print_image('images/chart_curve.png', true, ['border' => '0', 'alt' => '']).''; + } + + $data[7] .= ''.html_print_image( + 'images/binary.png', + true, + [ + 'border' => '0', + 'alt' => '', + ] + ).''; + + $data[7] .= ''.$row['module_name'].''; + } + } + + if (in_array('warn', $show_fields) || is_metaconsole()) { + $data[8] = ui_print_module_warn_value( + $row['max_warning'], + $row['min_warning'], + $row['str_warning'], + $row['max_critical'], + $row['min_critical'], + $row['str_critical'] + ); + + if (is_numeric($row['datos']) && !modules_is_string_type($row['module_type'])) { + if ($config['render_proc']) { + switch ($row['module_type']) { + case 2: + case 6: + case 9: + case 18: + case 21: + case 31: + if ($row['datos'] >= 1) { + $salida = $config['render_proc_ok']; + } else { + $salida = $config['render_proc_fail']; + } + break; + + default: + switch ($row['module_type']) { + case 15: + $value = db_get_value('snmp_oid', 'tagente_modulo', 'id_agente_modulo', $row['id_agente_modulo']); + if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { + $salida = human_milliseconds_to_string($row['datos']); + } else { + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + } + break; + + default: + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + break; + } + break; + } + } else { + switch ($row['module_type']) { + case 15: + $value = db_get_value('snmp_oid', 'tagente_modulo', 'id_agente_modulo', $row['id_agente_modulo']); + if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { + $salida = human_milliseconds_to_string($row['datos']); + } else { + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + } + break; + + default: + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + break; + } + } + + // Show units ONLY in numeric data types + if (isset($row['unit'])) { + $data_macro = modules_get_unit_macro($row['datos'], $row['unit']); + if ($data_macro) { + $salida = $data_macro; + } else { + $salida .= ' '.''.io_safe_output($row['unit']).''; + if (strlen($salida) > $config['agent_size_text_small']) { + $salida = ui_print_truncate_text($salida, 'agent_small', true, true, false, '[…]', 'font-size:7.5pt;'); + // clean tag + $text_aux = explode(' $row['id_agente_modulo'], + 'interval' => $row['current_interval'], + 'module_name' => $row['module_name'], + 'id_node' => $row['server_id'], + ] + ); + $salida = ui_get_snapshot_image($link, $is_snapshot).'  '; + } else { + $sub_string = substr(io_safe_output($row['datos']), 0, 12); + if ($module_value == $sub_string) { + if ($module_value == 0 && !$sub_string) { + $salida = 0; + } else { + $data_macro = modules_get_unit_macro($row['datos'], $row['unit']); + if ($data_macro) { + $salida = $data_macro; + } else { + $salida = $row['datos']; + } + } + } else { + // Fixed the goliat sends the strings from web + // without HTML entities + if ($is_web_content_string) { + $sub_string = substr($row['datos'], 0, 12); + } else { + // Fixed the data from Selenium Plugin + if ($module_value != strip_tags($module_value)) { + $module_value = io_safe_input($module_value); + $sub_string = substr($row['datos'], 0, 12); + } else { + $sub_string = substr(io_safe_output($row['datos']), 0, 12); + } + } + + if ($module_value == $sub_string) { + $salida = $module_value; + } else { + $salida = '".$module_value.''.'".''.$sub_string.' '."".html_print_image('images/rosette.png', true).''; + } + } + } + } + } + + if (in_array('data', $show_fields) || is_metaconsole()) { + $data[9] = $salida; + } + + if (in_array('timestamp', $show_fields) || is_metaconsole()) { + if ($row['module_interval'] > 0) { + $interval = $row['module_interval']; + } else { + $interval = $row['agent_interval']; + } + + if ($row['estado'] == 3) { + $option = [ + 'html_attr' => 'class="redb"', + 'style' => 'font-size:7pt;', + ]; + } else { + $option = ['style' => 'font-size:7pt;']; + } + + $data[10] = ui_print_timestamp($row['utimestamp'], true, $option); + } + + if (in_array('to_critical', $show_fields)) { + $change_status_timestamp = db_get_sql('SELECT utimestamp FROM tevento WHERE id_agentmodule='.$row['id_agente_modulo'].' ORDER BY utimestamp DESC'); + $data[11] = ui_print_timestamp($change_status_timestamp, true, $option); + } + + array_push($table->data, $data); + } html_print_table($table); } else { diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 45a436a127..bf81ae5110 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -105,6 +105,7 @@ if (!empty($sub2)) { } enterprise_hook('cluster_menu'); +enterprise_hook('aws_menu'); if (!empty($sub)) { $menu_operation['estado']['text'] = __('Monitoring'); @@ -375,6 +376,11 @@ $sub['operation/users/user_edit']['text'] = __('Edit my user'); $sub['operation/users/user_edit']['id'] = 'Edit my user'; $sub['operation/users/user_edit']['refr'] = 0; +// Users +$sub['operation/users/user_edit_notifications']['text'] = __('Configure user notifications'); +$sub['operation/users/user_edit_notifications']['id'] = 'Configure user notifications'; +$sub['operation/users/user_edit_notifications']['refr'] = 0; + // ANY user can chat with other user and dogs. // Users $sub['operation/users/webchat']['text'] = __('WebChat'); diff --git a/pandora_console/operation/messages/message_edit.php b/pandora_console/operation/messages/message_edit.php index a1f2c430e7..f116e6609d 100644 --- a/pandora_console/operation/messages/message_edit.php +++ b/pandora_console/operation/messages/message_edit.php @@ -1,24 +1,39 @@ false, - 'text' => ''.html_print_image('images/email_inbox.png', true, ['title' => __('Received messages')]).'', + 'text' => ''.html_print_image( + 'images/email_inbox.png', + true, + ['title' => __('Received messages')] + ).'', ]; $buttons['sent_messages'] = [ 'active' => false, - 'text' => ''.html_print_image('images/email_outbox.png', true, ['title' => __('Sent messages')]).'', + 'text' => ''.html_print_image( + 'images/email_outbox.png', + true, + ['title' => __('Sent messages')] + ).'', ]; $buttons['create_message'] = [ 'active' => true, - 'text' => ''.html_print_image('images/new_message.png', true, ['title' => __('Create message')]).'', + 'text' => ''.html_print_image( + 'images/new_message.png', + true, + ['title' => __('Create message')] + ).'', ]; -// Header -ui_print_page_header(__('Messages'), 'images/email_mc.png', false, '', false, $buttons); +// Header. +ui_print_page_header( + __('Messages'), + 'images/email_mc.png', + false, + '', + false, + $buttons +); -// read a message +// Read a message. if ($read_message) { $message_id = (int) get_parameter('id_message'); if ($show_sent) { @@ -56,10 +90,10 @@ if ($read_message) { messages_process_read($message_id); } - if ($message == false) { + if ($message === false) { echo '
    '.__('This message does not exist in the system').'
    '; return; - // Move out of this page and go processing other pages + // Move out of this page and go processing other pages. } $user_name = get_user_fullname($message['id_usuario_origen']); @@ -72,19 +106,70 @@ if ($read_message) { $dst_name = $message['id_usuario_destino']; } - $table = new stdClass(); - $table->width = '100%'; - $table->class = 'databox filters'; - $table->data = []; + if (isset($user_name) !== true || empty($user_name) === true) { + echo '

    Notification

    '; + } else { + echo '

    Conversation with '.$user_name.'

    '; + } - $table->data[0][0] = __('Sender'); - $table->data[0][1] = $user_name.' '.__('at').' '.ui_print_timestamp($message['timestamp'], true, ['prominent' => 'timestamp']); + echo '

    Subject: '.$message['subject'].'

    '; - $table->data[1][0] = __('Destination'); - $table->data[1][1] = $dst_name; + $conversation = []; + $target_str = $message['mensaje']; + + while (preg_match_all( + '/(.*)On(.*)wrote:(.*)/', + $target_str, + $decoded, + PREG_PATTERN_ORDER + ) !== false && empty($target_str) !== true) { + if (empty($decoded[2]) !== true) { + array_push( + $conversation, + [ + 'message' => array_pop($decoded)[0], + 'date' => array_pop($decoded)[0], + ] + ); + } else { + array_push( + $conversation, + ['message' => $target_str] + ); + } + + $target_str = $decoded[1][0]; + } + + ui_require_css_file('message_edit'); + foreach ($conversation as $row) { + $date = $row['date']; + + if ($date === null) { + $date = date( + $config['date_format'], + $message['timestamp'] + ).' '.$user_name; + } + + $order = [ + "\r\n", + "\n", + "\r", + ]; + $replace = '
    '; + $parsed_message = str_replace( + $order, + $replace, + trim(io_safe_output($row['message'])) + ); + + echo '
    '; + echo '

    '.$parsed_message.'

    '; + echo ''.$date.''; + echo '
    '; + } - $table->data[2][0] = __('Subject'); - $table->data[2][1] = html_print_input_text_extended('subject', $message['subject'], 'text-subject', '', 50, 70, true, false, '', 'readonly'); $order = [ "\r\n", @@ -94,21 +179,21 @@ if ($read_message) { $replace = '
    '; $parsed_message = str_replace($order, $replace, $message['mensaje']); - $table->data[3][0] = __('Message'); - $table->data[3][1] = html_print_textarea('message', 15, 255, $message['mensaje'], 'readonly', true); - - // Prevent RE: RE: RE: + // Prevent RE: RE: RE:. if (strstr($message['subject'], 'RE:')) { $new_subj = $message['subject']; } else { $new_subj = 'RE: '.$message['subject']; } - // Start the message much like an e-mail reply - $new_msg = "\n\n\nOn ".date($config['date_format'], $message['timestamp']).' '.$user_name.' '.__('wrote').":\n\n".$message['mensaje']; + // Start the message much like an e-mail reply. + $new_msg = "\n\n\nOn ".date( + $config['date_format'], + $message['timestamp'] + ).' '.$user_name.' '.__('wrote').":\n\n".$message['mensaje']; + echo '
    '; - html_print_table($table); echo '
    '; echo '
    '; @@ -119,17 +204,33 @@ if ($read_message) { echo '
    '; echo "
    "; - html_print_submit_button(__('Delete'), 'delete_btn', false, 'form="delete_message" class="sub delete"'); + html_print_submit_button( + __('Delete conversation'), + 'delete_btn', + false, + 'form="delete_message" class="sub delete"' + ); echo ' '; - html_print_submit_button(__('Reply'), 'reply', false, 'form="reply_message" class="sub next"'); + html_print_submit_button( + __('Reply'), + 'reply', + false, + 'form="reply_message" class="sub next"' + ); echo '
    '; return; } -// Create message (destination user) +// Create message (destination user). if (($new_msg) && (!empty($dst_user)) && (!$reply)) { - $return = messages_create_message($config['id_user'], $dst_user, $subject, $message); + $return = messages_create_message( + $config['id_user'], + [$dst_user], + [], + $subject, + $message + ); $user_name = get_user_fullname($dst_user); if (!$user_name) { @@ -143,9 +244,15 @@ if (($new_msg) && (!empty($dst_user)) && (!$reply)) { ); } -// Create message (destination group) +// Create message (destination group). if (($new_msg) && ($dst_group != '') && (!$reply)) { - $return = messages_create_group($config['id_user'], $dst_group, $subject, $message); + $return = messages_create_message( + $config['id_user'], + [], + [$dst_group], + $subject, + $message + ); ui_print_result_message( $return, @@ -154,8 +261,8 @@ if (($new_msg) && ($dst_group != '') && (!$reply)) { ); } -// message creation form -// user info +// Message creation form. +// User info. $own_info = get_user_info($config['id_user']); $table = new stdClass(); @@ -174,12 +281,28 @@ if (!empty($own_info['fullname'])) { $table->data[1][0] = __('Destination'); -$is_admin = (bool) db_get_value('is_admin', 'tusuario', 'id_user', $config['id_user']); +$is_admin = (bool) db_get_value( + 'is_admin', + 'tusuario', + 'id_user', + $config['id_user'] +); if ($is_admin) { - $users_full = db_get_all_rows_filter('tusuario', [], ['id_user', 'fullname']); + $users_full = db_get_all_rows_filter( + 'tusuario', + [], + [ + 'id_user', + 'fullname', + ] + ); } else { - $users_full = groups_get_users(array_keys(users_get_groups()), false, false); + $users_full = groups_get_users( + array_keys(users_get_groups()), + false, + false + ); } $users = []; @@ -187,17 +310,16 @@ foreach ($users_full as $user_id => $user_info) { $users[$user_info['id_user']] = $user_info['fullname']; } -// Check if the user to reply is in the list, if not add reply user +// Check if the user to reply is in the list, if not add reply user. if ($reply) { if (!array_key_exists($dst_user, $users)) { - // Add the user to reply + // Add the user to reply. $user_reply = db_get_row('tusuario', 'id_user', $dst_user); $users[$user_reply['id_user']] = $user_reply['fullname']; } } - if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'PM')) { $return_all_groups = true; } else { @@ -205,21 +327,61 @@ if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'PM')) { } $groups = users_get_groups($config['id_user'], 'AR'); -// Get a list of all groups -$table->data[1][1] = html_print_select($users, 'dst_user', $dst_user, '', __('Select user'), false, true, false, '', false); +// Get a list of all groups. +$table->data[1][1] = html_print_select( + $users, + 'dst_user', + $dst_user, + '', + __('Select user'), + false, + true, + false, + '', + false +); $table->data[1][1] .= '  '.__('OR').'  '; -$table->data[1][1] .= html_print_select_groups($config['id_user'], 'AR', $return_all_groups, 'dst_group', $dst_group, '', __('Select group'), '', true); +$table->data[1][1] .= html_print_select_groups( + $config['id_user'], + 'AR', + $return_all_groups, + 'dst_group', + $dst_group, + '', + __('Select group'), + '', + true +); $table->data[2][0] = __('Subject'); -$table->data[2][1] = html_print_input_text('subject', $subject, '', 50, 70, true); +$table->data[2][1] = html_print_input_text( + 'subject', + $subject, + '', + 50, + 70, + true +); $table->data[3][0] = __('Message'); -$table->data[3][1] = html_print_textarea('message', 15, 255, $message, '', true); +$table->data[3][1] = html_print_textarea( + 'message', + 15, + 255, + $message, + '', + true +); echo '
    '; html_print_table($table); echo '
    '; - html_print_submit_button(__('Send message'), 'send_mes', false, 'class="sub wand"'); -echo ''; -echo '
    '; + html_print_submit_button( + __('Send message'), + 'send_mes', + false, + 'class="sub wand"' + ); + echo ''; + echo ''; diff --git a/pandora_console/operation/messages/message_list.php b/pandora_console/operation/messages/message_list.php index a9108d9fc0..9427159432 100644 --- a/pandora_console/operation/messages/message_list.php +++ b/pandora_console/operation/messages/message_list.php @@ -1,16 +1,32 @@ false, - 'text' => ''.html_print_image('images/new_message.png', true, ['title' => __('Create message')]).'', + 'text' => ''.html_print_image( + 'images/new_message.png', + true, + ['title' => __('Create message')] + ).'', ]; if (!is_ajax()) { - ui_print_page_header(__('Messages'), 'images/email_mc.png', false, '', false, $buttons); + ui_print_page_header( + __('Messages'), + 'images/email_mc.png', + false, + '', + false, + $buttons + ); } if ($mark_unread) { @@ -52,7 +79,7 @@ if ($mark_unread) { if ($delete_msg) { $id = (int) get_parameter('id'); $result = messages_delete_message($id); - // Delete message function will actually check the credentials + // Delete message function will actually check the credentials. ui_print_result_message( $result, __('Successfully deleted'), @@ -61,13 +88,10 @@ if ($delete_msg) { } if ($multiple_delete) { - $ids = (array) get_parameter('delete_multiple', []); + $ids = (array) get_parameter('delete_multiple_messages', []); foreach ($ids as $id) { - $result = db_process_sql_delete( - 'tmensajes', - ['id_mensaje' => $id] - ); + $result = messages_delete_message($id); if ($result === false) { break; @@ -82,21 +106,23 @@ if ($multiple_delete) { } if ($show_sent) { - // sent view + // Sent view. $num_messages = messages_get_count_sent($config['id_user']); if ($num_messages > 0 && !is_ajax()) { - echo '

    '.__('You have').' '.$num_messages.' '.' '.__('sent message(s)').'.

    '; + echo '

    '.__('You have').' '.$num_messages.' '.__('sent message(s)').'.

    '; } $messages = messages_get_overview_sent('', 'DESC'); } else { - // messages received - $num_messages = messages_get_count($config['id_user']); + // Messages received. + $num_messages = messages_get_count($config['id_user'], true, true); if ($num_messages > 0 && !is_ajax()) { - echo '

    '.__('You have').' '.$num_messages.' '.' '.__('unread message(s)').'.

    '; + $unread_messages = messages_get_count($config['id_user'], false, true); + echo '

    '.__('You have').' '.$unread_messages.' '.__('unread message(s)').'.

    '; + $messages = messages_get_overview(); + } else { + $messages = messages_get_overview('status', 'ASC'); } - - $messages = messages_get_overview(); } if (empty($messages)) { @@ -139,10 +165,12 @@ if (empty($messages)) { $table->head[3] = __('Timestamp'); $table->head[4] = __('Delete').html_print_checkbox('all_delete_messages', 0, false, true, false); - foreach ($messages as $message_id => $message) { + + foreach ($messages as $message) { + $message_id = $message['id_mensaje']; $data = []; $data[0] = ''; - if ($message['status'] == 1) { + if ($message['read'] == 1) { if ($show_sent) { $data[0] .= ''; $data[0] .= html_print_image('images/email_open.png', true, ['border' => 0, 'title' => __('Click to read')]); @@ -202,10 +230,10 @@ if (empty($messages)) { if ($show_sent) { $data[4] = ''.html_print_image('images/cross.png', true, ['title' => __('Delete')]).''.html_print_checkbox_extended('delete_multiple_messages[]', $message_id, false, false, '', 'class="check_delete_messages"', true); + onClick="javascript:if (!confirm(\''.__('Are you sure?').'\')) return false;">'.html_print_image('images/cross.png', true, ['title' => __('Delete')]).''.html_print_checkbox_extended('delete_multiple_messages[]', $message_id, false, false, '', 'class="check_delete_messages"', true); } else { $data[4] = ''.html_print_image('images/cross.png', true, ['title' => __('Delete')]).''.html_print_checkbox_extended('delete_multiple_messages[]', $message_id, false, false, '', 'class="check_delete_messages"', true); + onClick="javascript:if (!confirm(\''.__('Are you sure?').'\')) return false;">'.html_print_image('images/cross.png', true, ['title' => __('Delete')]).''.html_print_checkbox_extended('delete_multiple_messages[]', $message_id, false, false, '', 'class="check_delete_messages"', true); } array_push($table->data, $data); diff --git a/pandora_console/operation/servers/recon_view.php b/pandora_console/operation/servers/recon_view.php index d91b838e8b..84a057d69c 100644 --- a/pandora_console/operation/servers/recon_view.php +++ b/pandora_console/operation/servers/recon_view.php @@ -30,7 +30,7 @@ $servers = db_get_all_rows_sql('SELECT * FROM tserver WHERE server_type = 3'); if ($servers === false) { $servers = []; ui_print_page_header(__('Recon View'), 'images/op_recon.png', false, '', false); - ui_print_error_message(__('Recon Server is disabled')); + ui_print_error_message(__('Discovery Server is disabled')); return; } else { $recon_task = db_get_all_rows_sql('SELECT * FROM trecon_task'); diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index ccf10a4b00..3e3338ff96 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -29,69 +29,10 @@ global $config; -check_login(); +// Load the header +require $config['homedir'].'/operation/users/user_edit_header.php'; -enterprise_hook('open_meta_frame'); - -require_once $config['homedir'].'/include/functions_profile.php'; -require_once $config['homedir'].'/include/functions_users.php'; -require_once $config['homedir'].'/include/functions_groups.php'; -require_once $config['homedir'].'/include/functions_visual_map.php'; - -$meta = false; -if (enterprise_installed() && defined('METACONSOLE')) { - $meta = true; -} - -$id = get_parameter_get('id', $config['id_user']); -// ID given as parameter. -$status = get_parameter('status', -1); -// Flag to print action status message. -$user_info = get_user_info($id); - -$id = $user_info['id_user']; -// This is done in case there are problems with uppercase/lowercase -// (MySQL auth has that problem). -if ((!check_acl($config['id_user'], users_get_groups($id), 'UM')) - && ($id != $config['id_user']) -) { - db_pandora_audit( - 'ACL Violation', - 'Trying to view a user without privileges' - ); - include 'general/noaccess.php'; - exit; -} - -// If current user is editing himself or if the user has UM (User Management) -// rights on any groups the user is part of AND the authorization scheme allows -// for users/admins to update info. -if (($config['id_user'] == $id || check_acl($config['id_user'], users_get_groups($id), 'UM')) - && $config['user_can_update_info'] -) { - $view_mode = false; -} else { - $view_mode = true; -} - -// Header. -if ($meta) { - user_meta_print_header(); - $url = 'index.php?sec=advanced&sec2=advanced/users_setup&tab=user_edit'; -} else { - ui_print_page_header( - __('User detail editor'), - 'images/op_workspace.png', - false, - '', - false, - '' - ); - $url = 'index.php?sec=workspace&sec2=operation/users/user_edit'; -} - - -// Update user info. +// Update user info if (isset($_GET['modified']) && !$view_mode) { if (html_print_csrf_error()) { return; @@ -441,11 +382,11 @@ $table->data[] = $data; // Double auth. $double_auth_enabled = (bool) db_get_value('id', 'tuser_double_auth', 'id_user', $config['id_user']); -$data = array(); +$data = []; if ($config['double_auth_enabled']) { - $data[0] = ''.__('Double authentication').''; - $data[0] .= $jump; - $data[0] .= ''.html_print_checkbox('double_auth', 1, $double_auth_enabled, true).''; + $data[0] = ''.__('Double authentication').''; + $data[0] .= $jump; + $data[0] .= ''.html_print_checkbox('double_auth', 1, $double_auth_enabled, true).''; } if ($double_auth_enabled) { @@ -659,7 +600,7 @@ $table->rowclass[] = ''; $table->rowstyle[] = ''; $table->data[] = $data; -echo '
    '; +echo ''; html_print_table($table); diff --git a/pandora_console/operation/users/user_edit_header.php b/pandora_console/operation/users/user_edit_header.php new file mode 100644 index 0000000000..4b329eee77 --- /dev/null +++ b/pandora_console/operation/users/user_edit_header.php @@ -0,0 +1,87 @@ + [ + 'active' => $_GET['sec2'] === 'operation/users/user_edit', + 'text' => "".html_print_image( + 'images/user_green.png', + true, + ['title' => __('User management')] + ).'', + ], + 'notifications' => [ + 'active' => $_GET['sec2'] === 'operation/users/user_edit_notifications', + 'text' => "".html_print_image( + 'images/alerts_template.png', + true, + ['title' => __('User notifications')] + ).'', + ], + ]; + + ui_print_page_header( + __('User detail editor'), + 'images/op_workspace.png', + false, + '', + false, + $buttons + ); +} diff --git a/pandora_console/operation/users/user_edit_notifications.php b/pandora_console/operation/users/user_edit_notifications.php new file mode 100644 index 0000000000..6ffbf87976 --- /dev/null +++ b/pandora_console/operation/users/user_edit_notifications.php @@ -0,0 +1,122 @@ + notifications_set_user_label_status( + $source, + $user, + $label, + $value + ), + ] + ); + return; +} + +// User notification table. It is just a wrapper. +$table_content = new StdClass(); +$table_content->data = []; +$table_content->width = '100%'; +$table_content->id = 'user-notifications-wrapper'; +$table_content->class = 'databox filters'; +$table_content->size[0] = '33%'; +$table_content->size[1] = '33%'; +$table_content->size[2] = '33%'; + +// Print the header. +$table_content->data[] = [ + '', + __('Enable'), + __('Also receive an email'), +]; + +$sources = notifications_get_all_sources(); +foreach ($sources as $source) { + $table_content->data[] = [ + $source['description'], + notifications_print_user_switch($source, $id, 'enabled'), + notifications_print_user_switch($source, $id, 'also_mail'), + ]; +} + +html_print_table($table_content); + +// Print id user to handle it on js. +html_print_input_hidden('id_user', $id); + +?> + diff --git a/pandora_console/pandora_console.redhat.spec b/pandora_console/pandora_console.redhat.spec index b4c96d5d9a..5ffa0a60fd 100644 --- a/pandora_console/pandora_console.redhat.spec +++ b/pandora_console/pandora_console.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.731 -%define release 190225 +%define release 190226 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.spec b/pandora_console/pandora_console.spec index ecf0647314..1cc5f88b10 100644 --- a/pandora_console/pandora_console.spec +++ b/pandora_console/pandora_console.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.731 -%define release 190225 +%define release 190226 %define httpd_name httpd # User and Group under which Apache is running %define httpd_name apache2 diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 7f8197540b..ae780a5470 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -655,6 +655,19 @@ CREATE TABLE IF NOT EXISTS `tevento` ( -- Criticity: 3 - Warning (yellow) (status 2) -- Criticity: 4 - Critical (red) (status 1) +-- --------------------------------------------------------------------- +-- Table `tevent_extended` +-- --------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tevent_extended` ( + `id` serial PRIMARY KEY, + `id_evento` bigint(20) unsigned NOT NULL, + `external_id` bigint(20) unsigned, + `utimestamp` bigint(20) NOT NULL default '0', + `description` text, + FOREIGN KEY `tevent_ext_fk`(`id_evento`) REFERENCES `tevento`(`id_evento`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- --------------------------------------------------------------------- -- Table `tgrupo` -- --------------------------------------------------------------------- @@ -719,20 +732,6 @@ CREATE TABLE IF NOT EXISTS `tlink` ( PRIMARY KEY (`id_link`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; --- ----------------------------------------------------- --- Table `tmensajes` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tmensajes` ( - `id_mensaje` int(10) unsigned NOT NULL auto_increment, - `id_usuario_origen` varchar(60) NOT NULL default '', - `id_usuario_destino` varchar(60) NOT NULL default '', - `mensaje` text NOT NULL, - `timestamp` bigint (20) unsigned NOT NULL default '0', - `subject` varchar(255) NOT NULL default '', - `estado` int(4) unsigned NOT NULL default '0', - PRIMARY KEY (`id_mensaje`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -- ---------------------------------------------------------------------- -- Table `tmodule_group` -- ---------------------------------------------------------------------- @@ -783,6 +782,9 @@ CREATE TABLE IF NOT EXISTS `trecon_task` ( `snmp_privacy_method` varchar(25) NOT NULL default '', `snmp_privacy_pass` varchar(255) NOT NULL default '', `snmp_security_level` varchar(25) NOT NULL default '', + `wmi_enabled` tinyint(1) unsigned DEFAULT '0', + `auth_strings` text, + `autoconfiguration_enabled` tinyint(1) unsigned default '0', PRIMARY KEY (`id_rt`), KEY `recon_task_daemon` (`id_recon_server`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1177,6 +1179,113 @@ CREATE TABLE IF NOT EXISTS `treset_pass_history` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- ----------------------------------------------------- +-- Table `tnotification_source` +-- ----------------------------------------------------- +CREATE TABLE `tnotification_source` ( + `id` serial, + `description` VARCHAR(255) DEFAULT NULL, + `icon` text, + `max_postpone_time` int(11) DEFAULT NULL, + `enabled` int(1) DEFAULT NULL, + `user_editable` int(1) DEFAULT NULL, + `also_mail` int(1) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ----------------------------------------------------- +-- Table `tmensajes` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tmensajes` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `id_usuario_origen` VARCHAR(60) NOT NULL DEFAULT '', + `mensaje` TEXT NOT NULL, + `timestamp` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0', + `subject` VARCHAR(255) NOT NULL DEFAULT '', + `estado` INT(4) UNSIGNED NOT NULL DEFAULT '0', + `url` TEXT, + `response_mode` VARCHAR(200) DEFAULT NULL, + `citicity` INT(10) UNSIGNED DEFAULT '0', + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `subtype` VARCHAR(255) DEFAULT '', + PRIMARY KEY (`id_mensaje`), + UNIQUE KEY `id_mensaje` (`id_mensaje`), + KEY `tsource_fk` (`id_source`), + CONSTRAINT `tsource_fk` FOREIGN KEY (`id_source`) REFERENCES `tnotification_source` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_user` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_user` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL, + `id_user` VARCHAR(60) NOT NULL, + `utimestamp_read` BIGINT(20), + `utimestamp_erased` BIGINT(20), + `postpone` INT, + PRIMARY KEY (`id_mensaje`,`id_user`), + FOREIGN KEY (`id_mensaje`) REFERENCES `tmensajes`(`id_mensaje`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_group` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_group` ( + `id_mensaje` INT(10) UNSIGNED NOT NULL, + `id_group` mediumint(4) UNSIGNED NOT NULL, + PRIMARY KEY (`id_mensaje`,`id_group`), + FOREIGN KEY (`id_mensaje`) REFERENCES `tmensajes`(`id_mensaje`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_source_user` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_source_user` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_user` VARCHAR(60), + `enabled` INT(1) DEFAULT NULL, + `also_mail` INT(1) DEFAULT NULL, + PRIMARY KEY (`id_source`,`id_user`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_source_group` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_source_group` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL, + PRIMARY KEY (`id_source`,`id_group`), + INDEX (`id_group`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tnotification_source_user` +-- ---------------------------------------------------------------------- +CREATE TABLE `tnotification_source_group_user` ( + `id_source` BIGINT(20) UNSIGNED NOT NULL, + `id_group` mediumint(4) unsigned NOT NULL, + `id_user` VARCHAR(60), + `enabled` INT(1) DEFAULT NULL, + `also_mail` INT(1) DEFAULT NULL, + PRIMARY KEY (`id_source`,`id_user`), + FOREIGN KEY (`id_source`) REFERENCES `tnotification_source`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_user`) REFERENCES `tusuario`(`id_user`) + ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_group`) REFERENCES `tnotification_source_group`(`id_group`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- ---------------------------------------------------------------------- -- Table `tnews` -- ---------------------------------------------------------------------- diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 8c2f47956a..f5da1f12fa 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -23,7 +23,8 @@ INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (9,'SMS','sendsms _field1_ _field2_','Send SMS using the standard SMS device, using smstools. Uses field2 as text message, field1 as destination phone (include international prefix!)',0,'[\"Destination number\",\"Message\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (10,'Validate Event','Internal type','This alert validate the events matched with a module given the agent name (_field1_) and module name (_field2_)',1,'[\"Agent name\",\"Module name\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (11,'Integria IMS Ticket','Internal type','This alert create a ticket into your Integria IMS.',1,'[\"Integria IMS API path\",\"Integria IMS API pass\",\"Integria IMS user\",\"Integria IMS user pass\",\"Ticket title\",\"Ticket group ID\",\"Ticket priority\",\"Email copy\",\"Ticket owner\",\"Ticket description\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"10,Maintenance;0,Informative;1,Low;2,Medium;3,Serious;4,Very Serious\",\"\",\"\",\"\"]'); - +INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (12,'Remote agent control','/usr/share/pandora_server/util/udp_client.pl _address_ 41122 "_field1_"','This command is used to send commands to the agents with the UDP server enabled. The UDP server is used to order agents (Windows and UNIX) to "refresh" the agent execution: that means, to force the agent to execute and send data',0,'[\"Command\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); +INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (13,'Generate Notification','Internal type','This command allows you to send an internal notification to any user or group.',1,'[\"Destination user\",\"Destination group\",\"Title\",\"Message\",\"Link\",\"Criticity\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); -- -- Dumping data for table `tconfig` -- @@ -1105,10 +1106,7 @@ INSERT INTO `tgis_map_layer` VALUES (1,'Group All',1,0,1,0); -- example alert template -INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (12,'Remote agent control','/usr/share/pandora_server/util/udp_client.pl _address_ 41122 "_field1_"','This command is used to send commands to the agents with the UDP server enabled. The UDP server is used to order agents (Windows and UNIX) to "refresh" the agent execution: that means, to force the agent to execute and send data',0,'[\"Command\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); - -- alert actions (default) - INSERT INTO `talert_actions` (`id`, `name`, `id_alert_command`, `field1`, `field2`, `field3`, `field4`, `field5`, `field6`, `field7`, `field8`, `field9`, `field10`, `id_group`, `action_threshold`, `field1_recovery`, `field2_recovery`, `field3_recovery`, `field4_recovery`, `field5_recovery`, `field6_recovery`, `field7_recovery`, `field8_recovery`, `field9_recovery`, `field10_recovery`) VALUES (1,'Mail to Admin',1,'yourmail@domain.es','[PANDORA] Alert from agent _agent_ on module _module_','<style type="text/css"> /* Take care of image borders and formatting */ img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; } a { border: 0; outline: none; } a img { border: none; } /* General styling */ td, h1, h2, h3 { font-family: Helvetica, Arial, sans-serif; font-weight: 400; } td { font-size: 14px; line-height: 150%; text-align: left; } body { -webkit-font-smoothing:antialiased; -webkit-text-size-adjust:none; width: 100%; height: 100%; color: #37302d; background: #ffffff; } table { border-collapse: collapse !important; } h1, h2, h3 { padding: 0; margin: 0; color: #444444; font-weight: 400; line-height: 110%; } h1 { font-size: 35px; } h2 { font-size: 30px; } h3 { font-size: 24px; } h4 { font-size: 18px; font-weight: normal; } .important-font { color: #21BEB4; font-weight: bold; } .hide { display: none !important; } .force-full-width { width: 100% !important; } </style> <style type="text/css" media="screen"> @media screen { @import url(http://fonts.googleapis.com/css?family=Open+Sans:400); /* Thanks Outlook 2013! */ td, h1, h2, h3 { font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif !important; } } </style> <style type="text/css" media="only screen and (max-width: 600px)"> /* Mobile styles */ @media only screen and (max-width: 600px) { table[class="w320"] { width: 320px !important; } table[class="w300"] { width: 300px !important; } table[class="w290"] { width: 290px !important; } td[class="w320"] { width: 320px !important; } td[class~="mobile-padding"] { padding-left: 14px !important; padding-right: 14px !important; } td[class*="mobile-padding-left"] { padding-left: 14px !important; } td[class*="mobile-padding-right"] { padding-right: 14px !important; } td[class*="mobile-block"] { display: block !important; width: 100% !important; text-align: left !important; padding-left: 0 !important; padding-right: 0 !important; padding-bottom: 15px !important; } td[class*="mobile-no-padding-bottom"] { padding-bottom: 0 !important; } td[class~="mobile-center"] { text-align: center !important; } table[class*="mobile-center-block"] { float: none !important; margin: 0 auto !important; } *[class*="mobile-hide"] { display: none !important; width: 0 !important; height: 0 !important; line-height: 0 !important; font-size: 0 !important; } td[class*="mobile-border"] { border: 0 !important; } } </style> <table style="width: 100%;" cellspacing="0" cellpadding="0" align="center"> <tbody> <tr> <td align="center" valign="top" bgcolor="#ffffff" width="100%"> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="background: #1f1f1f; height: 70px;" width="100%"><center> <table class="w320" style="width: 600px;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="mobile-block mobile-no-padding-bottom mobile-center" style="background: #1f1f1f; padding: 10px 10px 10px 20px;" valign="top" width="270"><a style="text-decoration: none;" href="#"> <img src="https://pandorafms.com/images/logo_pandora_email.png" alt="Your Logo" width="200"> </a></td> <td class="mobile-block mobile-center" style="background: #1f1f1f; padding: 17px 15px 10px 10px;" valign="top" width="270">&nbsp;</td> </tr> </tbody> </table> </center></td> </tr> <tr> <td style="border-bottom: 1px solid #e7e7e7;"><center style="padding-bottom: 20px;"> <table class="w320" style="width: 600px;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="mobile-padding" style="padding: 20px;" align="left"><br class="mobile-hide"> <h2>Pandora FMS alert system</h2> <br> Dear customer,<br><br> We have <strong>bad news</strong> for you. Something is on <strong>CRITICAL</strong> status!<br> <br> <table style="width: 100%;" cellspacing="0" cellpadding="0" bgcolor="#ffffff"> <tbody> <tr> <td style="width: 100px; background: #D84A38;"> <div><!--[if mso]> <v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#" style="height:33px;v-text-anchor:middle;width:100px;" stroke="f" fillcolor="#D84A38"> <w:anchorlock/> <center> <![endif]--> <a style="background-color: #1f1f1f; color: whitesmoke; display: inline-block; font-family: sans-serif; font-size: 13px; font-weight: bold; line-height: 33px; text-align: center; text-decoration: none; width: 250px; -webkit-text-size-adjust: none;" href="_homeurl_">Go to Pandora FMS Console</a> <!--[if mso]> </center> </v:rect> <![endif]--></div> </td> <td style="background-color: #ffffff; font-size: 0; line-height: 0;" width="281">&nbsp;</td> </tr> </tbody> </table> </td> <td class="mobile-hide" style="padding-top: 20px; padding-bottom: 0; vertical-align: bottom;" valign="bottom"> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="padding-bottom: 0px; vertical-align: bottom;" align="right" valign="bottom"><img style="vertical-align: bottom; padding-bottom: 10px;" src="https://pandorafms.com/images/alerta_roja.png" alt="" width="130"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </center></td> </tr> <tr> <td style="background-color: #f8f8f8; border-bottom: 1px solid #e7e7e7; padding-top: 10px;" valign="top"><center> <table class="w320" style="height: 100%; width: 600px;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="mobile-padding" style="padding: 20px;" valign="top"> <table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="padding-right: 20px;" colspan="2"><strong>Monitoring details</strong></td> </tr> <tr> <td style="padding-top: 25px; width: 150px; border-top: 1px solid #E7E7E7; vertical-align: top;"><strong>Data</strong></td> <td style="padding-top: 25px; padding-right: 20px; border-top: 1px solid #E7E7E7; vertical-align: top;">_data_ <em>(_modulestatus_)</em></td> </tr> <tr> <td><strong>Agent</strong></td> <td>_agent_ <em>_address_</em></td> </tr> <tr> <td><strong>Module</strong></td> <td>_module_ <em>_moduledescription_ </em></td> </tr> <tr> <td><strong>Timestamp</strong></td> <td>_timestamp_</td> </tr> </tbody> </table> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="padding-top: 20px;"> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="vertical-align: top;" width="350">This is a graph of latest 24hr data for this module: <br><br> _modulegraph_24h_</td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </center></td> </tr> <tr> <td style="background-color: #1f1f1f;"><center> <table class="w320" style="height: 100%; color: #ffffff; width: 600px;" border="0" cellspacing="0" cellpadding="0" bgcolor="#1f1f1f"> <tbody> <tr> <td class="mobile-padding" style="font-size: 12px; padding: 20px; background-color: #1f1f1f; color: #ffffff; text-align: center;" align="right" valign="middle"><a style="color: #ffffff;" href="https://pandorafms.com/company/contact/">Contact Us</a>&nbsp;&nbsp;|&nbsp;&nbsp; <a style="color: #ffffff;" href="https://forums.pandorafms.com/">Support</a>&nbsp;&nbsp;|&nbsp;&nbsp; <a style="color: #ffffff;" href="https://wiki.pandorafms.com">Docs</a>&nbsp;&nbsp;|&nbsp;&nbsp;</td> </tr> </tbody> </table> </center></td> </tr> </tbody> </table> </td> </tr> </tbody> </table>','','','','','','','',0,0,'','','<style type="text/css"><!-- /* Take care of image borders and formatting */ img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; } a { border: 0; outline: none; } a img { border: none; } /* General styling */ td, h1, h2, h3 { font-family: Helvetica, Arial, sans-serif; font-weight: 400; } td { font-size: 14px; line-height: 150%; text-align: left; } body { -webkit-font-smoothing:antialiased; -webkit-text-size-adjust:none; width: 100%; height: 100%; color: #37302d; background: #ffffff; } table { border-collapse: collapse !important; } h1, h2, h3 { padding: 0; margin: 0; color: #444444; font-weight: 400; line-height: 110%; } h1 { font-size: 35px; } h2 { font-size: 30px; } h3 { font-size: 24px; } h4 { font-size: 18px; font-weight: normal; } .important-font { color: #21BEB4; font-weight: bold; } .hide { display: none !important; } .force-full-width { width: 100% !important; } --></style> <style type="text/css" media="screen"><!-- @media screen { @import url(http://fonts.googleapis.com/css?family=Open+Sans:400); /* Thanks Outlook 2013! */ td, h1, h2, h3 { font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif !important; } } --></style> <style type="text/css" media="only screen and (max-width: 600px)"><!-- /* Mobile styles */ @media only screen and (max-width: 600px) { table[class="w320"] { width: 320px !important; } table[class="w300"] { width: 300px !important; } table[class="w290"] { width: 290px !important; } td[class="w320"] { width: 320px !important; } td[class~="mobile-padding"] { padding-left: 14px !important; padding-right: 14px !important; } td[class*="mobile-padding-left"] { padding-left: 14px !important; } td[class*="mobile-padding-right"] { padding-right: 14px !important; } td[class*="mobile-block"] { display: block !important; width: 100% !important; text-align: left !important; padding-left: 0 !important; padding-right: 0 !important; padding-bottom: 15px !important; } td[class*="mobile-no-padding-bottom"] { padding-bottom: 0 !important; } td[class~="mobile-center"] { text-align: center !important; } table[class*="mobile-center-block"] { float: none !important; margin: 0 auto !important; } *[class*="mobile-hide"] { display: none !important; width: 0 !important; height: 0 !important; line-height: 0 !important; font-size: 0 !important; } td[class*="mobile-border"] { border: 0 !important; } } --></style> <table style="width: 100%;" cellspacing="0" cellpadding="0" align="center"> <tbody> <tr> <td align="center" valign="top" bgcolor="#ffffff" width="100%"> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="background: #1f1f1f; height: 70px;" width="100%"><center> <table class="w320" style="width: 600px;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="mobile-block mobile-no-padding-bottom mobile-center" style="background: #1f1f1f; padding: 10px 10px 10px 20px;" valign="top" width="270"><a style="text-decoration: none;" href="#"> <img src="https://pandorafms.com/images/logo_pandora_email.png" alt="Your Logo" width="200"> </a></td> <td class="mobile-block mobile-center" style="background: #1f1f1f; padding: 17px 15px 10px 10px;" valign="top" width="270">&nbsp;</td> </tr> </tbody> </table> </center></td> </tr> <tr> <td style="border-bottom: 1px solid #e7e7e7;"><center style="padding-bottom: 20px;"> <table class="w320" style="width: 600px;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="mobile-padding" style="padding: 20px;" align="left"><br class="mobile-hide"> <h2>Pandora FMS alert system</h2> <br> Dear customer,<br><br> We have <strong>good news</strong> for you. Alert has been <strong>RECOVERED</strong>&nbsp;status!<br> <br> <table style="width: 100%;" cellspacing="0" cellpadding="0" bgcolor="#ffffff"> <tbody> <tr> <td style="width: 100px; background: #D84A38;"> <div><!--[if mso]> <v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#" style="height:33px;v-text-anchor:middle;width:100px;" stroke="f" fillcolor="#D84A38"> <w:anchorlock/> <center> <![endif]--> <a style="background-color: #1f1f1f; color: whitesmoke; display: inline-block; font-family: sans-serif; font-size: 13px; font-weight: bold; line-height: 33px; text-align: center; text-decoration: none; width: 250px; -webkit-text-size-adjust: none;" href="_homeurl_">Go to Pandora FMS Console</a> <!--[if mso]> </center> </v:rect> <![endif]--></div> </td> <td style="background-color: #ffffff; font-size: 0; line-height: 0;" width="281">&nbsp;</td> </tr> </tbody> </table> </td> <td class="mobile-hide" style="padding-top: 20px; padding-bottom: 0; vertical-align: bottom;" valign="bottom"> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="padding-bottom: 0px; vertical-align: bottom;" align="right" valign="bottom"><img style="vertical-align: bottom; padding-bottom: 10px;" src="https://pandorafms.com/images/alerta_verde.png" alt="" width="130"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </center></td> </tr> <tr> <td style="background-color: #f8f8f8; border-bottom: 1px solid #e7e7e7; padding-top: 10px;" valign="top"><center> <table class="w320" style="height: 100%; width: 600px;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="mobile-padding" style="padding: 20px;" valign="top"> <table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="padding-right: 20px;" colspan="2"><strong>Monitoring details</strong></td> </tr> <tr> <td style="padding-top: 25px; width: 150px; border-top: 1px solid #E7E7E7; vertical-align: top;"><strong>Data</strong></td> <td style="padding-top: 25px; padding-right: 20px; border-top: 1px solid #E7E7E7; vertical-align: top;">_data_ <em>(_modulestatus_)</em></td> </tr> <tr> <td><strong>Agent</strong></td> <td>_agent_ <em>_address_</em></td> </tr> <tr> <td><strong>Module</strong></td> <td>_module_ <em>_moduledescription_ </em></td> </tr> <tr> <td><strong>Timestamp</strong></td> <td>_timestamp_</td> </tr> </tbody> </table> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="padding-top: 20px;"> <table style="width: 100%;" cellspacing="0" cellpadding="0"> <tbody> <tr> <td style="vertical-align: top;" width="350">This is a graph of latest 24hr data for this module: <br><br> _modulegraph_24h_</td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </center></td> </tr> <tr> <td style="background-color: #1f1f1f;"><center> <table class="w320" style="height: 100%; color: #ffffff; width: 600px;" border="0" cellspacing="0" cellpadding="0" bgcolor="#1f1f1f"> <tbody> <tr> <td class="mobile-padding" style="font-size: 12px; padding: 20px; background-color: #1f1f1f; color: #ffffff; text-align: center;" align="right" valign="middle"><a style="color: #ffffff;" href="https://pandorafms.com/company/contact/">Contact Us</a>&nbsp;&nbsp;|&nbsp;&nbsp; <a style="color: #ffffff;" href="https://forums.pandorafms.com/">Support</a>&nbsp;&nbsp;|&nbsp;&nbsp; <a style="color: #ffffff;" href="https://wiki.pandorafms.com">Docs</a>&nbsp;&nbsp;|&nbsp;&nbsp;</td> </tr> </tbody> </table> </center></td> </tr> </tbody> </table> </td> </tr> </tbody> </table>','text/html','','','','','',''); INSERT INTO `talert_actions` (`id`, `name`, `id_alert_command`, `field1`, `field2`, `field3`, `field4`, `field5`, `field6`, `field7`, `field8`, `field9`, `field10`, `id_group`, `action_threshold`, `field1_recovery`, `field2_recovery`, `field3_recovery`, `field4_recovery`, `field5_recovery`, `field6_recovery`, `field7_recovery`, `field8_recovery`, `field9_recovery`, `field10_recovery`) VALUES @@ -1133,9 +1131,11 @@ INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (2, 'Monitoring&#x INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (3, 'Monitoring Report Alerts', 'select t1.alias as agent_name, t2.nombre as module_name, (select talert_templates.name from talert_templates where talert_templates.id = t3.id_alert_template) as template, (select group_concat(t02.name) from talert_template_module_actions as t01 inner join talert_actions as t02 on t01.id_alert_action = t02.id where t01.id_alert_template_module = t3.id group by t01.id_alert_template_module) as actions from tagente as t1 inner join tagente_modulo as t2 on t1.id_agente = t2.id_agente inner join talert_template_modules as t3 on t2.id_agente_modulo = t3.id_agent_module order by agent_name, module_name;'); INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (4, 'Group view', 'select t1.nombre, (select count(t3.id_agente) from tagente as t3 where t1.id_grupo = t3.id_grupo) as agents, (SELECT COUNT(t4.id_agente) FROM tagente as t4 WHERE t4.id_grupo = t1.id_grupo AND t4.disabled = 0 AND t4.ultimo_contacto < NOW() - (intervalo / (1/2))) as agent_unknown, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND utimestamp > 0 AND tagente_modulo.id_tipo_modulo NOT IN(21,22,23,24,100) AND (UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) >= (tagente_estado.current_interval / (1/2))) as monitor_unknow, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente_modulo.id_tipo_modulo NOT IN (21,22,23,24) AND utimestamp = 0) as monitor_no_init, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 0 AND ((UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) < (tagente_estado.current_interval / (1/2)) OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24,100))) AND (utimestamp > 0 OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24)))) as monitor_ok, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 1 AND ((UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) < (tagente_estado.current_interval / (1/2)) OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24,100))) AND utimestamp > 0) as monitor_critical, (SELECT COUNT(talert_template_modules.id) FROM talert_template_modules, tagente_modulo, tagente_estado, tagente WHERE tagente.id_grupo = t1.id_grupo AND tagente_modulo.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente.disabled = 0 AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo AND times_fired > 0) as monitor_alert_fired from tgrupo as t1 where 0 < (select count(t2.id_agente) from tagente as t2 where t1.id_grupo = t2.id_grupo)'); +-- trecon scripts INSERT INTO `trecon_script` VALUES (2,'IPMI Recon','Specific Pandora FMS Intel DCM Discovery (c) Artica ST 2011 <info@artica.es> Usage: ./ipmi-recon.pl <task_id> <group_id> <create_incident_flag> <custom_field1> <custom_field2> <custom_field3> <custom_field4> * custom_field1 = Network i.e.: 192.168.100.0/24 * custom_field2 = Username * custom_field3 = Password * custom_field4 = Additional parameters i.e.: -D LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.: 192.168.100.0/24\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Additional parameters\",\"help\":\"Optional additional parameters such as -D LAN_2_0 to use IPMI ver 2.0 instead of 1.5. These options will also be passed to the IPMI plugin when the current values are read.\",\"value\":\"\",\"hide\":\"\"}}'); - INSERT INTO `trecon_script` VALUES (5,'WMI Recon Script','This script is used to automatically gather host information via WMI. Available parameters: * Network = network to scan (e.g. 192.168.100.0/24). * WMI auth = comma separated list of WMI authentication tokens in the format username%password (e.g. Administrador%pass). See the documentation for more information.','/usr/share/pandora_server/util/recon_scripts/wmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"WMI auth\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}'); +INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Application.VMware', 'Discovery Application script to monitor VMware technologies (ESXi, VCenter, VSphere)', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `execute`, `plugin_type`, `macros`, `parameters`) VALUES (1,'IPMI Plugin','Plugin to get IPMI monitors from a IPMI Device.',0,'/usr/share/pandora_server/util/plugin/ipmi-plugin.pl',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Target IP\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"true\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Sensor\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Additional Options\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-h _field1_ -u _field2_ -p _field3_ -s _field4_ -- _field5_'); @@ -1268,3 +1268,48 @@ INSERT INTO `tcontainer` SET `name` = 'Default graph container'; INSERT INTO tlog_graph_models VALUES (1, 'Apache log model', '^.*?\s+.*".*?\s(\/.*?)\?.*1.1"\s+(.*?)\s+(.*?)\s+', 'pagina, html_err_code, _tiempo_', 1); + +INSERT INTO tlog_graph_models VALUES (2, 'Apache accesses per client and status', +'(.*?)\ -.*1.1"\ (\d+)\ \d+', +'host,status', 1); + +INSERT INTO tlog_graph_models VALUES (3, 'Apache time per requester and html code', +'(.*?)\ -.*1.1"\ (\d+)\ (\d+)', +'origin,respose,_time_', 1); + +INSERT INTO tlog_graph_models VALUES (4, 'Count output', +'.*', +'Coincidences', 0); + +INSERT INTO tlog_graph_models VALUES (5, 'Events replicated to metaconsole', +'.* (.*?) .* (\d+) events replicated to metaconsole', +'server,_events_', 0); + +INSERT INTO tlog_graph_models VALUES (6, 'Pages with warnings', +'PHP Warning:.*in (.*?) on', +'page', 0); + +INSERT INTO tlog_graph_models VALUES (7, 'Users login', +'Starting Session \d+\ of user (.*)', +'user', 0); + +-- +-- Dumping data for table `tnotification_source` +-- +INSERT INTO `tnotification_source`(`description`, `icon`, `max_postpone_time`, `enabled`, `user_editable`, `also_mail`) VALUES + ("System status", "icono_info_mr.png", 86400, 1, 1, 0), + ("Message", "icono_info_mr.png", 86400, 1, 1, 0), + ("Pending task", "icono_info_mr.png", 86400, 1, 1, 0), + ("Advertisement", "icono_info_mr.png", 86400, 1, 1, 0), + ("Official communication", "icono_info_mr.png", 86400, 1, 1, 0), + ("Sugerence", "icono_info_mr.png", 86400, 1, 1, 0); + +-- +-- Dumping data for table `tnotification_source_user` +-- +INSERT INTO `tnotification_source_user`(`id_source`,`id_user`,`enabled`,`also_mail`) VALUES + ((SELECT `id` FROM `tnotification_source` WHERE `description`="System status"), "admin",1,0); + +INSERT INTO `tnotification_source_group` SELECT `id`,0 FROM `tnotification_source` WHERE `description`="Message"; + + \ No newline at end of file diff --git a/pandora_server/DEBIAN/control b/pandora_server/DEBIAN/control index 85b4842031..52e071fda9 100644 --- a/pandora_server/DEBIAN/control +++ b/pandora_server/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-server -Version: 7.0NG.731-190225 +Version: 7.0NG.731-190226 Architecture: all Priority: optional Section: admin diff --git a/pandora_server/DEBIAN/make_deb_package.sh b/pandora_server/DEBIAN/make_deb_package.sh index 0a9ad7006c..937c46f882 100644 --- a/pandora_server/DEBIAN/make_deb_package.sh +++ b/pandora_server/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.731-190225" +pandora_version="7.0NG.731-190226" package_cpan=0 package_pandora=1 diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index a5e8be893d..53265cb0a0 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -33,7 +33,7 @@ use PandoraFMS::Core; use PandoraFMS::DataServer; use PandoraFMS::NetworkServer; use PandoraFMS::SNMPServer; -use PandoraFMS::ReconServer; +use PandoraFMS::DiscoveryServer; use PandoraFMS::WMIServer; use PandoraFMS::PluginServer; use PandoraFMS::PredictionServer; @@ -123,7 +123,7 @@ sub pandora_startup () { pandora_reset_server (\%Config, $DBH); push (@Servers, new PandoraFMS::DataServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::NetworkServer (\%Config, $DBH)); - push (@Servers, new PandoraFMS::ReconServer (\%Config, $DBH)); + push (@Servers, new PandoraFMS::DiscoveryServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::SNMPServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::WMIServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::PluginServer (\%Config, $DBH)); diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 78ce6924ba..1b1ed03412 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -45,7 +45,7 @@ our @EXPORT = qw( # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.731"; -my $pandora_build = "190225"; +my $pandora_build = "190226"; our $VERSION = $pandora_version." ".$pandora_build; # Setup hash @@ -226,7 +226,7 @@ sub pandora_load_config { $pa_config->{"dataserver"} = 1; # default $pa_config->{"networkserver"} = 1; # default $pa_config->{"snmpconsole"} = 1; # default - $pa_config->{"reconserver"} = 1; # default + $pa_config->{"discoveryserver"} = 1; # default $pa_config->{"wmiserver"} = 1; # default $pa_config->{"pluginserver"} = 1; # default $pa_config->{"predictionserver"} = 1; # default @@ -254,6 +254,7 @@ sub pandora_load_config { $pa_config->{"plugin_threads"} = 2; # Introduced on 2.0 $pa_config->{"plugin_exec"} = '/usr/bin/timeout'; # 3.0 $pa_config->{"recon_threads"} = 2; # Introduced on 2.0 + $pa_config->{"discovery_threads"} = 2; # Introduced on 732 $pa_config->{"prediction_threads"} = 1; # Introduced on 2.0 $pa_config->{"plugin_timeout"} = 5; # Introduced on 2.0 $pa_config->{"wmi_threads"} = 2; # Introduced on 2.0 @@ -659,8 +660,8 @@ sub pandora_load_config { elsif ($parametro =~ m/^predictionserver\s+([0-9]*)/i){ $pa_config->{'predictionserver'}= clean_blank($1); } - elsif ($parametro =~ m/^reconserver\s+([0-9]*)/i) { - $pa_config->{'reconserver'}= clean_blank($1); + elsif ($parametro =~ m/^discoveryserver\s+([0-9]*)/i) { + $pa_config->{'discoveryserver'}= clean_blank($1); } elsif ($parametro =~ m/^reconserver\s+([0-9]*)/i) { $pa_config->{'reconserver'}= clean_blank($1); @@ -809,6 +810,9 @@ sub pandora_load_config { elsif ($parametro =~ m/^autocreate_group\s+([0-9*]*)/i) { $pa_config->{'autocreate_group'}= clean_blank($1); } + elsif ($parametro =~ m/^discovery_threads\s+([0-9]*)/i) { + $pa_config->{'discovery_threads'}= clean_blank($1); + } elsif ($parametro =~ m/^recon_threads\s+([0-9]*)/i) { $pa_config->{'recon_threads'}= clean_blank($1); } diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index fd46a27ee9..4155b2d432 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -179,6 +179,7 @@ our @EXPORT = qw( pandora_evaluate_alert pandora_evaluate_snmp_alerts pandora_event + pandora_extended_event pandora_execute_alert pandora_execute_action pandora_exec_forced_alerts @@ -250,6 +251,7 @@ our @EXPORT = qw( pandora_delete_graph_source pandora_delete_custom_graph pandora_edit_custom_graph + notification_set_targets ); # Some global variables @@ -1460,6 +1462,35 @@ sub pandora_execute_action ($$$$$$$$$;$) { pandora_create_integria_ticket($pa_config, $api_path, $api_pass, $integria_user, $integria_user_pass, $ticket_name, $ticket_group_id, $ticket_priority, $ticket_email, $ticket_owner, $ticket_description); + + # Generate notification + } elsif ($clean_name eq "Generate Notification") { + + # Translate macros + $field3 = subst_alert_macros($field3, \%macros, $pa_config, $dbh, $agent, $module); + $field4 = subst_alert_macros($field4, \%macros, $pa_config, $dbh, $agent, $module); + + # If no targets ignore notification + if (defined($field1) && defined($field2) && ($field1 ne "" || $field2 ne "")) { + my @user_list = map {clean_blank($_)} split /,/, $field1; + my @group_list = map {clean_blank($_)} split /,/, $field2; + + my $notification = {}; + $notification->{'subject'} = safe_input($field3); + $notification->{'mensaje'} = safe_input($field4); + $notification->{'id_source'} = get_db_value($dbh, 'SELECT id FROM tnotification_source WHERE description = ?', safe_input('System status')); + + # Create message + my $notification_id = db_process_insert($dbh,'id_mensaje','tmensajes',$notification); + if (!$notification_id) { + logger($pa_config, "Failed action '" . $action->{'name'} . "' for alert '". $alert->{'name'} . "' agent '" . (defined($agent) ? $agent->{'alias'} : 'N/A') . "'.", 3); + } else { + notification_set_targets($pa_config, $dbh, $notification_id, \@user_list, \@group_list); + } + } else { + logger($pa_config, "Failed action '" . $action->{'name'} . "' for alert '". $alert->{'name'} . "' agent '" . (defined($agent) ? $agent->{'alias'} : 'N/A') . "' Empty targets. Ignored.", 3); + } + # Unknown } else { logger($pa_config, "Unknown action '" . $action->{'name'} . "' for alert '". $alert->{'name'} . "' agent '" . (defined ($agent) ? $agent->{'alias'} : 'N/A') . "'.", 3); @@ -3241,11 +3272,11 @@ sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$) { # Create the event logger($pa_config, "Generating event '$evento' for agent ID $id_agente module ID $id_agentmodule.", 10); - db_do ($dbh, 'INSERT INTO ' . $event_table . ' (id_agente, id_grupo, evento, timestamp, estado, utimestamp, event_type, id_agentmodule, id_alert_am, criticity, user_comment, tags, source, id_extra, id_usuario, critical_instructions, warning_instructions, unknown_instructions, ack_utimestamp, custom_data, data, module_status) + my $event_id = db_insert ($dbh, 'id_evento','INSERT INTO ' . $event_table . ' (id_agente, id_grupo, evento, timestamp, estado, utimestamp, event_type, id_agentmodule, id_alert_am, criticity, user_comment, tags, source, id_extra, id_usuario, critical_instructions, warning_instructions, unknown_instructions, ack_utimestamp, custom_data, data, module_status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $id_agente, $id_grupo, safe_input ($evento), $timestamp, $event_status, $utimestamp, $event_type, $id_agentmodule, $id_alert_am, $severity, $comment, $module_tags, $source, $id_extra, $user_name, $critical_instructions, $warning_instructions, $unknown_instructions, $ack_utimestamp, $custom_data, $module_data, $module_status); - + # Do not write to the event file - return if ($pa_config->{'event_file'} eq ''); + return $event_id if ($pa_config->{'event_file'} eq ''); # Add a header when the event file is created my $header = undef; @@ -3256,7 +3287,7 @@ sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$) { # Open the event file for writing if (! open (EVENT_FILE, '>>' . $pa_config->{'event_file'})) { logger($pa_config, "Error opening event file " . $pa_config->{'event_file'} . ": $!", 10); - return; + return $event_id; } # Resolve ids @@ -3279,6 +3310,29 @@ sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$) { print EVENT_FILE "$agent_name,".safe_output($group_name)."," . safe_output ($evento) . ",$timestamp,$event_status,$utimestamp,$event_type,".safe_output($module_name).",".safe_output($alert_name).",$severity,".safe_output($comment).",".safe_output($module_tags).",$source,$id_extra,$user_name,".safe_output($critical_instructions).",".safe_output($warning_instructions).",".safe_output($unknown_instructions).",$ack_utimestamp\n"; close (EVENT_FILE); + + return $event_id; +} + +########################################################################## +=head2 C<< pandora_extended_event (I<$pa_config>, I<$dbh>, I<$event_id>, I<$description>) >> + +Creates an extended event linked to an existing main event id. + +=cut +########################################################################## +sub pandora_extended_event($$$$) { + my ($pa_config, $dbh, $event_id, $description) = @_; + + return unless defined($event_id) && "$event_id" ne "" && $event_id > 0; + + return db_do( + $dbh, + 'INSERT INTO tevent_extended (id_evento, utimestamp, description) VALUES (?,?,?)', + $event_id, + time(), + safe_input($description) + ); } ########################################################################## @@ -4544,7 +4598,7 @@ sub pandora_server_statistics ($$) { $server->{"lag"} = 0; $server->{"module_lag"} = 0; # Recon server - } elsif ($server->{"server_type"} == RECONSERVER) { + } elsif ($server->{"server_type"} == DISCOVERYSERVER) { # Total jobs running on this recon server $server->{"modules"} = get_db_value ($dbh, "SELECT COUNT(id_rt) FROM trecon_task WHERE id_recon_server = ?", $server->{"id_server"}); @@ -5776,6 +5830,62 @@ sub pandora_safe_mode_modules_update { } } +########################################################################## + +=head2 C<< message_set_targets (I<$dbh>, I<$pa_config>, I<$notification_id>, I<$users>, I<$groups>) >> +Set targets for given messaje (users and groups in hash ref) +=cut + +########################################################################## +sub notification_set_targets { + my ($pa_config, $dbh, $notification_id, $users, $groups) = @_; + my $ret = undef; + + if (!defined($pa_config)) { + return undef; + } + + if (!defined($notification_id)) { + return undef; + } + + if (ref($users) eq "ARRAY") { + my $values = {}; + foreach my $user (@{$users}) { + if (defined($user) && $user eq "") { + next; + } + + $values->{'id_mensaje'} = $notification_id; + $values->{'id_user'} = $user; + } + + $ret = db_process_insert($dbh, '', 'tnotification_user', $values); + if (!$ret) { + return undef; + } + } + + if (ref($groups) eq "ARRAY") { + my $values = {}; + foreach my $group (@{$groups}) { + if ($group != 0 && empty($group)) { + next; + } + + $values->{'id_mensaje'} = $notification_id; + $values->{'id_group'} = $group; + } + + $ret = db_process_insert($dbh, '', 'tnotification_group', $values); + if (!$ret) { + return undef; + } + } + + return 1; +} + # End of function declaration # End of defined Code diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index 20bece94e6..a257d5df07 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -20,6 +20,8 @@ package PandoraFMS::DB; use strict; use warnings; use DBI; + +use lib '/usr/lib/perl5'; use PandoraFMS::Tools; #use Data::Dumper; diff --git a/pandora_server/lib/PandoraFMS/ReconServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm similarity index 87% rename from pandora_server/lib/PandoraFMS/ReconServer.pm rename to pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 277e3a3ec8..bc4e1caa73 100644 --- a/pandora_server/lib/PandoraFMS/ReconServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -1,6 +1,6 @@ -package PandoraFMS::ReconServer; +package PandoraFMS::DiscoveryServer; ########################################################################## -# Pandora FMS Recon Server. +# Pandora FMS Discovery Server. # Pandora FMS. the Flexible Monitoring System. http://www.pandorafms.org ########################################################################## # Copyright (c) 2005-2009 Artica Soluciones Tecnologicas S.L @@ -28,6 +28,7 @@ use IO::Socket::INET; use POSIX qw(strftime ceil); use JSON qw(decode_json encode_json); use Encode qw(encode_utf8); +use MIME::Base64; # Default lib dir for RPM and DEB packages use lib '/usr/lib/perl5'; @@ -57,16 +58,16 @@ use constant OS_ROUTER => 17; use constant OS_SWITCH => 18; ######################################################################################## -# Recon Server class constructor. +# Discovery Server class constructor. ######################################################################################## sub new ($$$$$$) { my ($class, $config, $dbh) = @_; - return undef unless $config->{'reconserver'} == 1; + return undef unless $config->{'reconserver'} == 1 || $config->{'discoveryserver'} == 1; if (! -e $config->{'nmap'}) { - logger ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Recon Server not found.", 1); - print_message ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Recon Server not found.", 1); + logger ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Discovery Server not found.", 1); + print_message ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Discovery Server not found.", 1); return undef; } @@ -78,14 +79,14 @@ sub new ($$$$$$) { # Restart automatic recon tasks. db_do ($dbh, 'UPDATE trecon_task SET utimestamp = 0 WHERE id_recon_server = ? AND status <> -1 AND interval_sweep > 0', - get_server_id ($dbh, $config->{'servername'}, RECONSERVER)); + get_server_id ($dbh, $config->{'servername'}, DISCOVERYSERVER)); # Reset (but do not restart) manual recon tasks. db_do ($dbh, 'UPDATE trecon_task SET status = -1 WHERE id_recon_server = ? AND status <> -1 AND interval_sweep = 0', - get_server_id ($dbh, $config->{'servername'}, RECONSERVER)); + get_server_id ($dbh, $config->{'servername'}, DISCOVERYSERVER)); # Call the constructor of the parent class - my $self = $class->SUPER::new($config, RECONSERVER, \&PandoraFMS::ReconServer::data_producer, \&PandoraFMS::ReconServer::data_consumer, $dbh); + my $self = $class->SUPER::new($config, DISCOVERYSERVER, \&PandoraFMS::DiscoveryServer::data_producer, \&PandoraFMS::DiscoveryServer::data_consumer, $dbh); bless $self, $class; return $self; @@ -98,8 +99,14 @@ sub run ($) { my $self = shift; my $pa_config = $self->getConfig (); - print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Recon Server.", 1); - $self->setNumThreads ($pa_config->{'recon_threads'}); + print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Discovery Server.", 1); + my $threads = $pa_config->{'recon_threads'}; + + # Use hightest value + if ($pa_config->{'discovery_threads'} > $pa_config->{'recon_threads'}) { + $threads = $pa_config->{'discovery_threads'}; + } + $self->setNumThreads($threads); $self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem); } @@ -121,9 +128,10 @@ sub data_producer ($) { # Status -1 means "done". my @rows = get_db_rows ($dbh, 'SELECT * FROM trecon_task - WHERE id_recon_server = ? - AND disabled = 0 - AND utimestamp = 0 OR (status = -1 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP())', $server_id); + WHERE id_recon_server = ? + AND disabled = 0 + AND ((utimestamp = 0 AND interval_sweep != 0 OR status = 1) + OR (status = -1 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()))', $server_id); foreach my $row (@rows) { # Update task status @@ -154,12 +162,15 @@ sub data_consumer ($$) { logger($pa_config, 'Starting recon task for net ' . $task->{'subnet'} . '.', 10); } - # Call nmap - my $nmap_args = '-nsP -PE --max-retries '.$pa_config->{'icmp_checks'}.' --host-timeout '.$pa_config->{'networktimeout'}.'s -T'.$pa_config->{'recon_timing_template'}; - my $np = new PandoraFMS::NmapParser; eval { my @subnets = split(/,/, safe_output($task->{'subnet'})); my @communities = split(/,/, safe_output($task->{'snmp_community'})); + my @auth_strings = (); + if(defined($task->{'auth_strings'})) { + @auth_strings = split(/,/, safe_output($task->{'auth_strings'})); + } + + my $main_event = pandora_event($pa_config, "[Discovery] Execution summary",$task->{'id_group'}, 0, 0, 0, 0, 'system', 0, $dbh); my $recon = new PandoraFMS::Recon::Base( communities => \@communities, @@ -186,6 +197,10 @@ sub data_consumer ($$) { subnets => \@subnets, task_id => $task->{'id_rt'}, vlan_cache_enabled => $task->{'vlan_enabled'}, + wmi_enabled => $task->{'wmi_enabled'}, + auth_strings_array => \@auth_strings, + autoconfiguration_enabled => $task->{'autoconfiguration_enabled'}, + main_event_id => $main_event, %{$pa_config} ); @@ -225,7 +240,13 @@ sub exec_recon_script ($$$) { # \r and \n should be escaped for decode_json(). $macros =~ s/\n/\\n/g; $macros =~ s/\r/\\r/g; - my $decoded_macros = decode_json (encode_utf8($macros)); + my $decoded_macros; + + if ($macros) { + eval { + $decoded_macros = decode_json(encode_utf8($macros)); + }; + } my $macros_parameters = ''; @@ -244,15 +265,28 @@ sub exec_recon_script ($$$) { $macros_parameters = $macros_parameters . ' "' . $m->{"value"} . '"'; } } + + my $ent_script = 0; + my $args = enterprise_hook('discovery_custom_recon_scripts',[$pa_config, $dbh, $task, $script]); + if (!$args) { + $args = "$task->{'id_rt'} $task->{'id_group'} $task->{'create_incident'} $macros_parameters"; + } else { + $ent_script = 1; + } if (-x $command) { - `$command $task->{'id_rt'} $task->{'id_group'} $task->{'create_incident'} $macros_parameters`; + my $exec_output = `$command $args`; + logger($pa_config, "Execution output: \n". $exec_output, 10); } else { - logger ($pa_config, "Cannot execute recon task command $command."); + logger($pa_config, "Cannot execute recon task command $command.", 10); } # Only update the timestamp in case something went wrong. The script should set the status. db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ? WHERE id_rt = ?', time (), $task->{'id_rt'}); + + if ($ent_script == 1) { + enterprise_hook('discovery_clean_custom_recon',[$pa_config, $dbh, $task, $script]); + } logger($pa_config, 'Done executing recon script ' . safe_output($script->{'name'}), 10); return 0; @@ -441,7 +475,23 @@ sub PandoraFMS::Recon::Base::create_agent($$) { $location->{'longitude'}, $location->{'latitude'} ); return undef unless defined ($agent_id) and ($agent_id > 0); - pandora_event($self->{'pa_config'}, "[RECON] New " . safe_output($self->get_device_type($device)) . " found (" . join(',', safe_output($self->get_addresses($device))) . ").", $self->{'group_id'}, $agent_id, 2, 0, 0, 'recon_host_detected', 0, $self->{'dbh'}); + + # Autoconfigure agent + if (defined($self->{'autoconfiguration_enabled'}) && $self->{'autoconfiguration_enabled'} == 1) { + my $agent_data = PandoraFMS::DB::get_db_single_row($self->{'dbh'}, 'SELECT * FROM tagente WHERE id_agente = ?', $agent_id); + # Update agent configuration once, after create agent. + enterprise_hook('autoconfigure_agent', [$self->{'pa_config'}, $host_name, $agent_id, $agent_data, $self->{'dbh'}, 1]); + } + + if (defined($self->{'main_event_id'})) { + my $addresses_str = join(',', safe_output($self->get_addresses($device))); + pandora_extended_event( + $self->{'pa_config'}, $self->{'dbh'}, $self->{'main_event_id'}, + "[Discovery] New " . safe_output($self->get_device_type($device)) . " found " . $host_name . " (" . $addresses_str . ") Agent $agent_id." + ); + + } + $agent_learning = 1; # Create network profile modules for the agent @@ -748,6 +798,35 @@ sub PandoraFMS::Recon::Base::set_parent($$$) { db_do($self->{'dbh'}, 'UPDATE tagente SET id_parent=? WHERE id_agente=?', $agent_parent->{'id_agente'}, $agent->{'id_agente'}); } +########################################################################## +# Create a WMI module for the given agent. +########################################################################## +sub PandoraFMS::Recon::Base::wmi_module { + my ($self, $agent_id, $target, $wmi_query, $wmi_auth, $column, + $module_name, $module_description, $module_type, $unit) = @_; + + # Check whether the module already exists. + my $module_id = get_agent_module_id($self->{'dbh'}, $module_name, $agent_id); + return if ($module_id > 0); + + my ($user, $pass) = ($wmi_auth ne '') ? split('%', $wmi_auth) : (undef, undef); + my %module = ( + 'descripcion' => safe_input($module_description), + 'id_agente' => $agent_id, + 'id_modulo' => 6, + 'id_tipo_modulo' => get_module_id($self->{'dbh'}, $module_type), + 'ip_target' => $target, + 'nombre' => safe_input($module_name), + 'plugin_pass' => defined($pass) ? $pass : '', + 'plugin_user' => defined($user) ? $user : '', + 'snmp_oid' => $wmi_query, + 'tcp_port' => $column, + 'unit' => defined($unit) ? $unit : '' + ); + + pandora_create_module_from_hash($self->{'pa_config'}, \%module, $self->{'dbh'}); +} + ########################################################################## # Update recon task status. ########################################################################## diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index b7a200124f..41cb56f39b 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -32,7 +32,7 @@ our @ISA = qw(Exporter); # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.731"; -my $pandora_build = "190225"; +my $pandora_build = "190226"; our $VERSION = $pandora_version." ".$pandora_build; our %EXPORT_TAGS = ( 'all' => [ qw() ] ); @@ -163,6 +163,8 @@ sub csv_to_obj { @hr_headers = map { $_ =~ s/\"//g; trim($_); } @hr_headers; foreach my $line (@lines) { + next if empty($line); + my $i = 0; my %hr = map { $_ =~ s/\"//g; $hr_headers[$i++] => trim($_) } split /,/, $line; diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index a214d6ba4b..ec3eb0d853 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -123,6 +123,12 @@ sub new { # Globally enable/disable SNMP scans. snmp_enabled => 1, + # Globally enable/disable WMI scans. + wmi_enabled => 0, + auth_strings_array => [], + wmi_timeout => 3, + timeout_cmd => '', + # Switch to switch connections. Used to properly connect hosts # that are connected to a switch wich is in turn connected to another switch, # since the hosts will show up in the latter's switch AFT too. @@ -160,6 +166,7 @@ sub new { snmp_timeout => 2, snmp_version => 1, subnets => [], + autoconfiguration_enabled => 0, @_, }; @@ -217,6 +224,19 @@ sub new { } } + # Prepare auth array. + # WMI could be launched with '-N' - no pass - argument. + if ($self->{'wmi_enabled'} == 1){ + if (defined($self->{'auth_strings_str'})) { + @{$self->{'auth_strings_array'}} = split(',', $self->{'auth_strings_str'}); + } + + # Timeout available only in linux environments. + if ($^O =~ /lin/i && defined($self->{'plugin_exec'}) && defined($self->{'wmi_timeout'})) { + $self->{'timeout_cmd'} = $self->{'plugin_exec'}.' '.$self->{'wmi_timeout'}.' '; + } + } + # Remove all snmp related values if disabled if (!$self->{'snmp_enabled'}) { $self->{'communities'} = []; @@ -1312,6 +1332,9 @@ sub scan_subnet($) { $progress += $step; $self->snmp_discovery($host); + + # Add wmi scan if enabled. + $self->wmi_scan($host) if ($self->{'wmi_enabled'} == 1); } } # ping scan. @@ -1330,6 +1353,9 @@ sub scan_subnet($) { next if ($self->ping($host) == 0); $self->snmp_discovery($host); + + # Add wmi scan if enabled. + $self->wmi_scan($host) if ($self->{'wmi_enabled'} == 1); } } } @@ -1475,6 +1501,9 @@ sub snmp_get_command { my $command = "snmpwalk -M/dev/null -r$self->{'snmp_checks'} -t$self->{'snmp_timeout'} -v$self->{'snmp_version'} -On -Oe "; if ($self->{'snmp_version'} eq "3") { + if ($self->{'community'}) { # Context + $command .= " -N $self->{'community'} "; + } $command .= " -l$self->{'snmp_security_level'} "; if ($self->{'snmp_security_level'} ne "noAuthNoPriv") { $command .= " -u$self->{'snmp_auth_user'} -a$self->{'snmp_auth_method'} -A$self->{'snmp_auth_pass'} "; @@ -1579,6 +1608,168 @@ sub traceroute_connectivity($$) { } } +########################################################################## +# Returns the credentials with which the host responds to WMI queries or +# undef if it does not respond to WMI. +########################################################################## +sub responds_to_wmi { + my ($self, $target) = @_; + + foreach my $auth (@{$self->{'auth_strings_array'}}) { + my @output; + if ($auth ne '') { + @output = `$self->{'timeout_cmd'}$self->{'wmi_client'} -U $auth //$target "SELECT * FROM Win32_ComputerSystem" 2>&1`; + } else { + @output = `$self->{'timeout_cmd'}$self->{'wmi_client'} -N //$target "SELECT * FROM Win32_ComputerSystem" 2>&1`; + } + + foreach my $line (@output) { + chomp($line); + return $auth if ($line =~ m/^CLASS: Win32_ComputerSystem$/); + } + } + + return undef; +} + +########################################################################## +# Add wmi modules to the given host. +########################################################################## +sub wmi_scan { + my ($self, $target) = @_; + + $self->call('message', "[".$target."] Checking WMI.", 5); + + my $auth = $self->responds_to_wmi($target); + return unless defined($auth); + + $self->call('message', "[".$target."] WMI available.", 10); + # Create the agent if it does not exist. + my $agent_id = $self->call('create_agent', $target); + next unless defined($agent_id); + + # CPU. + my @cpus = $self->wmi_get_value_array($target, $auth, 'SELECT DeviceId FROM Win32_Processor', 0); + foreach my $cpu (@cpus) { + $self->call( + 'wmi_module', + ( + $agent_id, + $target, + "SELECT LoadPercentage FROM Win32_Processor WHERE DeviceId='$cpu'", + $auth, + 1, + "CPU Load $cpu", + "Load for $cpu (%)", + 'generic_data' + ) + ); + } + + # Memory. + my $mem = $self->wmi_get_value($target, $auth, 'SELECT FreePhysicalMemory FROM Win32_OperatingSystem', 0); + if (defined($mem)) { + $self->call('wmi_module', + ( + $agent_id, + $target, + "SELECT FreePhysicalMemory, TotalVisibleMemorySize FROM Win32_OperatingSystem", + $auth, + 0, + 'FreeMemory', + 'Free memory', + 'generic_data', + 'KB' + ) + ); + } + + # Disk. + my @units = $self->wmi_get_value_array($target, $auth, 'SELECT DeviceID FROM Win32_LogicalDisk', 0); + foreach my $unit (@units) { + $self->call( + 'wmi_module', + ( + $agent_id, + $target, + "SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID='$unit'", + $auth, + 1, + "FreeDisk $unit", + 'Available disk space in kilobytes', + 'generic_data', + 'KB' + ) + ); + } +} + +########################################################################## +# Extra: WMI imported methods. DO NOT EXPORT TO AVOID DOUBLE DEF. +########################################################################## + +########################################################################## +# Performs a wmi get requests and returns the response as an array. +########################################################################## +sub wmi_get { + my ($self, $target, $auth, $query) = @_; + + my @output; + if (defined($auth) && $auth ne '') { + @output = `$self->{'timeout_cmd'}"$self->{'wmi_client'}" -U $auth //$target "$query" 2>&1`; + }else { + @output = `$self->{'timeout_cmd'}"$self->{'wmi_client'}" -N //$target "$query" 2>&1`; + } + + # Something went wrong. + return () if ($? != 0); + + return @output; +} + +########################################################################## +# Performs a WMI request and returns the requested column of the first row. +# Returns undef on error. +########################################################################## +sub wmi_get_value { + my ($self, $target, $auth, $query, $column) = @_; + my @result; + + my @output = $self->wmi_get($target, $auth, $query); + return undef unless defined($output[2]); + + my $line = $output[2]; + chomp($line); + my @columns = split(/\|/, $line); + return undef unless defined($columns[$column]); + + return $columns[$column]; +} + +########################################################################## +# Performs a WMI request and returns row values for the requested column +# in an array. +########################################################################## +sub wmi_get_value_array { + my ($self, $target, $auth, $query, $column) = @_; + my @result; + + my @output = $self->wmi_get($target, $auth, $query); + foreach (my $i = 2; defined($output[$i]); $i++) { + my $line = $output[$i]; + chomp($line); + my @columns = split(/\|/, $line); + next unless defined($columns[$column]); + push(@result, $columns[$column]); + } + + return @result; +} + +########################################################################## +# END: WMI imported methods. +########################################################################## + 1; __END__ diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 1146e8ce92..aababebd69 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -51,7 +51,7 @@ our @EXPORT = qw( DATASERVER NETWORKSERVER SNMPCONSOLE - RECONSERVER + DISCOVERYSERVER PLUGINSERVER PREDICTIONSERVER WMISERVER @@ -134,7 +134,7 @@ our @EXPORT = qw( use constant DATASERVER => 0; use constant NETWORKSERVER => 1; use constant SNMPCONSOLE => 2; -use constant RECONSERVER => 3; +use constant DISCOVERYSERVER => 3; use constant PLUGINSERVER => 4; use constant PREDICTIONSERVER => 5; use constant WMISERVER => 6; diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 5da2297eb0..076f19497a 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.731 -%define release 190225 +%define release 190226 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index e56f0ab35b..e3adf2711e 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.731 -%define release 190225 +%define release 190226 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index d06e349eb9..55915d85a0 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.731" -PI_BUILD="190225" +PI_BUILD="190226" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 881ded4495..c8eb037f7a 100644 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -34,7 +34,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.731 PS190225"; +my $version = "7.0NG.731 PS190226"; # Pandora server configuration my %conf; @@ -432,6 +432,13 @@ sub pandora_purgedb ($$) { # Delete old tgraph_source data db_do ($dbh,"DELETE FROM tgraph_source WHERE id_graph NOT IN (SELECT id_graph FROM tgraph)"); + + # Delete old messages + log_message ('PURGE', "Deleting old messages."); + if ($conf->{'_delete_old_messages'} > 0) { + my $message_limit = time() - 86400 * $conf->{'_delete_old_messages'}; + db_do ($dbh, "DELETE FROM tmensajes WHERE timestamp < ?", $message_limit); + } } ############################################################################### @@ -651,6 +658,7 @@ sub pandora_load_config_pdb ($) { $conf->{'_history_db_delay'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'history_db_delay'"); $conf->{'_days_delete_unknown'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'days_delete_unknown'"); $conf->{'_inventory_purge'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'inventory_purge'"); + $conf->{'_delete_old_messages'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'delete_old_messages'"); $conf->{'_enterprise_installed'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'enterprise_installed'"); $conf->{'_metaconsole'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'metaconsole'"); $conf->{'_metaconsole_events_history'} = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = 'metaconsole_events_history'"); diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 7a04ff00f1..33a9c811b8 100644 --- 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.731 PS190225"; +my $version = "7.0NG.731 PS190226"; # save program name for logging my $progname = basename($0);