Пример #1
0
/******************************************************************************
 *                                                                            *
 * Function: register_host                                                    *
 *                                                                            *
 * Purpose: register host if one does not exist                               *
 *                                                                            *
 * Parameters: host ip address                                                *
 *                                                                            *
 * Return value: dhostid or 0 if we didn't add host                           *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void register_host(DB_DHOST *host,DB_DCHECK *check, zbx_uint64_t druleid, char *ip)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		hostname[MAX_STRING_LEN], hostname_esc[MAX_STRING_LEN];

	assert(host);
	assert(check);
	assert(ip);

	zabbix_log(LOG_LEVEL_DEBUG, "In register_host(ip:%s)",
		ip);

	host->dhostid=0;
	result = DBselect("select dhostid,druleid,ip,status,lastup,lastdown from dhosts where ip='%s'", ip);
	row=DBfetch(result);
	if(!row || DBis_null(row[0])==SUCCEED)
	{
		/* Add host only if service is up */
		if(check->status == DOBJECT_STATUS_UP)
		{
			alarm(CONFIG_TIMEOUT);
			zbx_gethost_by_ip(ip, hostname, sizeof(hostname));
			alarm(0);

			if (hostname[0] != '\0')
				DBescape_string(hostname, hostname_esc, sizeof(hostname_esc));
			else
				hostname_esc[0] = '\0';

			zabbix_log(LOG_LEVEL_DEBUG, "New host discovered at %s (%s)",
				ip, hostname);

			host->dhostid = DBget_maxid("dhosts","dhostid");
			DBexecute("insert into dhosts (dhostid, druleid, dns, ip) values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ", '%s','%s')",
				host->dhostid,
				druleid,
				hostname_esc,
				ip);
			host->druleid	= druleid;
			strscpy(host->ip,ip);
			host->status	= 0;
			host->lastup	= 0;
			host->lastdown  = 0;
		}
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "Host is already in database");
		ZBX_STR2UINT64(host->dhostid,row[0]);
		ZBX_STR2UINT64(host->druleid,row[1]);
		strscpy(host->ip,	row[2]);
		host->status		= atoi(row[3]);
		host->lastup		= atoi(row[4]);
		host->lastdown		= atoi(row[5]);
	}
	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End register_host()");
}
Пример #2
0
/******************************************************************************
 *                                                                            *
 * Function: add host if not added already                                    *
 *                                                                            *
 * Purpose: add discovered host                                               *
 *                                                                            *
 * Parameters: dhostid - discovered host id                                   *
 *                                                                            *
 * Return value: hostid - new/existing hostid                                 *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static zbx_uint64_t	add_discovered_host(DB_EVENT *event)
{
	const char	*__function_name = "add_discovered_host";
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW		row;
	DB_ROW		row2;
	zbx_uint64_t	hostid = 0, proxy_hostid, host_proxy_hostid;
	char		host[MAX_STRING_LEN], *host_esc, *ip_esc, *host_unique, *host_unique_esc;
	int		port;
	zbx_uint64_t	groupid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s(eventid:" ZBX_FS_UI64 ")",
			__function_name, event->eventid);

	result = DBselect(
			"select discovery_groupid"
			" from config"
			" where 1=1"
				DB_NODE,
			DBnode_local("configid"));

	if (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(groupid, row[0]);
	}
	else
	{
		zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined");
		return 0;
	}
	DBfree_result(result);

	switch (event->object)
	{
		case EVENT_OBJECT_DHOST:
			result = DBselect(
					"select dr.proxy_hostid,ds.ip"
					" from drules dr,dchecks dc,dservices ds"
					" where dc.druleid=dr.druleid"
						" and ds.dcheckid=dc.dcheckid"
						" and ds.dhostid=" ZBX_FS_UI64
					" order by ds.dserviceid",
					event->objectid);
			break;
		case EVENT_OBJECT_DSERVICE:
			result = DBselect(
					"select dr.proxy_hostid,ds.ip"
					" from drules dr,dchecks dc,dservices ds,dservices ds1"
					" where dc.druleid=dr.druleid"
						" and ds.dcheckid=dc.dcheckid"
						" and ds1.dhostid=ds.dhostid"
						" and ds1.dserviceid=" ZBX_FS_UI64
					" order by ds.dserviceid",
					event->objectid);
			break;
		case EVENT_OBJECT_ZABBIX_ACTIVE:
			result = DBselect("select proxy_hostid,host from autoreg_host"
					" where autoreg_hostid=" ZBX_FS_UI64,
					event->objectid);
			break;
		default:
			return 0;
	}

	if (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(proxy_hostid, row[0]);

		if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object)
		{
			char	sql[512];

			host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN);

			zbx_snprintf(sql, sizeof(sql),
					"select hostid,proxy_hostid"
					" from hosts"
					" where host='%s'"
						DB_NODE
					" order by hostid",
					host_esc,
					DBnode_local("hostid"));

			result2 = DBselectN(sql, 1);

			if (NULL == (row2 = DBfetch(result2)))
			{
				hostid = DBget_maxid("hosts");

				DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,dns)"
						" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',0,'%s')",
						hostid, proxy_hostid, host_esc, host_esc);
			}
			else
			{
				ZBX_STR2UINT64(hostid, row2[0]);
				ZBX_STR2UINT64(host_proxy_hostid, row2[1]);

				if (host_proxy_hostid != proxy_hostid)
				{
					DBexecute("update hosts"
							" set proxy_hostid=" ZBX_FS_UI64
							" where hostid=" ZBX_FS_UI64,
							proxy_hostid, hostid);
				}
			}
			DBfree_result(result2);

			zbx_free(host_esc);
		}
		else	/* EVENT_OBJECT_DHOST, EVENT_OBJECT_DSERVICE */
		{
			alarm(CONFIG_TIMEOUT);
			zbx_gethost_by_ip(row[1], host, sizeof(host));
			alarm(0);

			host_esc = DBdyn_escape_string_len(host, HOST_HOST_LEN);
			ip_esc = DBdyn_escape_string_len(row[1], HOST_IP_LEN);

			port = get_discovered_agent_port(event);

			result2 = DBselect(
					"select hostid,dns,port,proxy_hostid"
					" from hosts"
					" where ip='%s'"
						DB_NODE,
					ip_esc,
					DBnode_local("hostid"));

			if (NULL == (row2 = DBfetch(result2)))
			{
				hostid = DBget_maxid("hosts");

				/* for host uniqueness purposes */
				if ('\0' != *host)
				{
					/* by host name */
					make_hostname(host);	/* replace not-allowed characters */
					host_unique = DBget_unique_hostname_by_sample(host);
				}
				else
				{
					/* by ip */
					make_hostname(row[1]);	/* replace not-allowed characters */
					host_unique = DBget_unique_hostname_by_sample(row[1]);
				}

				host_unique_esc = DBdyn_escape_string(host_unique);

				DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,ip,dns,port)"
						" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',1,'%s','%s',%d)",
						hostid, proxy_hostid, host_unique_esc, ip_esc, host_esc, port);

				zbx_free(host_unique);
				zbx_free(host_unique_esc);
			}
			else
			{
				ZBX_STR2UINT64(hostid, row2[0]);
				ZBX_STR2UINT64(host_proxy_hostid, row2[3]);

				if (0 != strcmp(host, row2[1]) || host_proxy_hostid != proxy_hostid)
				{
					DBexecute("update hosts"
							" set dns='%s',proxy_hostid=" ZBX_FS_UI64
							" where hostid=" ZBX_FS_UI64,
							host_esc, proxy_hostid, hostid);
				}
			}
			DBfree_result(result2);

			zbx_free(host_esc);
			zbx_free(ip_esc);
		}
	}
	DBfree_result(result);

	if (0 != hostid)
		add_discovered_host_group(hostid, groupid);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return hostid;
}
Пример #3
0
/******************************************************************************
 *                                                                            *
 * Function: process_rule                                                     *
 *                                                                            *
 * Purpose: process single discovery rule                                     *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 ******************************************************************************/
static void	process_rule(DB_DRULE *drule)
{
	const char	*__function_name = "process_rule";

	DB_DHOST	dhost;
	int		host_status, now;
	unsigned short	j[9];
	unsigned int	i, first, last, ip_dig;
	char		ip[INTERFACE_IP_LEN_MAX], *start, *comma, *dash, *slash, dns[INTERFACE_DNS_LEN_MAX];
	int		invalid_range;
#ifdef HAVE_IPV6
	int		ipv6;
#endif

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() rule:'%s' range:'%s'", __function_name,
			drule->name, drule->iprange);

	for (start = drule->iprange; '\0' != *start;)
	{
		invalid_range = 0;

		if (NULL != (comma = strchr(start, ',')))
			*comma = '\0';

		zabbix_log(LOG_LEVEL_DEBUG, "%s() range:'%s'", __function_name, start);

		if (NULL != (dash = strchr(start, '-')))
			*dash = '\0';
		else if (NULL != (slash = strchr(start, '/')))
			*slash = '\0';

		if (SUCCEED == ip6_str2dig(start, j))
		{
#ifdef HAVE_IPV6
			ipv6 = 1;

			if (NULL != dash)
			{
				if (1 != sscanf(dash + 1, "%hx", &j[8]))
				{
					invalid_range = 1;
					goto next;
				}

				first = j[7];
				last = j[8];
			}
			else if (NULL != slash)
			{
				unsigned short	mask;

				if (1 != sscanf(slash + 1, "%hu", &j[8]) || 112 > j[8] || j[8] > 128)
				{
					invalid_range = 1;
					goto next;
				}

				mask = 0xffff << (128 - j[8]);
				first = j[7] & mask;
				last = 0xffff & (j[7] | ~mask);
			}
			else
			{
				first = j[7];
				last = j[7];
			}
#else
			invalid_range = 2;
			goto next;
#endif
		}
		else if (SUCCEED == ip4_str2dig(start, &ip_dig))
		{
#ifdef HAVE_IPV6
			ipv6 = 0;
#endif
			if (NULL != dash)
			{
				if (1 != sscanf(dash + 1, "%hu", &j[4]) || 255 < j[4])
				{
					invalid_range = 1;
					goto next;
				}

				first = ip_dig;
				last = (ip_dig & 0xffffff00) + j[4];
			}
			else if (NULL != slash)
			{
				unsigned int	mask;

				if (1 != sscanf(slash + 1, "%hu", &j[4]) || 16 > j[4] || j[4] > 30)
				{
					invalid_range = 1;
					goto next;
				}

				mask = 0xffffffff << (32 - j[4]);
				first = (ip_dig & mask) + 1;
				last = (ip_dig | ~mask) - 1;
			}
			else
			{
				first = ip_dig;
				last = ip_dig;
			}
		}
		else
		{
			invalid_range = 1;
			goto next;
		}

		if (first > last)
		{
			invalid_range = 1;
			goto next;
		}

		for (i = first; i <= last; i++)
		{
			memset(&dhost, 0, sizeof(dhost));
			host_status = -1;

			now = time(NULL);
#ifdef HAVE_IPV6
			switch (ipv6)
			{
				case 0:
#endif
					zbx_snprintf(ip, sizeof(ip), "%u.%u.%u.%u",
							(i & 0xff000000) >> 24, (i & 0x00ff0000) >> 16,
							(i & 0x0000ff00) >> 8, i & 0x000000ff);
#ifdef HAVE_IPV6
					break;
				case 1:
					j[7] = i;
					ip6_dig2str(j, ip, sizeof(ip));
					break;
			}
#endif
			zabbix_log(LOG_LEVEL_DEBUG, "%s() ip:'%s'", __function_name, ip);

			alarm(CONFIG_TIMEOUT);
			zbx_gethost_by_ip(ip, dns, sizeof(dns));
			alarm(0);

			if (drule->unique_dcheckid)
				process_checks(drule, &dhost, &host_status, ip, dns, 1);
			process_checks(drule, &dhost, &host_status, ip, dns, 0);

			DBbegin();

			if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
				discovery_update_host(&dhost, ip, host_status, now);
			else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY))
				proxy_update_host(drule, ip, dns, host_status, now);

			DBcommit();

		}
next:
		if (NULL != dash)
			*dash = '-';
		else if (NULL != slash)
			*slash = '/';

		switch (invalid_range)
		{
			case 1:
				zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": wrong format of IP range \"%s\"",
						drule->name, start);
				break;
			case 2:
				zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": encountered IP range \"%s\","
						" but IPv6 support not compiled in", drule->name, start);
				break;
		}

		if (NULL != comma)
		{
			*comma = ',';
			start = comma + 1;
		}
		else
			break;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Пример #4
0
/******************************************************************************
 *                                                                            *
 * Function: get_hostid_by_host                                               *
 *                                                                            *
 * Purpose: check for host name and return hostid                             *
 *                                                                            *
 * Parameters: host - [IN] require size 'HOST_HOST_LEN_MAX'                   *
 *                                                                            *
 * Return value:  SUCCEED - host is found                                     *
 *                FAIL - an error occurred or host not found                  *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	get_hostid_by_host(const char *host, const char *ip, unsigned short port, zbx_uint64_t *hostid, char *error)
{
	const char	*__function_name = "get_hostid_by_host";

	char		*host_esc, dns[INTERFACE_DNS_LEN_MAX];
	DB_RESULT	result;
	DB_ROW		row;
	int		res = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s'", __function_name, host);

	if (FAIL == zbx_check_hostname(host))
	{
		zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]", host);
		goto out;
	}

	host_esc = DBdyn_escape_string(host);

	result = DBselect(
			"select hostid,status"
			" from hosts"
			" where host='%s'"
				" and status in (%d,%d)"
		       		" and proxy_hostid is null"
				DB_NODE,
			host_esc,
			HOST_STATUS_MONITORED,
			HOST_STATUS_NOT_MONITORED,
			DBnode_local("hostid"));

	if (NULL != (row = DBfetch(result)))
	{
		if (HOST_STATUS_MONITORED == atoi(row[1]))
		{
			ZBX_STR2UINT64(*hostid, row[0]);
			res = SUCCEED;
		}
		else
			zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host);
	}
	else
	{
		zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host);

		/* remove ::ffff: prefix from IPv4-mapped IPv6 addresses */
		if (0 == strncmp("::ffff:", ip, 7) && SUCCEED == is_ip4(ip + 7))
			ip += 7;

		alarm(CONFIG_TIMEOUT);
		zbx_gethost_by_ip(ip, dns, sizeof(dns));
		alarm(0);

		DBbegin();

		if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
		{
			DBregister_host(0, host, ip, dns, port, (int)time(NULL));
		}
		else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY))
		{
			DBproxy_register_host(host, ip, dns, port);
		}

		DBcommit();
	}

	DBfree_result(result);

	zbx_free(host_esc);
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res));

	return res;
}
Пример #5
0
/******************************************************************************
 *                                                                            *
 * Function: get_hostid_by_host                                               *
 *                                                                            *
 * Purpose: check for host name and return hostid                             *
 *                                                                            *
 * Parameters: host - [IN] require size 'HOST_HOST_LEN_MAX'                   *
 *                                                                            *
 * Return value:  SUCCEED - host is found                                     *
 *                FAIL - an error occurred or host not found                  *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments: NB! adds host to the database if it does not exist               *
 *                                                                            *
 ******************************************************************************/
static int	get_hostid_by_host(const zbx_socket_t *sock, const char *host, const char *ip, unsigned short port,
		const char *host_metadata, zbx_uint64_t *hostid, char *error)
{
	const char	*__function_name = "get_hostid_by_host";

	char		*host_esc, dns[INTERFACE_DNS_LEN_MAX], *ch_error;
	DB_RESULT	result;
	DB_ROW		row;
	int		ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s'", __function_name, host);

	if (FAIL == zbx_check_hostname(host, &ch_error))
	{
		zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]: %s", host, ch_error);
		zbx_free(ch_error);
		goto out;
	}

	host_esc = DBdyn_escape_string(host);

	result =
#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
		DBselect(
			"select hostid,status,tls_accept,tls_issuer,tls_subject,tls_psk_identity"
			" from hosts"
			" where host='%s'"
				" and status in (%d,%d)"
				" and flags<>%d"
				" and proxy_hostid is null",
			host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE);
#else
		DBselect(
			"select hostid,status,tls_accept"
			" from hosts"
			" where host='%s'"
				" and status in (%d,%d)"
				" and flags<>%d"
				" and proxy_hostid is null",
			host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE);
#endif
	if (NULL != (row = DBfetch(result)))
	{
		if (HOST_STATUS_MONITORED == atoi(row[1]))
		{
			unsigned int	tls_accept;

			tls_accept = (unsigned int)atoi(row[2]);

			if (0 == (tls_accept & sock->connection_type))
			{
				zbx_snprintf(error, MAX_STRING_LEN, "connection of type \"%s\" is not allowed for host"
						" \"%s\"", zbx_tls_connection_type_name(sock->connection_type), host);
				goto done;
			}

#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
			if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type)
			{
				zbx_tls_conn_attr_t	attr;

				if (SUCCEED != zbx_tls_get_attr_cert(sock, &attr))
				{
					THIS_SHOULD_NEVER_HAPPEN;

					zbx_snprintf(error, MAX_STRING_LEN, "cannot get connection attributes for host"
							" \"%s\"", host);
					goto done;
				}

				/* simplified match, not compliant with RFC 4517, 4518 */
				if ('\0' != *row[3] && 0 != strcmp(row[3], attr.issuer))
				{
					zbx_snprintf(error, MAX_STRING_LEN, "certificate issuer does not match for"
							" host \"%s\"", host);
					goto done;
				}

				/* simplified match, not compliant with RFC 4517, 4518 */
				if ('\0' != *row[4] && 0 != strcmp(row[4], attr.subject))
				{
					zbx_snprintf(error, MAX_STRING_LEN, "certificate subject does not match for"
							" host \"%s\"", host);
					goto done;
				}
			}
			else if (ZBX_TCP_SEC_TLS_PSK == sock->connection_type)
			{
				zbx_tls_conn_attr_t	attr;

				if (SUCCEED != zbx_tls_get_attr_psk(sock, &attr))
				{
					THIS_SHOULD_NEVER_HAPPEN;

					zbx_snprintf(error, MAX_STRING_LEN, "cannot get connection attributes for host"
							" \"%s\"", host);
					goto done;
				}

				if (strlen(row[5]) != attr.psk_identity_len ||
						0 != memcmp(row[5], attr.psk_identity, attr.psk_identity_len))
				{
					zbx_snprintf(error, MAX_STRING_LEN, "false PSK identity for host \"%s\"", host);
					goto done;
				}
			}
#endif
			ZBX_STR2UINT64(*hostid, row[0]);

			ret = SUCCEED;
		}
		else
			zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host);
	}
	else
	{
		zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host);

		/* remove ::ffff: prefix from IPv4-mapped IPv6 addresses */
		if (0 == strncmp("::ffff:", ip, 7) && SUCCEED == is_ip4(ip + 7))
			ip += 7;

		zbx_alarm_on(CONFIG_TIMEOUT);
		zbx_gethost_by_ip(ip, dns, sizeof(dns));
		zbx_alarm_off();

		DBbegin();

		if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
			DBregister_host(0, host, ip, dns, port, host_metadata, (int)time(NULL));
		else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY))
			DBproxy_register_host(host, ip, dns, port, host_metadata);

		DBcommit();
	}
done:
	DBfree_result(result);

	zbx_free(host_esc);
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}