/* ** Zabbix ** Copyright (C) 2001-2023 Zabbix SIA ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "trapper_request.h" #include "log.h" #include "cfg.h" #include "trapper_auth.h" #include "zbxdbhigh.h" #include "../zbxreport.h" #include "../alerter/alerter.h" #include "zbxipcservice.h" #include "zbxcommshigh.h" #include "zbxnum.h" #include "proxyconfigread/proxyconfig_read.h" extern int CONFIG_FORKS[ZBX_PROCESS_TYPE_COUNT]; static void trapper_process_report_test(zbx_socket_t *sock, const struct zbx_json_parse *jp, int config_timeout) { zbx_user_t user; struct zbx_json_parse jp_data; struct zbx_json j; if (0 == CONFIG_FORKS[ZBX_PROCESS_TYPE_REPORTMANAGER]) { zbx_send_response(sock, FAIL, "Report manager is disabled.", config_timeout); return; } zbx_user_init(&user); if (FAIL == zbx_get_user_from_json(jp, &user, NULL)) { zbx_send_response(sock, FAIL, "Permission denied.", config_timeout); goto out; } if (SUCCEED != zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)) { char *error; error = zbx_dsprintf(NULL, "cannot find tag: %s", ZBX_PROTO_TAG_DATA); zbx_send_response(sock, FAIL, error, config_timeout); zbx_free(error); goto out; } zbx_report_test(&jp_data, user.userid, &j); zbx_tcp_send_bytes_to(sock, j.buffer, j.buffer_size, config_timeout); zbx_json_clean(&j); out: zbx_user_free(&user); } /****************************************************************************** * * * Purpose: process alert send request that is used to test media types * * * * Parameters: sock - [IN] the request socket * * jp - [IN] the request data * * * ******************************************************************************/ static void trapper_process_alert_send(zbx_socket_t *sock, const struct zbx_json_parse *jp) { DB_RESULT result; DB_ROW row; int ret = FAIL, errcode; char tmp[ZBX_MAX_UINT64_LEN + 1], *sendto = NULL, *subject = NULL, *message = NULL, *error = NULL, *params = NULL, *value = NULL, *debug = NULL; zbx_uint64_t mediatypeid; size_t string_alloc; struct zbx_json json; struct zbx_json_parse jp_data, jp_params; unsigned char *data = NULL, smtp_security, smtp_verify_peer, smtp_verify_host, smtp_authentication, content_type, *response = NULL; zbx_uint32_t size; zbx_user_t user; unsigned short smtp_port; unsigned char type; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_user_init(&user); if (FAIL == zbx_get_user_from_json(jp, &user, NULL) || USER_TYPE_SUPER_ADMIN > user.type) { error = zbx_strdup(NULL, "Permission denied."); goto fail; } if (SUCCEED != zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)) { error = zbx_dsprintf(NULL, "Cannot parse request tag: %s.", ZBX_PROTO_TAG_DATA); goto fail; } if (SUCCEED != zbx_json_value_by_name(&jp_data, ZBX_PROTO_TAG_MEDIATYPEID, tmp, sizeof(tmp), NULL) || SUCCEED != zbx_is_uint64(tmp, &mediatypeid)) { error = zbx_dsprintf(NULL, "Cannot parse request tag: %s.", ZBX_PROTO_TAG_MEDIATYPEID); goto fail; } string_alloc = 0; if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_SENDTO, &sendto, &string_alloc, NULL)) string_alloc = 0; if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_SUBJECT, &subject, &string_alloc, NULL)) string_alloc = 0; if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_MESSAGE, &message, &string_alloc, NULL)) string_alloc = 0; if (SUCCEED == zbx_json_brackets_by_name(&jp_data, ZBX_PROTO_TAG_PARAMETERS, &jp_params)) { size_t string_offset = 0; zbx_strncpy_alloc(¶ms, &string_alloc, &string_offset, jp_params.start, (size_t)(jp_params.end - jp_params.start + 1)); } result = zbx_db_select( "select type,smtp_server,smtp_helo,smtp_email,exec_path,gsm_modem,username,passwd,smtp_port" ",smtp_security,smtp_verify_peer,smtp_verify_host,smtp_authentication,maxsessions" ",maxattempts,attempt_interval,content_type,script,timeout" " from media_type" " where mediatypeid=" ZBX_FS_UI64, mediatypeid); if (NULL == (row = zbx_db_fetch(result))) { zbx_db_free_result(result); error = zbx_dsprintf(NULL, "Cannot find the specified media type."); goto fail; } if (FAIL == zbx_is_ushort(row[8], &smtp_port)) { zbx_db_free_result(result); error = zbx_dsprintf(NULL, "Invalid port value."); goto fail; } ZBX_STR2UCHAR(smtp_security, row[9]); ZBX_STR2UCHAR(smtp_verify_peer, row[10]); ZBX_STR2UCHAR(smtp_verify_host, row[11]); ZBX_STR2UCHAR(smtp_authentication, row[12]); ZBX_STR2UCHAR(content_type, row[16]); ZBX_STR2UCHAR(type, row[0]); size = zbx_alerter_serialize_alert_send(&data, mediatypeid, type, row[1], row[2], row[3], row[4], row[5], row[6], row[7], smtp_port, smtp_security, smtp_verify_peer, smtp_verify_host, smtp_authentication, atoi(row[13]), atoi(row[14]), row[15], content_type, row[17], row[18], sendto, subject, message, params); zbx_db_free_result(result); if (SUCCEED != zbx_ipc_async_exchange(ZBX_IPC_SERVICE_ALERTER, ZBX_IPC_ALERTER_SEND_ALERT, SEC_PER_MIN, data, size, &response, &error)) { goto fail; } zbx_free(sendto); zbx_alerter_deserialize_result_ext(response, &sendto, &value, &errcode, &error, &debug); zbx_free(response); if (SUCCEED == errcode) ret = SUCCEED; fail: zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, SUCCEED == ret ? ZBX_PROTO_VALUE_SUCCESS : ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); if (SUCCEED == ret) { if (NULL != value) zbx_json_addstring(&json, ZBX_PROTO_TAG_DATA, value, ZBX_JSON_TYPE_STRING); } else { if (NULL != error && '\0' != *error) zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); } if (NULL != debug) zbx_json_addraw(&json, "debug", debug); (void)zbx_tcp_send(sock, json.buffer); zbx_free(params); zbx_free(message); zbx_free(subject); zbx_free(sendto); zbx_free(data); zbx_free(value); zbx_free(error); zbx_free(debug); zbx_json_free(&json); zbx_user_free(&user); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); } int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp, const zbx_config_tls_t *config_tls, const zbx_config_vault_t *config_vault, zbx_get_program_type_f get_program_type_cb, int config_timeout) { ZBX_UNUSED(config_tls); ZBX_UNUSED(get_program_type_cb); if (0 == strcmp(request, ZBX_PROTO_VALUE_REPORT_TEST)) { trapper_process_report_test(sock, jp, config_timeout); return SUCCEED; } else if (0 == strcmp(request, ZBX_PROTO_VALUE_ZABBIX_ALERT_SEND)) { trapper_process_alert_send(sock, jp); return SUCCEED; } else if (0 == strcmp(request, ZBX_PROTO_VALUE_PROXY_CONFIG)) { zbx_send_proxyconfig(sock, jp, config_vault, config_timeout); return SUCCEED; } return FAIL; }