static int zbx_execute_script_on_agent(DC_HOST *host, const char *command, char **result, char *error, size_t max_error_len) { const char *__function_name = "zbx_execute_script_on_agent"; int ret; AGENT_RESULT agent_result; char *param, *port = NULL; DC_ITEM item; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); *error = '\0'; memset(&item, 0, sizeof(item)); memcpy(&item.host, host, sizeof(item.host)); if (SUCCEED != (ret = DCconfig_get_interface_by_type(&item.interface, host->hostid, INTERFACE_TYPE_AGENT))) { zbx_snprintf(error, max_error_len, "Whatap agent interface is not defined for host [%s]", host->host); goto fail; } port = zbx_strdup(port, item.interface.port_orig); substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL, &port, MACRO_TYPE_COMMON, NULL, 0); if (SUCCEED != (ret = is_ushort(port, &item.interface.port))) { zbx_snprintf(error, max_error_len, "Invalid port number [%s]", item.interface.port_orig); goto fail; } param = zbx_dyn_escape_string(command, "\""); item.key = zbx_dsprintf(item.key, "system.run[\"%s\",\"%s\"]", param, NULL == result ? "nowait" : "wait"); item.value_type = ITEM_VALUE_TYPE_TEXT; zbx_free(param); init_result(&agent_result); alarm(CONFIG_TIMEOUT); if (SUCCEED != (ret = get_value_agent(&item, &agent_result))) { if (ISSET_MSG(&agent_result)) zbx_strlcpy(error, agent_result.msg, max_error_len); ret = FAIL; } else if (NULL != result && ISSET_TEXT(&agent_result)) *result = zbx_strdup(*result, agent_result.text); alarm(0); free_result(&agent_result); zbx_free(item.key); fail: zbx_free(port); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static int DBpatch_2010176(void) { DB_RESULT result; DB_ROW row; char *name, *name_esc; int ret = SUCCEED; result = DBselect("select scriptid,name from scripts"); while (SUCCEED == ret && NULL != (row = DBfetch(result))) { name = zbx_dyn_escape_string(row[1], "/\\"); if (0 != strcmp(name, row[1])) { name_esc = DBdyn_escape_string_len(name, 255); if (ZBX_DB_OK > DBexecute("update scripts set name='%s' where scriptid=%s", name_esc, row[0])) ret = FAIL; zbx_free(name_esc); } zbx_free(name); } DBfree_result(result); return ret; }
static void run_remote_command(char* host_name, char* command) { int ret = 9; AGENT_RESULT agent_result; DC_ITEM item; DB_RESULT result; DB_ROW row; char *p, *host_esc, *param; #ifdef HAVE_OPENIPMI int val; char error[MAX_STRING_LEN]; #endif assert(host_name); assert(command); zabbix_log(LOG_LEVEL_DEBUG, "In run_remote_command(hostname:%s,command:%s)", host_name, command); host_esc = DBdyn_escape_string(host_name); result = DBselect( "select hostid,host,useip,ip,dns,port,useipmi,ipmi_ip,ipmi_port,ipmi_authtype," "ipmi_privilege,ipmi_username,ipmi_password" " from hosts" " where status in (%d)" " and host='%s'" DB_NODE, HOST_STATUS_MONITORED, host_esc, DBnode_local("hostid")); zbx_free(host_esc); if (NULL != (row = DBfetch(result))) { memset(&item, 0, sizeof(item)); ZBX_STR2UINT64(item.host.hostid, row[0]); zbx_strlcpy(item.host.host, row[1], sizeof(item.host.host)); item.host.useip = (unsigned char)atoi(row[2]); zbx_strlcpy(item.host.ip, row[3], sizeof(item.host.ip)); zbx_strlcpy(item.host.dns, row[4], sizeof(item.host.dns)); item.host.port = (unsigned short)atoi(row[5]); p = command; while (*p == ' ' && *p != '\0') p++; #ifdef HAVE_OPENIPMI if (0 == strncmp(p, "IPMI", 4)) { if (1 == atoi(row[6])) { zbx_strlcpy(item.host.ipmi_ip_orig, row[7], sizeof(item.host.ipmi_ip)); item.host.ipmi_port = (unsigned short)atoi(row[8]); item.host.ipmi_authtype = atoi(row[9]); item.host.ipmi_privilege = atoi(row[10]); zbx_strlcpy(item.host.ipmi_username, row[11], sizeof(item.host.ipmi_username)); zbx_strlcpy(item.host.ipmi_password, row[12], sizeof(item.host.ipmi_password)); } if (SUCCEED == (ret = parse_ipmi_command(p, item.ipmi_sensor, &val))) { item.key = item.ipmi_sensor; ret = set_ipmi_control_value(&item, val, error, sizeof(error)); } } else { #endif param = zbx_dyn_escape_string(p, "\""); item.key = zbx_dsprintf(NULL, "system.run[\"%s\",\"nowait\"]", param); zbx_free(param); init_result(&agent_result); alarm(CONFIG_TIMEOUT); ret = get_value_agent(&item, &agent_result); alarm(0); free_result(&agent_result); zbx_free(item.key); #ifdef HAVE_OPENIPMI } #endif } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End run_remote_command(result:%d)", ret); }
/****************************************************************************** * * * Function: get_value_external * * * * Purpose: retrieve data from script executed on Zabbix server * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NOTSUPPORTED - requested item is not supported * * * * Author: Mike Nestor, rewritten by Alexander Vladishev * * * ******************************************************************************/ int get_value_external(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_external"; char key[MAX_STRING_LEN], params[MAX_STRING_LEN], error[ITEM_ERROR_LEN_MAX], *cmd = NULL, *buf = NULL; size_t cmd_alloc = ZBX_KIBIBYTE, cmd_offset = 0; int rc, ret = NOTSUPPORTED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __function_name, item->key_orig); if (ZBX_COMMAND_ERROR == (rc = parse_command(item->key, key, sizeof(key), params, sizeof(params)))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Key is badly formatted")); goto notsupported; } cmd = zbx_malloc(cmd, cmd_alloc); zbx_snprintf_alloc(&cmd, &cmd_alloc, &cmd_offset, "%s/%s", CONFIG_EXTERNALSCRIPTS, key); if (-1 == access(cmd, X_OK)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "%s: %s", cmd, zbx_strerror(errno))); goto notsupported; } if (ZBX_COMMAND_WITH_PARAMS == rc) { int i, n; char param[MAX_STRING_LEN], *param_esc; if (0 == (n = num_param(params))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Key is badly formatted")); goto notsupported; } for (i = 1; i <= n; i++) { if (0 != get_param(params, i, param, sizeof(param))) { THIS_SHOULD_NEVER_HAPPEN; *param = '\0'; } param_esc = zbx_dyn_escape_string(param, "\"\\"); zbx_snprintf_alloc(&cmd, &cmd_alloc, &cmd_offset, " \"%s\"", param_esc); zbx_free(param_esc); } } if (SUCCEED == zbx_execute(cmd, &buf, error, sizeof(error), CONFIG_TIMEOUT)) { zbx_rtrim(buf, ZBX_WHITESPACE); if (SUCCEED == set_result_type(result, item->value_type, item->data_type, buf)) ret = SUCCEED; zbx_free(buf); } else SET_MSG_RESULT(result, zbx_strdup(NULL, error)); notsupported: zbx_free(cmd); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: execute_action * * * * Purpose: execute an action depending on mediatype * * * * Parameters: alert - alert details * * mediatype - media details * * * * Return value: SUCCESS - action executed sucessfully * * FAIL - otherwise, error will contain error message * * * * Author: Alexei Vladishev * * * ******************************************************************************/ int execute_action(DB_ALERT *alert, DB_MEDIATYPE *mediatype, char *error, int max_error_len) { const char *__function_name = "execute_action"; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s(): alertid [" ZBX_FS_UI64 "] mediatype [%d]", __function_name, alert->alertid, mediatype->type); if (MEDIA_TYPE_EMAIL == mediatype->type) { alarm(ALARM_ACTION_TIMEOUT); res = send_email(mediatype->smtp_server, mediatype->smtp_helo, mediatype->smtp_email, alert->sendto, alert->subject, alert->message, error, max_error_len); alarm(0); } #ifdef HAVE_JABBER else if (MEDIA_TYPE_JABBER == mediatype->type) { /* Jabber uses its own timeouts */ res = send_jabber(mediatype->username, mediatype->passwd, alert->sendto, alert->subject, alert->message, error, max_error_len); } #endif else if (MEDIA_TYPE_SMS == mediatype->type) { /* SMS uses its own timeouts */ res = send_sms(mediatype->gsm_modem, alert->sendto, alert->message, error, max_error_len); } else if (MEDIA_TYPE_EZ_TEXTING == mediatype->type) { /* Ez Texting uses its own timeouts */ res = send_ez_texting(mediatype->username, mediatype->passwd, alert->sendto, alert->message, mediatype->exec_path, error, max_error_len); } else if (MEDIA_TYPE_EXEC == mediatype->type) { char full_path[MAX_STRING_LEN], *send_to, *subject, *message, *output = NULL; send_to = zbx_dyn_escape_string(alert->sendto, "\"\\"); subject = zbx_dyn_escape_string(alert->subject, "\"\\"); message = zbx_dyn_escape_string(alert->message, "\"\\"); zbx_snprintf(full_path, sizeof(full_path), "%s/%s \"%s\" \"%s\" \"%s\"", CONFIG_ALERT_SCRIPTS_PATH, mediatype->exec_path, send_to, subject, message); zbx_free(send_to); zbx_free(subject); zbx_free(message); if (SUCCEED == (res = zbx_execute(full_path, &output, error, max_error_len, ALARM_ACTION_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "%s output:\n%s", mediatype->exec_path, output); zbx_free(output); } else res = FAIL; } else { zbx_snprintf(error, max_error_len, "unsupported media type [%d]", mediatype->type); zabbix_log(LOG_LEVEL_ERR, "alert ID [" ZBX_FS_UI64 "]: %s", alert->alertid, error); zabbix_syslog("alert ID [" ZBX_FS_UI64 "]: %s", alert->alertid, error); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/* * Function: * zbx_module_vpoller() * * Purpose: * Sends task requests to vPoller for processing * * The `vpoller` key expects the following parameters * when called through Zabbix: * * vpoller[method, hostname, name, properties, <key>, <username>, <password>, <counter-name>, <instance>, <perf-interval>] * * And the parameters that it expects are these: * * method - vPoller method to be processed * hostname - VMware vSphere server hostname * name - Name of the vSphere object (e.g. VM name, ESXi name) * properties - vSphere properties to be collected * <key> - Additional information passed as a 'key' to vPoller * <username> - Username to use when logging into the guest system * <password> - Password to use when logging into the guest system * <counter-name> - Performance counter name * <instance> - Performance counter instance * <perf-interval> - Historical performance interval */ int zbx_module_vpoller(AGENT_REQUEST *request, AGENT_RESULT *result) { unsigned int i; void *zsocket = NULL; /* ZeroMQ socket */ zmq_msg_t msg_in; /* Incoming ZeroMQ message from vPoller */ char *params[PARAM_NUM]; /* Params received from Zabbix */ char *key_esc; bool got_reply = false; /* A flag to indicate whether a reply from vPoller was received or not */ int retries = CONFIG_VPOLLER_RETRIES; /* Number of retries */ int linger = 0; /* Set the ZeroMQ socket option ZMQ_LINGER to 0 */ int msg_len = 0; /* Length of the received message */ char msg_buf[MAX_BUFFER_LEN]; /* Buffer to hold the final message we send out to vPoller */ for (i = 0; i < PARAM_NUM; i++) params[i] = "(null)"; /* * The Zabbix `vpoller` key expects these parameters * in the following order: * * vpoller[method, hostname, name, properties, <key>, <username>, <password>, <counter-name>, <instance>, <perf-interval>] */ if ((request->nparam < 4) || (request->nparam > PARAM_NUM)) { SET_MSG_RESULT(result, strdup("Invalid number of arguments")); return (SYSINFO_RET_FAIL); } for (i = 0; i < request->nparam; i++) params[i] = get_rparam(request, i); /* * Create the task request which we send to vPoller */ key_esc = zbx_dyn_escape_string(params[PARAM_KEY], "\\"); zbx_snprintf(msg_buf, sizeof(msg_buf), VPOLLER_TASK_TEMPLATE, params[PARAM_METHOD], params[PARAM_HOSTNAME], params[PARAM_NAME], params[PARAM_PROPERTIES], key_esc, params[PARAM_USERNAME], params[PARAM_PASSWORD], params[PARAM_COUNTER_NAME], params[PARAM_INSTANCE], params[PARAM_PERF_INTERVAL]); zbx_free(key_esc); zabbix_log(LOG_LEVEL_DEBUG, "Creating a ZeroMQ socket for connecting to vPoller"); if ((zsocket = zmq_socket(zcontext, ZMQ_REQ)) == NULL) { SET_MSG_RESULT(result, strdup("Cannot create a ZeroMQ socket")); return (SYSINFO_RET_FAIL); } /* * Connect to the vPoller Proxy */ zabbix_log(LOG_LEVEL_DEBUG, "Connecting to vPoller endpoint at %s", CONFIG_VPOLLER_PROXY); zmq_connect(zsocket, CONFIG_VPOLLER_PROXY); zmq_setsockopt(zsocket, ZMQ_LINGER, &linger, sizeof(linger)); zmq_msg_init(&msg_in); /* * Send the task request to vPoller, using a retry mechanism */ while (retries > 0) { zabbix_log(LOG_LEVEL_DEBUG, "Sending task request to vPoller: %s", msg_buf); zmq_pollitem_t items[] = { { zsocket, 0, ZMQ_POLLIN, 0 }, }; zmq_send(zsocket, msg_buf, strlen(msg_buf), 0); zmq_poll(items, 1, CONFIG_VPOLLER_TIMEOUT); /* Do we have a reply? */ if (items[0].revents & ZMQ_POLLIN) { zabbix_log(LOG_LEVEL_DEBUG, "Received reply from vPoller"); if ((msg_len = zmq_msg_recv(&msg_in, zsocket, 0)) != -1) { got_reply = true; break; } } else { /* We didn't get a reply from the server, let's retry */ retries--; if (retries > 0) { zabbix_log(LOG_LEVEL_WARNING, "Did not receive response from vPoller, retrying..."); } else { zabbix_log(LOG_LEVEL_WARNING, "Did not receive response from vPoller, giving up."); } /* Socket is confused, close and remove it */ zabbix_log(LOG_LEVEL_DEBUG, "Closing socket and re-establishing connection to vPoller..."); zmq_close(zsocket); if ((zsocket = zmq_socket(zcontext, ZMQ_REQ)) == NULL) { SET_MSG_RESULT(result, strdup("Cannot create a ZeroMQ socket")); zmq_msg_close(&msg_in); return (SYSINFO_RET_FAIL); } zmq_connect(zsocket, CONFIG_VPOLLER_PROXY); zmq_setsockopt(zsocket, ZMQ_LINGER, &linger, sizeof(linger)); } } /* Do we have any result? */ if (got_reply == false) { zmq_msg_close(&msg_in); zmq_close(zsocket); SET_MSG_RESULT(result, strdup("Did not receive response from vPoller")); return (SYSINFO_RET_FAIL); } SET_STR_RESULT(result, strdup(zmq_msg_data(&msg_in))); zmq_msg_close(&msg_in); zmq_close(zsocket); return (SYSINFO_RET_OK); }