/* get Nth error from event log. 1 is the first. */ static int zbx_get_eventlog_message(const wchar_t *wsource, HANDLE eventlog_handle, DWORD which, char **out_source, char **out_message, unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid) { const char *__function_name = "zbx_get_eventlog_message"; int buffer_size = 512; EVENTLOGRECORD *pELR = NULL; DWORD dwRead, dwNeeded, dwErr; wchar_t *pEventMessageFile = NULL, *pParamMessageFile = NULL, *pFile = NULL, *pNextFile = NULL, *pCh, *aInsertStrings[MAX_INSERT_STRS]; HINSTANCE hLib = NULL, hParamLib = NULL; long i, err = 0; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() lastlogsize:%lu", __function_name, which); *out_source = NULL; *out_message = NULL; *out_severity = 0; *out_timestamp = 0; *out_eventid = 0; memset(aInsertStrings, 0, sizeof(aInsertStrings)); pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size); while (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which, pELR, buffer_size, &dwRead, &dwNeeded)) { if (ERROR_INSUFFICIENT_BUFFER != (dwErr = GetLastError())) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr)); goto out; } buffer_size = dwNeeded; pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size); } *out_severity = pELR->EventType; /* return event type */ *out_timestamp = pELR->TimeGenerated; /* return timestamp */ *out_eventid = pELR->EventID & 0xffff; *out_source = zbx_unicode_to_utf8((wchar_t *)(pELR + 1)); /* copy source name */ /* get message file names */ zbx_get_message_files(wsource, (wchar_t *)(pELR + 1), &pEventMessageFile, &pParamMessageFile); /* prepare insert string array */ if (0 < pELR->NumStrings) { pCh = (wchar_t *)((unsigned char *)pELR + pELR->StringOffset); for (i = 0; i < pELR->NumStrings && i < MAX_INSERT_STRS; i++) { aInsertStrings[i] = pCh; pCh += wcslen(pCh) + 1; } } err = FAIL; for (pFile = pEventMessageFile; NULL != pFile && err != SUCCEED; pFile = pNextFile) { if (NULL != (pNextFile = wcschr(pFile, TEXT(';')))) { *pNextFile = '\0'; pNextFile++; } if (NULL != (hLib = zbx_load_message_file(pFile))) { if (NULL != (*out_message = zbx_format_message(hLib, pELR->EventID, aInsertStrings))) { err = SUCCEED; if (NULL != (hParamLib = zbx_load_message_file(pParamMessageFile))) { zbx_translate_message_params(out_message, hParamLib); FreeLibrary(hParamLib); } } FreeLibrary(hLib); } } zbx_free(pEventMessageFile); zbx_free(pParamMessageFile); if (SUCCEED != err) { *out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'" " cannot be found. The local computer may not have the necessary registry" " information or message DLL files to display messages from a remote computer.", *out_eventid, NULL == *out_source ? "" : *out_source); if (0 < pELR->NumStrings) { char *buf; *out_message = zbx_strdcat(*out_message, " The following information is part of the event: "); for (i = 0, pCh = (wchar_t *)((unsigned char *)pELR + pELR->StringOffset); i < pELR->NumStrings; i++, pCh += wcslen(pCh) + 1) { if (0 < i) *out_message = zbx_strdcat(*out_message, "; "); buf = zbx_unicode_to_utf8(pCh); *out_message = zbx_strdcat(*out_message, buf); zbx_free(buf); } } } ret = SUCCEED; out: zbx_free(pELR); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/* obtain a particular message from a desired eventlog */ static int zbx_get_eventlog_message6(const wchar_t *wsource, zbx_uint64_t *which, unsigned short *out_severity, unsigned long *out_timestamp, char **out_provider, char **out_source, char **out_message, unsigned long *out_eventid, EVT_HANDLE *render_context, EVT_HANDLE *query, zbx_uint64_t *keywords) { const char *__function_name = "zbx_get_eventlog_message6"; EVT_HANDLE event_bookmark = NULL; EVT_VARIANT* renderedContent = NULL; const wchar_t *pprovider = NULL; char *tmp_str = NULL; DWORD size = DEFAULT_EVENT_CONTENT_SIZE; DWORD bookmarkedCount = 0; DWORD require = 0; const zbx_uint64_t sec_1970 = 116444736000000000; const zbx_uint64_t success_audit = 0x20000000000000; const zbx_uint64_t failure_audit = 0x10000000000000; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() EventRecordID:" ZBX_FS_UI64, __function_name, *which); if (NULL == *query) { zabbix_log(LOG_LEVEL_DEBUG, "%s() no EvtQuery handle", __function_name); goto out; } /* get the entries */ if (TRUE != EvtNext(*query, 1, &event_bookmark, INFINITE, 0, &require)) { /* The event reading query had less items than we calculated before. */ /* Either the eventlog was cleaned or our calculations were wrong. */ /* Either way we can safely abort the query by setting NULL value */ /* and returning success, which is interpreted as empty eventlog. */ if (ERROR_NO_MORE_ITEMS == GetLastError()) { ret = SUCCEED; } else { zabbix_log(LOG_LEVEL_WARNING, "EvtNext failed: %s, EventRecordID:" ZBX_FS_UI64, strerror_from_system(GetLastError()), *which); } goto out; } /* obtain the information from the selected events */ renderedContent = (EVT_VARIANT *)zbx_malloc((void *)renderedContent, size); if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent, &require, &bookmarkedCount)) { /* information exceeds the space allocated */ if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed: %s", strerror_from_system(GetLastError())); goto out; } renderedContent = (EVT_VARIANT *)zbx_realloc((void *)renderedContent, require); size = require; if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent, &require, &bookmarkedCount)) { zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed: %s", strerror_from_system(GetLastError())); goto out; } } pprovider = VAR_PROVIDER_NAME(renderedContent); *out_provider = zbx_unicode_to_utf8(pprovider); if (NULL != VAR_SOURCE_NAME(renderedContent)) { *out_source = zbx_unicode_to_utf8(VAR_SOURCE_NAME(renderedContent)); } *keywords = VAR_KEYWORDS(renderedContent) & (success_audit | failure_audit); *out_severity = VAR_LEVEL(renderedContent); *out_timestamp = (unsigned long)((VAR_TIME_CREATED(renderedContent) - sec_1970) / 10000000); *out_eventid = VAR_EVENT_ID(renderedContent); *out_message = expand_message6(pprovider, event_bookmark); tmp_str = zbx_unicode_to_utf8(wsource); if (VAR_RECORD_NUMBER(renderedContent) != *which) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Overwriting expected EventRecordID:" ZBX_FS_UI64 " with the real" " EventRecordID:" ZBX_FS_UI64 " in eventlog '%s'", __function_name, *which, VAR_RECORD_NUMBER(renderedContent), tmp_str); *which = VAR_RECORD_NUMBER(renderedContent); } /* some events don't have enough information for making event message */ if (NULL == *out_message) { *out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'" " cannot be found. Either the component that raises this event is not installed" " on your local computer or the installation is corrupted. You can install or repair" " the component on the local computer. If the event originated on another computer," " the display information had to be saved with the event.", *out_eventid, NULL == *out_provider ? "" : *out_provider); if (EvtVarTypeString == (VAR_EVENT_DATA_TYPE(renderedContent) & EVT_VARIANT_TYPE_MASK)) { unsigned int i; char *data = NULL; if (0 != (VAR_EVENT_DATA_TYPE(renderedContent) & EVT_VARIANT_TYPE_ARRAY) && 0 < VAR_EVENT_DATA_COUNT(renderedContent)) { *out_message = zbx_strdcatf(*out_message, " The following information was included" " with the event: "); for (i = 0; i < VAR_EVENT_DATA_COUNT(renderedContent); i++) { if (NULL != VAR_EVENT_DATA_STRING_ARRAY(renderedContent, i)) { if (0 < i) *out_message = zbx_strdcat(*out_message, "; "); data = zbx_unicode_to_utf8(VAR_EVENT_DATA_STRING_ARRAY(renderedContent, i)); *out_message = zbx_strdcatf(*out_message, "%s", data); zbx_free(data); } } } else if (NULL != VAR_EVENT_DATA_STRING(renderedContent)) { data = zbx_unicode_to_utf8(VAR_EVENT_DATA_STRING(renderedContent)); *out_message = zbx_strdcatf(*out_message, "The following information was included" " with the event: %s", data); zbx_free(data); } } } ret = SUCCEED; out: if (NULL != event_bookmark) EvtClose(event_bookmark); zbx_free(tmp_str); zbx_free(renderedContent); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: load_modules * * * * Purpose: load loadable modules (dynamic libraries) * * It skips a module in case of any errors * * * * Parameters: path - directory where modules are located * * file_names - list of module names * * timeout - timeout in seconds for processing of items by module * * verbose - output list of loaded modules * * * * Return value: SUCCEED - all modules is successfully loaded * * FAIL - loading of modules failed * * * ******************************************************************************/ int load_modules(const char *path, char **file_names, int timeout, int verbose) { const char *__function_name = "load_modules"; char **file_name, *buffer = NULL; void *lib; char full_name[MAX_STRING_LEN], error[MAX_STRING_LEN]; int (*func_init)(), (*func_version)(); ZBX_METRIC *(*func_list)(); void (*func_timeout)(); int i, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); for (file_name = file_names; NULL != *file_name; file_name++) { zbx_snprintf(full_name, sizeof(full_name), "%s/%s", path, *file_name); zabbix_log(LOG_LEVEL_DEBUG, "loading module \"%s\"", full_name); if (NULL == (lib = dlopen(full_name, RTLD_NOW))) { zabbix_log(LOG_LEVEL_CRIT, "cannot load module \"%s\": %s", *file_name, dlerror()); goto fail; } *(void **)(&func_version) = dlsym(lib, ZBX_MODULE_FUNC_API_VERSION); if (NULL == func_version) { zabbix_log(LOG_LEVEL_CRIT, "cannot find \"" ZBX_MODULE_FUNC_API_VERSION "()\"" " function in module \"%s\": %s", *file_name, dlerror()); dlclose(lib); goto fail; } if (ZBX_MODULE_API_VERSION_ONE != (i = func_version())) { zabbix_log(LOG_LEVEL_CRIT, "unsupported module \"%s\" version: %d", *file_name, i); dlclose(lib); goto fail; } *(void **)(&func_init) = dlsym(lib, ZBX_MODULE_FUNC_INIT); if (NULL == func_init) { zabbix_log(LOG_LEVEL_CRIT, "cannot find \"" ZBX_MODULE_FUNC_INIT "()\"" " function in module \"%s\": %s", *file_name, dlerror()); dlclose(lib); goto fail; } if (ZBX_MODULE_OK != func_init()) { zabbix_log(LOG_LEVEL_CRIT, "cannot initialize module \"%s\"", *file_name); dlclose(lib); goto fail; } /* the function is optional, zabbix will load the module ieven if it is missing */ *(void **)(&func_timeout) = dlsym(lib, ZBX_MODULE_FUNC_ITEM_TIMEOUT); if (NULL == func_timeout) { zabbix_log(LOG_LEVEL_DEBUG, "cannot find \"" ZBX_MODULE_FUNC_ITEM_TIMEOUT "()\"" " function in module \"%s\": %s", *file_name, dlerror()); } else func_timeout(timeout); *(void **)(&func_list) = dlsym(lib, ZBX_MODULE_FUNC_ITEM_LIST); if (NULL == func_list) { zabbix_log(LOG_LEVEL_WARNING, "cannot find \"" ZBX_MODULE_FUNC_ITEM_LIST "()\"" " function in module \"%s\": %s", *file_name, dlerror()); dlclose(lib); continue; } if (SUCCEED == register_module(lib)) { ZBX_METRIC *metrics; metrics = func_list(); for (i = 0; NULL != metrics[i].key; i++) { /* accept only CF_HAVEPARAMS flag from module items */ metrics[i].flags &= CF_HAVEPARAMS; /* the flag means that the items comes from a loadable module */ metrics[i].flags |= CF_MODULE; if (SUCCEED != add_metric(&metrics[i], error, sizeof(error))) { zabbix_log(LOG_LEVEL_CRIT, "cannot load module \"%s\": %s", *file_name, error); exit(EXIT_FAILURE); } } if (1 == verbose) { if (NULL != buffer) buffer = zbx_strdcat(buffer, ", "); buffer = zbx_strdcat(buffer, *file_name); } } } if (NULL != buffer) zabbix_log(LOG_LEVEL_WARNING, "loaded modules: %s", buffer); ret = SUCCEED; fail: zbx_free(buffer); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int EXECUTE_STR(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(_WINDOWS) STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; SECURITY_ATTRIBUTES sa; HANDLE hWrite=NULL, hRead=NULL; #else /* not _WINDOWS */ FILE *hRead = NULL; #endif /* _WINDOWS */ int ret = SYSINFO_RET_FAIL; char stat_buf[128]; char *cmd_result=NULL; char *command=NULL; int len; assert(result); init_result(result); cmd_result = zbx_dsprintf(cmd_result,""); memset(stat_buf, 0, sizeof(stat_buf)); #if defined(_WINDOWS) /* Set the bInheritHandle flag so pipe handles are inherited */ sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; /* Create a pipe for the child process's STDOUT */ if (! CreatePipe(&hRead, &hWrite, &sa, sizeof(cmd_result))) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to create pipe [%s]", strerror_from_system(GetLastError())); ret = SYSINFO_RET_FAIL; goto lbl_exit; } /* Fill in process startup info structure */ memset(&si,0,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = hWrite; si.hStdError = hWrite; command = zbx_dsprintf(command, "cmd /C \"%s\"", param); /* Create new process */ if (!CreateProcess(NULL,command,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to create process: '%s' [%s]", command, strerror_from_system(GetLastError())); ret = SYSINFO_RET_FAIL; goto lbl_exit; } CloseHandle(hWrite); hWrite = NULL; /* Read process output */ while( ReadFile(hRead, stat_buf, sizeof(stat_buf)-1, &len, NULL) && len > 0 ) { cmd_result = zbx_strdcat(cmd_result, stat_buf); memset(stat_buf, 0, sizeof(stat_buf)); } /* Don't wait child process exiting. */ /* WaitForSingleObject( pi.hProcess, INFINITE ); */ /* Terminate child process */ /* TerminateProcess(pi.hProcess, 0); */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(hRead); hRead = NULL; #else /* not _WINDOWS */ command = zbx_dsprintf(command, "%s", param); if(0 == (hRead = popen(command,"r"))) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } ; /* Read process output */ while( (len = fread(stat_buf, 1, sizeof(stat_buf)-1, hRead)) > 0 ) { cmd_result = zbx_strdcat(cmd_result, stat_buf); memset(stat_buf, 0, sizeof(stat_buf)); } if(0 != ferror(hRead)) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } if(pclose(hRead) == -1) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } hRead = NULL; #endif /* _WINDOWS */ zabbix_log(LOG_LEVEL_DEBUG, "Before"); zbx_rtrim(cmd_result,"\n\r\0"); /* We got EOL only */ if(cmd_result[0] == '\0') { ret = SYSINFO_RET_FAIL; goto lbl_exit; } zabbix_log(LOG_LEVEL_DEBUG, "Run remote command [%s] Result [%d] [%.20s]...", command, strlen(cmd_result), cmd_result); SET_TEXT_RESULT(result, strdup(cmd_result)); ret = SYSINFO_RET_OK; lbl_exit: #if defined(_WINDOWS) if ( hWrite ) { CloseHandle(hWrite); hWrite = NULL; } if ( hRead) { CloseHandle(hRead); hRead = NULL; } #else /* not _WINDOWS */ if ( hRead ) { pclose(hRead); hRead = NULL; } #endif /* _WINDOWS */ zbx_free(command) zbx_free(cmd_result); return ret; }
/****************************************************************************** * * * Function: comms_create_request * * * * Purpose: dinamical xml request generation * * * * Return value: XML request * * * * Author: Eugene Grigorjev * * * * Comments: required free allocated string with function 'zbx_free' * * * ******************************************************************************/ char* comms_create_request( const char *host, const char *key, const char *data, const char *error, long *lastlogsize, unsigned long *timestamp, const char *source, unsigned short *severity ) { #define ADD_XML_DATA(tag_name, var) \ data_b64[0] = '\0'; \ str_base64_encode(var, data_b64, (int)strlen(var)); \ request = zbx_strdcatf(request, "<" tag_name ">%s</" tag_name ">", data_b64) char data_b64[ZBX_MAX_B64_LEN]; char *tmp_str = NULL; char *request = NULL; assert(host); assert(key); assert(data); /* zabbix_log(LOG_LEVEL_DEBUG, "comms_create_request host [%s] key [%s] data [%s]",host,key,data); */ memset(data_b64,0,sizeof(data_b64)); request = zbx_dsprintf(NULL,"%s", "<req>"); ADD_XML_DATA("host", host); ADD_XML_DATA("key", key); ADD_XML_DATA("data", data); if (error) { ADD_XML_DATA ("error", error); } if(lastlogsize) { tmp_str = zbx_dsprintf(NULL, "%li", *lastlogsize); ADD_XML_DATA("lastlogsize", tmp_str); zbx_free(tmp_str); } if(timestamp) { assert(source); assert(severity); tmp_str = zbx_dsprintf(NULL, "%lu", *timestamp); ADD_XML_DATA("timestamp", tmp_str); zbx_free(tmp_str); ADD_XML_DATA("source", source); tmp_str = zbx_dsprintf(NULL, "%u", *severity); ADD_XML_DATA("severity", tmp_str); zbx_free(tmp_str); } return zbx_strdcat(request, "</req>"); }
char* comms_finish_multi_request (char* request) { return zbx_strdcat (request, "</values><reqs>"); }
static int read_initial_buffer () { unsigned long sig; unsigned int i, j, len; int index; char c; char buf[1024]; zabbix_log (LOG_LEVEL_DEBUG, "read_initial_buffer"); /* check signature */ if (!fread (&sig, sizeof (sig), 1, buffer.file)) return 0; if (sig != buffer_signature) return 0; if (fread (&buffer.size, sizeof (unsigned int), 1, buffer.file) != 1) return 0; if (!buffer.size) /* read finished, there are no items in buffer */ return 1; zabbix_log (LOG_LEVEL_DEBUG, "Reading %d items of history from buffer", buffer.size); buffer.entries = (buffer_check_entry_t*)calloc (buffer.size, sizeof (buffer_check_entry_t)); if (!buffer.entries) { buffer.size = 0; return 1; } for (i = 0; i < buffer.size; i++) { buffer.entries[i].key = NULL; len = 0; while ((c = fgetc (buffer.file))) { buf[len++] = c; if (len == 1023) { buf[len] = 0; buffer.entries[i].key = zbx_strdcat (buffer.entries[i].key, buf); len = 0; } } if (len) { buf[len] = 0; buffer.entries[i].key = zbx_strdcat (buffer.entries[i].key, buf); } fread (&buffer.entries[i].refresh, sizeof (int), 1, buffer.file); fread (&buffer.entries[i].beg_offset, sizeof (size_t), 1, buffer.file); fread (&buffer.entries[i].max_offset, sizeof (size_t), 1, buffer.file); fread (&buffer.entries[i].max_items, sizeof (int), 1, buffer.file); buffer.entries[i].sizes = (unsigned short*)malloc (buffer.entries[i].max_items * sizeof (unsigned short)); fread (buffer.entries[i].sizes, sizeof (unsigned short), buffer.entries[i].max_items, buffer.file); /* find index (hm-hm) and item's count */ index = -1; buffer.entries[i].count = 0; buffer.entries[i].index = 0; for (j = 0; j < buffer.entries[i].max_items; j++) { if (!buffer.entries[i].sizes[j]) { if (index < 0) index = j; } else buffer.entries[i].count++; } if (index >= 0) buffer.entries[i].index = index; zabbix_log (LOG_LEVEL_DEBUG, "Read item history. Key %s, refresh %d, len: %lu, items: %d, index: %d, count: %d", buffer.entries[i].key, buffer.entries[i].refresh, buffer.entries[i].max_offset - buffer.entries[i].beg_offset, buffer.entries[i].max_items, buffer.entries[i].index, buffer.entries[i].count); } return 1; }