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 "common.h"
21 #include "sysinfo.h"
22 
23 #include "log.h"
24 
25 #include "file.h"
26 #include "dir.h"
27 #include "http.h"
28 #include "net.h"
29 #include "system.h"
30 #include "zabbix_stats.h"
31 #include "zbxexec.h"
32 
33 #if !defined(_WINDOWS)
34 #	define VFS_TEST_FILE "/etc/passwd"
35 #	define VFS_TEST_REGEXP "root"
36 #	define VFS_TEST_DIR  "/var/log"
37 #else
38 #	define VFS_TEST_FILE "c:\\windows\\win.ini"
39 #	define VFS_TEST_REGEXP "fonts"
40 #	define VFS_TEST_DIR  "c:\\windows"
41 #endif
42 
43 extern int	CONFIG_TIMEOUT;
44 
45 static int	ONLY_ACTIVE(AGENT_REQUEST *request, AGENT_RESULT *result);
46 static int	SYSTEM_RUN(AGENT_REQUEST *request, AGENT_RESULT *result);
47 
48 ZBX_METRIC	parameters_common[] =
49 /*      KEY                     FLAG		FUNCTION        	TEST PARAMETERS */
50 {
51 	{"system.localtime",	CF_HAVEPARAMS,	SYSTEM_LOCALTIME,	"utc"},
52 	{"system.run",		CF_HAVEPARAMS,	SYSTEM_RUN,	 	"echo test"},
53 
54 	{"web.page.get",	CF_HAVEPARAMS,	WEB_PAGE_GET,	 	"localhost,,80"},
55 	{"web.page.perf",	CF_HAVEPARAMS,	WEB_PAGE_PERF,	 	"localhost,,80"},
56 	{"web.page.regexp",	CF_HAVEPARAMS,	WEB_PAGE_REGEXP,	"localhost,,80,OK"},
57 
58 	{"vfs.file.size",	CF_HAVEPARAMS,	VFS_FILE_SIZE, 		VFS_TEST_FILE},
59 	{"vfs.file.time",	CF_HAVEPARAMS,	VFS_FILE_TIME,		VFS_TEST_FILE ",modify"},
60 	{"vfs.file.exists",	CF_HAVEPARAMS,	VFS_FILE_EXISTS,	VFS_TEST_FILE},
61 	{"vfs.file.contents",	CF_HAVEPARAMS,	VFS_FILE_CONTENTS,	VFS_TEST_FILE},
62 	{"vfs.file.regexp",	CF_HAVEPARAMS,	VFS_FILE_REGEXP,	VFS_TEST_FILE "," VFS_TEST_REGEXP},
63 	{"vfs.file.regmatch",	CF_HAVEPARAMS,	VFS_FILE_REGMATCH, 	VFS_TEST_FILE "," VFS_TEST_REGEXP},
64 	{"vfs.file.md5sum",	CF_HAVEPARAMS,	VFS_FILE_MD5SUM,	VFS_TEST_FILE},
65 	{"vfs.file.cksum",	CF_HAVEPARAMS,	VFS_FILE_CKSUM,		VFS_TEST_FILE},
66 
67 	{"vfs.dir.size",	CF_HAVEPARAMS,	VFS_DIR_SIZE,		VFS_TEST_DIR},
68 	{"vfs.dir.count",	CF_HAVEPARAMS,	VFS_DIR_COUNT,		VFS_TEST_DIR},
69 
70 	{"net.dns",		CF_HAVEPARAMS,	NET_DNS,		",zabbix.com"},
71 	{"net.dns.record",	CF_HAVEPARAMS,	NET_DNS_RECORD,		",zabbix.com"},
72 	{"net.tcp.dns",		CF_HAVEPARAMS,	NET_DNS,		",zabbix.com"}, /* deprecated */
73 	{"net.tcp.dns.query",	CF_HAVEPARAMS,	NET_DNS_RECORD,		",zabbix.com"}, /* deprecated */
74 	{"net.tcp.port",	CF_HAVEPARAMS,	NET_TCP_PORT,		",80"},
75 
76 	{"system.users.num",	0,		SYSTEM_USERS_NUM,	NULL},
77 
78 	{"log",			CF_HAVEPARAMS,	ONLY_ACTIVE, 		"logfile"},
79 	{"log.count",		CF_HAVEPARAMS,	ONLY_ACTIVE, 		"logfile"},
80 	{"logrt",		CF_HAVEPARAMS,	ONLY_ACTIVE,		"logfile"},
81 	{"logrt.count",		CF_HAVEPARAMS,	ONLY_ACTIVE,		"logfile"},
82 	{"eventlog",		CF_HAVEPARAMS,	ONLY_ACTIVE, 		"system"},
83 
84 	{"zabbix.stats",	CF_HAVEPARAMS,	ZABBIX_STATS,		"127.0.0.1,10051"},
85 
86 	{NULL}
87 };
88 
ONLY_ACTIVE(AGENT_REQUEST * request,AGENT_RESULT * result)89 static int	ONLY_ACTIVE(AGENT_REQUEST *request, AGENT_RESULT *result)
90 {
91 	ZBX_UNUSED(request);
92 
93 	SET_MSG_RESULT(result, zbx_strdup(NULL, "Accessible only as active check."));
94 
95 	return SYSINFO_RET_FAIL;
96 }
97 
EXECUTE_USER_PARAMETER(AGENT_REQUEST * request,AGENT_RESULT * result)98 int	EXECUTE_USER_PARAMETER(AGENT_REQUEST *request, AGENT_RESULT *result)
99 {
100 	char	*command;
101 
102 	if (1 != request->nparam)
103 	{
104 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
105 		return SYSINFO_RET_FAIL;
106 	}
107 
108 	command = get_rparam(request, 0);
109 
110 	return EXECUTE_STR(command, result);
111 }
112 
EXECUTE_STR(const char * command,AGENT_RESULT * result)113 int	EXECUTE_STR(const char *command, AGENT_RESULT *result)
114 {
115 	const char	*__function_name = "EXECUTE_STR";
116 
117 	int		ret = SYSINFO_RET_FAIL;
118 	char		*cmd_result = NULL, error[MAX_STRING_LEN];
119 
120 	if (SUCCEED != zbx_execute(command, &cmd_result, error, sizeof(error), CONFIG_TIMEOUT,
121 			ZBX_EXIT_CODE_CHECKS_DISABLED))
122 	{
123 		SET_MSG_RESULT(result, zbx_strdup(NULL, error));
124 		goto out;
125 	}
126 
127 	zbx_rtrim(cmd_result, ZBX_WHITESPACE);
128 
129 	zabbix_log(LOG_LEVEL_DEBUG, "%s() command:'%s' len:" ZBX_FS_SIZE_T " cmd_result:'%.20s'",
130 			__function_name, command, (zbx_fs_size_t)strlen(cmd_result), cmd_result);
131 
132 	SET_TEXT_RESULT(result, zbx_strdup(NULL, cmd_result));
133 
134 	ret = SYSINFO_RET_OK;
135 out:
136 	zbx_free(cmd_result);
137 
138 	return ret;
139 }
140 
EXECUTE_DBL(const char * command,AGENT_RESULT * result)141 int	EXECUTE_DBL(const char *command, AGENT_RESULT *result)
142 {
143 	if (SYSINFO_RET_OK != EXECUTE_STR(command, result))
144 		return SYSINFO_RET_FAIL;
145 
146 	if (NULL == GET_DBL_RESULT(result))
147 	{
148 		zabbix_log(LOG_LEVEL_WARNING, "Remote command [%s] result is not double", command);
149 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid result. Double is expected."));
150 		return SYSINFO_RET_FAIL;
151 	}
152 
153 	UNSET_RESULT_EXCLUDING(result, AR_DOUBLE);
154 
155 	return SYSINFO_RET_OK;
156 }
157 
EXECUTE_INT(const char * command,AGENT_RESULT * result)158 int	EXECUTE_INT(const char *command, AGENT_RESULT *result)
159 {
160 	if (SYSINFO_RET_OK != EXECUTE_STR(command, result))
161 		return SYSINFO_RET_FAIL;
162 
163 	if (NULL == GET_UI64_RESULT(result))
164 	{
165 		zabbix_log(LOG_LEVEL_WARNING, "Remote command [%s] result is not unsigned integer", command);
166 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid result. Unsigned integer is expected."));
167 		return SYSINFO_RET_FAIL;
168 	}
169 
170 	UNSET_RESULT_EXCLUDING(result, AR_UINT64);
171 
172 	return SYSINFO_RET_OK;
173 }
174 
SYSTEM_RUN(AGENT_REQUEST * request,AGENT_RESULT * result)175 static int	SYSTEM_RUN(AGENT_REQUEST *request, AGENT_RESULT *result)
176 {
177 	char	*command, *flag;
178 
179 	if (2 < request->nparam)
180 	{
181 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
182 		return SYSINFO_RET_FAIL;
183 	}
184 
185 	command = get_rparam(request, 0);
186 	flag = get_rparam(request, 1);
187 
188 	if (NULL == command || '\0' == *command)
189 	{
190 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
191 		return SYSINFO_RET_FAIL;
192 	}
193 
194 	if (1 == CONFIG_LOG_REMOTE_COMMANDS)
195 		zabbix_log(LOG_LEVEL_WARNING, "Executing command '%s'", command);
196 	else
197 		zabbix_log(LOG_LEVEL_DEBUG, "Executing command '%s'", command);
198 
199 	if (NULL == flag || '\0' == *flag || 0 == strcmp(flag, "wait"))	/* default parameter */
200 	{
201 		return EXECUTE_STR(command, result);
202 	}
203 	else if (0 == strcmp(flag, "nowait"))
204 	{
205 		if (SUCCEED != zbx_execute_nowait(command))
206 		{
207 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot execute command."));
208 			return SYSINFO_RET_FAIL;
209 		}
210 	}
211 	else
212 	{
213 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
214 		return SYSINFO_RET_FAIL;
215 	}
216 
217 	SET_UI64_RESULT(result, 1);
218 
219 	return SYSINFO_RET_OK;
220 }
221