1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "db.h"
21 #include "dbcache.h"
22 #include "get_host_from_event.h"
23 #include "log.h"
24 
25 #ifdef HAVE_OPENIPMI
26 #	define ZBX_IPMI_FIELDS_NUM	4	/* number of selected IPMI-related fields in function */
27 						/* get_host_from_event() */
28 #else
29 #	define ZBX_IPMI_FIELDS_NUM	0
30 #endif
31 
get_host_from_event(const DB_EVENT * event,DC_HOST * host,char * error,size_t max_error_len)32 int	get_host_from_event(const DB_EVENT *event, DC_HOST *host, char *error, size_t max_error_len)
33 {
34 	DB_RESULT	result;
35 	DB_ROW		row;
36 	char		sql[512];	/* do not forget to adjust size if SQLs change */
37 	size_t		offset;
38 	int		ret = SUCCEED;
39 
40 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
41 
42 	offset = zbx_snprintf(sql, sizeof(sql), "select distinct h.hostid,h.proxy_hostid,h.host,h.tls_connect");
43 #ifdef HAVE_OPENIPMI
44 	offset += zbx_snprintf(sql + offset, sizeof(sql) - offset,
45 			/* do not forget to update ZBX_IPMI_FIELDS_NUM if number of selected IPMI fields changes */
46 			",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password");
47 #endif
48 #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
49 	offset += zbx_snprintf(sql + offset, sizeof(sql) - offset,
50 			",h.tls_issuer,h.tls_subject,h.tls_psk_identity,h.tls_psk");
51 #endif
52 	switch (event->source)
53 	{
54 		case EVENT_SOURCE_TRIGGERS:
55 			zbx_snprintf(sql + offset, sizeof(sql) - offset,
56 					" from functions f,items i,hosts h"
57 					" where f.itemid=i.itemid"
58 						" and i.hostid=h.hostid"
59 						" and h.status=%d"
60 						" and f.triggerid=" ZBX_FS_UI64,
61 					HOST_STATUS_MONITORED, event->objectid);
62 
63 			break;
64 		case EVENT_SOURCE_DISCOVERY:
65 			offset += zbx_snprintf(sql + offset, sizeof(sql) - offset,
66 					" from hosts h,interface i,dservices ds"
67 					" where h.hostid=i.hostid"
68 						" and i.ip=ds.ip"
69 						" and i.useip=1"
70 						" and h.status=%d",
71 						HOST_STATUS_MONITORED);
72 
73 			switch (event->object)
74 			{
75 				case EVENT_OBJECT_DHOST:
76 					zbx_snprintf(sql + offset, sizeof(sql) - offset,
77 							" and ds.dhostid=" ZBX_FS_UI64, event->objectid);
78 					break;
79 				case EVENT_OBJECT_DSERVICE:
80 					zbx_snprintf(sql + offset, sizeof(sql) - offset,
81 							" and ds.dserviceid=" ZBX_FS_UI64, event->objectid);
82 					break;
83 			}
84 			break;
85 		case EVENT_SOURCE_AUTOREGISTRATION:
86 			zbx_snprintf(sql + offset, sizeof(sql) - offset,
87 					" from autoreg_host a,hosts h"
88 					" where " ZBX_SQL_NULLCMP("a.proxy_hostid", "h.proxy_hostid")
89 						" and a.host=h.host"
90 						" and h.status=%d"
91 						" and h.flags<>%d"
92 						" and a.autoreg_hostid=" ZBX_FS_UI64,
93 					HOST_STATUS_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE, event->objectid);
94 			break;
95 		default:
96 			zbx_snprintf(error, max_error_len, "Unsupported event source [%d]", event->source);
97 			return FAIL;
98 	}
99 
100 	host->hostid = 0;
101 
102 	result = DBselect("%s", sql);
103 
104 	while (NULL != (row = DBfetch(result)))
105 	{
106 		if (0 != host->hostid)
107 		{
108 			switch (event->source)
109 			{
110 				case EVENT_SOURCE_TRIGGERS:
111 					zbx_strlcpy(error, "Too many hosts in a trigger expression", max_error_len);
112 					break;
113 				case EVENT_SOURCE_DISCOVERY:
114 					zbx_strlcpy(error, "Too many hosts with same IP addresses", max_error_len);
115 					break;
116 			}
117 			ret = FAIL;
118 			break;
119 		}
120 
121 		ZBX_STR2UINT64(host->hostid, row[0]);
122 		ZBX_DBROW2UINT64(host->proxy_hostid, row[1]);
123 		strscpy(host->host, row[2]);
124 		ZBX_STR2UCHAR(host->tls_connect, row[3]);
125 
126 #ifdef HAVE_OPENIPMI
127 		host->ipmi_authtype = (signed char)atoi(row[4]);
128 		host->ipmi_privilege = (unsigned char)atoi(row[5]);
129 		strscpy(host->ipmi_username, row[6]);
130 		strscpy(host->ipmi_password, row[7]);
131 #endif
132 #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
133 		strscpy(host->tls_issuer, row[4 + ZBX_IPMI_FIELDS_NUM]);
134 		strscpy(host->tls_subject, row[5 + ZBX_IPMI_FIELDS_NUM]);
135 		strscpy(host->tls_psk_identity, row[6 + ZBX_IPMI_FIELDS_NUM]);
136 		strscpy(host->tls_psk, row[7 + ZBX_IPMI_FIELDS_NUM]);
137 #endif
138 	}
139 	DBfree_result(result);
140 
141 	if (FAIL == ret)
142 	{
143 		host->hostid = 0;
144 		*host->host = '\0';
145 	}
146 	else if (0 == host->hostid)
147 	{
148 		*host->host = '\0';
149 
150 		zbx_strlcpy(error, "Cannot find a corresponding host", max_error_len);
151 		ret = FAIL;
152 	}
153 
154 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
155 
156 	return ret;
157 }
158 #undef ZBX_IPMI_FIELDS_NUM
159