diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 886e1fadb1..84982a3c27 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,10 @@ +2012-04-12 Ramon Novoa + + * lib/PandoraFMS/DB.pm, + lib/PandoraFMS/Core.pm, + lib/PandoraFMS/ReconServer.pm: Improved Recon Server to detect + hostnames that resolve to multiple IP addresses. Fixes bug #3052350. + 2012-04-10 Ramon Novoa * lib/PandoraFMS/DataServer.pm: Check for single tag XMLs. Fixes bug #3514207. diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 5d9cea75e1..d5b60014fc 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -173,6 +173,7 @@ our @EXPORT = qw( pandora_self_monitoring pandora_process_policy_queue get_agent_from_addr + get_agent_from_name @ServerTypes ); @@ -194,7 +195,19 @@ sub get_agent_from_addr ($$) { WHERE tagente.id_agente = taddress_agent.id_agent AND taddress_agent.id_a = taddress.id_a AND ip = ?', $ip_address); - return $agent + return $agent; +} + +########################################################################## +# Return the agent given the agent name. +########################################################################## +sub get_agent_from_name ($$) { + my ($dbh, $name) = @_; + + return 0 if (! defined ($name) || $name eq ''); + + my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE tagente.nombre = ?', $name); + return $agent; } ########################################################################## diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index 25848fad2d..949d1b14a8 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -43,6 +43,7 @@ our @EXPORT = qw( db_update get_action_id get_addr_id + get_agent_addr_id get_agent_id get_agent_address get_agent_group @@ -578,6 +579,17 @@ sub get_addr_id ($$) { return (defined ($addr_id) ? $addr_id : -1); } +########################################################################## +# Return the agent address ID for the given agent ID and address ID, -1 if +# it does not exist. +########################################################################## +sub get_agent_addr_id ($$$) { + my ($dbh, $addr_id, $agent_id) = @_; + + my $agent_addr_id = get_db_value ($dbh, 'SELECT id_ag FROM taddress_agent WHERE id_a = ? AND id_agent = ?', $addr_id, $agent_id); + return (defined ($agent_addr_id) ? $agent_addr_id : -1); +} + ########################################################################## ## Generic SQL sentence. ########################################################################## diff --git a/pandora_server/lib/PandoraFMS/ReconServer.pm b/pandora_server/lib/PandoraFMS/ReconServer.pm index a01b567b23..91b7a0aaaa 100644 --- a/pandora_server/lib/PandoraFMS/ReconServer.pm +++ b/pandora_server/lib/PandoraFMS/ReconServer.pm @@ -152,19 +152,30 @@ sub data_consumer ($$) { # Get agent address my $addr = $host->addr(); next unless ($addr ne '0'); - + # 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'); - + + # 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); + # Does the host already exist? my $agent = get_agent_from_addr ($dbh, $addr); + if (! defined ($agent)) { + $agent = get_agent_from_name ($dbh, $host_name); + } + my $agent_id = defined ($agent) ? $agent->{'id_agente'} : 0; if ($agent_id > 0) { - # Skip if not in learning mode or parent detection is disabled - next if ($agent->{'modo'} != 1 || $task->{'parent_detection'} == 0); + # Skip if not in learning mode + next if ($agent->{'modo'} != 1); } - + # Filter by TCP port if ((defined ($task->{'recon_ports'})) && ($task->{'recon_ports'} ne "")) { next unless (tcp_scan ($pa_config, $addr, $task->{'recon_ports'}) > 0); @@ -182,21 +193,6 @@ sub data_consumer ($$) { if ($task->{'parent_detection'} == 1) { $parent_id = get_host_parent ($pa_config, $addr, $dbh, $task->{'id_group'}, $task->{'parent_recursion'}, $task->{'resolve_names'}, $task->{'os_detect'}); } - - # If the agent already exists update parent and continue - if ($agent_id > 0) { - if ($parent_id > 0) { - db_do ($dbh, 'UPDATE tagente SET id_parent = ? WHERE id_agente = ?', $parent_id, $agent_id ); - } - 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); @@ -206,6 +202,21 @@ sub data_consumer ($$) { next; } + # Assign the new address to the agent + my $agent_addr_id = get_agent_addr_id ($dbh, $addr_id, $agent_id); + if ($agent_addr_id <= 0) { + db_do ($dbh, 'INSERT INTO taddress_agent (`id_a`, `id_agent`) + VALUES (?, ?)', $addr_id, $agent_id); + } + + # If the agent already exists update parent and continue + if ($agent_id > 0) { + if ($parent_id > 0) { + db_do ($dbh, 'UPDATE tagente SET id_parent = ? WHERE id_agente = ?', $parent_id, $agent_id ); + } + next; + } + # GIS Code ----------------------------- # If GIS is activated try to geolocate the ip address of the agent @@ -269,10 +280,6 @@ sub data_consumer ($$) { 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'});