source: trunk/src/sh_log_evalrule.c@ 183

Last change on this file since 183 was 183, checked in by katerina, 16 years ago

Support for logfile monitoring (ticket #122). Also improved some configure error messages.

File size: 19.9 KB
Line 
1
2#include "config_xor.h"
3
4#include <stdio.h>
5#include <stdarg.h>
6#include <string.h>
7#include <time.h>
8#include <limits.h>
9#include <sys/types.h>
10
11#ifdef USE_LOGFILE_MONITOR
12
13#undef FIL__
14#define FIL__ _("sh_log_evalrule.c")
15
16/* Debian/Ubuntu: libpcre3-dev */
17#include <pcre.h>
18
19#include "samhain.h"
20#include "sh_pthread.h"
21#include "sh_utils.h"
22#include "sh_string.h"
23#include "sh_log_check.h"
24#include "sh_log_evalrule.h"
25#include "zAVLTree.h"
26
27/* #define DEBUG_EVALRULES */
28
29#ifdef DEBUG_EVALRULES
30void DEBUG(const char *fmt, ...)
31{
32 va_list ap;
33 va_start(ap, fmt);
34 vfprintf(stderr, fmt, ap); /* flawfinder: ignore *//* we control fmt string */
35 va_end(ap);
36 return;
37}
38#else
39void DEBUG(const char *fmt, ...)
40{
41 (void) fmt;
42 return;
43}
44#endif
45
46enum policies {
47 EVAL_REPORT,
48 EVAL_SUM
49};
50
51struct sh_ceval /* Counter for summarizing */
52{
53 sh_string * hostname;
54 sh_string * counted_str;
55 sh_string * filename;
56 unsigned long count;
57 time_t start;
58 time_t interval;
59};
60
61void sh_ceval_free(void * item)
62{
63 struct sh_ceval * counter = (struct sh_ceval *) item;
64 if (!counter)
65 return;
66 sh_string_destroy(&(counter->hostname));
67 sh_string_destroy(&(counter->counted_str));
68 sh_string_destroy(&(counter->filename));
69 SH_FREE(counter);
70}
71
72struct sh_qeval /* Queue with definitions */
73{
74 sh_string * label;
75 enum policies policy;
76 int severity;
77 time_t interval; /* if EVAL_SUM, interval */
78 struct sh_qeval * next;
79};
80
81struct sh_geval /* Group of rules (may be a single rule) */
82{
83 sh_string * label; /* label for this group */
84 pcre * rule; /* compiled regex for rule */
85 pcre_extra * rule_extra;
86 int * ovector; /* captured substrings */
87 int ovecnum; /* how many captured */
88 int captures; /* (captures+1)*3 required */
89 zAVLTree * counterlist; /* counters if EVAL_SUM */
90 struct sh_qeval * queue; /* queue for this rule */
91 struct sh_geval * nextrule; /* next rule in this group */
92 struct sh_geval * next; /* next group of rules */
93};
94
95struct sh_heval /* host-specific rules */
96{
97 pcre * hostname; /* compiled regex for hostname */
98 pcre_extra * hostname_extra;
99 struct sh_geval * rulegroups; /* list of group of rules */
100 struct sh_heval * next;
101};
102
103static struct sh_heval * hostlist = NULL;
104static struct sh_qeval * queuelist = NULL;
105static struct sh_geval * grouplist = NULL;
106
107/* These flags are set if we are within
108 * the define of a host/rule group.
109 */
110static struct sh_heval * host_open = NULL;
111static struct sh_geval * group_open = NULL;
112
113int sh_eval_gend (const char * str)
114{
115 (void) str;
116 if (group_open) {
117 group_open = NULL;
118 return 0;
119 }
120 return -1;
121}
122
123int sh_eval_gadd (const char * str)
124{
125 struct sh_geval * ng;
126 struct sh_geval * tmp;
127 pcre * group;
128 pcre_extra * group_extra;
129 const char * error;
130 int erroffset;
131 unsigned int nfields = 2;
132 size_t lengths[2];
133 char * new = sh_util_strdup(str);
134 char ** splits = split_array(new, &nfields, ':', lengths);
135
136 if (group_open)
137 group_open = NULL;
138
139 if (nfields != 2)
140 {
141 SH_FREE(splits);
142 SH_FREE(new);
143 return -1;
144 }
145
146 group = pcre_compile(splits[1], PCRE_NO_AUTO_CAPTURE,
147 &error, &erroffset, NULL);
148 if (!group)
149 {
150 sh_string * msg = sh_string_new(0);
151 sh_string_add_from_char(msg, _("Bad regex: "));
152 sh_string_add_from_char(msg, splits[1]);
153
154 SH_MUTEX_LOCK(mutex_thread_nolog);
155 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
156 sh_string_str(msg),
157 _("sh_eval_gadd"));
158 SH_MUTEX_UNLOCK(mutex_thread_nolog);
159 sh_string_destroy(&msg);
160
161 SH_FREE(splits);
162 SH_FREE(new);
163 return -1;
164 }
165 group_extra = NULL; /* pcre_study(group, 0, &error); */
166
167 ng = SH_ALLOC(sizeof(struct sh_geval));
168 ng->label = sh_string_new_from_lchar(splits[0], lengths[0]);
169 ng->rule = group;
170 ng->rule_extra = group_extra;
171 ng->ovector = NULL;
172 ng->captures = 0;
173 ng->counterlist = NULL;
174 ng->queue = NULL;
175 ng->nextrule = NULL;
176
177 /*
178 * Insert at end, to keep user-defined order
179 */
180 ng->next = NULL;
181 if (grouplist)
182 {
183 tmp = grouplist;
184 while (tmp->next != NULL) { tmp = tmp->next; }
185 tmp->next = ng;
186 } else {
187 grouplist = ng;
188 }
189
190 if (!host_open)
191 {
192 if (0 != sh_eval_hadd("^.*"))
193 {
194 pcre_free(group);
195 sh_string_destroy(&(ng->label));
196 SH_FREE(splits);
197 SH_FREE(new);
198 SH_FREE(ng);
199 return -1;
200 }
201 }
202
203 /*
204 * If there is an open host group, add it to its
205 * rulegroups
206 */
207 if (host_open)
208 {
209 if (host_open->rulegroups)
210 {
211 tmp = host_open->rulegroups;
212 while (tmp->next != NULL) { tmp = tmp->next; }
213 tmp->next = ng;
214 } else {
215 host_open->rulegroups = ng;
216 }
217 }
218
219 group_open = ng;
220 SH_FREE(splits);
221 SH_FREE(new);
222 return 0;
223}
224
225int sh_eval_hend (const char * str)
226{
227 (void) str;
228 if (host_open) {
229 host_open = NULL;
230 return 0;
231 }
232 return -1;
233}
234
235int sh_eval_hadd (const char * str)
236{
237 struct sh_heval * nh;
238 struct sh_heval * tmp;
239 pcre * host;
240 pcre_extra * host_extra;
241 const char * error;
242 int erroffset;
243
244 if (host_open)
245 host_open = NULL;
246
247 host = pcre_compile(str, PCRE_NO_AUTO_CAPTURE,
248 &error, &erroffset, NULL);
249 if (!host)
250 {
251 sh_string * msg = sh_string_new(0);
252 sh_string_add_from_char(msg, _("Bad regex: "));
253 sh_string_add_from_char(msg, str);
254
255 SH_MUTEX_LOCK(mutex_thread_nolog);
256 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
257 sh_string_str(msg),
258 _("sh_eval_hadd"));
259 SH_MUTEX_UNLOCK(mutex_thread_nolog);
260 sh_string_destroy(&msg);
261
262 return -1;
263 }
264 host_extra = NULL; /* pcre_study(host, 0, &error); */
265
266 nh = SH_ALLOC(sizeof(struct sh_heval));
267 nh->hostname = host;
268 nh->hostname_extra = host_extra;
269 nh->rulegroups = NULL;
270
271 /*
272 * Insert at end, to keep user-defined order
273 */
274 nh->next = NULL;
275 if (hostlist) {
276 tmp = hostlist;
277 while (tmp->next != NULL) { tmp = tmp->next; }
278 tmp->next = nh;
279 } else {
280 hostlist = nh;
281 }
282 host_open = nh;
283
284 return 0;
285}
286
287int sh_eval_qadd (const char * str)
288{
289 struct sh_qeval * nq;
290 int severity;
291 unsigned int nfields = 4; /* label:interval:(report|sum):severity */
292 size_t lengths[4];
293 char * new = sh_util_strdup(str);
294 char ** splits = split_array(new, &nfields, ':', lengths);
295
296 if (nfields != 4)
297 {
298 SH_FREE(splits);
299 SH_FREE(new);
300 return -1;
301 }
302
303 if (strcmp(splits[2], _("sum")) && strcmp(splits[2], _("report")))
304 {
305 SH_FREE(splits);
306 SH_FREE(new);
307 return -1;
308 }
309
310 if (!strcmp(splits[2], _("sum")) && atoi(splits[1]) < 0)
311 {
312 SH_FREE(splits);
313 SH_FREE(new);
314 return -1;
315 }
316
317 severity = sh_error_convert_level (splits[3]);
318 if (severity < 0)
319 {
320 SH_FREE(splits);
321 SH_FREE(new);
322 return -1;
323 }
324
325 nq = SH_ALLOC(sizeof(struct sh_qeval));
326 nq->label = sh_string_new_from_lchar(splits[0], lengths[0]);
327
328 DEBUG("debug: splits[2] = %s, policy = %d\n",splits[2],nq->policy);
329 if (0 == strcmp(splits[2], _("report"))) {
330 nq->policy = EVAL_REPORT;
331 nq->interval = 0;
332 }
333 else {
334 nq->policy = EVAL_SUM;
335 nq->interval = (time_t) atoi(splits[1]);
336 }
337
338 nq->severity = severity;
339 nq->next = queuelist;
340 queuelist = nq;
341
342 SH_FREE(splits);
343 SH_FREE(new);
344 return 0;
345}
346
347static struct sh_qeval * find_queue(const char * str)
348{
349 struct sh_qeval * retval = queuelist;
350
351 if (!str)
352 return NULL;
353
354 while (retval)
355 {
356 if (0 == strcmp(str, sh_string_str(retval->label)))
357 break;
358 retval = retval->next;
359 }
360 return retval;
361}
362
363int sh_eval_radd (const char * str)
364{
365 struct sh_geval * nr;
366 struct sh_geval * tmp;
367 struct sh_qeval * queue = NULL;
368 pcre * rule;
369 pcre_extra * rule_extra;
370 const char * error;
371 int erroffset;
372 int captures = 0;
373 unsigned int nfields = 2; /* queue:regex */
374 size_t lengths[2];
375 char * new = sh_util_strdup(str);
376 char ** splits = split_array(new, &nfields, ':', lengths);
377
378 if (nfields != 2)
379 {
380 SH_FREE(splits);
381 SH_FREE(new);
382 return -1;
383 }
384
385 if (0 != strcmp(splits[0], _("trash")))
386 {
387 queue = find_queue(splits[0]);
388 if (!queue)
389 {
390 SH_FREE(splits);
391 SH_FREE(new);
392 return -1;
393 }
394 }
395
396 rule = pcre_compile(splits[1], 0,
397 &error, &erroffset, NULL);
398 if (!rule)
399 {
400 sh_string * msg = sh_string_new(0);
401 sh_string_add_from_char(msg, _("Bad regex: "));
402 sh_string_add_from_char(msg, splits[1]);
403
404 SH_MUTEX_LOCK(mutex_thread_nolog);
405 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
406 sh_string_str(msg),
407 _("sh_eval_radd"));
408 SH_MUTEX_UNLOCK(mutex_thread_nolog);
409 sh_string_destroy(&msg);
410
411 SH_FREE(splits);
412 SH_FREE(new);
413 return -1;
414 }
415 rule_extra = NULL; /* pcre_study(rule, 0, &error); */
416 pcre_fullinfo(rule, rule_extra, PCRE_INFO_CAPTURECOUNT, &captures);
417
418 DEBUG("adding rule: |%s| with %d captures\n", splits[1], captures);
419
420 SH_FREE(splits);
421 SH_FREE(new);
422
423 nr = SH_ALLOC(sizeof(struct sh_geval));
424 nr->label = NULL;
425 nr->rule = rule;
426 nr->rule_extra = rule_extra;
427 nr->captures = captures;
428 nr->ovector = SH_ALLOC(sizeof(int) * (captures+1) * 3);
429 nr->counterlist = NULL;
430 nr->queue = queue;
431 nr->nextrule = NULL;
432 nr->next = NULL;
433
434 /*
435 * If there is an open group, add it to its
436 * rules
437 */
438 if (group_open)
439 {
440 if (group_open->nextrule)
441 {
442 tmp = group_open->nextrule;
443 while (tmp->next != NULL) { tmp = tmp->next; }
444 tmp->next = nr;
445 } else {
446 group_open->nextrule = nr;
447 }
448 }
449
450 /*
451 * ..else, add it to the currently open host (open the
452 * default host, if there is no open one)
453 */
454 else
455 {
456 /*
457 * Add rule as member to grouplist, to facilitate cleanup
458 */
459 if (grouplist)
460 {
461 tmp = grouplist;
462 while (tmp->next != NULL) { tmp = tmp->next; }
463 tmp->next = nr;
464 } else {
465 grouplist = nr;
466 }
467
468 if (!host_open)
469 {
470 if (0 != sh_eval_hadd("^.*"))
471 {
472 SH_FREE(nr);
473 return -1;
474 }
475 }
476
477 /*
478 * Add rule to host rulegroups
479 */
480 if (host_open)
481 {
482 if (host_open->rulegroups)
483 {
484 /* Second, third, ... rule go to host_open->rulegroups->nextrule,
485 * since test_rules() iterates over nextrules
486 */
487 tmp = host_open->rulegroups;
488 while (tmp->nextrule != NULL) { tmp = tmp->nextrule; }
489 tmp->nextrule = nr;
490 } else {
491 /* First rule goes to host_open->rulegroups */
492 host_open->rulegroups = nr;
493 }
494 }
495 else
496 {
497 SH_FREE(nr);
498 return -1;
499 }
500 }
501
502 return 0;
503}
504
505void sh_eval_cleanup()
506{
507 struct sh_geval * nr;
508 struct sh_geval * tmp;
509
510 struct sh_geval * gtmp;
511 struct sh_qeval * qtmp;
512 struct sh_heval * htmp;
513
514 gtmp = grouplist;
515 while (gtmp)
516 {
517 if (gtmp->label) sh_string_destroy(&(gtmp->label));
518 if (gtmp->rule_extra) (*pcre_free)(gtmp->rule_extra);
519 if (gtmp->rule) (*pcre_free)(gtmp->rule);
520 if (gtmp->counterlist)
521 zAVLFreeTree(gtmp->counterlist, sh_ceval_free);
522 if (gtmp->ovector)
523 SH_FREE(gtmp->ovector);
524 if (gtmp->nextrule)
525 {
526 tmp = gtmp->nextrule;
527 do {
528 nr = tmp->nextrule;
529 if (tmp->rule_extra) (*pcre_free)(tmp->rule_extra);
530 if (tmp->rule) (*pcre_free)(tmp->rule);
531 if (tmp->counterlist)
532 zAVLFreeTree(tmp->counterlist, sh_ceval_free);
533 if (tmp->ovector)
534 SH_FREE(tmp->ovector);
535 SH_FREE(tmp);
536 tmp = nr;
537 } while (tmp);
538 }
539 grouplist = gtmp->next;
540 SH_FREE(gtmp);
541 gtmp = grouplist;
542 }
543
544 qtmp = queuelist;
545 while (qtmp)
546 {
547 if (qtmp->label) sh_string_destroy(&(qtmp->label));
548 queuelist = qtmp->next;
549 SH_FREE(qtmp);
550 qtmp = queuelist;
551 }
552
553 htmp = hostlist;
554 while (htmp)
555 {
556 if (htmp->hostname_extra) (*pcre_free)(htmp->hostname_extra);
557 if (htmp->hostname) (*pcre_free)(htmp->hostname);
558 hostlist = htmp->next;
559 SH_FREE(htmp);
560 htmp = hostlist;
561 }
562
563}
564
565/**********************************************************************
566 *
567 * Actual rule processing
568 *
569 **********************************************************************/
570
571/* Test a list of rules against msg; return matched rule, with ovector
572 * filled in
573 */
574static struct sh_geval * test_rule (struct sh_geval * rule, sh_string *msg)
575{
576 int res, count;
577
578 if (!rule)
579 DEBUG("debug: (NULL) rule\n");
580
581 if (rule && sh_string_len(msg) < (size_t)INT_MAX)
582 {
583 count = 1;
584 do {
585 DEBUG("debug: check rule %d for <%s>\n", count, msg->str);
586 res = pcre_exec(rule->rule, rule->rule_extra,
587 sh_string_str(msg), (int)sh_string_len(msg), 0,
588 0, rule->ovector, (3*(1+rule->captures)));
589 if (res >= 0)
590 {
591 rule->ovecnum = res;
592 DEBUG("debug: rule %d matches, result = %d\n", count, res);
593 break; /* return the matching rule; ovector is filled in */
594 }
595 DEBUG("debug: rule %d did not match\n", count);
596 rule = rule->nextrule; ++count;
597 } while (rule);
598 }
599 if (!rule)
600 DEBUG("debug: no match found\n");
601 /* If there was no match, this is NULL */
602 return rule;
603}
604
605/* Test a (struct sh_geval *), which may be single rule or a group of rules,
606 * against msg (if it's a group of rules, test against prefix first).
607 */
608static struct sh_geval * test_grules (struct sh_heval * host,
609 sh_string *prefix, sh_string *msg)
610{
611 struct sh_geval * result = NULL;
612 struct sh_geval * rules = host->rulegroups;
613
614 if (rules && sh_string_len(prefix) < (size_t)INT_MAX)
615 {
616 DEBUG("debug: if rules\n");
617 do {
618 if(rules->label != NULL)
619 {
620 /* this is a rule group; only groups have labels */
621
622 DEBUG("debug: if rules->label %s\n", rules->label->str);
623 if (pcre_exec(rules->rule, rules->rule_extra,
624 sh_string_str(prefix), (int) sh_string_len(prefix),
625 0, 0, NULL, 0) >= 0)
626 {
627 result = test_rule(rules->nextrule, msg);
628 if (result)
629 break;
630 }
631 }
632 else
633 {
634 /* First rule is in host->rulegroups */
635
636 DEBUG("debug: else (single rule)\n");
637 result = test_rule(rules, msg);
638 if (result)
639 break;
640 }
641 rules = rules->next; /* next group of rules */
642 } while (rules);
643 }
644 return result;
645}
646
647/* Top-level find_rule() function
648 */
649static struct sh_geval * find_rule (sh_string *host,
650 sh_string *prefix, sh_string *msg)
651{
652 struct sh_geval * result = NULL;
653 struct sh_heval * hlist = hostlist;
654
655 if (hlist && sh_string_len(host) < (size_t)INT_MAX)
656 {
657 do {
658 if (pcre_exec(hlist->hostname, hlist->hostname_extra,
659 sh_string_str(host), (int) sh_string_len(host),
660 0, 0, NULL, 0) >= 0)
661 {
662 /* matching host, check rules/groups of rules */
663 result = test_grules(hlist, prefix, msg);
664 if (result)
665 break;
666 }
667 hlist = hlist->next;
668 } while (hlist);
669 }
670 return result;
671}
672
673static void msg_report(int severity, struct sh_logrecord * record)
674{
675 char * tmp;
676 char * msg;
677 char * ttt;
678 SH_MUTEX_LOCK(mutex_thread_nolog);
679 tmp = sh_util_safe_name (record->filename);
680 msg = sh_util_safe_name (sh_string_str(record->message));
681 ttt = sh_util_safe_name (sh_string_str(record->timestr));
682 sh_error_handle (severity, FIL__, __LINE__, 0, MSG_LOGMON_REP,
683 msg,
684 ttt,
685 sh_string_str(record->host),
686 tmp);
687 SH_FREE(ttt);
688 SH_FREE(msg);
689 SH_FREE(tmp);
690 SH_MUTEX_UNLOCK(mutex_thread_nolog);
691}
692
693static void sum_report(int severity, sh_string * host, sh_string * message, sh_string * path)
694{
695 char * tmp;
696 char * msg;
697 SH_MUTEX_LOCK(mutex_thread_nolog);
698 tmp = sh_util_safe_name (sh_string_str(path));
699 msg = sh_util_safe_name (sh_string_str(message));
700 sh_error_handle (severity, FIL__, __LINE__, 0, MSG_LOGMON_SUM,
701 msg,
702 sh_string_str(host),
703 tmp);
704 SH_FREE(msg);
705 SH_FREE(tmp);
706 SH_MUTEX_UNLOCK(mutex_thread_nolog);
707}
708
709static zAVLKey sh_eval_getkey(void const *item)
710{
711 return ((struct sh_ceval *)item)->hostname->str;
712}
713
714/* Find the counter, or initialize one if there is none already
715 */
716static struct sh_ceval * find_counter(struct sh_geval * rule,
717 sh_string * host, time_t interval)
718{
719 struct sh_ceval * counter;
720
721 if (!(rule->counterlist))
722 {
723 DEBUG("debug: allocate new counterlist AVL tree\n");
724 rule->counterlist = zAVLAllocTree(sh_eval_getkey);
725 }
726
727 counter = (struct sh_ceval *) zAVLSearch (rule->counterlist,
728 sh_string_str(host));
729
730 if (!counter)
731 {
732 DEBUG("debug: no counter found\n");
733
734 counter = SH_ALLOC(sizeof(struct sh_ceval));
735 counter->hostname = sh_string_new_from_lchar(sh_string_str(host),
736 sh_string_len(host));
737 counter->counted_str = NULL;
738 counter->filename = NULL;
739 counter->count = 0;
740 counter->start = time(NULL);
741 counter->interval = interval;
742
743 zAVLInsert(rule->counterlist, counter);
744 }
745 return counter;
746
747}
748
749/* copy the message and replace captured substrings with '___'
750 */
751static sh_string * replace_captures(const sh_string * message,
752 int * ovector, int ovecnum)
753{
754 sh_string * retval = sh_string_new_from_lchar(sh_string_str(message),
755 sh_string_len(message));
756
757 if (ovecnum > 1)
758 {
759 retval = sh_string_replace(retval, &(ovector[2]), (ovecnum-1), "___", 3);
760 }
761 return retval;
762}
763
764
765/* process the counter for a SUM rule
766 */
767static int process_counter(struct sh_ceval * counter,
768 struct sh_geval * rule, struct sh_logrecord * record)
769{
770 int retval = -1;
771 time_t now;
772
773 if (!(counter->counted_str))
774 {
775 counter->counted_str = replace_captures(record->message, rule->ovector,
776 rule->ovecnum);
777 counter->filename = sh_string_new_from_lchar(record->filename,
778 strlen(record->filename));
779 DEBUG("debug: counted_str after replace: %s\n",
780 sh_string_str(counter->counted_str));
781 }
782
783 ++(counter->count);
784 now = time(NULL); now -= counter->start;
785 DEBUG("debug: count %lu, interval %lu, time %lu\n",
786 counter->count, counter->interval, now);
787 if (now >= counter->interval)
788 {
789 DEBUG("debug: report count\n");
790 sum_report(rule->queue->severity, counter->hostname,
791 counter->counted_str, counter->filename);
792 counter->start = time(NULL);
793 counter->count = 0;
794 }
795 return retval;
796}
797
798/* Process a rule
799 */
800static int process_rule(struct sh_geval * rule, struct sh_logrecord * record)
801{
802 int retval = -1;
803 struct sh_qeval * queue = rule->queue;
804
805 if (queue)
806 {
807 DEBUG("debug: queue policy = %d found\n", queue->policy);
808 if (queue->policy == EVAL_REPORT)
809 {
810 DEBUG("debug: EVAL_REPORT host: %s, prefix: %s, message: %s\n",
811 sh_string_str(record->host),
812 sh_string_str(record->prefix),
813 sh_string_str(record->message));
814 msg_report(queue->severity, record);
815 retval = 0;
816 }
817 else if (queue->policy == EVAL_SUM)
818 {
819
820 struct sh_ceval * counter =
821 find_counter(rule, record->host, queue->interval);
822 DEBUG("debug: EVAL_SUM host: %s, prefix: %s, message: %s\n",
823 sh_string_str(record->host),
824 sh_string_str(record->prefix),
825 sh_string_str(record->message));
826 if (counter)
827 {
828 DEBUG("debug: counter found\n");
829 retval = process_counter(counter, rule, record);
830 }
831 }
832 }
833 else
834 {
835 DEBUG("debug: no queue found -- trash\n");
836 /* No queue means 'trash' */
837 retval = 0;
838 }
839 return retval;
840}
841
842#define DEFAULT_SEVERITY (-1)
843
844int sh_eval_process_msg(struct sh_logrecord * record)
845{
846 static unsigned long i = 0;
847 if (record)
848 {
849 struct sh_geval * rule = find_rule (record->host, record->prefix,
850 record->message);
851
852 if (rule)
853 {
854 DEBUG("debug: (%lu) rule found\n", i); ++i;
855 return process_rule(rule, record);
856 }
857 else
858 {
859 DEBUG("debug: (%lu) no rule found\n", i); ++i;
860 msg_report(DEFAULT_SEVERITY, record);
861 }
862 return 0;
863 }
864 return -1;
865}
866
867#endif
Note: See TracBrowser for help on using the repository browser.