diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 8f3d860eff..42d1053140 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,11 @@ +2012-06-12 Miguel de Dios + + * lib/PandoraFMS/ReconServer.pm: fixed the recode into html entities + the name of network component into the function + "create_network_profile_modules". + + MERGED FROM 4.0.2 + 2012-06-11 Miguel de Dios * pandora_server/util/pandora_xml_stress.pl: cleaned source code diff --git a/pandora_server/lib/PandoraFMS/ReconServer.pm b/pandora_server/lib/PandoraFMS/ReconServer.pm index 5e4dc7f977..47247cd836 100644 --- a/pandora_server/lib/PandoraFMS/ReconServer.pm +++ b/pandora_server/lib/PandoraFMS/ReconServer.pm @@ -53,9 +53,9 @@ my $TaskSem :shared = Thread::Semaphore->new (0); ######################################################################################## sub new ($$$$$$) { my ($class, $config, $dbh) = @_; - + return undef unless $config->{'reconserver'} == 1; - + if (! -e $config->{'nmap'}) { logger ($config, ' [E] ' . $config->{'nmap'} . " needed by Pandora FMS Recon Server not found.", 1); print_message ($config, ' [E] ' . $config->{'nmap'} . " needed by Pandora FMS Recon Server not found.", 1); @@ -64,9 +64,9 @@ sub new ($$$$$$) { # Call the constructor of the parent class my $self = $class->SUPER::new($config, 3, \&PandoraFMS::ReconServer::data_producer, \&PandoraFMS::ReconServer::data_consumer, $dbh); - - bless $self, $class; - return $self; + + bless $self, $class; + return $self; } ############################################################################### @@ -75,7 +75,7 @@ sub new ($$$$$$) { sub run ($) { my $self = shift; my $pa_config = $self->getConfig (); - + print_message ($pa_config, " [*] Starting Pandora FMS Recon Server.", 1); $self->setNumThreads ($pa_config->{'recon_threads'}); $self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem); @@ -87,29 +87,29 @@ sub run ($) { sub data_producer ($) { my $self = shift; my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); - + my @tasks; - + my $server_id = get_server_id ($dbh, $pa_config->{'servername'}, $self->getServerType ()); return @tasks unless defined ($server_id); - + # Manual tasks have interval_sweep = 0 # Manual tasks are "forced" like the other, setting the utimestamp to 1 # By default, after create a tasks it takes the utimestamp to 0 # 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); foreach my $row (@rows) { - + # Update task status update_recon_task ($dbh, $row->{'id_rt'}, 1); - + push (@tasks, $row->{'id_rt'}); } - + return @tasks; } @@ -155,7 +155,7 @@ sub data_consumer ($$) { # Update the recon task or break if it does not exist anymore last if (update_recon_task ($dbh, $task_id, ceil ($progress / ($total_up / 100))) eq '0E0'); - + # Does the host already exist? my $agent = get_agent_from_addr ($dbh, $addr); my $agent_id = defined ($agent) ? $agent->{'id_agente'} : 0; @@ -190,14 +190,14 @@ sub data_consumer ($$) { } next; } - + # Resolve hostnames my $host_name = undef; if ($task->{'resolve_names'} == 1){ $host_name = gethostbyaddr (inet_aton($addr), AF_INET); } $host_name = $addr unless defined ($host_name); - + # Add the new address if it does not exist my $addr_id = get_addr_id ($dbh, $addr); $addr_id = add_address ($dbh, $addr) unless ($addr_id > 0); @@ -205,14 +205,14 @@ sub data_consumer ($$) { logger($pa_config, "Could not add address '$addr' for host '".safe_output($host_name)."'.", 3); next; } - - # GIS Code ----------------------------- - + + # GIS Code ----------------------------- + # If GIS is activated try to geolocate the ip address of the agent - # and store also it's position. - + # and store also it's position. + if($pa_config->{'activate_gis'} == 1 && $pa_config->{'recon_reverse_geolocation_mode'} !~ m/^disabled$/i) { - + # Try to get aproximated positional information for the Agent. my $region_info = undef; if ($pa_config->{'recon_reverse_geolocation_mode'} =~ m/^sql$/i) { @@ -262,27 +262,27 @@ sub data_consumer ($$) { $host_name, $addr, $task->{'id_group'}, $parent_id, $id_os, '', 300, $dbh); } - + # Check agent creation if ($agent_id <= 0) { logger($pa_config, "Error creating agent '$host_name'.", 3); next; } - + # Assign the new address to the agent db_do ($dbh, 'INSERT INTO taddress_agent (`id_a`, `id_agent`) VALUES (?, ?)', $addr_id, $agent_id); - + # Create network profile modules for the agent create_network_profile_modules ($pa_config, $dbh, $agent_id, $task->{'id_network_profile'}, $addr, $task->{'snmp_community'}); - + # Generate an event pandora_event ($pa_config, "[RECON] New host [$host_name] detected on network [" . $task->{'subnet'} . ']', $task->{'id_group'}, $agent_id, 2, 0, 0, 'recon_host_detected', 0, $dbh); $added_hosts .= "$addr "; } - + # Create an incident with totals if ($added_hosts ne '' && $task->{'create_incident'} == 1) { my $text = "At " . strftime ("%Y-%m-%d %H:%M:%S", localtime()) . " ($added_hosts) new hosts were detected by Pandora FMS Recon Server running on [" . $pa_config->{'servername'} . "_Recon]. This incident has been automatically created following instructions for this recon task [" . $task->{'id_group'} . "].\n\n"; @@ -292,7 +292,7 @@ sub data_consumer ($$) { $text .= "\n\nThis is the list of IP addresses found: \n\n$added_hosts"; pandora_create_incident ($pa_config, $dbh, "[RECON] New hosts detected", $text, 0, 0, 'Pandora FMS Recon Server', $task->{'id_group'}); } - + # Mark recon task as done update_recon_task ($dbh, $task_id, -1); } @@ -303,7 +303,7 @@ sub data_consumer ($$) { ########################################################################## sub get_host_parent { my ($pa_config, $host, $dbh, $group, $max_depth, $resolve, $os_detect) = @_; - + # Call nmap my $np = new PandoraFMS::NmapParser; eval { @@ -312,7 +312,7 @@ sub get_host_parent { if ($@) { return 0; } - + # Get hops my ($h) = $np->all_hosts (); return 0 unless defined ($h); @@ -328,7 +328,7 @@ sub get_host_parent { last unless defined ($hop); push (@hops, $hop); } - + # Parse hops from first to last my $parent_id = 0; for (my $i = 0; $i < $max_depth; $i++) { @@ -337,7 +337,7 @@ sub get_host_parent { # Get host information my $host_addr = $hop->ipaddr (); - + # Check if the host exists my $agent_id = get_agent_from_addr ($dbh, $host_addr); if (defined ($agent_id)) { @@ -345,18 +345,18 @@ sub get_host_parent { $parent_id = $agent_id; next; } - - + + # Add the new address if it does not exist my $addr_id = get_addr_id ($dbh, $host_addr); $addr_id = add_address ($dbh, $host_addr) unless ($addr_id > 0); # Should not happen - if ($addr_id <= 0) { + if ($addr_id <= 0) { logger($pa_config, "Could not add address '$host_addr'", 1); return 0; } - + # Get the host's name my $host_name = undef; if ($resolve == 1){ @@ -402,14 +402,14 @@ sub guess_os { # Use xprobe2 if available my $xprobe = $pa_config->{'xprobe2'}; - if (-e $xprobe){ - my $output = `$xprobe $host 2> /dev/null | grep 'Running OS' | head -1`; - return 10 if ($? != 0); - return pandora_get_os ($output); - } - - # Use nmap by default - my $nmap = $pa_config->{'nmap'}; + if (-e $xprobe){ + my $output = `$xprobe $host 2> /dev/null | grep 'Running OS' | head -1`; + return 10 if ($? != 0); + return pandora_get_os ($output); + } + + # Use nmap by default + my $nmap = $pa_config->{'nmap'}; my $output = `$nmap -F -O $host 2> /dev/null | grep 'Aggressive OS guesses'`; return 10 if ($? != 0); return pandora_get_os ($output); @@ -420,7 +420,7 @@ sub guess_os { ########################################################################## sub update_recon_task ($$$) { my ($dbh, $id_task, $status) = @_; - + db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ?, status = ? WHERE id_rt = ?', time (), $status, $id_task); } @@ -431,33 +431,33 @@ sub create_network_profile_modules { my ($pa_config, $dbh, $agent_id, $np_id, $addr, $snmp_community) = @_; return unless ($np_id > 0); - + # Get network components associated to the network profile my @np_components = get_db_rows ($dbh, 'SELECT * FROM tnetwork_profile_component WHERE id_np = ?', $np_id); - + foreach my $np_component (@np_components) { - + # Get network component data my $component = get_db_single_row ($dbh, 'SELECT * FROM tnetwork_component wHERE id_nc = ?', $np_component->{'id_nc'}); if (! defined ($component)) { logger($pa_config, "Network component ID " . $np_component->{'id_nc'} . " for agent $addr not found.", 3); next; } - + logger($pa_config, "Processing network component '" . safe_output ($component->{'name'}) . "' for agent $addr.", 10); - - # Use snmp_community from network task instead the component snmp_community - $component->{'snmp_community'} = safe_output ($snmp_community); - + + # Use snmp_community from network task instead the component snmp_community + $component->{'snmp_community'} = safe_output ($snmp_community); + # Create the module my $module_id = db_insert ($dbh, 'id_agente_modulo', 'INSERT INTO tagente_modulo (id_agente, id_tipo_modulo, descripcion, nombre, max, min, module_interval, tcp_port, tcp_send, tcp_rcv, snmp_community, snmp_oid, ip_target, id_module_group, flag, disabled, plugin_user, plugin_pass, plugin_parameter, max_timeout, id_modulo, min_warning, max_warning, str_warning, min_critical, max_critical, str_critical, min_ff_event, id_plugin, post_process) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - $agent_id, $component->{'type'}, $component->{'description'}, safe_input($component->{'name'}), $component->{'max'}, $component->{'min'}, $component->{'module_interval'}, $component->{'tcp_port'}, $component->{'tcp_send'}, $component->{'tcp_rcv'}, $component->{'snmp_community'}, - $component->{'snmp_oid'}, $addr, $component->{'id_module_group'}, $component->{'plugin_user'}, $component->{'plugin_pass'}, $component->{'plugin_parameter'}, $component->{'max_timeout'}, $component->{'id_modulo'}, $component->{'min_warning'}, $component->{'max_warning'}, $component->{'str_warning'}, $component->{'min_critical'}, $component->{'max_critical'}, $component->{'str_critical'}, $component->{'min_ff_event'}, $component->{'id_plugin'}, $component->{'post_process'}); - + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + $agent_id, $component->{'type'}, $component->{'description'}, $component->{'name'}, $component->{'max'}, $component->{'min'}, $component->{'module_interval'}, $component->{'tcp_port'}, $component->{'tcp_send'}, $component->{'tcp_rcv'}, $component->{'snmp_community'}, + $component->{'snmp_oid'}, $addr, $component->{'id_module_group'}, $component->{'plugin_user'}, $component->{'plugin_pass'}, $component->{'plugin_parameter'}, $component->{'max_timeout'}, $component->{'id_modulo'}, $component->{'min_warning'}, $component->{'max_warning'}, $component->{'str_warning'}, $component->{'min_critical'}, $component->{'max_critical'}, $component->{'str_critical'}, $component->{'min_ff_event'}, $component->{'id_plugin'}, $component->{'post_process'}); + # An entry in tagente_estado is necessary for the module to work - db_do ($dbh, 'INSERT INTO tagente_estado (`id_agente_modulo`, `id_agente`, `last_try`, current_interval) VALUES (?, ?, \'1970-01-01 00:00:00\', ?)', $module_id, $agent_id, $component->{'module_interval'}); - + db_do ($dbh, 'INSERT INTO tagente_estado (`id_agente_modulo`, `id_agente`, `last_try`, current_interval) VALUES (?, ?, \'1970-01-01 00:00:00\', ?)', $module_id, $agent_id, $component->{'module_interval'}); + logger($pa_config, 'Creating module ' . safe_output ($component->{'name'}) . " for agent $addr from network component.", 10); } } @@ -471,20 +471,20 @@ sub exec_recon_script ($$$) { # Get recon plugin data my $script = get_db_single_row ($dbh, 'SELECT * FROM trecon_script WHERE id_recon_script = ?', $task->{'id_recon_script'}); return -1 unless defined ($script); - + logger($pa_config, 'Executing recon script ' . safe_output($script->{'name'}), 10); - + my $command = safe_output($script->{'script'}); my $field1 = safe_output($task->{'field1'}); my $field2 = safe_output($task->{'field2'}); my $field3 = safe_output($task->{'field3'}); my $field4 = safe_output($task->{'field4'}); - + `$command $task->{'id_rt'} $task->{'id_group'} $task->{'create_incident'} $field1 $field2 $field3 $field4`; - + # Notify this recon task is ended update_recon_task ($dbh, $task->{'id_rt'}, -1); - + return 0; }