Example #1
0
/* finalize eventlog6 and free the handles */
int	finalize_eventlog6(EVT_HANDLE *render_context, EVT_HANDLE *query)
{
	const char	*__function_name = "finalize_eventlog6";
	int		ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (NULL != *query)
	{
		EvtClose(*query);
		*query = NULL;
	}

	if (NULL != *render_context)
	{
		EvtClose(*render_context);
		*render_context = NULL;
	}

	ret = SUCCEED;

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Example #2
0
void	close_eventlog_context(void *v)
{
	zbx_eventlog_context *context = v;
	
	if (context == NULL || EvtClose == NULL)
		return;

	EvtClose(context->handle);
	EvtClose(context->context_handle);
	if (context->each_handle)
		EvtClose(context->each_handle);
	if (context->keyword_context_handle)
		EvtClose(context->keyword_context_handle);
	zbx_free(context);
}
Example #3
0
/* expand the string message from a specific event handler */
static char	*expand_message6(const wchar_t *pname, EVT_HANDLE event)
{
	const char	*__function_name = "expand_message6";
	wchar_t		*pmessage = NULL;
	EVT_HANDLE	provider = NULL;
	DWORD		require = 0;
	char		*out_message = NULL;
	char		*tmp_pname = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (NULL == (provider = EvtOpenPublisherMetadata(NULL, pname, NULL, 0, 0)))
	{
		tmp_pname = zbx_unicode_to_utf8(pname);
		zabbix_log(LOG_LEVEL_DEBUG, "provider '%s' could not be opened: %s",
				strerror_from_system(GetLastError()), tmp_pname);
		zbx_free(tmp_pname);
		goto out;
	}

	if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, 0, NULL, &require))
	{
		if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
		{
			DWORD	error = ERROR_SUCCESS;

			pmessage = zbx_malloc(pmessage, sizeof(WCHAR) * require);

			if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, require,
					pmessage, &require))
			{
				error = GetLastError();
			}

			if (ERROR_SUCCESS == error || ERROR_EVT_UNRESOLVED_VALUE_INSERT == error ||
					ERROR_EVT_UNRESOLVED_PARAMETER_INSERT == error ||
					ERROR_EVT_MAX_INSERTS_REACHED == error)
			{
				out_message = zbx_unicode_to_utf8(pmessage);
			}
			else
			{
				zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot format message: %s", __function_name,
						strerror_from_system(error));
				goto out;
			}
		}
	}
out:
	if (NULL != provider)
		EvtClose(provider);
	zbx_free(pmessage);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, out_message);

	/* should be freed */
	return out_message;
}
Example #4
0
/**
* @brief Enumerate all the events in the result set.

* @param results The handle to a query or subscription result set that
*                the EvtQuery function or the EvtSubscribe function returns.
*
* @return returns Status code.
*/
DWORD EventLogReader::PrintResults(EVT_HANDLE results)
{
    DWORD status = ERROR_SUCCESS;
    static const int ArraySize = 10;

    DWORD returned = 0;
    EVT_HANDLE events[ArraySize] = { 0 };
    bool run = true;
    while (run)
    {
        // Get a block of events from the result set.
        if (!EvtNext(results, ArraySize, events, INFINITE, 0, &returned))
            break;
        // For each event, call the PrintEvent function which renders the
        // event for display. PrintEvent is shown in RenderingEvents.
        for (DWORD i = 0; i < returned; i++)
        {
            _position++;
            status = PrintEvent(events[i]);
            if (status == ERROR_SUCCESS)
            {
                EvtClose(events[i]);
                events[i] = nullptr;
            }
            else
            {
                run = false;
                break;
            }
        }
    }
    for (DWORD i = 0; i < returned; i++)
    {
        if (events[i] != nullptr)
            EvtClose(events[i]);
    }
    return status;
}
Example #5
0
/* Get specific values from an event */
PEVT_VARIANT GetEventInfo(EVT_HANDLE hEvent)
{
	EVT_HANDLE hContext = NULL;
	PEVT_VARIANT pRenderedEvents = NULL;
	LPWSTR ppValues[] = {L"Event/System/Provider/@Name",
						 L"Event/System/TimeCreated/@SystemTime",
						 L"Event/System/EventID",
						 L"Event/System/Level",
						 L"Event/System/Keywords"};
    DWORD count = COUNT_OF(ppValues);
    DWORD dwReturned = 0;
	DWORD dwBufferSize = (256*sizeof(LPWSTR)*count);
	DWORD dwValuesCount = 0;
	DWORD status = 0;

	/* Create the context to use for EvtRender */
	hContext = EvtCreateRenderContext(count, (LPCWSTR*)ppValues, EvtRenderContextValues);
	if (NULL == hContext) {
		Log(LOG_ERROR|LOG_SYS, "EvtCreateRenderContext failed");
		goto cleanup;
	}

	pRenderedEvents = (PEVT_VARIANT)malloc(dwBufferSize);
	/* Use EvtRender to capture the Publisher name from the Event */
	/* Log Errors to the event log if things go wrong */
	if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedEvents, &dwReturned, &dwValuesCount)) {
		if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
			dwBufferSize = dwReturned;
			realloc(pRenderedEvents, dwBufferSize);
			if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedEvents, &dwReturned, &dwValuesCount)) {
				if (LogInteractive)
					Log(LOG_ERROR|LOG_SYS, "Error Rendering Event");
				status = ERR_FAIL;
			}
		} else {
			status = ERR_FAIL;
			if (LogInteractive)
				Log(LOG_ERROR|LOG_SYS, "Error Rendering Event");
		}
	}

cleanup:
	if (hContext)
		EvtClose(hContext);

	if (status == ERR_FAIL)
		return NULL;
	else 
		return pRenderedEvents;
}
Example #6
0
/* expand the string message from a specific event handler */
static char *expand_message6(const wchar_t *pname, EVT_HANDLE event)
{
	const char	*__function_name = "expand_message6";
	wchar_t		*pmessage = NULL;
	EVT_HANDLE	provider = NULL;
	DWORD		require = 0;
	char		*out_message = NULL;
	char		*tmp_pname = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (NULL == (provider = EvtOpenPublisherMetadata(NULL, pname, NULL, 0, 0)))
	{
		tmp_pname = zbx_unicode_to_utf8(pname);
		zabbix_log(LOG_LEVEL_DEBUG, "provider '%s' could not be opened: %s",
				strerror_from_system(GetLastError()), tmp_pname);
		zbx_free(tmp_pname);
		goto finish;
	}

	if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, 0, NULL, &require) )
	{
		if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
		{
			pmessage = zbx_malloc(pmessage, sizeof(WCHAR) * require);

			if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent,
					require, pmessage, &require))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "formatting message failed: %s",
						strerror_from_system(GetLastError()));
				goto finish;
			}
			out_message = zbx_unicode_to_utf8(pmessage);
		}
	}

finish:
	if (NULL != provider)
		EvtClose(provider);
	zbx_free(pmessage);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, out_message);

	/* should be freed*/
	return out_message;
}
Example #7
0
/**
* @brief Get the list of events.
*/
void EventLogReader::ReadEvents()
{
    DWORD status = ERROR_SUCCESS;
    std::wstring buf = base::string_to_wstring(_query);
    EVT_HANDLE results = EvtQuery(nullptr, nullptr, buf.c_str(), EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
    if (results == nullptr)
        return;

    if (!EvtSeek(results, _position, nullptr, 0, EvtSeekRelativeToFirst))
        return;

    if (PrintQueryStatuses(results) == ERROR_SUCCESS)
        PrintResults(results);

    if (results)
        EvtClose(results);
}
void win_start_event_channel(char *evt_log, char future, char *query)
{
    wchar_t *wchannel = NULL;
    wchar_t *wquery = NULL;
    os_channel *channel = NULL;
    DWORD flags = EvtSubscribeToFutureEvents;
    EVT_HANDLE bookmark = NULL;
    EVT_HANDLE result = NULL;
    int status = 0;

    if ((channel = calloc(1, sizeof(os_channel))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory for channel to start reading (%s) which returned [(%d)-(%s)]",
            ARGV0,
            evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    channel->evt_log = evt_log;

    /* Create copy of event log string */
    if ((channel->bookmark_name = strdup(channel->evt_log)) == NULL) {
        log2file(
            "%s: ERROR: Could not strdup() event log name to start reading (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Replace '/' with '_' */
    if (strchr(channel->bookmark_name, '/')) {
        *(strrchr(channel->bookmark_name, '/')) = '_';
    }

    /* Convert evt_log to Windows string */
    if ((wchannel = convert_unix_string(channel->evt_log)) == NULL) {
        log2file(
            "%s: ERROR: Could not convert_unix_string() evt_log for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Convert query to Windows string */
    if (query) {
        if ((wquery = convert_unix_string(query)) == NULL) {
            log2file(
                "%s: ERROR: Could not convert_unix_string() query for (%s) which returned [(%d)-(%s)]",
                ARGV0,
                channel->evt_log,
                errno,
                strerror(errno));
            goto cleanup;
        }
    }

    channel->bookmark_enabled = !future;

    if (channel->bookmark_enabled) {
        /* Create bookmark file name */
        snprintf(channel->bookmark_filename,
                 sizeof(channel->bookmark_filename), "%s/%s", BOOKMARKS_DIR,
                 channel->bookmark_name);

        /* Try to read existing bookmark */
        if ((bookmark = read_bookmark(channel)) != NULL) {
            flags = EvtSubscribeStartAfterBookmark;
        }
    }

    result = EvtSubscribe(NULL,
                          NULL,
                          wchannel,
                          wquery,
                          bookmark,
                          channel,
                          (EVT_SUBSCRIBE_CALLBACK)event_channel_callback,
                          flags);

    if (result == NULL && flags == EvtSubscribeStartAfterBookmark) {
        result = EvtSubscribe(NULL,
                              NULL,
                              wchannel,
                              wquery,
                              NULL,
                              channel,
                              (EVT_SUBSCRIBE_CALLBACK)event_channel_callback,
                              EvtSubscribeToFutureEvents);
    }

    if (result == NULL) {
        log2file(
            "%s: ERROR: Could not EvtSubscribe() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Success */
    status = 1;

cleanup:
    free(wchannel);
    free(wquery);

    if (status == 0) {
        free(channel->bookmark_name);
        free(channel);

        if (result != NULL) {
            EvtClose(result);
        }
    }

    if (bookmark != NULL) {
        EvtClose(bookmark);
    }

    return;
}
DWORD 
GetEventRawDescriptions (
    __in PCWSTR ProviderName,
    __in LCID Locale
    )

/*++

Routine Description:

    This function gets the raw event description strings.

Parameters:

    ProviderName - Supplies the provider name.

    Locale - Supplies the LCID.

Return Value:

    Win32 error code indicating the status of the function execution.

--*/

{
    PWSTR Description;
    ULONG BufferLength;
    ULONG BufferLengthNeeded;
    ULONG BufferUsed;
    EVT_VARIANT EventId;
    EVT_VARIANT EventMessageId;
    EVT_HANDLE EventMeta;
    EVT_HANDLE EventMetaEnum;
    EVT_HANDLE ProviderMetadata;
    ULONG Status;

    //
    // Open the provider meta data.
    //

    ProviderMetadata = EvtOpenPublisherMetadata(NULL,
                                                ProviderName,
                                                NULL,
                                                Locale,
                                                0);
    if (ProviderMetadata == NULL) {
        return GetLastError();
    }

    //
    // Open the Event meta data associated with the provider.
    //

    EventMetaEnum = EvtOpenEventMetadataEnum(ProviderMetadata, 0);
    if (EventMetaEnum == NULL) {
        Status = GetLastError();
        EvtClose(ProviderMetadata);
        return Status;
    }

    Description = NULL;
    BufferLength = 0;
    BufferLengthNeeded = 0;

    while ((EventMeta = EvtNextEventMetadata(EventMetaEnum, 0)) != NULL) {

        //
        // Get the event & message IDs.
        //

        if ((EvtGetEventMetadataProperty(EventMeta, 
                                         EventMetadataEventMessageID,
                                         0, 
                                         sizeof(EVT_VARIANT),
                                         &EventMessageId,
                                         &BufferUsed) == FALSE) ||
            (EvtGetEventMetadataProperty(EventMeta,
                                         EventMetadataEventID,
                                         0,
                                         sizeof(EVT_VARIANT),
                                         &EventId,
                                         &BufferUsed) == FALSE)) {
            EvtClose(EventMeta);
            continue;
        }

        //
        // Get the description, reallocating the buffer if needed.
        //

        do {
            if (BufferLengthNeeded > BufferLength) {
                free(Description);
                BufferLength = BufferLengthNeeded;
                Description = (PWSTR)malloc(BufferLength * sizeof(WCHAR));
                if (Description == NULL) {
                    Status = ERROR_OUTOFMEMORY;
                    BufferLength = 0;
                    break;
                }
            }

            if (EvtFormatMessage(ProviderMetadata,
                                 NULL,
                                 EventMessageId.UInt32Val,
                                 0,
                                 NULL,
                                 EvtFormatMessageId,
                                 BufferLength,
                                 Description,
                                 &BufferLengthNeeded) != FALSE) {
                Status = ERROR_SUCCESS;
            } else {
                Status = GetLastError();
            }
        } while (Status == ERROR_INSUFFICIENT_BUFFER);

        //
        // Display either the event message or an error message.
        //

        switch (Status) {
        case ERROR_SUCCESS:
        case ERROR_EVT_UNRESOLVED_VALUE_INSERT:
        case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT:
        case ERROR_EVT_MAX_INSERTS_REACHED:
            wprintf(L"Event %u raw description is: %s\n",
                    EventId.UInt32Val,
                    Description);
            break;

        default:
            wprintf(L"Get raw event description failed with error code %u\n",
                    Status);
        }

        //
        // Close this event's metadata and go to the next one.
        //

        EvtClose(EventMeta);
    }

    Status = GetLastError();
    if (Status == ERROR_NO_MORE_ITEMS) {
        Status = ERROR_SUCCESS;
    }

    free(Description);
    EvtClose(EventMetaEnum);
    EvtClose(ProviderMetadata);

    return Status;
}
/* Update the log position of a bookmark */
int update_bookmark(EVT_HANDLE evt, os_channel *channel)
{
    DWORD size = 0;
    DWORD count = 0;
    wchar_t *buffer = NULL;
    int result = 0;
    int status = 0;
    int clean_tmp = 0;
    EVT_HANDLE bookmark = NULL;
    FILE *fp = NULL;
    char tmp_file[OS_MAXSTR];

    /* Create temporary bookmark file name */
    snprintf(tmp_file,
             sizeof(tmp_file),
             "%s/%s-XXXXXX",
             TMP_DIR,
             channel->bookmark_name);

    if ((bookmark = EvtCreateBookmark(NULL)) == NULL) {
        log2file(
            "%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if (!EvtUpdateBookmark(bookmark, evt)) {
        log2file(
            "%s: ERROR: Could not EvtUpdateBookmark() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size */
    result = EvtRender(NULL,
                       bookmark,
                       EvtRenderBookmark,
                       0,
                       NULL,
                       &size,
                       &count);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtRender() to get buffer size to update bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if ((buffer = calloc(size, sizeof(char))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory to save bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    if (!EvtRender(NULL,
                   bookmark,
                   EvtRenderBookmark,
                   size,
                   buffer,
                   &size,
                   &count)) {
        log2file(
            "%s: ERROR: Could not EvtRender() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0, channel->bookmark_filename, channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if (mkstemp_ex(tmp_file)) {
        log2file(
            "%s: ERROR: Could not mkstemp_ex() temporary bookmark (%s) for (%s)",
            ARGV0,
            tmp_file,
            channel->evt_log);
        goto cleanup;
    }

    if ((fp = fopen(tmp_file, "w")) == NULL) {
        log2file(
            "%s: ERROR: Could not fopen() temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            tmp_file,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Help to determine whether or not temporary file needs to be removed when
     * function cleans up after itself
     */
    clean_tmp = 1;

    if ((fwrite(buffer, 1, size, fp)) < size) {
        log2file(
            "%s: ERROR: Could not fwrite() to temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            tmp_file,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    fclose(fp);

    if (rename_ex(tmp_file, channel->bookmark_filename)) {
        log2file(
            "%s: ERROR: Could not rename_ex() temporary bookmark (%s) to (%s) for (%s)",
            ARGV0,
            tmp_file,
            channel->bookmark_filename,
            channel->evt_log);
        goto cleanup;
    }

    /* Success */
    status = 1;

cleanup:
    free(buffer);

    if (bookmark != NULL) {
        EvtClose(bookmark);
    }

    if (fp) {
        fclose(fp);
    }

    if (status == 0 && clean_tmp == 1 && unlink(tmp_file)) {
        log2file(DELETE_ERROR,
                 ARGV0,
                 tmp_file,
                 errno,
                 strerror(errno));
    }

    return (status);
}
void send_channel_event(EVT_HANDLE evt, os_channel *channel)
{
    DWORD buffer_length = 0;
    PEVT_VARIANT properties_values = NULL;
    DWORD count = 0;
    EVT_HANDLE context = NULL;
    os_event event = {0};
    char final_msg[OS_MAXSTR];
    int result = 0;

    if ((context = EvtCreateRenderContext(count, NULL, EvtRenderContextSystem)) == NULL) {
        log2file(
            "%s: ERROR: Could not EvtCreateRenderContext() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size necessary */
    result = EvtRender(context,
                       evt,
                       EvtRenderEventValues,
                       0,
                       NULL,
                       &buffer_length,
                       &count);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtRender() to determine buffer size for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if ((properties_values = malloc(buffer_length)) == NULL) {
        log2file(
            "%s: ERROR: Could not malloc() memory to process event (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    if (!EvtRender(context,
                   evt,
                   EvtRenderEventValues,
                   buffer_length,
                   properties_values,
                   &buffer_length,
                   &count)) {
        log2file(
            "%s: ERROR: Could not EvtRender() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    event.name = get_property_value(&properties_values[EvtSystemChannel]);
    event.id = properties_values[EvtSystemEventID].UInt16Val;
    event.source = get_property_value(&properties_values[EvtSystemProviderName]);
    event.uid = properties_values[EvtSystemUserID].Type == EvtVarTypeNull ? NULL : properties_values[EvtSystemUserID].SidVal;
    event.computer = get_property_value(&properties_values[EvtSystemComputer]);
    event.time_created = properties_values[EvtSystemTimeCreated].FileTimeVal;
    event.keywords = properties_values[EvtSystemKeywords].Type == EvtVarTypeNull ? 0 : properties_values[EvtSystemKeywords].UInt64Val;
    event.level = properties_values[EvtSystemLevel].Type == EvtVarTypeNull ? -1 : properties_values[EvtSystemLevel].ByteVal;

    switch (event.level) {
        case WINEVENT_CRITICAL:
            event.category = "CRITICAL";
            break;
        case WINEVENT_ERROR:
            event.category = "ERROR";
            break;
        case WINEVENT_WARNING:
            event.category = "WARNING";
            break;
        case WINEVENT_INFORMATION:
            event.category = "INFORMATION";
            break;
        case WINEVENT_VERBOSE:
            event.category = "DEBUG";
            break;
        case WINEVENT_AUDIT:
            if (event.keywords & WINEVENT_AUDIT_FAILURE) {
                event.category = "AUDIT_FAILURE";
                break;
            } else if (event.keywords & WINEVENT_AUDIT_SUCCESS) {
                event.category = "AUDIT_SUCCESS";
                break;
            }
        default:
            event.category = "Unknown";
            break;
    }

    if ((event.timestamp = WinEvtTimeToString(event.time_created)) == NULL) {
        log2file(
            "%s: ERROR: Could not convert timestamp for (%s)",
            ARGV0,
            channel->evt_log);
        goto cleanup;
    }

    /* Determine user and domain */
    get_username_and_domain(&event);

    /* Get event log message */
    if ((event.message = get_message(evt, properties_values[EvtSystemProviderName].StringVal, EvtFormatMessageEvent)) == NULL) {
        log2file(
            "%s: ERROR: Could not get message for (%s)",
            ARGV0,
            channel->evt_log);
    } else {
        /* Format message */
        win_format_event_string(event.message);
    }

    snprintf(
        final_msg,
        sizeof(final_msg),
        "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s",
        event.timestamp,
        event.name,
        event.category,
        event.id,
        event.source && strlen(event.source) ? event.source : "no source",
        event.user && strlen(event.user) ? event.user : "******",
        event.domain && strlen(event.domain) ? event.domain : "no domain",
        event.computer && strlen(event.computer) ? event.computer : "no computer",
        event.message && strlen(event.message) ? event.message : "(no message)"
    );

    if (SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) {
        merror(QUEUE_SEND, ARGV0);
    }

    if (channel->bookmark_enabled) {
        update_bookmark(evt, channel);
    }

cleanup:
    free(properties_values);
    free_event(&event);

    if (context != NULL) {
        EvtClose(context);
    }

    return;
}
Example #12
0
ULONG
EnumerateChannels (
    VOID
)

/*++

Routine Description:

    This function enumerates all the EventLog channels and prints their names
    to the standard output.

Arguments:

    None.

Return Value:

    Win32 error code indicating if enumeration was successful.

--*/

{
    PWSTR Buffer;
    ULONG BufferLength;
    ULONG BufferLengthNeeded;
    EVT_HANDLE ChannelEnum;
    ULONG Status;

    //
    // Create the channel enumeration handle.
    //

    ChannelEnum = EvtOpenChannelEnum(NULL, 0);
    if (ChannelEnum == NULL) {
        return GetLastError();
    }

    Buffer = NULL;
    BufferLength = 0;
    BufferLengthNeeded = 0;

    do {

        //
        // Expand the buffer size if needed.
        //

        if (BufferLengthNeeded > BufferLength) {
            free(Buffer);
            BufferLength = BufferLengthNeeded;
            Buffer = malloc(BufferLength * sizeof(WCHAR));
            if (Buffer == NULL) {
                Status = ERROR_OUTOFMEMORY;
                break;
            }
        }

        //
        // Try to get the next channel name.
        //

        if (EvtNextChannelPath(ChannelEnum,
                               BufferLength,
                               Buffer,
                               &BufferLengthNeeded) == FALSE) {
            Status = GetLastError();
        } else {
            Status = ERROR_SUCCESS;
            wprintf(L"%s\n", Buffer);
        }

    } while ((Status == ERROR_SUCCESS) ||
             (Status == ERROR_INSUFFICIENT_BUFFER));

    //
    // Free all resources associated with channel enumeration.
    //

    free(Buffer);

    EvtClose(ChannelEnum);

    //
    // When EvtNextChannelPath returns ERROR_NO_MORE_ITEMS, we have actually
    // iterated through all the channels and thus succeeded.
    //

    if (Status == ERROR_NO_MORE_ITEMS) {
        Status = ERROR_SUCCESS;
    }

    return Status;
}
char *get_message(EVT_HANDLE evt, LPCWSTR provider_name, DWORD flags)
{
    char *message = NULL;
    EVT_HANDLE publisher = NULL;
    DWORD size = 0;
    wchar_t *buffer = NULL;
    int result = 0;

    publisher = EvtOpenPublisherMetadata(NULL,
                                         provider_name,
                                         NULL,
                                         0,
                                         0);
    if (publisher == NULL) {
        log2file(
            "%s: ERROR: Could not EvtOpenPublisherMetadata() with flags (%lu) which returned (%lu)",
            ARGV0,
            flags,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size */
    result = EvtFormatMessage(publisher,
                              evt,
                              0,
                              0,
                              NULL,
                              flags,
                              0,
                              NULL,
                              &size);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtFormatMessage() to determine buffer size with flags (%lu) which returned (%lu)",
            ARGV0,
            flags,
            GetLastError());
        goto cleanup;
    }

    if ((buffer = calloc(size, sizeof(wchar_t))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory which returned [(%d)-(%s)]",
            ARGV0,
            errno,
            strerror(errno));
        goto cleanup;
    }

    result = EvtFormatMessage(publisher,
                              evt,
                              0,
                              0,
                              NULL,
                              flags,
                              size,
                              buffer,
                              &size);
    if (result == FALSE) {
        log2file(
            "%s: ERROR: Could not EvtFormatMessage() with flags (%lu) which returned (%lu)",
            ARGV0,
            flags,
            GetLastError());
        goto cleanup;
    }

    message = convert_windows_string(buffer);

cleanup:
    free(buffer);

    if (publisher != NULL) {
        EvtClose(publisher);
    }

    return (message);
}
Example #14
0
/* Process a given event */
DWORD ProcessEvent(EVT_HANDLE hEvent)
{
    EVT_HANDLE hProviderMetadata = NULL;
	PEVT_VARIANT eventInfo = NULL;
    LPWSTR pwsMessage = NULL;
    LPWSTR pwszPublisherName = NULL;
	ULONGLONG eventTime;
	ULONGLONG keyword;
    DWORD status = ERROR_SUCCESS;
	int event_id = 0;
	int winlevel = 0;
	int level = 0;

	WCHAR source[SOURCE_SZ];
	WCHAR hostname[HOSTNAME_SZ];
	WCHAR * formatted_string = NULL;
	WCHAR * tstamp = NULL;
	WCHAR * index = NULL;
	WCHAR defmsg[ERRMSG_SZ];
	WCHAR tstamped_message[SYSLOG_DEF_SZ];

    /* Get and store the publishers new Windows Events name */
	eventInfo = GetEventInfo(hEvent);
	if (eventInfo) {
		pwszPublisherName = (LPWSTR)eventInfo[0].StringVal;
	}
	else {
		return ERR_CONTINUE;
	}
	eventTime = eventInfo[1].FileTimeVal;
	event_id = eventInfo[2].UInt16Val;

	/* Check for the "Microsoft-Windows-" prefix in the publisher name */
	/* and remove it if found. Saves 18 characters in the message */
	if(wcsncmp(pwszPublisherName, L"Microsoft-Windows-", 18) == 0)
		wcsncpy_s(source, COUNT_OF(source), pwszPublisherName+18, _TRUNCATE);
	else
		wcsncpy_s(source, COUNT_OF(source), pwszPublisherName, _TRUNCATE);

	/* Format Event Timestamp */
	if ((tstamp = WinEventTimeToString(eventTime)) == NULL)
		tstamp = L"TIME_ERROR";

	/* Add hostname for RFC compliance (RFC 3164) */
	if (ProgramUseIPAddress == TRUE) {
		_snwprintf_s(hostname, HOSTNAME_SZ, _TRUNCATE, L"%S", ProgramHostName);
	} else {
		if (ExpandEnvironmentStringsW(L"%COMPUTERNAME%", hostname, COUNT_OF(hostname)) == 0) {
			wcscpy_s(hostname, COUNT_OF(hostname), L"HOSTNAME_ERR");
			Log(LOG_ERROR|LOG_SYS, "Cannot expand %COMPUTERNAME%");
		}
    }

	/* replace every space in source by underscores */
	index = source;
	while( *index ) {
		if( *index == L' ' ) {
			*index = L'_';
		}
		index++;
	}

	/* Add Timestamp and hostname then format source & event ID for consistency with Event Viewer */
    if(SyslogIncludeTag)
    {
        _snwprintf_s(tstamped_message, COUNT_OF(tstamped_message), _TRUNCATE, L"%s %s %S: %s: %i: ",
            tstamp,
            hostname,
            SyslogTag,
            source,
            event_id
        );
    }
    else
    {
        _snwprintf_s(tstamped_message, COUNT_OF(tstamped_message), _TRUNCATE, L"%s %s %s: %i: ",
            tstamp,
            hostname,
            source,
            event_id
        );
    }

	/* Get the handle to the provider's metadata that contains the message strings. */
	hProviderMetadata = EvtOpenPublisherMetadata(NULL, pwszPublisherName, NULL, 0, 0);
	if (NULL == hProviderMetadata) {
		if (LogInteractive)
			Log(LOG_ERROR|LOG_SYS, "OpenPublisherMetadata failed for Publisher: \"%S\"", source);
		return ERR_CONTINUE;
	}

	/* Get the message string from the event */
	pwsMessage = GetMessageString(hProviderMetadata, hEvent);
	if (pwsMessage == NULL) {
		Log(LOG_ERROR|LOG_SYS, "Error getting message string for event DETAILS: Publisher: %S EventID: %i", source, event_id);
		return ERR_CONTINUE;
	}

	/* Get string and strip whitespace */
	formatted_string = CollapseExpandMessageW(pwsMessage);

	/* Create a default message if resources or formatting didn't work */
	if (formatted_string == NULL) {
        if(SyslogIncludeTag)
        {
		    _snwprintf_s(defmsg, COUNT_OF(defmsg), _TRUNCATE,
                L"%S: (Facility: %u, Status: %s)",
                SyslogTag,
			    HRESULT_FACILITY(event_id),
			    FAILED(event_id) ? L"Failure" : L"Success"
		    );
        }
        else
        {
            _snwprintf_s(defmsg, COUNT_OF(defmsg), _TRUNCATE,
                L"(Facility: %u, Status: %s)",
			    HRESULT_FACILITY(event_id),
			    FAILED(event_id) ? L"Failure" : L"Success"
		    );
        }
		formatted_string = defmsg;
	}

	/* Get Event Error Level. In the case of Security Events,
	 * set Failures to Error instead of notice using the
	 * keyword attribute
	 */
	keyword = (EvtVarTypeNull == eventInfo[4].Type) ? 0 : eventInfo[4].UInt64Val;
	if ((keyword & WINEVENT_KEYWORD_AUDIT_FAILURE) != 0) {
        // Add AUDIT_FAILURE message for better parsing
        wcsncat_s(tstamped_message, COUNT_OF(tstamped_message), L"AUDIT_FAILURE ", _TRUNCATE);
		winlevel = WINEVENT_ERROR_LEVEL;
    }
	else
		winlevel = (int)eventInfo[3].ByteVal;

	/* Select syslog level */
	switch (winlevel) {
		case WINEVENT_CRITICAL_LEVEL:
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_CRIT);
			break;		
		case WINEVENT_ERROR_LEVEL:
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_ERR);
			break;
		case WINEVENT_WARNING_LEVEL:
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_WARNING);
			break;
		case WINEVENT_INFORMATION_LEVEL:
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_NOTICE);
			break;
		case WINEVENT_AUDIT_LEVEL:
            wcsncat_s(tstamped_message, COUNT_OF(tstamped_message), L"AUDIT_SUCCESS ", _TRUNCATE);
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_NOTICE);
			break;
		case WINEVENT_VERBOSE_LEVEL:
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_DEBUG);
			break;

		/* Everything else */
		default:
			level = SYSLOG_BUILD(SyslogFacility, SYSLOG_NOTICE);
			break;
	}

	/* Combine the message strings */
	wcsncat_s(tstamped_message, COUNT_OF(tstamped_message), formatted_string, _TRUNCATE);

	/* Send the event to the Syslog Server */
	/* Making sure it is severe enough to be logged */
	if (SyslogLogLevel == 0 || (SyslogLogLevel >= (DWORD)winlevel && winlevel > 0))
		if (SyslogSendW(tstamped_message, level))
			status = ERR_FAIL;

	/* Cleanup memory and open handles */
	if(pwsMessage)
		free(pwsMessage);
	if(eventInfo)
		free(eventInfo);

	if (hProviderMetadata)
		EvtClose(hProviderMetadata);
	if (hEvent)
		EvtClose(hEvent);

	return status;
}
EVT_HANDLE
CperOpenWheaLogQuery (
    __in_opt PWSTR ComputerName,
    __in_opt PWSTR UserName,
    __in_opt PWSTR Domain,
    __in_opt PWSTR Password,
    __in_opt PWSTR FileName,
    __out EVT_HANDLE *Session
    )

/*++

Routine Description:

    This routine will initialize an event log query that may be used to
    enumerate any WHEA error records contained in the WHEA event log.

Arguments:

    ComputerName - Supplies an optional computer name for remote queries. This
        should be NULL for the local event log query or if an exported event log
        is to be queried.

    UserName - Supplies the username to be used to authenticate to the remote
        computer.

    Domain - Supplies the username to be used to authenticate to the remote
        computer.

    Password - Supplies the password to be used to authenticate to the remote
        computer.

    FileName - Supplies an optional filename for an exported event log. This
        should be NULL for a live (local or remote) event log query.

    Session - Supplies a variable in which a handle to the session is returned,
        but only if the query is for events on a remote computer.

Return Value:

    A handle to the ETW query if successful, NULL otherwise.

--*/

{

    DWORD Error;
    DWORD Flags;
    EVT_RPC_LOGIN Login;
    PCWSTR Path;
    EVT_HANDLE QueryHandle;
    EVT_HANDLE SessionHandle;

    QueryHandle = NULL;
    SessionHandle = NULL;
    Error = ERROR_SUCCESS;

    //
    // If a computer name is specified, then an event log session to that
    // computer must be opened. It is invalid to specify a remote computer as
    // well as a filename.
    //

    if (ComputerName != NULL) {
        if (FileName != NULL) {
            Error = ERROR_INVALID_PARAMETER;
            goto OpenWheaLogQueryEnd;
        }

        RtlZeroMemory(&Login, sizeof(EVT_RPC_LOGIN));
        Login.Server = ComputerName;
        Login.User = UserName;
        Login.Domain = Domain;
        Login.Password = Password;
        Login.Flags = EvtRpcLoginAuthDefault;
        SessionHandle = EvtOpenSession(EvtRpcLogin, &Login, 0, 0);
        if (SessionHandle == NULL) {
            Error = GetLastError();
            goto OpenWheaLogQueryEnd;
        }
    }

    if (FileName == NULL) {
        Path = WHEA_CHANNEL;
        Flags = EvtQueryChannelPath | EvtQueryForwardDirection;

    } else {
        Path = (PCWSTR)FileName;
        Flags = EvtQueryFilePath | EvtQueryForwardDirection;
    }

    //
    // Open the query. If this is not a file query and the open fails, try the
    // legacy log name.
    //

    QueryHandle = EvtQuery(SessionHandle, Path, WHEA_LOG_QUERY, Flags);
    if (QueryHandle == NULL) {
        Error = GetLastError();
        if (FileName == NULL) {
            Path = WHEA_CHANNEL_LEGACY;
            QueryHandle = EvtQuery(SessionHandle, Path, WHEA_LOG_QUERY, Flags);
            if (QueryHandle == NULL) {
                Error = GetLastError();
                goto OpenWheaLogQueryEnd;
            }
        }
    }

    *Session = SessionHandle;

OpenWheaLogQueryEnd:
    if (QueryHandle == NULL) {
        if (SessionHandle != NULL) {
            EvtClose(SessionHandle);
        }

        SetLastError(Error);
    }

    return QueryHandle;
}
Example #16
0
/**
* @brief Enumerate all the events in the result set.
* @param eventHandle A handle to an event.
*
* @return returns Print event status.
*/
DWORD EventLogReader::PrintEvent(EVT_HANDLE eventHandle)
{
    EVT_HANDLE context = nullptr;
    PEVT_VARIANT renderedValues = nullptr;
    DWORD status = ERROR_SUCCESS;
    do
    {
        // Identify the components of the event that you want to render. In this case,
        // render the system section of the event.
        context = EvtCreateRenderContext(0, nullptr, EvtRenderContextSystem);
        if (context == nullptr)
        {
            status = GetLastError();
            break;
        }
        // When you render the user data or system section of the event, you must specify
        // the EvtRenderEventValues flag. The function returns an array of variant values
        // for each element in the user data or system section of the event. For user data
        // or event data, the values are returned in the same order as the elements are
        // defined in the event. For system data, the values are returned in the order defined
        // in the EVT_SYSTEM_PROPERTY_ID enumeration.
        DWORD bufferSize = 0;
        DWORD bufferUsed = 0;
        DWORD propertyCount = 0;
        if (!EvtRender(context, eventHandle, EvtRenderEventValues, bufferSize, renderedValues, &bufferUsed, &propertyCount))
        {
            status = GetLastError();
            if (status == ERROR_INSUFFICIENT_BUFFER)
            {
                bufferSize = bufferUsed;
                renderedValues = (PEVT_VARIANT)malloc(bufferSize);
                if (renderedValues != nullptr)
                {
                    EvtRender(context, eventHandle, EvtRenderEventValues, bufferSize, renderedValues, &bufferUsed, &propertyCount);
                    status = GetLastError();
                }
                else
                {
                    status = ERROR_OUTOFMEMORY;
                    break;
                }
            }
            if (status != ERROR_SUCCESS)
                break;
        }
        std::map<std::string, std::string> eventData;

        std::wstring tempBuf = (renderedValues[EvtSystemProviderName].StringVal) ? renderedValues[EvtSystemProviderName].StringVal : L"";
        eventData["providername"] = base::wstring_to_string(tempBuf);
        if (renderedValues[EvtSystemProviderGuid].GuidVal != nullptr)
        {
            WCHAR guid[50] = {0};
            StringFromGUID2(*(renderedValues[EvtSystemProviderGuid].GuidVal), guid, sizeof(guid) / sizeof(WCHAR));
            eventData["providerguid"] = base::wstring_to_string(guid);
        }

        DWORD eventId = renderedValues[EvtSystemEventID].UInt16Val;
        if (renderedValues[EvtSystemQualifiers].Type == EvtVarTypeNull)
            eventId = MAKELONG(renderedValues[EvtSystemEventID].UInt16Val, renderedValues[EvtSystemQualifiers].UInt16Val);
        char buf[1024] = { 0 };
        snprintf(buf, sizeof(buf), "%lu", eventId);
        eventData["eventid"] = buf;

        snprintf(buf, sizeof(buf), "%u", (renderedValues[EvtSystemVersion].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemVersion].ByteVal);
        eventData["version"] = buf;

        snprintf(buf, sizeof(buf), "%u", (renderedValues[EvtSystemLevel].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemLevel].ByteVal);
        eventData["level"] = buf;

        snprintf(buf, sizeof(buf), "%hu", (renderedValues[EvtSystemTask].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemTask].ByteVal);
        eventData["task"] = buf;

        snprintf(buf, sizeof(buf), "%u", (renderedValues[EvtSystemOpcode].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemOpcode].UInt16Val);
        eventData["opcode"] = buf;

        snprintf(buf, sizeof(buf), "%0x%I64x", (renderedValues[EvtSystemKeywords].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemOpcode].UInt64Val);
        eventData["keywords"] = buf;

        ULONGLONG ullTimeStamp = renderedValues[EvtSystemTimeCreated].FileTimeVal;
        FILETIME ft;
        ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
        ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        ULONGLONG ullNanoseconds = (ullTimeStamp % 10000000) * 100; // Display nanoseconds instead of milliseconds for higher resolution
        snprintf(buf, sizeof(buf), "%02d/%02d/%02d %02d:%02d:%02d.%I64u", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, ullNanoseconds);
        eventData["timecreated"] = buf;

        snprintf(buf, sizeof(buf), "%I64u", renderedValues[EvtSystemEventRecordId].UInt64Val);
        eventData["eventrecordid"] = buf;

        if (renderedValues[EvtSystemActivityID].Type != EvtVarTypeNull)
        {
            WCHAR guid[50] = { 0 };
            StringFromGUID2(*(renderedValues[EvtSystemActivityID].GuidVal), guid, sizeof(guid) / sizeof(WCHAR));;
            eventData["activityid"] = base::wstring_to_string(guid);
        }

        if (renderedValues[EvtSystemRelatedActivityID].Type != EvtVarTypeNull)
        {
            WCHAR guid[50] = { 0 };
            StringFromGUID2(*(renderedValues[EvtSystemRelatedActivityID].GuidVal), guid, sizeof(guid) / sizeof(WCHAR));;
            eventData["relatedactivityid"] = base::wstring_to_string(guid);
        }

        snprintf(buf, sizeof(buf), "%lu", renderedValues[EvtSystemProcessID].UInt32Val);
        eventData["processid"] = buf;

        snprintf(buf, sizeof(buf), "%lu", renderedValues[EvtSystemThreadID].UInt32Val);
        eventData["threadid"] = buf;

        tempBuf = (renderedValues[EvtSystemChannel].Type == EvtVarTypeNull) ? renderedValues[EvtSystemChannel].StringVal : L"";
        eventData["channel"] = base::wstring_to_string(tempBuf);

        eventData["computer"] = base::wstring_to_string(renderedValues[EvtSystemComputer].StringVal);

        if (renderedValues[EvtSystemUserID].Type != EvtVarTypeNull)
        {
            LPWSTR pwsSid = nullptr;
            if (ConvertSidToStringSid(renderedValues[EvtSystemUserID].SidVal, &pwsSid))
            {
                eventData["secuserid"] = base::wstring_to_string(pwsSid);
                LocalFree(pwsSid);
            }
        }
        // Get the handle to the provider's metadata that contains the message strings.
        EVT_HANDLE providerMetadata = EvtOpenPublisherMetadata(nullptr, renderedValues[EvtSystemProviderName].StringVal, nullptr, 0, 0);
        if (providerMetadata == nullptr)
            break;
        eventData["message"] = GetMessageString(providerMetadata, eventHandle);
        _printResultsCallback(eventData);
    } while (false);

    if (context)
        EvtClose(context);
    if (renderedValues)
        free(renderedValues);
    return status;
}
Example #17
0
/* 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;
}
Example #18
0
/* open eventlog using API 6 and return the number of records */
static int	zbx_open_eventlog6(const wchar_t *wsource, zbx_uint64_t *lastlogsize, EVT_HANDLE *render_context,
		zbx_uint64_t *FirstID, zbx_uint64_t *LastID)
{
	const char	*__function_name = "zbx_open_eventlog6";
	EVT_HANDLE	log = NULL;
	EVT_VARIANT	var;
	EVT_HANDLE	tmp_all_event_query = NULL;
	EVT_HANDLE	event_bookmark = NULL;
	EVT_VARIANT*	renderedContent = NULL;
	DWORD		status = 0;
	DWORD		size_required = 0;
	DWORD		size = DEFAULT_EVENT_CONTENT_SIZE;
	DWORD		bookmarkedCount = 0;
	zbx_uint64_t	numIDs = 0;
	char		*tmp_str = NULL;
	int		ret = FAIL;

	*FirstID = 0;
	*LastID = 0;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	/* try to open the desired log */
	if (NULL == (log = EvtOpenLog(NULL, wsource, EvtOpenChannelPath)))
	{
		tmp_str = zbx_unicode_to_utf8(wsource);
		zabbix_log(LOG_LEVEL_WARNING, "cannot open eventlog '%s':%s", tmp_str,
				strerror_from_system(GetLastError()));
		goto out;
	}

	/* obtain the number of records in the log */
	if (TRUE != EvtGetLogInfo(log, EvtLogNumberOfLogRecords, sizeof(var), &var, &size_required))
	{
		zabbix_log(LOG_LEVEL_WARNING, "EvtGetLogInfo failed:%s",
				strerror_from_system(GetLastError()));
		goto out;
	}

	numIDs = var.UInt64Val;

	/* get the number of the oldest record in the log				*/
	/* "EvtGetLogInfo()" does not work properly with "EvtLogOldestRecordNumber"	*/
	/* we have to get it from the first EventRecordID				*/

	/* create the system render */
	if (NULL == (*render_context = EvtCreateRenderContext(RENDER_ITEMS_COUNT, RENDER_ITEMS, EvtRenderContextValues)))
	{
		zabbix_log(LOG_LEVEL_WARNING, "EvtCreateRenderContext failed:%s", strerror_from_system(GetLastError()));
		goto out;
	}

	/* get all eventlog */
	tmp_all_event_query = EvtQuery(NULL, wsource, NULL, EvtQueryChannelPath);
	if (NULL == tmp_all_event_query)
	{
		if (ERROR_EVT_CHANNEL_NOT_FOUND == (status = GetLastError()))
			zabbix_log(LOG_LEVEL_WARNING, "EvtQuery channel missed:%s", strerror_from_system(status));
		else
			zabbix_log(LOG_LEVEL_WARNING, "EvtQuery failed:%s", strerror_from_system(status));

		goto out;
	}

	/* get the entries and allocate the required space */
	renderedContent = zbx_malloc(renderedContent, size);
	if (TRUE != EvtNext(tmp_all_event_query, 1, &event_bookmark, INFINITE, 0, &size_required))
	{
		/* no data in eventlog */
		zabbix_log(LOG_LEVEL_DEBUG, "first EvtNext failed:%s", strerror_from_system(GetLastError()));
		*FirstID = 1;
		*LastID = 1;
		numIDs = 0;
		*lastlogsize = 0;
		ret = SUCCEED;
		goto out;
	}

	/* obtain the information from selected events */
	if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
			&size_required, &bookmarkedCount))
	{
		/* information exceeds the allocated space */
		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, size_required);
		size = size_required;

		if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
				&size_required, &bookmarkedCount))
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed:%s", strerror_from_system(GetLastError()));
			goto out;
		}
	}

	*FirstID = VAR_RECORD_NUMBER(renderedContent);
	*LastID = *FirstID + numIDs;

	if (*lastlogsize >= *LastID)
	{
		*lastlogsize = *FirstID - 1;
		zabbix_log(LOG_LEVEL_DEBUG, "lastlogsize is too big. It is set to:" ZBX_FS_UI64, *lastlogsize);
	}

	ret = SUCCEED;
out:
	if (NULL != log)
		EvtClose(log);
	if (NULL != tmp_all_event_query)
		EvtClose(tmp_all_event_query);
	if (NULL != event_bookmark)
		EvtClose(event_bookmark);
	zbx_free(tmp_str);
	zbx_free(renderedContent);
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s FirstID:" ZBX_FS_UI64 " LastID:" ZBX_FS_UI64 " numIDs:" ZBX_FS_UI64,
			__function_name, zbx_result_string(ret), *FirstID, *LastID, numIDs);

	return ret;
}
Example #19
0
/* Cancel the subscription */
void WinEventCancelSubscribes()
{
    if (WinEventSub != NULL)
        EvtClose(WinEventSub);
}
Example #20
0
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;
}
Example #21
0
/****
 * ProcessResults
 *
 * DESC:
 *     Creates a remote context 
 *
 * ARGS:
 *     hRemote - Remote session context
 *     hResults - An open set of results
 *     outputFormat - 0 for JSON, otherwise XML
 *     mode - last record vs dump results
 *     debug - set to 0 (none) 1 (basic) or 2 (verbose)
 */
DWORD64 ProcessResults(EVT_HANDLE hRemote, EVT_HANDLE hResults, int outputFormat, int mode, int debug)
{
    DWORD64 status = ERROR_SUCCESS;
    EVT_HANDLE hEvents[CHUNK_SIZE + 1];
    DWORD dwReturned = 0;
	BOOL completed = FALSE;	
	BOOL firstRecordCompleted = FALSE;

	// Print header information for our events
	if( outputFormat == OUTPUT_FORMAT_JSON ) {
		// Note: Marc requested this to be removed
		//wprintf(L"[");
	} else {
		wprintf(L"%s||%s||%s||%s||%s||%s||%s||%s\n\n", L"RecordID", L"EventID", L"Channel", L"Provider", L"Computer", L"TimeCreated", L"Task", L"Level");
	}

	// Begin an infinite loop, as we want to continue reading records as long as they are available.
	// The break-condition is a manual one at the bottom (i.e. no more records found)
    while (TRUE)
    {
        // Get a block of events from the result set.
        if (EvtNext(hResults, CHUNK_SIZE, hEvents, INFINITE, 0, &dwReturned))
        {
			// Cycle through all the events that we received
			for (DWORD i = 0; i < dwReturned; i++)
			{
				// Only print the separator characters once the first record is completed
				if( firstRecordCompleted )
					wprintf(L"||");

				// Extract event details and output the screen
				DWORD64 result = DumpEventInfo(hRemote, hEvents[i], outputFormat, mode, debug);
				
				// Set flag indicating first record is completed so that
				// the top of our loop knows to begin printing the separator character
				firstRecordCompleted = TRUE;

				// Close the handle to the current event, as we are done
				EvtClose(hEvents[i]);

				// Clear the event handle so our cleanup routine does not attempt to re-close
				hEvents[i] = NULL;

				// If currently in "last record" mode			
				if( mode == MODE_FETCH_LAST_RECORD ) {
					// We do not need to process anymore events
					// Recall that all we were looking for was the record ID of the most recent record
					// This should be stored in "status" as, this is the variable that's returned
					status = result;

					completed = true;

					break;
				}
			}
        }
		else 
		{
			// Call to retrieve events failed. Get the error code
			status = GetLastError();

			// If the error was the result of not having any more records
            if (status == ERROR_NO_MORE_ITEMS)
            {
				// Exit the loop. No more records to process
				completed = TRUE;
            }
			else 
			{
				// Otherwise, notify user of the error
                fwprintf(stderr, L"Failed to fetch next batch with following error: %lu\n", status);
			}
		}

		// Cycle through all records that we received
		// Recall that dwReturned contains the number of records received
		for (DWORD i = 0; i < dwReturned; i++)
		{
			// If the event isn't already closed
			if (hEvents[i] != NULL) 
			{
				// Close the event record
				EvtClose(hEvents[i]);
			}
		}

		// Exit the loop if required (i.e. we're done)
		if( completed )
			break;
	}

	// Add closing tag if this is JSON
	if( outputFormat == OUTPUT_FORMAT_JSON ) {
		// Marc requested this to be removed
		// wprintf(L"]");
	}

    return status;
}
Example #22
0
ULONG
QueryEvents (
    __in PCWSTR Channel,
    __in PCWSTR XPath
)

/*++

Routine Description:

    This function queries events from the given channel and prints their
    description to the standard output.

Arguments:

    Channel - Supplies the name of the channel whose events will be displayed.

    XPath - Supplies the XPath expression to filter events with.

Return Value:

    Win32 error code indicating if querying was successful.

--*/

{
    PWSTR Buffer;
    ULONG BufferSize;
    ULONG BufferSizeNeeded;
    ULONG Count;
    EVT_HANDLE Event;
    EVT_HANDLE Query;
    ULONG Status;

    //
    // Create the query.
    //

    Query = EvtQuery(NULL, Channel, XPath, EvtQueryChannelPath);
    if (Query == NULL) {
        return GetLastError();
    }

    //
    // Read each event and render it as XML.
    //

    Buffer = NULL;
    BufferSize = 0;
    BufferSizeNeeded = 0;

    while (EvtNext(Query, 1, &Event, INFINITE, 0, &Count) != FALSE) {

        do {
            if (BufferSizeNeeded > BufferSize) {
                free(Buffer);
                BufferSize = BufferSizeNeeded;
                Buffer = malloc(BufferSize);
                if (Buffer == NULL) {
                    Status = ERROR_OUTOFMEMORY;
                    BufferSize = 0;
                    break;
                }
            }

            if (EvtRender(NULL,
                          Event,
                          EvtRenderEventXml,
                          BufferSize,
                          Buffer,
                          &BufferSizeNeeded,
                          &Count) != FALSE) {
                Status = ERROR_SUCCESS;
            } else {
                Status = GetLastError();
            }
        } while (Status == ERROR_INSUFFICIENT_BUFFER);

        //
        // Display either the event xml or an error message.
        //

        if (Status == ERROR_SUCCESS) {
            wprintf(L"%s\n", Buffer);
        } else {
            wprintf(L"Error rendering event.\n");
        }

        EvtClose(Event);
    }

    //
    // When EvtNextChannelPath returns ERROR_NO_MORE_ITEMS, we have actually
    // iterated through all matching events and thus succeeded.
    //

    Status = GetLastError();
    if (Status == ERROR_NO_MORE_ITEMS) {
        Status = ERROR_SUCCESS;
    }

    //
    // Free resources.
    //

    EvtClose(Query);
    free(Buffer);

    return Status;
}
Example #23
0
/****
 * ParseEventLogInternal
 *
 * DESC:
 *     Gets the most recent event log record
 *
 * ARGS:
 *     server - IP or host to connect to
 *     domain - domain within the host (empty string for none)
 *     username - username within the domain
 *     password - password for above user
 *     logName - event log to open (default to "Application" if NULL)
 *     query - XPath query to retrieve (see remarks)
 *     outputFormat - set to 0 (JSON) otherwise XML
 *     debug - set to 0 (none) 1 (basic) or 2 (verbose)
 *     mode - mode to run the parser (see remarks)
 *
 * REMARKS:
 *     XPath:
 * 
 *     The Windows Event log is structurally an XML document. You
 *     may therefore use XPath queries to retrieve the information 
 *     you want. Pre-defined XPath queries have been built into the
 *     supplementary Perl module. However, you are free to modify
 *     that module to include newer queries, based on your requirements
 *
 *     mode:
 *
 *     Can be set to either MODE_FETCH_LAST_RECORD or MODE_DEFAULT. The
 *     former will simply return the Event Log Record ID of the topmost
 *     (i.e. the latest) event record. The latter will do the actual
 *     processing of parsing an event log record to the screen.
 *
 *     Note: As per previous discussions, output format is forced as
 *     JSON here. To re-allow XML, simply replace OUTPUT_FORMAT_JSON
 *     with outputFormat, in the line of code, below
 */
DWORD64 ParseEventLogInternal(LPWSTR server, LPWSTR domain, LPWSTR username, LPWSTR password, LPWSTR logName, LPWSTR query, INT outputFormat, INT debug, INT mode) {	
	bool getLastRecord = false;
	DWORD64 result = 0;

	if( debug > DEBUG_L1 ) {
		wprintf(L"[ParseEventLogInternal]: Attempting to connect to '%s' on domain '%s' using %s:%s...\n", server, domain, username, password);
	}

	// If no domain was supplied
	if( wcslen(domain) == 0 ) {
		// Official MSDN specs request NULL instead of an empty string
		domain = NULL;

		if( debug >= DEBUG_L1 ) {
			wprintf(L"[ParseEventLogInternal]: Empty domain supplied. Default to NULL\n");
		}		
	}
		
	// If a blank query was supplied, assume no query (NULL)
	if( lstrlen(query) == 0 )
		query = NULL;

	// If the supplied query is our special token that retrieves the last record
	if( lstrcmpW( query, L"LAST_RECORD") == 0 ) {
		if( debug >= DEBUG_L1 ) {
			wprintf(L"[ParseEventLogInternal]: Mode is last record fetch\n");
		}

		// Flag the processing routine to only fetch the lastest record
		getLastRecord = true;

		// Force an empty query so that the last record is not affected by query filters
		// An empty query means it will get ALL records, in which case we are guaranteed
		// the latest record (i.e. the record ID we want) is the first to be retrieved
		query = NULL;
	} else {
		if( debug >= DEBUG_L1 ) {
			if( query == NULL ) {
				wprintf(L"[ParseEventLogInternal]: (no query specified)\n");
			} else {
				wprintf(L"[ParseEventLogInternal]: Using query: %s\n", query);
			}
		}
	}

	// Create a remote context to the external server
    EVT_HANDLE hRemote = CreateRemoteSession(server, domain, username, password);

    if (hRemote != NULL)
    {
		// NOTE: Reaching here does not mean the connection succeeded. It merely 
		// means that we successfully created the remote context

		if( debug >= DEBUG_L1 ) {
			wprintf(L"[ParseEventLogInternal]: Attempting to query the EventLog...\n\n", hRemote);
		}

		// Attempt to query event log in reverse chronological order (newest to oldest)
		EVT_HANDLE hResults = EvtQuery( hRemote, logName, query, EvtQueryChannelPath | EvtQueryReverseDirection);

		// If the query was successful
		if (hResults != NULL) 
		{
			// Process the first event found
			DumpEventInfo(hRemote, hResults, outputFormat, getLastRecord ? MODE_FETCH_LAST_RECORD : 0, debug);

			// Process subsequent events
			result = ProcessResults(hRemote, hResults, outputFormat, getLastRecord ? MODE_FETCH_LAST_RECORD : 0, debug);
		}
		else
		{
			// Query was not successful. Get the error code
			DWORD dwError = GetLastError();

			if (dwError == ERROR_EVT_CHANNEL_NOT_FOUND) 
			{
				fwprintf(stderr, L"[Error][ParseEventLog]: Could not open the '%s' log on this machine.\n", logName);
			}
			else if (dwError == ERROR_EVT_INVALID_QUERY)
			{
				// You can call the EvtGetExtendedStatus function to try to get 
				// additional information as to what is wrong with the query.
				fwprintf(stderr, L"[Error][ParseEventLog]: The specified search query is not valid.\n");
			}
			else
			{
				fwprintf(stderr, L"[Error][ParseEventLog]: Could not read event logs due to the following Windows error: %lu.\n", dwError);
			}
		}

		// Close the handle to the query we opened
		EvtClose(hRemote);
    }
	else 
	{
        fwprintf(stderr, L"[Error][ParseEventLog]: Failed to connect to remote computer. Error code is %d.\n", GetLastError());
	}

	return result;
}
Example #24
0
/* 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() lastlogsize:" ZBX_FS_UI64, __function_name, *which);

	if (NULL == *query)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "no EvtQuery handle");
		goto finish;
	}

	/* get the entries and allocate required space */
	renderedContent = zbx_malloc(renderedContent, size);
	if (TRUE != EvtNext(*query, 1, &event_bookmark, INFINITE, 0, &require))
	{
		zabbix_log(LOG_LEVEL_WARNING, "EvtNext failed: %s, lastlogsize:" ZBX_FS_UI64,
				strerror_from_system(GetLastError()), *which);
		goto finish;
	}

	/* obtain the information from the selected events */
	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 finish;
		}

		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 finish;
		}
	}

	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, "Overwriting expected EventRecordID:" ZBX_FS_UI64 " with the real"
				" EventRecordID:" ZBX_FS_UI64 " in eventlog '%s'", *which,
				VAR_RECORD_NUMBER(renderedContent), tmp_str);
		*which = VAR_RECORD_NUMBER(renderedContent);
	}

	/* some events dont 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);
	}

	ret = SUCCEED;

finish:
	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;
}