source: nscp/modules/CheckEventLog/CheckEventLog.cpp @ 1b7ae3d

0.4.00.4.10.4.2stable
Last change on this file since 1b7ae3d was 6817602, checked in by Michael Medin <michael@…>, 7 years ago

Lots of update (I really should checkin more often :)

  • Property mode set to 100644
File size: 8.8 KB
Line 
1// CheckEventLog.cpp : Defines the entry point for the DLL application.
2//
3
4#include "stdafx.h"
5#include "CheckEventLog.h"
6#include <strEx.h>
7#include <time.h>
8#include <utils.h>
9
10CheckEventLog gCheckEventLog;
11
12BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
13{
14        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
15        return TRUE;
16}
17
18CheckEventLog::CheckEventLog() {
19}
20CheckEventLog::~CheckEventLog() {
21}
22
23
24bool CheckEventLog::loadModule() {
25        return true;
26}
27bool CheckEventLog::unloadModule() {
28        return true;
29}
30
31bool CheckEventLog::hasCommandHandler() {
32        return true;
33}
34bool CheckEventLog::hasMessageHandler() {
35        return false;
36}
37
38
39
40class EventLogRecord {
41        EVENTLOGRECORD *pevlr_;
42        __int64 currentTime_;
43public:
44        EventLogRecord(EVENTLOGRECORD *pevlr, __int64 currentTime) : pevlr_(pevlr), currentTime_(currentTime) {
45        }
46        inline __int64 timeGenerated() const {
47                return (currentTime_-pevlr_->TimeGenerated)*1000;
48        }
49        inline __int64 timeWritten() const {
50                return (currentTime_-pevlr_->TimeWritten)*1000;
51        }
52        inline std::string eventSource() const {
53                return reinterpret_cast<LPSTR>(reinterpret_cast<LPBYTE>(pevlr_) + sizeof(EVENTLOGRECORD));
54        }
55        inline DWORD eventID() const {
56                return (pevlr_->EventID&0xffff);
57        }
58        inline DWORD severity() const {
59                return (pevlr_->EventID>>30);
60        }
61
62        inline DWORD eventType() const {
63                return pevlr_->EventType;
64        }
65/*
66        std::string userSID() const {
67                if (pevlr_->UserSidOffset == 0)
68                        return "";
69                PSID p = reinterpret_cast<PSID>(reinterpret_cast<LPBYTE>(pevlr_) + + pevlr_->UserSidOffset);
70                LPSTR user = new CHAR[1025];
71                LPSTR domain = new CHAR[1025];
72                DWORD userLen = 1024;
73                DWORD domainLen = 1024;
74                SID_NAME_USE sidName;
75                LookupAccountSid(NULL, p, user, &userLen, domain, &domainLen, &sidName);
76                user[userLen] = 0;
77                domain[domainLen] = 0;
78                return std::string(domain) + "\\" + std::string(user);
79        }
80        */
81
82        std::string enumStrings() const {
83                std::string ret;
84                LPSTR p = reinterpret_cast<LPSTR>(reinterpret_cast<LPBYTE>(pevlr_) + pevlr_->StringOffset);
85                for (unsigned int i =0;i<pevlr_->NumStrings;i++) {
86                        std::string s = p;
87                        if (!s.empty())
88                                s += ", ";
89                        ret += s;
90                        p+= strlen(p)+1;
91                }
92                return ret;
93        }
94
95        static DWORD appendType(DWORD dwType, std::string sType) {
96                return dwType | translateType(sType);
97        }
98        static DWORD subtractType(DWORD dwType, std::string sType) {
99                return dwType & (!translateType(sType));
100        }
101        static DWORD translateType(std::string sType) {
102                if (sType == "error")
103                        return EVENTLOG_ERROR_TYPE;
104                if (sType == "warning")
105                        return EVENTLOG_WARNING_TYPE;
106                if (sType == "info")
107                        return EVENTLOG_INFORMATION_TYPE;
108                if (sType == "auditSuccess")
109                        return EVENTLOG_AUDIT_SUCCESS;
110                if (sType == "auditFailure")
111                        return EVENTLOG_AUDIT_FAILURE;
112                return strEx::stoi(sType);
113        }
114        static std::string translateType(DWORD dwType) {
115                if (dwType == EVENTLOG_ERROR_TYPE)
116                        return "error";
117                if (dwType == EVENTLOG_WARNING_TYPE)
118                        return "warning";
119                if (dwType == EVENTLOG_INFORMATION_TYPE)
120                        return "info";
121                if (dwType == EVENTLOG_AUDIT_SUCCESS)
122                        return "auditSuccess";
123                if (dwType == EVENTLOG_AUDIT_FAILURE)
124                        return "auditFailure";
125                return strEx::itos(dwType);
126        }
127        static DWORD translateSeverity(std::string sType) {
128                if (sType == "success")
129                        return 0;
130                if (sType == "informational")
131                        return 1;
132                if (sType == "warning")
133                        return 2;
134                if (sType == "error")
135                        return 3;
136                return strEx::stoi(sType);
137        }
138        static std::string translateSeverity(DWORD dwType) {
139                if (dwType == 0)
140                        return "success";
141                if (dwType == 1)
142                        return "informational";
143                if (dwType == 2)
144                        return "warning";
145                if (dwType == 3)
146                        return "error";
147                return strEx::itos(dwType);
148        }
149};
150
151
152struct eventlog_filter {
153        filters::filter_all_strings eventSource;
154        filters::filter_all_numeric<unsigned int, filters::handlers::eventtype_handler> eventType;
155        filters::filter_all_numeric<unsigned int, filters::handlers::eventseverity_handler> eventSeverity;
156        filters::filter_all_strings message;
157        filters::filter_all_times timeWritten;
158        filters::filter_all_times timeGenerated;
159        filters::filter_all_numeric<DWORD, filters::handlers::eventtype_handler> eventID;
160
161        inline bool hasFilter() {
162                return eventSource.hasFilter() || eventType.hasFilter() || eventID.hasFilter() || eventSeverity.hasFilter() || message.hasFilter() ||
163                        timeWritten.hasFilter() || timeGenerated.hasFilter();
164        }
165        bool matchFilter(const EventLogRecord &value) const {
166                if ((eventSource.hasFilter())&&(eventSource.matchFilter(value.eventSource())))
167                        return true;
168                else if ((eventType.hasFilter())&&(eventType.matchFilter(value.eventType())))
169                        return true;
170                else if ((eventSeverity.hasFilter())&&(eventSeverity.matchFilter(value.severity())))
171                        return true;
172                else if ((eventID.hasFilter())&&(eventID.matchFilter(value.eventID())))
173                        return true;
174                else if ((message.hasFilter())&&(message.matchFilter(value.enumStrings())))
175                        return true;
176                else if ((timeWritten.hasFilter())&&(timeWritten.matchFilter(value.timeWritten())))
177                        return true;
178                else if ((timeGenerated.hasFilter())&&(timeGenerated.matchFilter(value.timeGenerated())))
179                        return true;
180                return false;
181        }
182};
183
184
185#define MAP_FILTER(value, obj) \
186                        else if (p__.first == value) { eventlog_filter filter; filter.obj = p__.second; filter_chain.push_back(filter); }
187
188
189#define BUFFER_SIZE 1024*64
190NSCAPI::nagiosReturn CheckEventLog::handleCommand(const strEx::blindstr command, const unsigned int argLen, char **char_args, std::string &message, std::string &perf) {
191        if (command != "CheckEventLog")
192                return NSCAPI::returnIgnored;
193        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBoundsUInteger> EventLogQueryConatiner;
194        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
195        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
196
197        std::list<std::string> files;
198        std::list<eventlog_filter> filter_chain;
199        EventLogQueryConatiner query;
200
201        bool bFilterIn = true;
202        bool bFilterAll = false;
203        bool bShowDescriptions = false;
204        unsigned int truncate = 0;
205
206        try {
207                MAP_OPTIONS_BEGIN(stl_args)
208                        MAP_OPTIONS_NUMERIC_ALL(query, "")
209                        MAP_OPTIONS_STR2INT("truncate", truncate)
210                        MAP_OPTIONS_BOOL_TRUE("descriptions", bShowDescriptions)
211                        MAP_OPTIONS_PUSH("file", files)
212                        MAP_OPTIONS_BOOL_EX("filter", bFilterIn, "in", "out")
213                        MAP_OPTIONS_BOOL_EX("filter", bFilterAll, "all", "any")
214                        MAP_FILTER("filter-eventType", eventType)
215                        MAP_FILTER("filter-severity", eventSeverity)
216                        MAP_FILTER("filter-eventID", eventID)
217                        MAP_FILTER("filter-eventSource", eventSource)
218                        MAP_FILTER("filter-generated", timeGenerated)
219                        MAP_FILTER("filter-written", timeWritten)
220                        MAP_FILTER("filter-message", message)
221                        MAP_OPTIONS_MISSING(message, "Unknown argument: ")
222                MAP_OPTIONS_END()
223        } catch (filters::parse_exception e) {
224                message = e.getMessage();
225                return NSCAPI::returnUNKNOWN;
226        } catch (filters::filter_exception e) {
227                message = e.getMessage();
228                return NSCAPI::returnUNKNOWN;
229        }
230
231        unsigned int hit_count = 0;
232
233        for (std::list<std::string>::const_iterator cit2 = files.begin(); cit2 != files.end(); ++cit2) {
234                HANDLE hLog = OpenEventLog(NULL, (*cit2).c_str());
235                if (hLog == NULL) {
236                        message = "Could not open the '" + (*cit2) + "' event log.";
237                        return NSCAPI::returnUNKNOWN;
238                }
239
240                DWORD dwThisRecord, dwRead, dwNeeded;
241                EVENTLOGRECORD *pevlr;
242                BYTE bBuffer[BUFFER_SIZE];
243
244                pevlr = reinterpret_cast<EVENTLOGRECORD*>(&bBuffer);
245
246                __time64_t ltime;
247                _time64(&ltime);
248
249                GetOldestEventLogRecord(hLog, &dwThisRecord);
250
251                while (ReadEventLog(hLog, EVENTLOG_FORWARDS_READ|EVENTLOG_SEQUENTIAL_READ,
252                        0, pevlr, BUFFER_SIZE, &dwRead, &dwNeeded))
253                {
254                        while (dwRead > 0)
255                        {
256                                bool bMatch = bFilterAll;
257                                EventLogRecord record(pevlr, ltime);
258
259                                for (std::list<eventlog_filter>::const_iterator cit3 = filter_chain.begin(); cit3 != filter_chain.end(); ++cit3 ) {
260                                        bool bTmpMatched = (*cit3).matchFilter(record);
261                                        if (bFilterAll) {
262                                                if (!bTmpMatched) {
263                                                        bMatch = false;
264                                                        break;
265                                                }
266                                        } else {
267                                                if (bTmpMatched) {
268                                                        bMatch = true;
269                                                        break;
270                                                }
271                                        }
272                                }
273
274                                if ((bFilterIn&&bMatch)||(!bFilterIn&&!bMatch)) {
275                                        strEx::append_list(message, record.eventSource());
276                                        if (bShowDescriptions) {
277                                                message += "(" + EventLogRecord::translateType(record.eventType()) + ", " + strEx::itos(record.eventID()) + ", " + EventLogRecord::translateSeverity(record.severity()) + ")";
278                                                message += "[" + record.enumStrings() + "]";
279                                        }
280                                        hit_count++;
281                                }
282                                dwRead -= pevlr->Length;
283                                pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length);
284                        }
285                        pevlr = (EVENTLOGRECORD *) &bBuffer;
286                }
287                CloseEventLog(hLog);
288        }
289        query.runCheck(hit_count, returnCode, message, perf);
290        if ((truncate > 0) && (message.length() > (truncate-4)))
291                message = message.substr(0, truncate-4) + "...";
292        if (message.empty())
293                message = "Eventlog check ok";
294        return returnCode;
295}
296
297
298NSC_WRAPPERS_MAIN_DEF(gCheckEventLog);
299NSC_WRAPPERS_IGNORE_MSG_DEF();
300NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckEventLog);
Note: See TracBrowser for help on using the repository browser.