int SERVICE_STATE(AGENT_REQUEST *request, AGENT_RESULT *result) { SC_HANDLE mgr, service; char *name; wchar_t *wname; wchar_t service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; int i; SERVICE_STATUS status; if (1 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); service = OpenService(mgr, wname, SERVICE_QUERY_STATUS); if (NULL == service && 0 != GetServiceKeyName(mgr, wname, service_name, &max_len_name)) service = OpenService(mgr, service_name, SERVICE_QUERY_STATUS); zbx_free(wname); if (NULL == service) { SET_UI64_RESULT(result, 255); } else { if (0 != QueryServiceStatus(service, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); CloseServiceHandle(service); } CloseServiceHandle(mgr); return SYSINFO_RET_OK; }
static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_answer) { #if defined(HAVE_RES_QUERY) || defined(_WINDOWS) size_t offset = 0; int res, type, retrans, retry, use_tcp, i, ret = SYSINFO_RET_FAIL; char *ip, zone[MAX_STRING_LEN], buffer[MAX_STRING_LEN], *zone_str, *param; struct in_addr inaddr; #ifndef _WINDOWS int saved_nscount = 0, saved_retrans, saved_retry; unsigned long saved_options; struct sockaddr_in saved_ns; #endif typedef struct { char *name; int type; } resolv_querytype_t; static const resolv_querytype_t qt[] = { {"ANY", T_ANY}, {"A", T_A}, {"NS", T_NS}, {"MD", T_MD}, {"MF", T_MF}, {"CNAME", T_CNAME}, {"SOA", T_SOA}, {"MB", T_MB}, {"MG", T_MG}, {"MR", T_MR}, {"NULL", T_NULL}, #ifndef _WINDOWS {"WKS", T_WKS}, #endif {"PTR", T_PTR}, {"HINFO", T_HINFO}, {"MINFO", T_MINFO}, {"MX", T_MX}, {"TXT", T_TXT}, {"SRV", T_SRV}, {NULL} }; #ifdef _WINDOWS PDNS_RECORD pQueryResults, pDnsRecord; wchar_t *wzone; char tmp2[MAX_STRING_LEN], tmp[MAX_STRING_LEN]; DWORD options; #else char *name; unsigned char *msg_end, *msg_ptr, *p; int num_answers, num_query, q_type, q_class, q_len, value, c, n; struct servent *s; HEADER *hp; struct protoent *pr; #if PACKETSZ > 1024 unsigned char buf[PACKETSZ]; #else unsigned char buf[1024]; #endif typedef union { HEADER h; #if defined(NS_PACKETSZ) unsigned char buffer[NS_PACKETSZ]; #elif defined(PACKETSZ) unsigned char buffer[PACKETSZ]; #else unsigned char buffer[512]; #endif } answer_t; answer_t answer; #endif /* _WINDOWS */ *buffer = '\0'; if (6 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } ip = get_rparam(request, 0); zone_str = get_rparam(request, 1); if (NULL == zone_str || '\0' == *zone_str) strscpy(zone, "zabbix.com"); else strscpy(zone, zone_str); param = get_rparam(request, 2); if (NULL == param || '\0' == *param) type = T_SOA; else { for (i = 0; NULL != qt[i].name; i++) { if (0 == strcasecmp(qt[i].name, param)) { type = qt[i].type; break; } } if (NULL == qt[i].name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } } param = get_rparam(request, 3); if (NULL == param || '\0' == *param) retrans = 1; else if (SUCCEED != is_uint31(param, &retrans) || 0 == retrans) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter.")); return SYSINFO_RET_FAIL; } param = get_rparam(request, 4); if (NULL == param || '\0' == *param) retry = 2; else if (SUCCEED != is_uint31(param, &retry) || 0 == retry) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter.")); return SYSINFO_RET_FAIL; } param = get_rparam(request, 5); if (NULL == param || '\0' == *param || 0 == strcmp(param, "udp")) use_tcp = 0; else if (0 == strcmp(param, "tcp")) use_tcp = 1; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter.")); return SYSINFO_RET_FAIL; } #ifdef _WINDOWS options = DNS_QUERY_STANDARD | DNS_QUERY_BYPASS_CACHE; if (0 != use_tcp) options |= DNS_QUERY_USE_TCP_ONLY; wzone = zbx_utf8_to_unicode(zone); res = DnsQuery(wzone, type, options, NULL, &pQueryResults, NULL); zbx_free(wzone); if (1 == short_answer) { SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1); ret = SYSINFO_RET_OK; goto clean; } if (DNS_RCODE_NOERROR != res) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot perform DNS query: [%d]", res)); return SYSINFO_RET_FAIL; } pDnsRecord = pQueryResults; while (NULL != pDnsRecord) { if (DnsSectionAnswer != pDnsRecord->Flags.S.Section) { pDnsRecord = pDnsRecord->pNext; continue; } if (NULL == pDnsRecord->pName) goto clean; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp))); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(pDnsRecord->wType)); switch (pDnsRecord->wType) { case T_A: inaddr.s_addr = pDnsRecord->Data.A.IpAddress; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; case T_NS: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp))); break; case T_MD: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp))); break; case T_MF: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp))); break; case T_CNAME: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp))); break; case T_SOA: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu", zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)), pDnsRecord->Data.SOA.dwSerialNo, pDnsRecord->Data.SOA.dwRefresh, pDnsRecord->Data.SOA.dwRetry, pDnsRecord->Data.SOA.dwExpire, pDnsRecord->Data.SOA.dwDefaultTtl); break; case T_MB: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp))); break; case T_MG: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp))); break; case T_MR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp))); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu", pDnsRecord->Data.Null.dwByteCount); break; case T_PTR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp))); break; case T_HINFO: for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"", zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp))); break; case T_MINFO: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2))); break; case T_MX: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s", pDnsRecord->Data.MX.wPreference, zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp))); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ", zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp))); if (0 < i) offset -= 1; /* remove the trailing space */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s", pDnsRecord->Data.SRV.wPriority, pDnsRecord->Data.SRV.wWeight, pDnsRecord->Data.SRV.wPort, zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp))); break; default: break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); pDnsRecord = pDnsRecord->pNext; } #else /* not _WINDOWS */ if (-1 == res_init()) /* initialize always, settings might have changed */ { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot initialize DNS subsystem: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot create DNS query: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } if (NULL != ip && '\0' != *ip) { if (0 == inet_aton(ip, &inaddr)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IP address.")); return SYSINFO_RET_FAIL; } memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; _res.nsaddr_list[0].sin_addr = inaddr; _res.nsaddr_list[0].sin_family = AF_INET; _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); _res.nscount = 1; } saved_options = _res.options; saved_retrans = _res.retrans; saved_retry = _res.retry; if (0 != use_tcp) _res.options |= RES_USEVC; _res.retrans = retrans; _res.retry = retry; res = res_send(buf, res, answer.buffer, sizeof(answer.buffer)); _res.options = saved_options; _res.retrans = saved_retrans; _res.retry = saved_retry; if (NULL != ip && '\0' != *ip) { memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in)); _res.nscount = saved_nscount; } hp = (HEADER *)answer.buffer; if (1 == short_answer) { SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1); return SYSINFO_RET_OK; } if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot perform DNS query.")); return SYSINFO_RET_FAIL; } msg_end = answer.buffer + res; num_answers = ntohs(answer.h.ancount); num_query = ntohs(answer.h.qdcount); msg_ptr = answer.buffer + HFIXEDSZ; /* skipping query records */ for (; 0 < num_query && msg_ptr < msg_end; num_query--) msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; for (; 0 < num_answers && msg_ptr < msg_end; num_answers--) { if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name); GETSHORT(q_type, msg_ptr); GETSHORT(q_class, msg_ptr); msg_ptr += INT32SZ; /* skipping TTL */ GETSHORT(q_len, msg_ptr); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type)); switch (q_type) { case T_A: switch (q_class) { case C_IN: case C_HS: memcpy(&inaddr, msg_ptr, INADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; default: ; } msg_ptr += q_len; break; case T_NS: case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_PTR: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_MX: GETSHORT(value, msg_ptr); /* preference */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_SOA: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); GETLONG(value, msg_ptr); /* serial number */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* refresh time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* retry time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* expire time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* minimum TTL */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len); msg_ptr += q_len; break; case T_WKS: if (INT32SZ + 1 > q_len) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } p = msg_ptr + q_len; memcpy(&inaddr, msg_ptr, INADDRSZ); msg_ptr += INT32SZ; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); if (NULL != (pr = getprotobynumber(*msg_ptr))) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr); msg_ptr++; n = 0; while (msg_ptr < p) { c = *msg_ptr++; do { if (0 != (c & 0200)) { s = getservbyport((int)htons(n), pr ? pr->p_name : NULL); if (NULL != s) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n); } c <<= 1; } while (0 != (++n & 07)); } break; case T_HINFO: p = msg_ptr + q_len; c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } if (msg_ptr < p) { c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } } break; case T_MINFO: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); p = msg_ptr + q_len; while (msg_ptr < p) { for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++); } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: GETSHORT(value, msg_ptr); /* priority */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* weight */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* port */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; default: msg_ptr += q_len; break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); } #endif /* _WINDOWS */ if (0 != offset) buffer[--offset] = '\0'; SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); ret = SYSINFO_RET_OK; #ifdef _WINDOWS clean: if (DNS_RCODE_NOERROR == res) DnsRecordListFree(pQueryResults, DnsFreeRecordList); #endif return ret; #else /* both HAVE_RES_QUERY and _WINDOWS not defined */ return SYSINFO_RET_FAIL; #endif /* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */ }
static int zbx_get_eventlog_message_xpath(LPCTSTR wsource, zbx_uint64_t *lastlogsize, char **out_source, char **out_message, unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid, unsigned char skip_old_data, void **pcontext) { const char *__function_name = "zbx_get_eventlog_message_xpath"; int ret = FAIL; LPSTR tmp_str = NULL; LPWSTR tmp_wstr = NULL; LPWSTR event_query = NULL; /* L"Event/System[EventRecordID=WHICH]" */ unsigned long status = ERROR_SUCCESS; PEVT_VARIANT eventlog_array = NULL; HANDLE providermetadata_handle = NULL; LPWSTR query_array[] = { L"/Event/System/Provider/@Name", L"/Event/System/EventID", L"/Event/System/Level", L"/Event/System/TimeCreated/@SystemTime", L"/Event/System/EventRecordID"}; DWORD array_count = 5; DWORD dwReturned = 0, dwValuesCount = 0, dwBufferSize = 0; const ULONGLONG sec_1970 = 116444736000000000; static HMODULE hmod_wevtapi = NULL; zbx_eventlog_context *context; assert(out_source); assert(out_message); assert(out_severity); assert(out_timestamp); assert(out_eventid); zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%lld", __function_name, *lastlogsize); *out_source = NULL; *out_message = NULL; *out_severity = 0; *out_timestamp = 0; *out_eventid = 0; /* We have to use LoadLibrary() to load wevtapi.dll to avoid it required even before Vista. */ /* load wevtapi.dll once */ if (NULL == hmod_wevtapi) { hmod_wevtapi = LoadLibrary(L"wevtapi.dll"); if (NULL == hmod_wevtapi) { zabbix_log(LOG_LEVEL_WARNING, "Can't load wevtapi.dll"); goto finish; } zabbix_log(LOG_LEVEL_DEBUG, "wevtapi.dll was loaded"); /* get function pointer from wevtapi.dll */ (FARPROC)EvtQuery = GetProcAddress(hmod_wevtapi, "EvtQuery"); (FARPROC)EvtCreateRenderContext = GetProcAddress(hmod_wevtapi, "EvtCreateRenderContext"); (FARPROC)EvtNext = GetProcAddress(hmod_wevtapi, "EvtNext"); (FARPROC)EvtRender = GetProcAddress(hmod_wevtapi, "EvtRender"); (FARPROC)EvtOpenPublisherMetadata = GetProcAddress(hmod_wevtapi, "EvtOpenPublisherMetadata"); (FARPROC)EvtFormatMessage = GetProcAddress(hmod_wevtapi, "EvtFormatMessage"); (FARPROC)EvtClose = GetProcAddress(hmod_wevtapi, "EvtClose"); if (NULL == EvtQuery || NULL == EvtCreateRenderContext || NULL == EvtNext || NULL == EvtRender || NULL == EvtOpenPublisherMetadata || NULL == EvtFormatMessage || NULL == EvtClose) { zabbix_log(LOG_LEVEL_WARNING, "Can't load wevtapi.dll functions"); goto finish; } zabbix_log(LOG_LEVEL_DEBUG, "wevtapi.dll functions were loaded"); } context = *pcontext; if (context == NULL) { context = zbx_malloc(NULL, sizeof(*context)); memset(context, 0, sizeof(*context)); tmp_str = zbx_dsprintf(NULL, "Event/System[EventRecordID>%lld]", *lastlogsize); event_query = zbx_utf8_to_unicode(tmp_str); zbx_free(tmp_str); context->handle = EvtQuery(NULL, wsource, event_query, skip_old_data? EvtQueryChannelPath|EvtQueryReverseDirection: EvtQueryChannelPath); if (NULL == context->handle) { status = GetLastError(); if (ERROR_EVT_CHANNEL_NOT_FOUND == status) { zabbix_log(LOG_LEVEL_WARNING, "Missed eventlog"); } else { zabbix_log(LOG_LEVEL_WARNING, "EvtQuery failed"); } goto finish; } context->context_handle = EvtCreateRenderContext(array_count, (LPCWSTR*)query_array, EvtRenderContextValues); if (NULL == context->context_handle) { zabbix_log(LOG_LEVEL_WARNING, "EvtCreateRenderContext failed"); goto finish; } *pcontext = context; } if (context->each_handle) { EvtClose(context->each_handle); context->each_handle = NULL; } if (!EvtNext(context->handle, 1, &context->each_handle, INFINITE, 0, &dwReturned)) { status = GetLastError(); if (ERROR_NO_MORE_ITEMS == status) { zabbix_log(LOG_LEVEL_DEBUG, "EvtNext no more items."); ret = SUCCEED; } else { zabbix_log(LOG_LEVEL_WARNING, "First EvtNext failed with %lu", status); } goto finish; } if (!EvtRender(context->context_handle, context->each_handle, EvtRenderEventValues, dwBufferSize, eventlog_array, &dwReturned, &dwValuesCount)) { if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError())) { dwBufferSize = dwReturned; if (NULL == (eventlog_array = (PEVT_VARIANT)zbx_malloc(eventlog_array, dwBufferSize))) { zabbix_log(LOG_LEVEL_WARNING, "EvtRender malloc failed"); goto finish; } if (!EvtRender(context->context_handle, context->each_handle, EvtRenderEventValues, dwBufferSize, eventlog_array, &dwReturned, &dwValuesCount)) { zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed"); goto finish; } } if (ERROR_SUCCESS != (status = GetLastError())) { zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed with %d", status); goto finish; } } *out_source = zbx_unicode_to_utf8(eventlog_array[0].StringVal); providermetadata_handle = EvtOpenPublisherMetadata(NULL, eventlog_array[0].StringVal, NULL, 0, 0); if (NULL != providermetadata_handle) { dwBufferSize = 0; dwReturned = 0; if (!EvtFormatMessage(providermetadata_handle, context->each_handle, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, tmp_wstr, &dwReturned)) { if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError())) { dwBufferSize = dwReturned; if (NULL == (tmp_wstr = (LPWSTR)zbx_malloc(tmp_wstr, dwBufferSize * sizeof(WCHAR)))) { zabbix_log(LOG_LEVEL_WARNING, "EvtFormatMessage malloc failed"); goto finish; } if (!EvtFormatMessage(providermetadata_handle, context->each_handle, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, tmp_wstr, &dwReturned)) { zabbix_log(LOG_LEVEL_WARNING, "EvtFormatMessage failed"); goto finish; } } if (ERROR_SUCCESS != (status = GetLastError())) { zabbix_log(LOG_LEVEL_WARNING, "EvtFormatMessage failed with %d", status); goto finish; } } *out_message= zbx_unicode_to_utf8(tmp_wstr); } else { zabbix_log(LOG_LEVEL_DEBUG, "EvtOpenPublisherMetadata failed with %d: no description availabel", GetLastError()); *out_message = zbx_strdup(NULL, ""); } *out_eventid = eventlog_array[1].UInt16Val; *out_severity = eventlog_array[2].ByteVal; *out_timestamp = (unsigned long)((eventlog_array[3].FileTimeVal - sec_1970) / 10000000); *lastlogsize = eventlog_array[4].UInt64Val; ret = SUCCEED; finish: zbx_free(tmp_str); zbx_free(tmp_wstr); zbx_free(event_query); zbx_free(eventlog_array); if (FAIL == ret) { zbx_free(*out_source); zbx_free(*out_message); } if (providermetadata_handle) EvtClose(providermetadata_handle); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int SERVICE_INFO(AGENT_REQUEST *request, AGENT_RESULT *result) { QUERY_SERVICE_CONFIG *qsc = NULL; SERVICE_DESCRIPTION *scd = NULL; SERVICE_STATUS status; SC_HANDLE h_mgr, h_srv; DWORD sz = 0; int param_type, i; char *name, *param; wchar_t *wname, service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == param || '\0' == *param || 0 == strcmp(param, "state")) /* default second parameter */ param_type = ZBX_SRV_PARAM_STATE; else if (0 == strcmp(param, "displayname")) param_type = ZBX_SRV_PARAM_DISPLAYNAME; else if (0 == strcmp(param, "path")) param_type = ZBX_SRV_PARAM_PATH; else if (0 == strcmp(param, "user")) param_type = ZBX_SRV_PARAM_USER; else if (0 == strcmp(param, "startup")) param_type = ZBX_SRV_PARAM_STARTUP; else if (0 == strcmp(param, "description")) param_type = ZBX_SRV_PARAM_DESCRIPTION; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); h_srv = OpenService(h_mgr, wname, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); if (NULL == h_srv && 0 != GetServiceKeyName(h_mgr, wname, service_name, &max_len_name)) h_srv = OpenService(h_mgr, service_name, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); zbx_free(wname); if (NULL == h_srv) { int ret; if (ZBX_SRV_PARAM_STATE == param_type) { SET_UI64_RESULT(result, 255); ret = SYSINFO_RET_OK; } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot find the specified service.")); ret = SYSINFO_RET_FAIL; } CloseServiceHandle(h_mgr); return ret; } if (ZBX_SRV_PARAM_STATE == param_type) { if (0 != QueryServiceStatus(h_srv, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); } else if (ZBX_SRV_PARAM_DESCRIPTION == param_type) { QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz); if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); zbx_free(scd); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } if (NULL == scd->lpDescription) SET_TEXT_RESULT(result, zbx_strdup(NULL, "")); else SET_TEXT_RESULT(result, zbx_unicode_to_utf8(scd->lpDescription)); zbx_free(scd); } else { QueryServiceConfig(h_srv, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz); if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); zbx_free(qsc); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } switch (param_type) { case ZBX_SRV_PARAM_DISPLAYNAME: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpDisplayName)); break; case ZBX_SRV_PARAM_PATH: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpBinaryPathName)); break; case ZBX_SRV_PARAM_USER: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpServiceStartName)); break; case ZBX_SRV_PARAM_STARTUP: if (SERVICE_AUTO_START == qsc->dwStartType) { if (SUCCEED == check_delayed_start(h_srv)) SET_UI64_RESULT(result, 1); else SET_UI64_RESULT(result, 0); } else { for (i = 2; i < ARRSIZE(start_types) && qsc->dwStartType != start_types[i]; i++) ; SET_UI64_RESULT(result, i); } break; } zbx_free(qsc); } CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_OK; }
/****************************************************************************** * * * Function: zbx_execute_nowait * * * * Purpose: this function executes a script in the background and * * suppresses the std output * * * * Parameters: command - [IN] command for execution * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ int zbx_execute_nowait(const char *command) { #ifdef _WINDOWS const char *__function_name = "zbx_execute_nowait"; char *full_command; STARTUPINFO si; PROCESS_INFORMATION pi; wchar_t *wcommand; full_command = zbx_dsprintf(NULL, "cmd /C \"%s\"", command); wcommand = zbx_utf8_to_unicode(full_command); /* fill in process startup info structure */ memset(&si, 0, sizeof(si)); si.cb = sizeof(si); GetStartupInfo(&si); zabbix_log(LOG_LEVEL_DEBUG, "%s(): executing [%s]", __function_name, full_command); if (0 == CreateProcess( NULL, /* no module name (use command line) */ wcommand, /* name of app to launch */ NULL, /* default process security attributes */ NULL, /* default thread security attributes */ FALSE, /* do not inherit handles from the parent */ 0, /* normal priority */ NULL, /* use the same environment as the parent */ NULL, /* launch in the current directory */ &si, /* startup information */ &pi)) /* process information stored upon return */ { zabbix_log(LOG_LEVEL_WARNING, "failed to create process for [%s]: %s", full_command, strerror_from_system(GetLastError())); return FAIL; } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); zbx_free(wcommand); zbx_free(full_command); return SUCCEED; #else /* not _WINDOWS */ pid_t pid; /* use a double fork for running the command in background */ if (-1 == (pid = zbx_fork())) { zabbix_log(LOG_LEVEL_WARNING, "first fork() failed for executing [%s]: %s", command, zbx_strerror(errno)); return FAIL; } else if (0 != pid) { waitpid(pid, NULL, 0); return SUCCEED; } /* This is the child process. Now create a grand child process which */ /* will be replaced by execl() with the actual command to be executed. */ pid = zbx_fork(); switch (pid) { case -1: zabbix_log(LOG_LEVEL_WARNING, "second fork() failed for executing [%s]: %s", command, zbx_strerror(errno)); break; case 0: /* this is the grand child process */ /* suppress the output of the executed script, otherwise */ /* the output might get written to a logfile or elsewhere */ redirect_std(NULL); /* replace the process with actual command to be executed */ execl("/bin/sh", "sh", "-c", command, NULL); /* execl() returns only when an error occurs */ zabbix_log(LOG_LEVEL_WARNING, "execl() failed for [%s]: %s", command, zbx_strerror(errno)); break; default: /* this is the child process, exit to complete the double fork */ waitpid(pid, NULL, WNOHANG); break; } /* always exit, parent has already returned */ exit(EXIT_SUCCESS); #endif }
int process_eventlog(const char *source, zbx_uint64_t *lastlogsize, unsigned long *out_timestamp, char **out_source, unsigned short *out_severity, char **out_message, unsigned long *out_eventid, unsigned char skip_old_data, void **pcontext) { const char *__function_name = "process_eventlog"; int ret = FAIL; HANDLE eventlog_handle; long FirstID, LastID; register long i; LPTSTR wsource; OSVERSIONINFO versionInfo; assert(NULL != lastlogsize); assert(NULL != out_timestamp); assert(NULL != out_source); assert(NULL != out_severity); assert(NULL != out_message); assert(NULL != out_eventid); zabbix_log(LOG_LEVEL_DEBUG, "In %s() source:'%s' lastlogsize:" ZBX_FS_UI64, __function_name, source, *lastlogsize); *out_timestamp = 0; *out_source = NULL; *out_severity = 0; *out_message = NULL; *out_eventid = 0; if (NULL == source || '\0' == *source) { zabbix_log(LOG_LEVEL_WARNING, "cannot open eventlog with empty name"); return ret; } wsource = zbx_utf8_to_unicode(source); versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&versionInfo); if (versionInfo.dwMajorVersion >= 6) { ret = zbx_get_eventlog_message_xpath(wsource, lastlogsize, out_source, out_message, out_severity, out_timestamp, out_eventid, skip_old_data, pcontext); } else if (SUCCEED == zbx_open_eventlog(wsource, &eventlog_handle, &LastID /* number */, &FirstID /* oldest */)) { LastID += FirstID; if (1 == skip_old_data) { *lastlogsize = LastID - 1; zabbix_log(LOG_LEVEL_DEBUG, "skipping existing data: lastlogsize:" ZBX_FS_UI64, *lastlogsize); } if (*lastlogsize > LastID) *lastlogsize = FirstID; else if (*lastlogsize >= FirstID) FirstID = (*lastlogsize) + 1; for (i = FirstID; i < LastID; i++) { if (SUCCEED == zbx_get_eventlog_message(wsource, eventlog_handle, i, out_source, out_message, out_severity, out_timestamp, out_eventid)) { *lastlogsize = i; break; } } zbx_close_eventlog(eventlog_handle); ret = SUCCEED; } else zabbix_log(LOG_LEVEL_ERR, "cannot open eventlog '%s': %s", source, strerror_from_system(GetLastError())); zbx_free(wsource); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: zbx_waitpid * * * * Purpose: this function waits for process to change state * * * * Parameters: pid - [IN] child process PID * * * * Return value: on success, PID is returned. On error, * * -1 is returned, and errno is set appropriately * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static int zbx_waitpid(pid_t pid) { const char *__function_name = "zbx_waitpid"; int rc, status; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); do { #ifdef WCONTINUED static int wcontinued = WCONTINUED; retry: if (-1 == (rc = waitpid(pid, &status, WUNTRACED | wcontinued))) { if (EINVAL == errno && 0 != wcontinued) { wcontinued = 0; goto retry; } #else if (-1 == (rc = waitpid(pid, &status, WUNTRACED))) { #endif zabbix_log(LOG_LEVEL_DEBUG, "%s() waitpid failure: %s", __function_name, zbx_strerror(errno)); goto exit; } if (WIFEXITED(status)) zabbix_log(LOG_LEVEL_DEBUG, "%s() exited, status:%d", __function_name, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) zabbix_log(LOG_LEVEL_DEBUG, "%s() killed by signal %d", __function_name, WTERMSIG(status)); else if (WIFSTOPPED(status)) zabbix_log(LOG_LEVEL_DEBUG, "%s() stopped by signal %d", __function_name, WSTOPSIG(status)); #ifdef WIFCONTINUED else if (WIFCONTINUED(status)) zabbix_log(LOG_LEVEL_DEBUG, "%s() continued", __function_name); #endif } while (!WIFEXITED(status) && !WIFSIGNALED(status)); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, rc); return rc; } #endif /* _WINDOWS */ /****************************************************************************** * * * Function: zbx_execute * * * * Purpose: this function executes a script and returns result from stdout * * * * Parameters: command - [IN] command for execution * * buffer - [OUT] buffer for output, if NULL - ignored * * error - [OUT] error string if function fails * * max_error_len - [IN] length of error buffer * * * * Return value: SUCCEED if processed successfully, TIMEOUT_ERROR if * * timeout occurred or FAIL otherwise * * * * Author: Alexander Vladishev * * * ******************************************************************************/ int zbx_execute(const char *command, char **buffer, char *error, size_t max_error_len, int timeout) { size_t buf_size = PIPE_BUFFER_SIZE, offset = 0; int ret = FAIL; #ifdef _WINDOWS STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; HANDLE job = NULL, hWrite = NULL, hRead = NULL; char *cmd = NULL; wchar_t *wcmd = NULL; struct _timeb start_time, current_time; #else pid_t pid; int fd; #endif *error = '\0'; if (NULL != buffer) { *buffer = zbx_realloc(*buffer, buf_size); **buffer = '\0'; } #ifdef _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 (0 == CreatePipe(&hRead, &hWrite, &sa, 0)) { zbx_snprintf(error, max_error_len, "unable to create a pipe: %s", strerror_from_system(GetLastError())); goto close; } /* create a new job where the script will be executed */ if (0 == (job = CreateJobObject(&sa, NULL))) { zbx_snprintf(error, max_error_len, "unable to create a job: %s", strerror_from_system(GetLastError())); goto close; } /* 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; /* use cmd command to support scripts */ cmd = zbx_dsprintf(cmd, "cmd /C \"%s\"", command); wcmd = zbx_utf8_to_unicode(cmd); /* create the new process */ if (0 == CreateProcess(NULL, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { zbx_snprintf(error, max_error_len, "unable to create process [%s]: %s", cmd, strerror_from_system(GetLastError())); goto close; } CloseHandle(hWrite); hWrite = NULL; /* assign the new process to the created job */ if (0 == AssignProcessToJobObject(job, pi.hProcess)) { zbx_snprintf(error, max_error_len, "unable to assign process [%s] to a job: %s", cmd, strerror_from_system(GetLastError())); if (0 == TerminateProcess(pi.hProcess, 0)) { zabbix_log(LOG_LEVEL_ERR, "failed to terminate [%s]: %s", cmd, strerror_from_system(GetLastError())); } } else if (-1 == ResumeThread(pi.hThread)) { zbx_snprintf(error, max_error_len, "unable to assign process [%s] to a job: %s", cmd, strerror_from_system(GetLastError())); } else ret = SUCCEED; if (FAIL == ret) goto close; _ftime(&start_time); timeout *= 1000; ret = zbx_read_from_pipe(hRead, buffer, &buf_size, &offset, timeout); if (TIMEOUT_ERROR != ret) { _ftime(¤t_time); if (0 < (timeout -= zbx_get_timediff_ms(&start_time, ¤t_time)) && WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, timeout)) { ret = TIMEOUT_ERROR; } } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); close: if (NULL != job) { /* terminate the child process and it's childs */ if (0 == TerminateJobObject(job, 0)) zabbix_log(LOG_LEVEL_ERR, "failed to terminate job [%s]: %s", cmd, strerror_from_system(GetLastError())); CloseHandle(job); } if (NULL != hWrite) CloseHandle(hWrite); if (NULL != hRead) CloseHandle(hRead); zbx_free(cmd); zbx_free(wcmd); #else /* not _WINDOWS */ alarm(timeout); if (-1 != (fd = zbx_popen(&pid, command))) { int rc; char tmp_buf[PIPE_BUFFER_SIZE]; while (0 < (rc = read(fd, tmp_buf, sizeof(tmp_buf) - 1)) && MAX_EXECUTE_OUTPUT_LEN > offset + rc) { if (NULL != buffer) { tmp_buf[rc] = '\0'; zbx_strcpy_alloc(buffer, &buf_size, &offset, tmp_buf); } } close(fd); if (-1 == rc || -1 == zbx_waitpid(pid)) { if (EINTR == errno) ret = TIMEOUT_ERROR; else zbx_snprintf(error, max_error_len, "zbx_waitpid() failed: %s", zbx_strerror(errno)); /* kill the whole process group, pid must be the leader */ if (-1 == kill(-pid, SIGTERM)) zabbix_log(LOG_LEVEL_ERR, "failed to kill [%s]: %s", command, zbx_strerror(errno)); zbx_waitpid(pid); } else if (MAX_EXECUTE_OUTPUT_LEN <= offset + rc) { zabbix_log(LOG_LEVEL_ERR, "command output exceeded limit of %d KB", MAX_EXECUTE_OUTPUT_LEN / ZBX_KIBIBYTE); } else ret = SUCCEED; } else zbx_strlcpy(error, zbx_strerror(errno), max_error_len); alarm(0); #endif /* _WINDOWS */ if (TIMEOUT_ERROR == ret) zbx_strlcpy(error, "Timeout while executing a shell script.", max_error_len); else if ('\0' != *error) zabbix_log(LOG_LEVEL_WARNING, "%s", error); if (SUCCEED != ret && NULL != buffer) zbx_free(*buffer); return ret; }
/* process eventlog with Windows API version 6 */ int process_eventlog6(const char *source, zbx_uint64_t *lastlogsize, unsigned long *out_timestamp, char **out_provider, char **out_source, unsigned short *out_severity, char **out_message, unsigned long *out_eventid, zbx_uint64_t *FirstID, zbx_uint64_t *LastID, EVT_HANDLE *render_context, EVT_HANDLE *query, zbx_uint64_t *keywords, unsigned char skip_old_data) { const char *__function_name = "process_eventlog6"; zbx_uint64_t i = 0; zbx_uint64_t reading_startpoint = 0; wchar_t *wsource = NULL; int ret = FAIL; *out_timestamp = 0; *out_provider = NULL; *out_source = NULL; *out_severity = 0; *out_message = NULL; *out_eventid = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s() source: '%s' previous lastlogsize: " ZBX_FS_UI64 ", FirstID: " ZBX_FS_UI64 ", LastID: " ZBX_FS_UI64, __function_name, source, *lastlogsize, *FirstID, *LastID); wsource = zbx_utf8_to_unicode(source); /* update counters */ if (1 == skip_old_data) { (*lastlogsize) = *LastID - 1; zabbix_log(LOG_LEVEL_DEBUG, "skipping existing data: lastlogsize:" ZBX_FS_UI64, *lastlogsize); ret = SUCCEED; goto finish; } else if (*lastlogsize >= *FirstID && *lastlogsize < *LastID) reading_startpoint = (*lastlogsize) + 1; else reading_startpoint = *FirstID; if (reading_startpoint == *LastID) { ret = SUCCEED; goto finish; } /* cycle through the new records */ for (i = reading_startpoint; i < *LastID; i++) { if (SUCCEED == zbx_get_eventlog_message6(wsource, &i, out_severity, out_timestamp, out_provider, out_source, out_message, out_eventid, render_context, query, keywords)) { *lastlogsize = i; ret = SUCCEED; goto finish; } } finish: zbx_free(wsource); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int process_eventlog(const char *source, zbx_uint64_t *lastlogsize, unsigned long *out_timestamp, char **out_source, unsigned short *out_severity, char **out_message, unsigned long *out_eventid, unsigned char skip_old_data) { const char *__function_name = "process_eventlog"; int ret = FAIL; HANDLE eventlog_handle; wchar_t *wsource; zbx_uint64_t FirstID, LastID; register long i; zabbix_log(LOG_LEVEL_DEBUG, "In %s() source:'%s' lastlogsize:" ZBX_FS_UI64, __function_name, source, *lastlogsize); *out_timestamp = 0; *out_source = NULL; *out_severity = 0; *out_message = NULL; *out_eventid = 0; if (NULL == source || '\0' == *source) { zabbix_log(LOG_LEVEL_WARNING, "cannot open eventlog with empty name"); return ret; } wsource = zbx_utf8_to_unicode(source); if (SUCCEED == zbx_open_eventlog(wsource, &eventlog_handle, &LastID /* number */, &FirstID /* oldest */)) { LastID += FirstID; if (1 == skip_old_data) { *lastlogsize = LastID - 1; zabbix_log(LOG_LEVEL_DEBUG, "skipping existing data: lastlogsize:" ZBX_FS_UI64, *lastlogsize); } if (*lastlogsize > LastID) *lastlogsize = FirstID; else if (*lastlogsize >= FirstID) FirstID = (long)*lastlogsize + 1; for (i = (long)FirstID; i < LastID; i++) { if (SUCCEED == zbx_get_eventlog_message(wsource, eventlog_handle, i, out_source, out_message, out_severity, out_timestamp, out_eventid)) { *lastlogsize = i; break; } } zbx_close_eventlog(eventlog_handle); ret = SUCCEED; } else zabbix_log(LOG_LEVEL_ERR, "cannot open eventlog '%s': %s", source, strerror_from_system(GetLastError())); zbx_free(wsource); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int process_eventlog(const char *source, long *lastlogsize, unsigned long *out_timestamp, char **out_source, unsigned short *out_severity, char **out_message, unsigned long *out_eventid) { const char *__function_name = "process_eventlog"; int ret = FAIL; HANDLE eventlog_handle; long FirstID, LastID; register long i; LPTSTR wsource; assert(lastlogsize); assert(out_timestamp); assert(out_source); assert(out_severity); assert(out_message); assert(out_eventid); *out_timestamp = 0; *out_source = NULL; *out_severity = 0; *out_message = NULL; *out_eventid = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s() source:'%s' lastlogsize:%ld", __function_name, source, *lastlogsize); if (NULL == source || '\0' == *source) { zabbix_log(LOG_LEVEL_WARNING, "Can't open eventlog with empty name"); return ret; } wsource = zbx_utf8_to_unicode(source); if (SUCCEED == zbx_open_eventlog(wsource, &eventlog_handle, &LastID /* number */, &FirstID /* oldest */)) { LastID += FirstID; if (*lastlogsize > LastID) *lastlogsize = FirstID; else if (*lastlogsize >= FirstID) FirstID = (*lastlogsize) + 1; for (i = FirstID; i < LastID; i++) { if (SUCCEED == zbx_get_eventlog_message(wsource, eventlog_handle, i, out_source, out_message, out_severity, out_timestamp, out_eventid)) { *lastlogsize = i; break; } } zbx_close_eventlog(eventlog_handle); ret = SUCCEED; } else zabbix_log(LOG_LEVEL_ERR, "Can't open eventlog '%s' [%s]", source, strerror_from_system(GetLastError())); zbx_free(wsource); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: zbx_wmi_get_variant * * * * Purpose: retrieves WMI value and stores it in the provided memory location * * * * Parameters: wmi_namespace [IN] - object path of the WMI namespace (UTF-8) * * wmi_query [IN] - WQL query (UTF-8) * * vtProp [OUT] - pointer to memory for the queried value * * * * Return value: SYSINFO_RET_OK - *vtProp contains the retrieved WMI value * * SYSINFO_RET_FAIL - retreiving WMI value failed * * * * Comments: *vtProp must be initialized with VariantInit(), * * wmi_* must not be NULL. The callers must convert value to the * * intended format using VariantChangeType() * * * ******************************************************************************/ extern "C" int zbx_wmi_get_variant(const char *wmi_namespace, const char *wmi_query, VARIANT *vtProp) { IWbemLocator *pLoc = 0; IWbemServices *pService = 0; IEnumWbemClassObject *pEnumerator = 0; IWbemClassObject *pclsObj = 0; ULONG uReturn = 0; int ret = SYSINFO_RET_FAIL; HRESULT hres; wchar_t *wmi_namespace_wide; wchar_t *wmi_query_wide; /* obtain the initial locator to Windows Management on a particular host computer */ hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain WMI locator service"); goto out; } wmi_namespace_wide = zbx_utf8_to_unicode(wmi_namespace); hres = pLoc->ConnectServer(_bstr_t(wmi_namespace_wide), NULL, NULL, 0, NULL, 0, 0, &pService); zbx_free(wmi_namespace_wide); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain %s WMI service", wmi_namespace); goto out; } /* set the IWbemServices proxy so that impersonation of the user (client) occurs */ hres = CoSetProxyBlanket(pService, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot set IWbemServices proxy"); goto out; } wmi_query_wide = zbx_utf8_to_unicode(wmi_query); hres = pService->ExecQuery(_bstr_t("WQL"), _bstr_t(wmi_query_wide), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); zbx_free(wmi_query_wide); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "failed to execute WMI query %s", wmi_query); goto out; } hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) goto out; hres = pclsObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot start WMI query result enumeration"); goto out; } hres = pclsObj->Next(0, NULL, vtProp, 0, 0); pclsObj->EndEnumeration(); if (FAILED(hres) || hres == WBEM_S_NO_MORE_DATA) goto out; ret = SYSINFO_RET_OK; out: if (0 != pclsObj) pclsObj->Release(); if (0 != pEnumerator) pEnumerator->Release(); if (0 != pService) pService->Release(); if (0 != pLoc) pLoc->Release(); return ret; }