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 "net.h"
28 #include "dns.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 static int SYSTEM_RUN_LOCAL(AGENT_REQUEST *request, AGENT_RESULT *result);
48
49 ZBX_METRIC parameters_common_local[] =
50 /* KEY FLAG FUNCTION TEST PARAMETERS */
51 {
52 {"system.run", CF_HAVEPARAMS, SYSTEM_RUN_LOCAL, "echo test"},
53 {NULL}
54 };
55
56 ZBX_METRIC parameters_common[] =
57 /* KEY FLAG FUNCTION TEST PARAMETERS */
58 {
59 {"system.localtime", CF_HAVEPARAMS, SYSTEM_LOCALTIME, "utc"},
60 {"system.run", CF_HAVEPARAMS, SYSTEM_RUN, "echo test"},
61
62 {"vfs.file.size", CF_HAVEPARAMS, VFS_FILE_SIZE, VFS_TEST_FILE},
63 {"vfs.file.time", CF_HAVEPARAMS, VFS_FILE_TIME, VFS_TEST_FILE ",modify"},
64 {"vfs.file.exists", CF_HAVEPARAMS, VFS_FILE_EXISTS, VFS_TEST_FILE},
65 {"vfs.file.contents", CF_HAVEPARAMS, VFS_FILE_CONTENTS, VFS_TEST_FILE},
66 {"vfs.file.regexp", CF_HAVEPARAMS, VFS_FILE_REGEXP, VFS_TEST_FILE "," VFS_TEST_REGEXP},
67 {"vfs.file.regmatch", CF_HAVEPARAMS, VFS_FILE_REGMATCH, VFS_TEST_FILE "," VFS_TEST_REGEXP},
68 {"vfs.file.md5sum", CF_HAVEPARAMS, VFS_FILE_MD5SUM, VFS_TEST_FILE},
69 {"vfs.file.cksum", CF_HAVEPARAMS, VFS_FILE_CKSUM, VFS_TEST_FILE},
70
71 {"vfs.dir.size", CF_HAVEPARAMS, VFS_DIR_SIZE, VFS_TEST_DIR},
72 {"vfs.dir.count", CF_HAVEPARAMS, VFS_DIR_COUNT, VFS_TEST_DIR},
73
74 {"net.dns", CF_HAVEPARAMS, NET_DNS, ",zabbix.com"},
75 {"net.dns.record", CF_HAVEPARAMS, NET_DNS_RECORD, ",zabbix.com"},
76 {"net.tcp.dns", CF_HAVEPARAMS, NET_DNS, ",zabbix.com"}, /* deprecated */
77 {"net.tcp.dns.query", CF_HAVEPARAMS, NET_DNS_RECORD, ",zabbix.com"}, /* deprecated */
78 {"net.tcp.port", CF_HAVEPARAMS, NET_TCP_PORT, ",80"},
79
80 {"system.users.num", 0, SYSTEM_USERS_NUM, NULL},
81
82 {"log", CF_HAVEPARAMS, ONLY_ACTIVE, "logfile"},
83 {"log.count", CF_HAVEPARAMS, ONLY_ACTIVE, "logfile"},
84 {"logrt", CF_HAVEPARAMS, ONLY_ACTIVE, "logfile"},
85 {"logrt.count", CF_HAVEPARAMS, ONLY_ACTIVE, "logfile"},
86 {"eventlog", CF_HAVEPARAMS, ONLY_ACTIVE, "system"},
87
88 {"zabbix.stats", CF_HAVEPARAMS, ZABBIX_STATS, "127.0.0.1,10051"},
89
90 {NULL}
91 };
92
93 static const char *user_parameter_dir = NULL;
94
set_user_parameter_dir(const char * path)95 void set_user_parameter_dir(const char *path)
96 {
97 user_parameter_dir = path;
98 }
99
ONLY_ACTIVE(AGENT_REQUEST * request,AGENT_RESULT * result)100 static int ONLY_ACTIVE(AGENT_REQUEST *request, AGENT_RESULT *result)
101 {
102 ZBX_UNUSED(request);
103
104 SET_MSG_RESULT(result, zbx_strdup(NULL, "Accessible only as active check."));
105
106 return SYSINFO_RET_FAIL;
107 }
108
execute_str(const char * command,AGENT_RESULT * result,const char * dir)109 static int execute_str(const char *command, AGENT_RESULT *result, const char* dir)
110 {
111 int ret = SYSINFO_RET_FAIL;
112 char *cmd_result = NULL, error[MAX_STRING_LEN];
113
114 if (SUCCEED != zbx_execute(command, &cmd_result, error, sizeof(error), CONFIG_TIMEOUT,
115 ZBX_EXIT_CODE_CHECKS_DISABLED, dir))
116 {
117 SET_MSG_RESULT(result, zbx_strdup(NULL, error));
118 goto out;
119 }
120
121 zbx_rtrim(cmd_result, ZBX_WHITESPACE);
122
123 zabbix_log(LOG_LEVEL_DEBUG, "%s() command:'%s' len:" ZBX_FS_SIZE_T " cmd_result:'%.20s'",
124 __func__, command, (zbx_fs_size_t)strlen(cmd_result), cmd_result);
125
126 SET_TEXT_RESULT(result, zbx_strdup(NULL, cmd_result));
127
128 ret = SYSINFO_RET_OK;
129 out:
130 zbx_free(cmd_result);
131
132 return ret;
133 }
134
EXECUTE_USER_PARAMETER(AGENT_REQUEST * request,AGENT_RESULT * result)135 int EXECUTE_USER_PARAMETER(AGENT_REQUEST *request, AGENT_RESULT *result)
136 {
137 if (1 != request->nparam)
138 {
139 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
140 return SYSINFO_RET_FAIL;
141 }
142
143 return execute_str(get_rparam(request, 0), result, user_parameter_dir);
144 }
145
EXECUTE_STR(const char * command,AGENT_RESULT * result)146 int EXECUTE_STR(const char *command, AGENT_RESULT *result)
147 {
148 return execute_str(command, result, NULL);
149 }
150
EXECUTE_DBL(const char * command,AGENT_RESULT * result)151 int EXECUTE_DBL(const char *command, AGENT_RESULT *result)
152 {
153 if (SYSINFO_RET_OK != EXECUTE_STR(command, result))
154 return SYSINFO_RET_FAIL;
155
156 if (NULL == GET_DBL_RESULT(result))
157 {
158 zabbix_log(LOG_LEVEL_WARNING, "Remote command [%s] result is not double", command);
159 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid result. Double is expected."));
160 return SYSINFO_RET_FAIL;
161 }
162
163 UNSET_RESULT_EXCLUDING(result, AR_DOUBLE);
164
165 return SYSINFO_RET_OK;
166 }
167
EXECUTE_INT(const char * command,AGENT_RESULT * result)168 int EXECUTE_INT(const char *command, AGENT_RESULT *result)
169 {
170 if (SYSINFO_RET_OK != EXECUTE_STR(command, result))
171 return SYSINFO_RET_FAIL;
172
173 if (NULL == GET_UI64_RESULT(result))
174 {
175 zabbix_log(LOG_LEVEL_WARNING, "Remote command [%s] result is not unsigned integer", command);
176 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid result. Unsigned integer is expected."));
177 return SYSINFO_RET_FAIL;
178 }
179
180 UNSET_RESULT_EXCLUDING(result, AR_UINT64);
181
182 return SYSINFO_RET_OK;
183 }
184
system_run(AGENT_REQUEST * request,AGENT_RESULT * result,int level)185 static int system_run(AGENT_REQUEST *request, AGENT_RESULT *result, int level)
186 {
187 char *command, *flag;
188
189 if (2 < request->nparam)
190 {
191 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
192 return SYSINFO_RET_FAIL;
193 }
194
195 command = get_rparam(request, 0);
196 flag = get_rparam(request, 1);
197
198 if (NULL == command || '\0' == *command)
199 {
200 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
201 return SYSINFO_RET_FAIL;
202 }
203
204 zabbix_log(level, "Executing command '%s'", command);
205
206 if (NULL == flag || '\0' == *flag || 0 == strcmp(flag, "wait")) /* default parameter */
207 {
208 return EXECUTE_STR(command, result);
209 }
210 else if (0 == strcmp(flag, "nowait"))
211 {
212 if (SUCCEED != zbx_execute_nowait(command))
213 {
214 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot execute command."));
215 return SYSINFO_RET_FAIL;
216 }
217 }
218 else
219 {
220 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
221 return SYSINFO_RET_FAIL;
222 }
223
224 SET_UI64_RESULT(result, 1);
225
226 return SYSINFO_RET_OK;
227 }
228
SYSTEM_RUN(AGENT_REQUEST * request,AGENT_RESULT * result)229 static int SYSTEM_RUN(AGENT_REQUEST *request, AGENT_RESULT *result)
230 {
231 int level;
232
233 level = LOG_LEVEL_DEBUG;
234
235 if (0 != CONFIG_LOG_REMOTE_COMMANDS)
236 level = LOG_LEVEL_WARNING;
237
238 return system_run(request, result, level);
239 }
240
SYSTEM_RUN_LOCAL(AGENT_REQUEST * request,AGENT_RESULT * result)241 static int SYSTEM_RUN_LOCAL(AGENT_REQUEST *request, AGENT_RESULT *result)
242 {
243 return system_run(request, result, LOG_LEVEL_DEBUG);
244 }
245
246