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 <assert.h>
21
22 #include "common.h"
23 #include "log.h"
24
25 #include "db.h"
26 #include "zbxjson.h"
27 #include "zbxtasks.h"
28
29 /******************************************************************************
30 * *
31 * Function: tm_remote_command_clear *
32 * *
33 * Purpose: frees remote command task resources *
34 * *
35 * Parameters: data - [IN] the remote command task data *
36 * *
37 ******************************************************************************/
tm_remote_command_clear(zbx_tm_remote_command_t * data)38 static void tm_remote_command_clear(zbx_tm_remote_command_t *data)
39 {
40 zbx_free(data->command);
41 zbx_free(data->username);
42 zbx_free(data->password);
43 zbx_free(data->publickey);
44 zbx_free(data->privatekey);
45 }
46
47 /******************************************************************************
48 * *
49 * Function: tm_remote_command_result_clear *
50 * *
51 * Purpose: frees remote command result task resources *
52 * *
53 * Parameters: data - [IN] the remote command result task data *
54 * *
55 ******************************************************************************/
tm_remote_command_result_clear(zbx_tm_remote_command_result_t * data)56 static void tm_remote_command_result_clear(zbx_tm_remote_command_result_t *data)
57 {
58 zbx_free(data->info);
59 }
60
61 /******************************************************************************
62 * *
63 * Function: zbx_tm_task_clear *
64 * *
65 * Purpose: frees task resources *
66 * *
67 * Parameters: task - [IN] *
68 * *
69 ******************************************************************************/
zbx_tm_task_clear(zbx_tm_task_t * task)70 void zbx_tm_task_clear(zbx_tm_task_t *task)
71 {
72 if (NULL != task->data)
73 {
74 switch (task->type)
75 {
76 case ZBX_TM_TASK_REMOTE_COMMAND:
77 tm_remote_command_clear((zbx_tm_remote_command_t *)task->data);
78 break;
79 case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
80 tm_remote_command_result_clear((zbx_tm_remote_command_result_t *)task->data);
81 break;
82 case ZBX_TM_TASK_CHECK_NOW:
83 /* nothing to clear */
84 break;
85 default:
86 THIS_SHOULD_NEVER_HAPPEN;
87 }
88 }
89
90 zbx_free(task->data);
91 task->type = ZBX_TM_TASK_UNDEFINED;
92 }
93
94 /******************************************************************************
95 * *
96 * Function: zbx_tm_task_free *
97 * *
98 * Purpose: frees task and its resources *
99 * *
100 * Parameters: task - [IN] the task to free *
101 * *
102 ******************************************************************************/
zbx_tm_task_free(zbx_tm_task_t * task)103 void zbx_tm_task_free(zbx_tm_task_t *task)
104 {
105 zbx_tm_task_clear(task);
106 zbx_free(task);
107 }
108
109 /******************************************************************************
110 * *
111 * Function: zbx_tm_remote_command_create *
112 * *
113 * Purpose: create a remote command task data *
114 * *
115 * Parameters: command_type - [IN] the remote command type (ZBX_SCRIPT_TYPE_)*
116 * command - [IN] the command to execute *
117 * execute_on - [IN] the execution target (ZBX_SCRIPT_EXECUTE_)*
118 * port - [IN] the target port *
119 * authtype - [IN] the authentication type *
120 * username - [IN] the username (can be NULL) *
121 * password - [IN] the password (can be NULL) *
122 * publickey - [IN] the public key (can be NULL) *
123 * privatekey - [IN] the private key (can be NULL) *
124 * parent_taskid - [IN] the parent task identifier *
125 * hostid - [IN] the target host identifier *
126 * alertid - [IN] the alert identifier *
127 * *
128 * Return value: The created remote command data. *
129 * *
130 ******************************************************************************/
zbx_tm_remote_command_create(int command_type,const char * command,int execute_on,int port,int authtype,const char * username,const char * password,const char * publickey,const char * privatekey,zbx_uint64_t parent_taskid,zbx_uint64_t hostid,zbx_uint64_t alertid)131 zbx_tm_remote_command_t *zbx_tm_remote_command_create(int command_type, const char *command, int execute_on, int port,
132 int authtype, const char *username, const char *password, const char *publickey, const char *privatekey,
133 zbx_uint64_t parent_taskid, zbx_uint64_t hostid, zbx_uint64_t alertid)
134 {
135 zbx_tm_remote_command_t *data;
136
137 data = (zbx_tm_remote_command_t *)zbx_malloc(NULL, sizeof(zbx_tm_remote_command_t));
138 data->command_type = command_type;
139 data->command = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(command));
140 data->execute_on = execute_on;
141 data->port = port;
142 data->authtype = authtype;
143 data->username = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(username));
144 data->password = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(password));
145 data->publickey = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(publickey));
146 data->privatekey = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(privatekey));
147 data->parent_taskid = parent_taskid;
148 data->hostid = hostid;
149 data->alertid = alertid;
150
151 return data;
152 }
153
154 /******************************************************************************
155 * *
156 * Function: zbx_tm_remote_command_result_create *
157 * *
158 * Purpose: create a remote command result task data *
159 * *
160 * Parameters: parent_taskid - [IN] the parent task identifier *
161 * status - [IN] the remote command execution status *
162 * info - [IN] the remote command execution result *
163 * *
164 * Return value: The created remote command result data. *
165 * *
166 ******************************************************************************/
zbx_tm_remote_command_result_create(zbx_uint64_t parent_taskid,int status,const char * info)167 zbx_tm_remote_command_result_t *zbx_tm_remote_command_result_create(zbx_uint64_t parent_taskid, int status,
168 const char *info)
169 {
170 zbx_tm_remote_command_result_t *data;
171
172 data = (zbx_tm_remote_command_result_t *)zbx_malloc(NULL, sizeof(zbx_tm_remote_command_result_t));
173 data->status = status;
174 data->parent_taskid = parent_taskid;
175 data->info = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(info));
176
177 return data;
178 }
179
180 /******************************************************************************
181 * *
182 * Function: zbx_tm_check_now_create *
183 * *
184 * Purpose: create a check now task data *
185 * *
186 * Parameters: itemid - [IN] the item identifier *
187 * *
188 * Return value: The created check now data. *
189 * *
190 ******************************************************************************/
zbx_tm_check_now_create(zbx_uint64_t itemid)191 zbx_tm_check_now_t *zbx_tm_check_now_create(zbx_uint64_t itemid)
192 {
193 zbx_tm_check_now_t *data;
194
195 data = (zbx_tm_check_now_t *)zbx_malloc(NULL, sizeof(zbx_tm_check_now_t));
196 data->itemid = itemid;
197
198 return data;
199 }
200
201 /******************************************************************************
202 * *
203 * Function: zbx_tm_task_create *
204 * *
205 * Purpose: create a new task *
206 * *
207 * Parameters: taskid - [IN] the task identifier *
208 * type - [IN] the task type (see ZBX_TM_TASK_*) *
209 * status - [IN] the task status (see ZBX_TM_STATUS_*) *
210 * clock - [IN] the task creation time *
211 * ttl - [IN] the task expiration period in seconds *
212 * proxy_hostid - [IN] the destination proxy identifier (or 0) *
213 * *
214 * Return value: The created task. *
215 * *
216 ******************************************************************************/
zbx_tm_task_create(zbx_uint64_t taskid,unsigned char type,unsigned char status,int clock,int ttl,zbx_uint64_t proxy_hostid)217 zbx_tm_task_t *zbx_tm_task_create(zbx_uint64_t taskid, unsigned char type, unsigned char status, int clock, int ttl,
218 zbx_uint64_t proxy_hostid)
219 {
220 zbx_tm_task_t *task;
221
222 task = (zbx_tm_task_t *)zbx_malloc(NULL, sizeof(zbx_tm_task_t));
223
224 task->taskid = taskid;
225 task->type = type;
226 task->status = status;
227 task->clock = clock;
228 task->ttl = ttl;
229 task->proxy_hostid = proxy_hostid;
230 task->data = NULL;
231
232 return task;
233 }
234
235 /******************************************************************************
236 * *
237 * Function: tm_save_remote_command_tasks *
238 * *
239 * Purpose: saves remote command task data in database *
240 * *
241 * Parameters: tasks - [IN] the tasks *
242 * tasks_num - [IN] the number of tasks to process *
243 * *
244 * Return value: SUCCEED - the data was saved successfully *
245 * FAIL - otherwise *
246 * *
247 * Comments: The tasks array can contain mixture of task types. *
248 * *
249 ******************************************************************************/
tm_save_remote_command_tasks(zbx_tm_task_t ** tasks,int tasks_num)250 static int tm_save_remote_command_tasks(zbx_tm_task_t **tasks, int tasks_num)
251 {
252 int i, ret;
253 zbx_db_insert_t db_insert;
254 zbx_tm_remote_command_t *data;
255
256 zbx_db_insert_prepare(&db_insert, "task_remote_command", "taskid", "command_type", "execute_on", "port",
257 "authtype", "username", "password", "publickey", "privatekey", "command", "alertid",
258 "parent_taskid", "hostid", NULL);
259
260 for (i = 0; i < tasks_num; i++)
261 {
262 zbx_tm_task_t *task = tasks[i];
263
264 switch (task->type)
265 {
266 case ZBX_TM_TASK_REMOTE_COMMAND:
267 data = (zbx_tm_remote_command_t *)task->data;
268 zbx_db_insert_add_values(&db_insert, task->taskid, data->command_type, data->execute_on,
269 data->port, data->authtype, data->username, data->password,
270 data->publickey, data->privatekey, data->command, data->alertid,
271 data->parent_taskid, data->hostid);
272 }
273 }
274
275 ret = zbx_db_insert_execute(&db_insert);
276 zbx_db_insert_clean(&db_insert);
277
278 return ret;
279 }
280
281 /******************************************************************************
282 * *
283 * Function: tm_save_remote_command_result_tasks *
284 * *
285 * Purpose: saves remote command result task data in database *
286 * *
287 * Parameters: tasks - [IN] the tasks *
288 * tasks_num - [IN] the number of tasks to process *
289 * *
290 * Return value: SUCCEED - the data was saved successfully *
291 * FAIL - otherwise *
292 * *
293 * Comments: The tasks array can contain mixture of task types. *
294 * *
295 ******************************************************************************/
tm_save_remote_command_result_tasks(zbx_tm_task_t ** tasks,int tasks_num)296 static int tm_save_remote_command_result_tasks(zbx_tm_task_t **tasks, int tasks_num)
297 {
298 int i, ret;
299 zbx_db_insert_t db_insert;
300 zbx_tm_remote_command_result_t *data;
301
302 zbx_db_insert_prepare(&db_insert, "task_remote_command_result", "taskid", "status", "parent_taskid", "info",
303 NULL);
304
305 for (i = 0; i < tasks_num; i++)
306 {
307 zbx_tm_task_t *task = tasks[i];
308
309 switch (task->type)
310 {
311 case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
312 data = (zbx_tm_remote_command_result_t *)task->data;
313 zbx_db_insert_add_values(&db_insert, task->taskid, data->status, data->parent_taskid,
314 data->info);
315 }
316 }
317
318 ret = zbx_db_insert_execute(&db_insert);
319 zbx_db_insert_clean(&db_insert);
320
321 return ret;
322 }
323
324 /******************************************************************************
325 * *
326 * Function: tm_save_check_now_tasks *
327 * *
328 * Purpose: saves remote command task data in database *
329 * *
330 * Parameters: tasks - [IN] the tasks *
331 * tasks_num - [IN] the number of tasks to process *
332 * *
333 * Return value: SUCCEED - the data was saved successfully *
334 * FAIL - otherwise *
335 * *
336 * Comments: The tasks array can contain mixture of task types. *
337 * *
338 ******************************************************************************/
tm_save_check_now_tasks(zbx_tm_task_t ** tasks,int tasks_num)339 static int tm_save_check_now_tasks(zbx_tm_task_t **tasks, int tasks_num)
340 {
341 int i, ret;
342 zbx_db_insert_t db_insert;
343 zbx_tm_check_now_t *data;
344
345 zbx_db_insert_prepare(&db_insert, "task_check_now", "taskid", "itemid", NULL);
346
347 for (i = 0; i < tasks_num; i++)
348 {
349 const zbx_tm_task_t *task = tasks[i];
350
351 switch (task->type)
352 {
353 case ZBX_TM_TASK_CHECK_NOW:
354 data = (zbx_tm_check_now_t *)task->data;
355 zbx_db_insert_add_values(&db_insert, task->taskid, data->itemid);
356 }
357 }
358
359 ret = zbx_db_insert_execute(&db_insert);
360 zbx_db_insert_clean(&db_insert);
361
362 return ret;
363 }
364
365 /******************************************************************************
366 * *
367 * Function: tm_save_tasks *
368 * *
369 * Purpose: saves tasks into database *
370 * *
371 * Parameters: tasks - [IN] the tasks *
372 * tasks_num - [IN] the number of tasks to process *
373 * *
374 * Return value: SUCCEED - the tasks were saved successfully *
375 * FAIL - otherwise *
376 * *
377 ******************************************************************************/
tm_save_tasks(zbx_tm_task_t ** tasks,int tasks_num)378 static int tm_save_tasks(zbx_tm_task_t **tasks, int tasks_num)
379 {
380 int i, ret, remote_command_num = 0, remote_command_result_num = 0, check_now_num = 0, ids_num = 0;
381 zbx_uint64_t taskid;
382 zbx_db_insert_t db_insert;
383
384 for (i = 0; i < tasks_num; i++)
385 {
386 if (0 == tasks[i]->taskid)
387 ids_num++;
388 }
389
390 if (0 != ids_num)
391 taskid = DBget_maxid_num("task", ids_num);
392
393 for (i = 0; i < tasks_num; i++)
394 {
395 switch (tasks[i]->type)
396 {
397 case ZBX_TM_TASK_REMOTE_COMMAND:
398 remote_command_num++;
399 break;
400 case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
401 remote_command_result_num++;
402 break;
403 case ZBX_TM_TASK_CHECK_NOW:
404 check_now_num++;
405 break;
406 default:
407 THIS_SHOULD_NEVER_HAPPEN;
408 continue;
409 }
410
411 if (0 == tasks[i]->taskid)
412 tasks[i]->taskid = taskid++;
413 }
414
415 zbx_db_insert_prepare(&db_insert, "task", "taskid", "type", "status", "clock", "ttl", "proxy_hostid", NULL);
416
417 for (i = 0; i < tasks_num; i++)
418 {
419 if (0 == tasks[i]->taskid)
420 continue;
421
422 zbx_db_insert_add_values(&db_insert, tasks[i]->taskid, (int)tasks[i]->type, (int)tasks[i]->status,
423 tasks[i]->clock, tasks[i]->ttl, tasks[i]->proxy_hostid);
424 }
425
426 ret = zbx_db_insert_execute(&db_insert);
427 zbx_db_insert_clean(&db_insert);
428
429 if (SUCCEED == ret && 0 != remote_command_num)
430 ret = tm_save_remote_command_tasks(tasks, tasks_num);
431
432 if (SUCCEED == ret && 0 != remote_command_result_num)
433 ret = tm_save_remote_command_result_tasks(tasks, tasks_num);
434
435 if (SUCCEED == ret && 0 != check_now_num)
436 ret = tm_save_check_now_tasks(tasks, tasks_num);
437
438 return ret;
439 }
440
441 /******************************************************************************
442 * *
443 * Function: zbx_tm_save_tasks *
444 * *
445 * Purpose: saves tasks and their data into database *
446 * *
447 * Parameters: tasks - [IN] the tasks *
448 * *
449 ******************************************************************************/
zbx_tm_save_tasks(zbx_vector_ptr_t * tasks)450 void zbx_tm_save_tasks(zbx_vector_ptr_t *tasks)
451 {
452 const char *__function_name = "zbx_tm_save_tasks";
453
454 zabbix_log(LOG_LEVEL_DEBUG, "In %s() tasks_num:%d", __function_name, tasks->values_num);
455
456 tm_save_tasks((zbx_tm_task_t **)tasks->values, tasks->values_num);
457
458 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
459 }
460
461 /******************************************************************************
462 * *
463 * Function: zbx_tm_save_task *
464 * *
465 * Purpose: saves task and its data into database *
466 * *
467 * Parameters: task - [IN] the task *
468 * *
469 * Return value: SUCCEED - the task was saved successfully *
470 * FAIL - otherwise *
471 * *
472 ******************************************************************************/
zbx_tm_save_task(zbx_tm_task_t * task)473 int zbx_tm_save_task(zbx_tm_task_t *task)
474 {
475 const char *__function_name = "zbx_tm_save_task";
476 int ret;
477
478 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
479
480 ret = tm_save_tasks(&task, 1);
481
482 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
483
484 return ret;
485 }
486
487 /******************************************************************************
488 * *
489 * Function: zbx_tm_update_task_status *
490 * *
491 * Purpose: update status of the specified tasks in database *
492 * *
493 * Parameters: tasks - [IN] the tasks *
494 * status - [IN] the new status *
495 * *
496 ******************************************************************************/
zbx_tm_update_task_status(zbx_vector_ptr_t * tasks,int status)497 void zbx_tm_update_task_status(zbx_vector_ptr_t *tasks, int status)
498 {
499 const char *__function_name = "zbx_tm_update_task_status";
500 zbx_vector_uint64_t taskids;
501 int i;
502 char *sql = NULL;
503 size_t sql_alloc = 0, sql_offset = 0;
504
505 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
506
507 zbx_vector_uint64_create(&taskids);
508
509 for (i = 0; i < tasks->values_num; i++)
510 {
511 zbx_tm_task_t *task = (zbx_tm_task_t *)tasks->values[i];
512 zbx_vector_uint64_append(&taskids, task->taskid);
513 }
514
515 zbx_vector_uint64_sort(&taskids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
516
517 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update task set status=%d where", status);
518 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "taskid", taskids.values, taskids.values_num);
519 DBexecute("%s", sql);
520 zbx_free(sql);
521
522 zbx_vector_uint64_destroy(&taskids);
523
524 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
525 }
526
527 /******************************************************************************
528 * *
529 * Function: tm_json_serialize_task *
530 * *
531 * Purpose: serializes common task data in json format *
532 * *
533 * Parameters: json - [OUT] the json data *
534 * data - [IN] the task to serialize *
535 * *
536 ******************************************************************************/
tm_json_serialize_task(struct zbx_json * json,const zbx_tm_task_t * task)537 static void tm_json_serialize_task(struct zbx_json *json, const zbx_tm_task_t *task)
538 {
539 zbx_json_addint64(json, ZBX_PROTO_TAG_TYPE, task->type);
540 zbx_json_addint64(json, ZBX_PROTO_TAG_CLOCK, task->clock);
541 zbx_json_addint64(json, ZBX_PROTO_TAG_TTL, task->ttl);
542 }
543
544 /******************************************************************************
545 * *
546 * Function: tm_json_serialize_remote_command *
547 * *
548 * Purpose: serializes remote command data in json format *
549 * *
550 * Parameters: json - [OUT] the json data *
551 * data - [IN] the remote command to serialize *
552 * *
553 ******************************************************************************/
tm_json_serialize_remote_command(struct zbx_json * json,const zbx_tm_remote_command_t * data)554 static void tm_json_serialize_remote_command(struct zbx_json *json, const zbx_tm_remote_command_t *data)
555 {
556 zbx_json_addint64(json, ZBX_PROTO_TAG_COMMANDTYPE, data->command_type);
557 zbx_json_addstring(json, ZBX_PROTO_TAG_COMMAND, data->command, ZBX_JSON_TYPE_STRING);
558 zbx_json_addint64(json, ZBX_PROTO_TAG_EXECUTE_ON, data->execute_on);
559 zbx_json_addint64(json, ZBX_PROTO_TAG_PORT, data->port);
560 zbx_json_addint64(json, ZBX_PROTO_TAG_AUTHTYPE, data->authtype);
561 zbx_json_addstring(json, ZBX_PROTO_TAG_USERNAME, data->username, ZBX_JSON_TYPE_STRING);
562 zbx_json_addstring(json, ZBX_PROTO_TAG_PASSWORD, data->password, ZBX_JSON_TYPE_STRING);
563 zbx_json_addstring(json, ZBX_PROTO_TAG_PUBLICKEY, data->publickey, ZBX_JSON_TYPE_STRING);
564 zbx_json_addstring(json, ZBX_PROTO_TAG_PRIVATEKEY, data->privatekey, ZBX_JSON_TYPE_STRING);
565 zbx_json_adduint64(json, ZBX_PROTO_TAG_ALERTID, data->alertid);
566 zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, data->parent_taskid);
567 zbx_json_adduint64(json, ZBX_PROTO_TAG_HOSTID, data->hostid);
568 }
569
570 /******************************************************************************
571 * *
572 * Function: tm_json_serialize_remote_command_result *
573 * *
574 * Purpose: serializes remote command result data in json format *
575 * *
576 * Parameters: json - [OUT] the json data *
577 * data - [IN] the remote command result to serialize *
578 * *
579 ******************************************************************************/
tm_json_serialize_remote_command_result(struct zbx_json * json,const zbx_tm_remote_command_result_t * data)580 static void tm_json_serialize_remote_command_result(struct zbx_json *json,
581 const zbx_tm_remote_command_result_t *data)
582 {
583 zbx_json_addint64(json, ZBX_PROTO_TAG_STATUS, data->status);
584 zbx_json_addstring(json, ZBX_PROTO_TAG_INFO, data->info, ZBX_JSON_TYPE_STRING);
585 zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, data->parent_taskid);
586 }
587
588 /******************************************************************************
589 * *
590 * Function: tm_json_serialize_check_now *
591 * *
592 * Purpose: serializes check now data in json format *
593 * *
594 * Parameters: json - [OUT] the json data *
595 * data - [IN] the check now to serialize *
596 * *
597 ******************************************************************************/
tm_json_serialize_check_now(struct zbx_json * json,const zbx_tm_check_now_t * data)598 static void tm_json_serialize_check_now(struct zbx_json *json, const zbx_tm_check_now_t *data)
599 {
600 zbx_json_addint64(json, ZBX_PROTO_TAG_ITEMID, data->itemid);
601 }
602
603 /******************************************************************************
604 * *
605 * Function: zbx_tm_json_serialize_tasks *
606 * *
607 * Purpose: serializes remote command data in json format *
608 * *
609 * Parameters: json - [OUT] the json data *
610 * tasks - [IN] the tasks to serialize *
611 * *
612 ******************************************************************************/
zbx_tm_json_serialize_tasks(struct zbx_json * json,const zbx_vector_ptr_t * tasks)613 void zbx_tm_json_serialize_tasks(struct zbx_json *json, const zbx_vector_ptr_t *tasks)
614 {
615 int i;
616
617 zbx_json_addarray(json, ZBX_PROTO_TAG_TASKS);
618
619 for (i = 0; i < tasks->values_num; i++)
620 {
621 const zbx_tm_task_t *task = (const zbx_tm_task_t *)tasks->values[i];
622
623 zbx_json_addobject(json, NULL);
624 tm_json_serialize_task(json, task);
625
626 switch (task->type)
627 {
628 case ZBX_TM_TASK_REMOTE_COMMAND:
629 tm_json_serialize_remote_command(json, (zbx_tm_remote_command_t *)task->data);
630 break;
631 case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
632 tm_json_serialize_remote_command_result(json, (zbx_tm_remote_command_result_t *)task->data);
633 break;
634 case ZBX_TM_TASK_CHECK_NOW:
635 tm_json_serialize_check_now(json, (zbx_tm_check_now_t *)task->data);
636 break;
637 default:
638 THIS_SHOULD_NEVER_HAPPEN;
639 break;
640 }
641
642 zbx_json_close(json);
643 }
644
645 zbx_json_close(json);
646 }
647
648 /******************************************************************************
649 * *
650 * Function: tm_json_deserialize_remote_command *
651 * *
652 * Purpose: deserializes remote command from json data *
653 * *
654 * Parameters: jp - [IN] the json data *
655 * *
656 * Return value: The deserialized remote command data or NULL if *
657 * deserialization failed. *
658 * *
659 ******************************************************************************/
tm_json_deserialize_remote_command(const struct zbx_json_parse * jp)660 static zbx_tm_remote_command_t *tm_json_deserialize_remote_command(const struct zbx_json_parse *jp)
661 {
662 char value[MAX_STRING_LEN];
663 int commandtype, execute_on, port, authtype;
664 zbx_uint64_t alertid, parent_taskid, hostid;
665 char *username = NULL, *password = NULL, *publickey = NULL, *privatekey = NULL,
666 *command = NULL;
667 size_t username_alloc = 0, password_alloc = 0, publickey_alloc = 0, privatekey_alloc = 0,
668 command_alloc = 0;
669 zbx_tm_remote_command_t *data = NULL;
670
671 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_COMMANDTYPE, value, sizeof(value), NULL))
672 goto out;
673
674 commandtype = atoi(value);
675
676 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_EXECUTE_ON, value, sizeof(value), NULL))
677 goto out;
678
679 execute_on = atoi(value);
680
681 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, value, sizeof(value), NULL))
682 goto out;
683
684 port = atoi(value);
685
686 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_AUTHTYPE, value, sizeof(value), NULL))
687 goto out;
688
689 authtype = atoi(value);
690
691 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_ALERTID, value, sizeof(value), NULL) ||
692 SUCCEED != is_uint64(value, &alertid))
693 {
694 goto out;
695 }
696
697 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PARENT_TASKID, value, sizeof(value), NULL) ||
698 SUCCEED != is_uint64(value, &parent_taskid))
699 {
700 goto out;
701 }
702
703 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOSTID, value, sizeof(value), NULL) ||
704 SUCCEED != is_uint64(value, &hostid))
705 {
706 goto out;
707 }
708
709 if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_USERNAME, &username, &username_alloc, NULL))
710 goto out;
711
712 if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_PASSWORD, &password, &password_alloc, NULL))
713 goto out;
714
715 if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_PUBLICKEY, &publickey, &publickey_alloc, NULL))
716 goto out;
717
718 if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_PRIVATEKEY, &privatekey, &privatekey_alloc, NULL))
719 goto out;
720
721 if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_COMMAND, &command, &command_alloc, NULL))
722 goto out;
723
724 data = zbx_tm_remote_command_create(commandtype, command, execute_on, port, authtype, username, password,
725 publickey, privatekey, parent_taskid, hostid, alertid);
726 out:
727 zbx_free(command);
728 zbx_free(privatekey);
729 zbx_free(publickey);
730 zbx_free(password);
731 zbx_free(username);
732
733 return data;
734 }
735
736 /******************************************************************************
737 * *
738 * Function: tm_json_deserialize_remote_command_result *
739 * *
740 * Purpose: deserializes remote command result from json data *
741 * *
742 * Parameters: jp - [IN] the json data *
743 * *
744 * Return value: The deserialized remote command result data or NULL if *
745 * deserialization failed. *
746 * *
747 ******************************************************************************/
tm_json_deserialize_remote_command_result(const struct zbx_json_parse * jp)748 static zbx_tm_remote_command_result_t *tm_json_deserialize_remote_command_result(const struct zbx_json_parse *jp)
749 {
750 char value[MAX_STRING_LEN];
751 int status;
752 zbx_uint64_t parent_taskid;
753 char *info = NULL;
754 size_t info_alloc = 0;
755 zbx_tm_remote_command_result_t *data = NULL;
756
757 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_STATUS, value, sizeof(value), NULL))
758 goto out;
759
760 status = atoi(value);
761
762 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PARENT_TASKID, value, sizeof(value), NULL) ||
763 SUCCEED != is_uint64(value, &parent_taskid))
764 {
765 goto out;
766 }
767
768 if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_INFO, &info, &info_alloc, NULL))
769 goto out;
770
771 data = zbx_tm_remote_command_result_create(parent_taskid, status, info);
772 out:
773 zbx_free(info);
774
775 return data;
776 }
777
778 /******************************************************************************
779 * *
780 * Function: tm_json_deserialize_check_now *
781 * *
782 * Purpose: deserializes check now from json data *
783 * *
784 * Parameters: jp - [IN] the json data *
785 * *
786 * Return value: The deserialized check now data or NULL if deserialization *
787 * failed. *
788 * *
789 ******************************************************************************/
tm_json_deserialize_check_now(const struct zbx_json_parse * jp)790 static zbx_tm_check_now_t *tm_json_deserialize_check_now(const struct zbx_json_parse *jp)
791 {
792 char value[MAX_ID_LEN + 1];
793 zbx_uint64_t itemid;
794
795 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_ITEMID, value, sizeof(value), NULL) ||
796 SUCCEED != is_uint64(value, &itemid))
797 {
798 return NULL;
799 }
800
801 return zbx_tm_check_now_create(itemid);
802 }
803
804 /******************************************************************************
805 * *
806 * Function: tm_json_deserialize_task *
807 * *
808 * Purpose: deserializes common task data from json data *
809 * *
810 * Parameters: jp - [IN] the json data *
811 * *
812 * Return value: The deserialized task data or NULL if deserialization failed.*
813 * *
814 ******************************************************************************/
tm_json_deserialize_task(const struct zbx_json_parse * jp)815 static zbx_tm_task_t *tm_json_deserialize_task(const struct zbx_json_parse *jp)
816 {
817 char value[MAX_STRING_LEN];
818 int type, clock, ttl;
819
820 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, value, sizeof(value), NULL))
821 return NULL;
822
823 ZBX_STR2UCHAR(type, value);
824
825 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_CLOCK, value, sizeof(value), NULL))
826 return NULL;
827
828 clock = atoi(value);
829
830 if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TTL, value, sizeof(value), NULL))
831 return NULL;
832
833 ttl = atoi(value);
834
835 return zbx_tm_task_create(0, type, ZBX_TM_STATUS_NEW, clock, ttl, 0);
836 }
837
838 /******************************************************************************
839 * *
840 * Function: zbx_tm_json_deserialize_tasks *
841 * *
842 * Purpose: deserializes tasks from json data *
843 * *
844 * Parameters: jp - [IN] the json data *
845 * tasks - [OUT] the deserialized tasks *
846 * *
847 ******************************************************************************/
zbx_tm_json_deserialize_tasks(const struct zbx_json_parse * jp,zbx_vector_ptr_t * tasks)848 void zbx_tm_json_deserialize_tasks(const struct zbx_json_parse *jp, zbx_vector_ptr_t *tasks)
849 {
850 const char *pnext = NULL;
851 struct zbx_json_parse jp_task;
852
853 while (NULL != (pnext = zbx_json_next(jp, pnext)))
854 {
855 zbx_tm_task_t *task;
856
857 if (SUCCEED != zbx_json_brackets_open(pnext, &jp_task))
858 {
859 zabbix_log(LOG_LEVEL_DEBUG, "Cannot deserialize task record: %s", jp->start);
860 continue;
861 }
862
863 task = tm_json_deserialize_task(&jp_task);
864
865 if (NULL == task)
866 {
867 zabbix_log(LOG_LEVEL_DEBUG, "Cannot deserialize task at: %s", jp_task.start);
868 continue;
869 }
870
871 switch (task->type)
872 {
873 case ZBX_TM_TASK_REMOTE_COMMAND:
874 task->data = tm_json_deserialize_remote_command(&jp_task);
875 break;
876 case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
877 task->data = tm_json_deserialize_remote_command_result(&jp_task);
878 break;
879 case ZBX_TM_TASK_CHECK_NOW:
880 task->data = tm_json_deserialize_check_now(&jp_task);
881 break;
882 default:
883 THIS_SHOULD_NEVER_HAPPEN;
884 break;
885 }
886
887 if (NULL == task->data)
888 {
889 zabbix_log(LOG_LEVEL_DEBUG, "Cannot deserialize task data at: %s", jp_task.start);
890 zbx_tm_task_free(task);
891 continue;
892 }
893
894 zbx_vector_ptr_append(tasks, task);
895 }
896 }
897