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 "daemon.h"
22
23 #include "pid.h"
24 #include "cfg.h"
25 #include "log.h"
26 #include "control.h"
27
28 #include "fatal.h"
29 #include "sighandler.h"
30 #include "sigcommon.h"
31
32 char *CONFIG_PID_FILE = NULL;
33 static int parent_pid = -1;
34
35 extern pid_t *threads;
36 extern int threads_num;
37
38 #ifdef HAVE_SIGQUEUE
39 extern unsigned char program_type;
40 #endif
41
42 extern int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type,
43 int *local_process_num);
44
45 static void (*zbx_sigusr_handler)(int flags);
46
47 #ifdef HAVE_SIGQUEUE
48 /******************************************************************************
49 * *
50 * Function: common_sigusr_handler *
51 * *
52 * Purpose: common SIGUSR1 handler for Zabbix processes *
53 * *
54 ******************************************************************************/
common_sigusr_handler(int flags)55 static void common_sigusr_handler(int flags)
56 {
57 switch (ZBX_RTC_GET_MSG(flags))
58 {
59 case ZBX_RTC_LOG_LEVEL_INCREASE:
60 if (SUCCEED != zabbix_increase_log_level())
61 {
62 zabbix_log(LOG_LEVEL_INFORMATION, "cannot increase log level:"
63 " maximum level has been already set");
64 }
65 else
66 {
67 zabbix_log(LOG_LEVEL_INFORMATION, "log level has been increased to %s",
68 zabbix_get_log_level_string());
69 }
70 break;
71 case ZBX_RTC_LOG_LEVEL_DECREASE:
72 if (SUCCEED != zabbix_decrease_log_level())
73 {
74 zabbix_log(LOG_LEVEL_INFORMATION, "cannot decrease log level:"
75 " minimum level has been already set");
76 }
77 else
78 {
79 zabbix_log(LOG_LEVEL_INFORMATION, "log level has been decreased to %s",
80 zabbix_get_log_level_string());
81 }
82 break;
83 default:
84 if (NULL != zbx_sigusr_handler)
85 zbx_sigusr_handler(flags);
86 break;
87 }
88 }
89
zbx_signal_process_by_type(int proc_type,int proc_num,int flags)90 static void zbx_signal_process_by_type(int proc_type, int proc_num, int flags)
91 {
92 int process_num, found = 0, i;
93 union sigval s;
94 unsigned char process_type;
95
96 s.ZBX_SIVAL_INT = flags;
97
98 for (i = 0; i < threads_num; i++)
99 {
100 if (FAIL == get_process_info_by_thread(i + 1, &process_type, &process_num))
101 break;
102
103 if (proc_type != process_type)
104 {
105 /* check if we have already checked processes of target type */
106 if (1 == found)
107 break;
108
109 continue;
110 }
111
112 if (0 != proc_num && proc_num != process_num)
113 continue;
114
115 found = 1;
116
117 if (-1 != sigqueue(threads[i], SIGUSR1, s))
118 {
119 zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to \"%s\" process"
120 " pid:%d", get_process_type_string(process_type), threads[i]);
121 }
122 else
123 zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno));
124 }
125
126 if (0 == found)
127 {
128 if (0 == proc_num)
129 {
130 zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal:"
131 " \"%s\" process does not exist",
132 get_process_type_string(proc_type));
133 }
134 else
135 {
136 zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal:"
137 " \"%s #%d\" process does not exist",
138 get_process_type_string(proc_type), proc_num);
139 }
140 }
141 }
142
zbx_signal_process_by_pid(int pid,int flags)143 static void zbx_signal_process_by_pid(int pid, int flags)
144 {
145 union sigval s;
146 int i, found = 0;
147
148 s.ZBX_SIVAL_INT = flags;
149
150 for (i = 0; i < threads_num; i++)
151 {
152 if (0 != pid && threads[i] != ZBX_RTC_GET_DATA(flags))
153 continue;
154
155 found = 1;
156
157 if (-1 != sigqueue(threads[i], SIGUSR1, s))
158 {
159 zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to process pid:%d",
160 threads[i]);
161 }
162 else
163 zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno));
164 }
165
166 if (0 != ZBX_RTC_GET_DATA(flags) && 0 == found)
167 {
168 zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: process pid:%d is not a Zabbix child"
169 " process", ZBX_RTC_GET_DATA(flags));
170 }
171 }
172
173 #endif
174
zbx_set_sigusr_handler(void (* handler)(int flags))175 void zbx_set_sigusr_handler(void (*handler)(int flags))
176 {
177 zbx_sigusr_handler = handler;
178 }
179
180 /******************************************************************************
181 * *
182 * Function: user1_signal_handler *
183 * *
184 * Purpose: handle user signal SIGUSR1 *
185 * *
186 ******************************************************************************/
user1_signal_handler(int sig,siginfo_t * siginfo,void * context)187 static void user1_signal_handler(int sig, siginfo_t *siginfo, void *context)
188 {
189 #ifdef HAVE_SIGQUEUE
190 int flags;
191 #endif
192 SIG_CHECK_PARAMS(sig, siginfo, context);
193
194 zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d(0x%08x)].",
195 sig, get_signal_name(sig),
196 SIG_CHECKED_FIELD(siginfo, si_pid),
197 SIG_CHECKED_FIELD(siginfo, si_uid),
198 SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT),
199 (unsigned int)SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT));
200 #ifdef HAVE_SIGQUEUE
201 flags = SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT);
202
203 if (!SIG_PARENT_PROCESS)
204 {
205 common_sigusr_handler(flags);
206 return;
207 }
208
209 if (NULL == threads)
210 {
211 zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: shutdown in progress");
212 return;
213 }
214
215 switch (ZBX_RTC_GET_MSG(flags))
216 {
217 case ZBX_RTC_CONFIG_CACHE_RELOAD:
218 if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
219 {
220 zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache"
221 " cannot be performed for a passive proxy");
222 return;
223 }
224
225 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_CONFSYNCER, 1, flags);
226 break;
227 case ZBX_RTC_HOUSEKEEPER_EXECUTE:
228 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_HOUSEKEEPER, 1, flags);
229 break;
230 case ZBX_RTC_LOG_LEVEL_INCREASE:
231 case ZBX_RTC_LOG_LEVEL_DECREASE:
232 if ((ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID) == ZBX_RTC_GET_SCOPE(flags))
233 zbx_signal_process_by_pid(ZBX_RTC_GET_DATA(flags), flags);
234 else
235 zbx_signal_process_by_type(ZBX_RTC_GET_SCOPE(flags), ZBX_RTC_GET_DATA(flags), flags);
236 break;
237 case ZBX_RTC_SNMP_CACHE_RELOAD:
238 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_UNREACHABLE, ZBX_RTC_GET_DATA(flags), flags);
239 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_POLLER, ZBX_RTC_GET_DATA(flags), flags);
240 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_TRAPPER, ZBX_RTC_GET_DATA(flags), flags);
241 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_DISCOVERER, ZBX_RTC_GET_DATA(flags), flags);
242 zbx_signal_process_by_type(ZBX_PROCESS_TYPE_TASKMANAGER, ZBX_RTC_GET_DATA(flags), flags);
243 break;
244 default:
245 if (NULL != zbx_sigusr_handler)
246 zbx_sigusr_handler(flags);
247 }
248 #endif
249 }
250
251 /******************************************************************************
252 * *
253 * Function: pipe_signal_handler *
254 * *
255 * Purpose: handle pipe signal SIGPIPE *
256 * *
257 ******************************************************************************/
pipe_signal_handler(int sig,siginfo_t * siginfo,void * context)258 static void pipe_signal_handler(int sig, siginfo_t *siginfo, void *context)
259 {
260 SIG_CHECK_PARAMS(sig, siginfo, context);
261
262 zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d]. Ignoring ...",
263 sig, get_signal_name(sig),
264 SIG_CHECKED_FIELD(siginfo, si_pid));
265 }
266
267 /******************************************************************************
268 * *
269 * Function: set_daemon_signal_handlers *
270 * *
271 * Purpose: set the signal handlers used by daemons *
272 * *
273 ******************************************************************************/
set_daemon_signal_handlers(void)274 static void set_daemon_signal_handlers(void)
275 {
276 struct sigaction phan;
277
278 sig_parent_pid = (int)getpid();
279
280 sigemptyset(&phan.sa_mask);
281 phan.sa_flags = SA_SIGINFO;
282
283 phan.sa_sigaction = user1_signal_handler;
284 sigaction(SIGUSR1, &phan, NULL);
285
286 phan.sa_sigaction = pipe_signal_handler;
287 sigaction(SIGPIPE, &phan, NULL);
288 }
289
290 /******************************************************************************
291 * *
292 * Function: daemon_start *
293 * *
294 * Purpose: init process as daemon *
295 * *
296 * Parameters: allow_root - allow root permission for application *
297 * user - user on the system to which to drop the *
298 * privileges *
299 * flags - daemon startup flags *
300 * *
301 * Author: Alexei Vladishev *
302 * *
303 * Comments: it doesn't allow running under 'root' if allow_root is zero *
304 * *
305 ******************************************************************************/
daemon_start(int allow_root,const char * user,unsigned int flags)306 int daemon_start(int allow_root, const char *user, unsigned int flags)
307 {
308 struct passwd *pwd;
309
310 if (0 == allow_root && 0 == getuid()) /* running as root? */
311 {
312 if (NULL == user)
313 user = "zabbix";
314
315 pwd = getpwnam(user);
316
317 if (NULL == pwd)
318 {
319 zbx_error("user %s does not exist", user);
320 zbx_error("cannot run as root!");
321 exit(EXIT_FAILURE);
322 }
323
324 if (0 == pwd->pw_uid)
325 {
326 zbx_error("User=%s contradicts AllowRoot=0", user);
327 zbx_error("cannot run as root!");
328 exit(EXIT_FAILURE);
329 }
330
331 if (-1 == setgid(pwd->pw_gid))
332 {
333 zbx_error("cannot setgid to %s: %s", user, zbx_strerror(errno));
334 exit(EXIT_FAILURE);
335 }
336
337 #ifdef HAVE_FUNCTION_INITGROUPS
338 if (-1 == initgroups(user, pwd->pw_gid))
339 {
340 zbx_error("cannot initgroups to %s: %s", user, zbx_strerror(errno));
341 exit(EXIT_FAILURE);
342 }
343 #endif
344
345 if (-1 == setuid(pwd->pw_uid))
346 {
347 zbx_error("cannot setuid to %s: %s", user, zbx_strerror(errno));
348 exit(EXIT_FAILURE);
349 }
350
351 #ifdef HAVE_FUNCTION_SETEUID
352 if (-1 == setegid(pwd->pw_gid) || -1 == seteuid(pwd->pw_uid))
353 {
354 zbx_error("cannot setegid or seteuid to %s: %s", user, zbx_strerror(errno));
355 exit(EXIT_FAILURE);
356 }
357 #endif
358 }
359
360 umask(0002);
361
362 if (0 == (flags & ZBX_TASK_FLAG_FOREGROUND))
363 {
364 if (0 != zbx_fork())
365 exit(EXIT_SUCCESS);
366
367 setsid();
368
369 signal(SIGHUP, SIG_IGN);
370
371 if (0 != zbx_fork())
372 exit(EXIT_SUCCESS);
373
374 if (-1 == chdir("/")) /* this is to eliminate warning: ignoring return value of chdir */
375 assert(0);
376
377 if (FAIL == zbx_redirect_stdio(LOG_TYPE_FILE == CONFIG_LOG_TYPE ? CONFIG_LOG_FILE : NULL))
378 exit(EXIT_FAILURE);
379 }
380
381 if (FAIL == create_pid_file(CONFIG_PID_FILE))
382 exit(EXIT_FAILURE);
383
384 atexit(daemon_stop);
385
386 parent_pid = (int)getpid();
387
388 zbx_set_common_signal_handlers();
389 set_daemon_signal_handlers();
390
391 /* Set SIGCHLD now to avoid race conditions when a child process is created before */
392 /* sigaction() is called. To avoid problems when scripts exit in zbx_execute() and */
393 /* other cases, SIGCHLD is set to SIG_DFL in zbx_child_fork(). */
394 zbx_set_child_signal_handler();
395
396 return MAIN_ZABBIX_ENTRY(flags);
397 }
398
daemon_stop(void)399 void daemon_stop(void)
400 {
401 /* this function is registered using atexit() to be called when we terminate */
402 /* there should be nothing like logging or calls to exit() beyond this point */
403
404 if (parent_pid != (int)getpid())
405 return;
406
407 drop_pid_file(CONFIG_PID_FILE);
408 }
409
zbx_sigusr_send(int flags)410 int zbx_sigusr_send(int flags)
411 {
412 int ret = FAIL;
413 char error[256];
414 #ifdef HAVE_SIGQUEUE
415 pid_t pid;
416
417 if (SUCCEED == read_pid_file(CONFIG_PID_FILE, &pid, error, sizeof(error)))
418 {
419 union sigval s;
420
421 s.ZBX_SIVAL_INT = flags;
422
423 if (-1 != sigqueue(pid, SIGUSR1, s))
424 {
425 zbx_error("command sent successfully");
426 ret = SUCCEED;
427 }
428 else
429 {
430 zbx_snprintf(error, sizeof(error), "cannot send command to PID [%d]: %s",
431 (int)pid, zbx_strerror(errno));
432 }
433 }
434 #else
435 zbx_snprintf(error, sizeof(error), "operation is not supported on the given operating system");
436 #endif
437 if (SUCCEED != ret)
438 zbx_error("%s", error);
439
440 return ret;
441 }
442