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
ONLY_ACTIVE(AGENT_REQUEST * request,AGENT_RESULT * result)93 static int ONLY_ACTIVE(AGENT_REQUEST *request, AGENT_RESULT *result)
94 {
95 ZBX_UNUSED(request);
96
97 SET_MSG_RESULT(result, zbx_strdup(NULL, "Accessible only as active check."));
98
99 return SYSINFO_RET_FAIL;
100 }
101
EXECUTE_USER_PARAMETER(AGENT_REQUEST * request,AGENT_RESULT * result)102 int EXECUTE_USER_PARAMETER(AGENT_REQUEST *request, AGENT_RESULT *result)
103 {
104 char *command;
105
106 if (1 != request->nparam)
107 {
108 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
109 return SYSINFO_RET_FAIL;
110 }
111
112 command = get_rparam(request, 0);
113
114 return EXECUTE_STR(command, result);
115 }
116
EXECUTE_STR(const char * command,AGENT_RESULT * result)117 int EXECUTE_STR(const char *command, AGENT_RESULT *result)
118 {
119 int ret = SYSINFO_RET_FAIL;
120 char *cmd_result = NULL, error[MAX_STRING_LEN];
121
122 if (SUCCEED != zbx_execute(command, &cmd_result, error, sizeof(error), CONFIG_TIMEOUT,
123 ZBX_EXIT_CODE_CHECKS_DISABLED))
124 {
125 SET_MSG_RESULT(result, zbx_strdup(NULL, error));
126 goto out;
127 }
128
129 zbx_rtrim(cmd_result, ZBX_WHITESPACE);
130
131 zabbix_log(LOG_LEVEL_DEBUG, "%s() command:'%s' len:" ZBX_FS_SIZE_T " cmd_result:'%.20s'",
132 __func__, command, (zbx_fs_size_t)strlen(cmd_result), cmd_result);
133
134 SET_TEXT_RESULT(result, zbx_strdup(NULL, cmd_result));
135
136 ret = SYSINFO_RET_OK;
137 out:
138 zbx_free(cmd_result);
139
140 return ret;
141 }
142
EXECUTE_DBL(const char * command,AGENT_RESULT * result)143 int EXECUTE_DBL(const char *command, AGENT_RESULT *result)
144 {
145 if (SYSINFO_RET_OK != EXECUTE_STR(command, result))
146 return SYSINFO_RET_FAIL;
147
148 if (NULL == GET_DBL_RESULT(result))
149 {
150 zabbix_log(LOG_LEVEL_WARNING, "Remote command [%s] result is not double", command);
151 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid result. Double is expected."));
152 return SYSINFO_RET_FAIL;
153 }
154
155 UNSET_RESULT_EXCLUDING(result, AR_DOUBLE);
156
157 return SYSINFO_RET_OK;
158 }
159
EXECUTE_INT(const char * command,AGENT_RESULT * result)160 int EXECUTE_INT(const char *command, AGENT_RESULT *result)
161 {
162 if (SYSINFO_RET_OK != EXECUTE_STR(command, result))
163 return SYSINFO_RET_FAIL;
164
165 if (NULL == GET_UI64_RESULT(result))
166 {
167 zabbix_log(LOG_LEVEL_WARNING, "Remote command [%s] result is not unsigned integer", command);
168 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid result. Unsigned integer is expected."));
169 return SYSINFO_RET_FAIL;
170 }
171
172 UNSET_RESULT_EXCLUDING(result, AR_UINT64);
173
174 return SYSINFO_RET_OK;
175 }
176
system_run(AGENT_REQUEST * request,AGENT_RESULT * result,int level)177 static int system_run(AGENT_REQUEST *request, AGENT_RESULT *result, int level)
178 {
179 char *command, *flag;
180
181 if (2 < request->nparam)
182 {
183 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
184 return SYSINFO_RET_FAIL;
185 }
186
187 command = get_rparam(request, 0);
188 flag = get_rparam(request, 1);
189
190 if (NULL == command || '\0' == *command)
191 {
192 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
193 return SYSINFO_RET_FAIL;
194 }
195
196 zabbix_log(level, "Executing command '%s'", command);
197
198 if (NULL == flag || '\0' == *flag || 0 == strcmp(flag, "wait")) /* default parameter */
199 {
200 return EXECUTE_STR(command, result);
201 }
202 else if (0 == strcmp(flag, "nowait"))
203 {
204 if (SUCCEED != zbx_execute_nowait(command))
205 {
206 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot execute command."));
207 return SYSINFO_RET_FAIL;
208 }
209 }
210 else
211 {
212 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
213 return SYSINFO_RET_FAIL;
214 }
215
216 SET_UI64_RESULT(result, 1);
217
218 return SYSINFO_RET_OK;
219 }
220
SYSTEM_RUN(AGENT_REQUEST * request,AGENT_RESULT * result)221 static int SYSTEM_RUN(AGENT_REQUEST *request, AGENT_RESULT *result)
222 {
223 int level;
224
225 level = LOG_LEVEL_DEBUG;
226
227 if (0 != CONFIG_LOG_REMOTE_COMMANDS)
228 level = LOG_LEVEL_WARNING;
229
230 return system_run(request, result, level);
231 }
232
SYSTEM_RUN_LOCAL(AGENT_REQUEST * request,AGENT_RESULT * result)233 static int SYSTEM_RUN_LOCAL(AGENT_REQUEST *request, AGENT_RESULT *result)
234 {
235 return system_run(request, result, LOG_LEVEL_DEBUG);
236 }
237
238