aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/audit/src
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/audit/src')
-rw-r--r--framework/src/audit/src/Makefile.am57
-rw-r--r--framework/src/audit/src/auditctl-listing.c577
-rw-r--r--framework/src/audit/src/auditctl-listing.h34
-rw-r--r--framework/src/audit/src/auditctl-llist.c105
-rw-r--r--framework/src/audit/src/auditctl-llist.h56
-rw-r--r--framework/src/audit/src/auditctl.c1472
-rw-r--r--framework/src/audit/src/auditd-config.c1744
-rw-r--r--framework/src/audit/src/auditd-config.h100
-rw-r--r--framework/src/audit/src/auditd-dispatch.c213
-rw-r--r--framework/src/audit/src/auditd-dispatch.h37
-rw-r--r--framework/src/audit/src/auditd-event.c1407
-rw-r--r--framework/src/audit/src/auditd-event.h49
-rw-r--r--framework/src/audit/src/auditd-listen.c1065
-rw-r--r--framework/src/audit/src/auditd-listen.h55
-rw-r--r--framework/src/audit/src/auditd-reconfig.c128
-rw-r--r--framework/src/audit/src/auditd-sendmail.c116
-rw-r--r--framework/src/audit/src/auditd.c917
-rw-r--r--framework/src/audit/src/aureport-options.c722
-rw-r--r--framework/src/audit/src/aureport-options.h55
-rw-r--r--framework/src/audit/src/aureport-output.c1023
-rw-r--r--framework/src/audit/src/aureport-scan.c974
-rw-r--r--framework/src/audit/src/aureport-scan.h76
-rw-r--r--framework/src/audit/src/aureport.c338
-rw-r--r--framework/src/audit/src/ausearch-avc.c222
-rw-r--r--framework/src/audit/src/ausearch-avc.h72
-rw-r--r--framework/src/audit/src/ausearch-checkpt.c263
-rw-r--r--framework/src/audit/src/ausearch-checkpt.h42
-rw-r--r--framework/src/audit/src/ausearch-common.h73
-rw-r--r--framework/src/audit/src/ausearch-int.c162
-rw-r--r--framework/src/audit/src/ausearch-int.h58
-rw-r--r--framework/src/audit/src/ausearch-llist.c257
-rw-r--r--framework/src/audit/src/ausearch-llist.h117
-rw-r--r--framework/src/audit/src/ausearch-lol.c296
-rw-r--r--framework/src/audit/src/ausearch-lol.h54
-rw-r--r--framework/src/audit/src/ausearch-lookup.c500
-rw-r--r--framework/src/audit/src/ausearch-lookup.h50
-rw-r--r--framework/src/audit/src/ausearch-match.c364
-rw-r--r--framework/src/audit/src/ausearch-nvpair.c97
-rw-r--r--framework/src/audit/src/ausearch-nvpair.h57
-rw-r--r--framework/src/audit/src/ausearch-options.c1175
-rw-r--r--framework/src/audit/src/ausearch-options.h52
-rw-r--r--framework/src/audit/src/ausearch-parse.c2310
-rw-r--r--framework/src/audit/src/ausearch-parse.h33
-rw-r--r--framework/src/audit/src/ausearch-report.c362
-rw-r--r--framework/src/audit/src/ausearch-string.c178
-rw-r--r--framework/src/audit/src/ausearch-string.h59
-rw-r--r--framework/src/audit/src/ausearch-time.c412
-rw-r--r--framework/src/audit/src/ausearch-time.h38
-rw-r--r--framework/src/audit/src/ausearch.c594
-rw-r--r--framework/src/audit/src/autrace.c329
-rw-r--r--framework/src/audit/src/delete_all.c109
-rw-r--r--framework/src/audit/src/libev/Makefile.am29
-rw-r--r--framework/src/audit/src/libev/README58
-rw-r--r--framework/src/audit/src/libev/ev.c4971
-rw-r--r--framework/src/audit/src/libev/ev.h854
-rw-r--r--framework/src/audit/src/libev/ev_epoll.c279
-rw-r--r--framework/src/audit/src/libev/ev_poll.c148
-rw-r--r--framework/src/audit/src/libev/ev_select.c314
-rw-r--r--framework/src/audit/src/libev/ev_vars.h204
-rw-r--r--framework/src/audit/src/libev/ev_wrap.h200
-rw-r--r--framework/src/audit/src/libev/event.c425
-rw-r--r--framework/src/audit/src/libev/event.h177
-rw-r--r--framework/src/audit/src/libev/libev.m442
-rw-r--r--framework/src/audit/src/mt/Makefile.am49
-rw-r--r--framework/src/audit/src/test/Makefile.am26
-rw-r--r--framework/src/audit/src/test/ilist_test.c69
-rw-r--r--framework/src/audit/src/test/slist_test.c98
67 files changed, 0 insertions, 27598 deletions
diff --git a/framework/src/audit/src/Makefile.am b/framework/src/audit/src/Makefile.am
deleted file mode 100644
index 8d1af865..00000000
--- a/framework/src/audit/src/Makefile.am
+++ /dev/null
@@ -1,57 +0,0 @@
-# Makefile.am--
-# Copyright 2004-2006, 2008,2011-15 Red Hat Inc., Durham, North Carolina.
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Authors:
-# Steve Grubb <sgrubb@redhat.com>
-#
-
-CONFIG_CLEAN_FILES = *.rej *.orig
-AUTOMAKE_OPTIONS = no-dependencies
-SUBDIRS = test
-AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/src/libev -I${top_srcdir}/auparse
-sbin_PROGRAMS = auditd auditctl aureport ausearch autrace
-AM_CFLAGS = -D_GNU_SOURCE
-noinst_HEADERS = auditd-config.h auditd-event.h auditd-listen.h ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h ausearch-avc.h ausearch-time.h ausearch-lol.h auditctl-listing.h ausearch-checkpt.h
-
-auditd_SOURCES = auditd.c auditd-event.c auditd-config.c auditd-reconfig.c auditd-sendmail.c auditd-dispatch.c
-if ENABLE_LISTENER
-auditd_SOURCES += auditd-listen.c
-endif
-auditd_CFLAGS = -fPIE -DPIE -g -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pthread
-auditd_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now
-auditd_DEPENDENCIES = mt/libauditmt.a libev/libev.a
-auditd_LDADD = @LIBWRAP_LIBS@ -Llibev -lev -Lmt -lauditmt -lpthread -lrt -lm $(gss_libs)
-
-auditctl_SOURCES = auditctl.c auditctl-llist.c delete_all.c auditctl-listing.c
-auditctl_CFLAGS = -fPIE -DPIE -g -D_GNU_SOURCE
-auditctl_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now
-auditctl_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse -lauparse
-
-aureport_SOURCES = aureport.c auditd-config.c ausearch-llist.c aureport-options.c ausearch-string.c ausearch-parse.c aureport-scan.c aureport-output.c ausearch-lookup.c ausearch-int.c ausearch-time.c ausearch-nvpair.c ausearch-avc.c ausearch-lol.c
-aureport_LDADD = -L${top_builddir}/lib -laudit
-
-ausearch_SOURCES = ausearch.c auditd-config.c ausearch-llist.c ausearch-options.c ausearch-report.c ausearch-match.c ausearch-string.c ausearch-parse.c ausearch-int.c ausearch-time.c ausearch-nvpair.c ausearch-lookup.c ausearch-avc.c ausearch-lol.c ausearch-checkpt.c
-ausearch_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse -lauparse
-
-autrace_SOURCES = autrace.c delete_all.c auditctl-llist.c
-autrace_LDADD = -L${top_builddir}/lib -laudit
-
-mt/libauditmt.a:
- make -C mt
-libev/libev.a:
- make -C libev
diff --git a/framework/src/audit/src/auditctl-listing.c b/framework/src/audit/src/auditctl-listing.c
deleted file mode 100644
index 88dac6c8..00000000
--- a/framework/src/audit/src/auditctl-listing.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* auditctl-listing.c --
- * Copyright 2014 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "auditctl-listing.h"
-#include "private.h"
-#include "auditctl-llist.h"
-#include "auparse-idata.h"
-
-/* Global vars */
-static llist l;
-static int printed;
-extern int list_requested, interpret;
-extern char key[AUDIT_MAX_KEY_LEN+1];
-extern const char key_sep[2];
-
-/*
- * Returns 1 if rule should be printed & 0 if not
- */
-int key_match(const struct audit_rule_data *r)
-{
- int i;
- size_t boffset = 0;
-
- if (key[0] == 0)
- return 1;
-
- // At this point, we have a key
- for (i = 0; i < r->field_count; i++) {
- int field = r->fields[i] & ~AUDIT_OPERATORS;
- if (field == AUDIT_FILTERKEY) {
- char *keyptr;
- if (asprintf(&keyptr, "%.*s", r->values[i],
- &r->buf[boffset]) < 0)
- keyptr = NULL;
- else if (strstr(keyptr, key)) {
- free(keyptr);
- return 1;
- }
- free(keyptr);
- }
- if (((field >= AUDIT_SUBJ_USER && field <= AUDIT_OBJ_LEV_HIGH)
- && field != AUDIT_PPID) || field == AUDIT_WATCH ||
- field == AUDIT_DIR || field == AUDIT_FILTERKEY) {
- boffset += r->values[i];
- }
- }
- return 0;
-}
-
-/*
- * This function detects if we have a watch. A watch is detected when we
- * have syscall == all and a perm field.
- */
-static int is_watch(const struct audit_rule_data *r)
-{
- int i, perm = 0, all = 1;
-
- for (i = 0; i < r->field_count; i++) {
- int field = r->fields[i] & ~AUDIT_OPERATORS;
- if (field == AUDIT_PERM)
- perm = 1;
- // Watches can have only 4 field types
- if (field != AUDIT_PERM && field != AUDIT_FILTERKEY &&
- field != AUDIT_DIR && field != AUDIT_WATCH)
- return 0;
- }
-
- if (((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_USER) &&
- ((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK) &&
- ((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_EXCLUDE)) {
- for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++) {
- if (r->mask[i] != (uint32_t)~0) {
- all = 0;
- break;
- }
- }
- }
- if (perm && all)
- return 1;
- return 0;
-}
-
-static int print_arch(unsigned int value, int op)
-{
- int machine;
- _audit_elf = value;
- machine = audit_elf_to_machine(_audit_elf);
- if (machine < 0)
- printf(" -F arch%s0x%X", audit_operator_to_symbol(op),
- (unsigned)value);
- else {
- if (interpret == 0) {
- if (__AUDIT_ARCH_64BIT & _audit_elf)
- printf(" -F arch%sb64",
- audit_operator_to_symbol(op));
- else
- printf(" -F arch%sb32",
- audit_operator_to_symbol(op));
- } else {
- const char *ptr = audit_machine_to_name(machine);
- printf(" -F arch%s%s", audit_operator_to_symbol(op),
- ptr);
- }
- }
- return machine;
-}
-
-static int print_syscall(const struct audit_rule_data *r, unsigned int *sc)
-{
- int count = 0;
- int all = 1;
- unsigned int i;
- int machine = audit_detect_machine();
-
- /* Rules on the following filters do not take a syscall */
- if (((r->flags & AUDIT_FILTER_MASK) == AUDIT_FILTER_USER) ||
- ((r->flags & AUDIT_FILTER_MASK) == AUDIT_FILTER_TASK) ||
- ((r->flags &AUDIT_FILTER_MASK) == AUDIT_FILTER_EXCLUDE))
- return 0;
-
- /* See if its all or specific syscalls */
- for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++) {
- if (r->mask[i] != (uint32_t)~0) {
- all = 0;
- break;
- }
- }
-
- if (all) {
- printf(" -S all");
- count = i;
- } else for (i = 0; i < AUDIT_BITMASK_SIZE * 32; i++) {
- int word = AUDIT_WORD(i);
- int bit = AUDIT_BIT(i);
- if (r->mask[word] & bit) {
- const char *ptr;
- if (_audit_elf)
- machine = audit_elf_to_machine(_audit_elf);
- if (machine < 0)
- ptr = NULL;
- else
- ptr = audit_syscall_to_name(i, machine);
- if (!count)
- printf(" -S ");
- if (ptr)
- printf("%s%s", !count ? "" : ",", ptr);
- else
- printf("%s%d", !count ? "" : ",", i);
- count++;
- *sc = i;
- }
- }
- return count;
-}
-
-static void print_field_cmp(int value, int op)
-{
- switch (value)
- {
- case AUDIT_COMPARE_UID_TO_OBJ_UID:
- printf(" -C uid%sobj_uid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_GID_TO_OBJ_GID:
- printf(" -C gid%sobj_gid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_EUID_TO_OBJ_UID:
- printf(" -C euid%sobj_uid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_EGID_TO_OBJ_GID:
- printf(" -C egid%sobj_gid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_AUID_TO_OBJ_UID:
- printf(" -C auid%sobj_uid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_SUID_TO_OBJ_UID:
- printf(" -C suid%sobj_uid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_SGID_TO_OBJ_GID:
- printf(" -C sgid%sobj_gid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
- printf(" -C fsuid%sobj_uid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
- printf(" -C fsgid%sobj_gid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_UID_TO_AUID:
- printf(" -C uid%sauid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_UID_TO_EUID:
- printf(" -C uid%seuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_UID_TO_FSUID:
- printf(" -C uid%sfsuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_UID_TO_SUID:
- printf(" -C uid%ssuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_AUID_TO_FSUID:
- printf(" -C auid%sfsuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_AUID_TO_SUID:
- printf(" -C auid%ssuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_AUID_TO_EUID:
- printf(" -C auid%seuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_EUID_TO_SUID:
- printf(" -C euid%ssuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_EUID_TO_FSUID:
- printf(" -C euid%sfsuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_SUID_TO_FSUID:
- printf(" -C suid%sfsuid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_GID_TO_EGID:
- printf(" -C gid%segid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_GID_TO_FSGID:
- printf(" -C gid%sfsgid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_GID_TO_SGID:
- printf(" -C gid%ssgid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_EGID_TO_FSGID:
- printf(" -C egid%sfsgid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_EGID_TO_SGID:
- printf(" -C egid%ssgid",
- audit_operator_to_symbol(op));
- break;
- case AUDIT_COMPARE_SGID_TO_FSGID:
- printf(" -C sgid%sfsgid",
- audit_operator_to_symbol(op));
- break;
- }
-}
-
-/*
- * This function prints 1 rule from the kernel reply
- */
-static void print_rule(const struct audit_rule_data *r)
-{
- unsigned int i, count = 0, sc = 0;
- size_t boffset = 0;
- int mach = -1, watch = is_watch(r);
- unsigned long long a0 = 0, a1 = 0;
-
- if (!watch) { /* This is syscall auditing */
- printf("-a %s,%s",
- audit_action_to_name((int)r->action),
- audit_flag_to_name(r->flags));
-
- // Now find the arch and print it
- for (i = 0; i < r->field_count; i++) {
- int field = r->fields[i] & ~AUDIT_OPERATORS;
- if (field == AUDIT_ARCH) {
- int op = r->fieldflags[i] & AUDIT_OPERATORS;
- mach = print_arch(r->values[i], op);
- }
- }
- // And last do the syscalls
- count = print_syscall(r, &sc);
- }
-
- // Now iterate over the fields
- for (i = 0; i < r->field_count; i++) {
- const char *name;
- int op = r->fieldflags[i] & AUDIT_OPERATORS;
- int field = r->fields[i] & ~AUDIT_OPERATORS;
-
- if (field == AUDIT_ARCH)
- continue; // already printed
-
- name = audit_field_to_name(field);
- if (name) {
- // Special cases to print the different field types
- // in a meaningful way.
- if (field == AUDIT_MSGTYPE) {
- if (!audit_msg_type_to_name(r->values[i]))
- printf(" -F %s%s%d", name,
- audit_operator_to_symbol(op),
- r->values[i]);
- else
- printf(" -F %s%s%s", name,
- audit_operator_to_symbol(op),
- audit_msg_type_to_name(
- r->values[i]));
- } else if ((field >= AUDIT_SUBJ_USER &&
- field <= AUDIT_OBJ_LEV_HIGH)
- && field != AUDIT_PPID) {
- printf(" -F %s%s%.*s", name,
- audit_operator_to_symbol(op),
- r->values[i], &r->buf[boffset]);
- boffset += r->values[i];
- } else if (field == AUDIT_WATCH) {
- if (watch)
- printf("-w %.*s", r->values[i],
- &r->buf[boffset]);
- else
- printf(" -F path=%.*s", r->values[i],
- &r->buf[boffset]);
- boffset += r->values[i];
- } else if (field == AUDIT_DIR) {
- if (watch)
- printf("-w %.*s/", r->values[i],
- &r->buf[boffset]);
- else
- printf(" -F dir=%.*s", r->values[i],
- &r->buf[boffset]);
-
- boffset += r->values[i];
- } else if (field == AUDIT_FILTERKEY) {
- char *rkey, *ptr, *saved;
- if (asprintf(&rkey, "%.*s", r->values[i],
- &r->buf[boffset]) < 0)
- rkey = NULL;
- boffset += r->values[i];
- ptr = strtok_r(rkey, key_sep, &saved);
- while (ptr) {
- if (watch)
- printf(" -k %s", ptr);
- else
- printf(" -F key=%s", ptr);
- ptr = strtok_r(NULL, key_sep, &saved);
- }
- free(rkey);
- } else if (field == AUDIT_PERM) {
- char perms[5];
- int val=r->values[i];
- perms[0] = 0;
- if (val & AUDIT_PERM_READ)
- strcat(perms, "r");
- if (val & AUDIT_PERM_WRITE)
- strcat(perms, "w");
- if (val & AUDIT_PERM_EXEC)
- strcat(perms, "x");
- if (val & AUDIT_PERM_ATTR)
- strcat(perms, "a");
- if (watch)
- printf(" -p %s", perms);
- else
- printf(" -F perm=%s", perms);
- } else if (field == AUDIT_INODE) {
- // This is unsigned
- printf(" -F %s%s%u", name,
- audit_operator_to_symbol(op),
- r->values[i]);
- } else if (field == AUDIT_FIELD_COMPARE) {
- print_field_cmp(r->values[i], op);
- } else if (field >= AUDIT_ARG0 && field <= AUDIT_ARG3){
- if (field == AUDIT_ARG0)
- a0 = r->values[i];
- else if (field == AUDIT_ARG1)
- a1 = r->values[i];
-
- // Show these as hex
- if (count > 1 || interpret == 0)
- printf(" -F %s%s0x%X", name,
- audit_operator_to_symbol(op),
- r->values[i]);
- else { // Use ignore to mean interpret
- const char *out;
- idata id;
- char val[32];
- int type;
-
- id.syscall = sc;
- id.machine = mach;
- id.a0 = a0;
- id.a1 = a1;
- id.name = name;
- snprintf(val, 32, "%x", r->values[i]);
- id.val = val;
- type = auparse_interp_adjust_type(
- AUDIT_SYSCALL, name, val);
- out = auparse_do_interpretation(type,
- &id);
- printf(" -F %s%s%s", name,
- audit_operator_to_symbol(op),
- out);
- free((void *)out);
- }
- } else if (field == AUDIT_EXIT) {
- int e = abs((int)r->values[i]);
- const char *err = audit_errno_to_name(e);
-
- if (((int)r->values[i] < 0) && err)
- printf(" -F %s%s-%s", name,
- audit_operator_to_symbol(op),
- err);
- else
- printf(" -F %s%s%d", name,
- audit_operator_to_symbol(op),
- (int)r->values[i]);
- } else {
- // The default is signed decimal
- printf(" -F %s%s%d", name,
- audit_operator_to_symbol(op),
- r->values[i]);
- }
- } else {
- // The field name is unknown
- printf(" f%d%s%d", r->fields[i],
- audit_operator_to_symbol(op),
- r->values[i]);
- }
- }
- printf("\n");
-}
-
-void audit_print_init(void)
-{
- printed = 0;
- list_create(&l);
-}
-
-const char *get_enable(unsigned e)
-{
- switch (e)
- {
- case 0:
- return "disable";
- case 1:
- return "enabled";
- case 2:
- return "enabl;ed+immutable";
- default:
- return "unknown";
- }
-}
-
-const char *get_failure(unsigned f)
-{
- switch (f)
- {
- case 0:
- return "silent";
- case 1:
- return "printk";
- case 2:
- return "panic";
- default:
- return "unknown";
- }
-}
-
-/*
- * This function interprets the reply and prints it to stdout. It returns
- * 0 if no more should be read and 1 to indicate that more messages of this
- * type may need to be read.
- */
-int audit_print_reply(struct audit_reply *rep, int fd)
-{
- _audit_elf = 0;
-
- switch (rep->type) {
- case NLMSG_NOOP:
- return 1;
- case NLMSG_DONE:
- // Close the socket so kernel can do other things
- audit_close(fd);
- if (printed == 0)
- printf("No rules\n");
- else {
- lnode *n;
- list_first(&l);
- n = l.cur;
- while (n) {
- print_rule(n->r);
- n = list_next(&l);
- }
- list_clear(&l);
- }
- break;
- case NLMSG_ERROR:
- printf("NLMSG_ERROR %d (%s)\n",
- -rep->error->error,
- strerror(-rep->error->error));
- printed = 1;
- break;
- case AUDIT_GET:
- if (interpret)
- printf("enabled %s\nfailure %s\n",
- get_enable(rep->status->enabled),
- get_failure(rep->status->failure));
- else
- printf("enabled %u\nfailure %u\n",
- rep->status->enabled, rep->status->failure);
- printf("pid %u\nrate_limit %u\nbacklog_limit %u\n"
- "lost %u\nbacklog %u\n",
- rep->status->pid, rep->status->rate_limit,
- rep->status->backlog_limit, rep->status->lost,
- rep->status->backlog);
-#if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME
- printf("backlog_wait_time %u\n",
- rep->status->backlog_wait_time);
-#endif
- printed = 1;
- break;
-#if HAVE_DECL_AUDIT_FEATURE_VERSION
- case AUDIT_GET_FEATURE:
- {
- uint32_t mask = AUDIT_FEATURE_TO_MASK(AUDIT_FEATURE_LOGINUID_IMMUTABLE);
- if (rep->features->mask & mask)
- printf("loginuid_immutable %u %s\n",
- !!(rep->features->features & mask),
- rep->features->lock & mask ? "locked" :
- "unlocked");
- }
- printed = 1;
- break;
-#endif
- case AUDIT_LIST_RULES:
- list_requested = 0;
- if (key_match(rep->ruledata))
- list_append(&l, rep->ruledata,
- sizeof(struct audit_rule_data) +
- rep->ruledata->buflen);
- printed = 1;
- return 1;
- default:
- printf("Unknown: type=%d, len=%d\n", rep->type,
- rep->nlh->nlmsg_len);
- printed = 1;
- break;
- }
- return 0;
-}
-
diff --git a/framework/src/audit/src/auditctl-listing.h b/framework/src/audit/src/auditctl-listing.h
deleted file mode 100644
index 8a412ef3..00000000
--- a/framework/src/audit/src/auditctl-listing.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* auditctl-listing.h - Header file for ausearch-llist.c
-* Copyright (c) 2014 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef CTLLISTING_HEADER
-#define CTLLISTING_HEADER
-
-#include "config.h"
-#include "libaudit.h"
-
-void audit_print_init(void);
-int audit_print_reply(struct audit_reply *rep, int fd);
-int key_match(const struct audit_rule_data *r);
-
-#endif
diff --git a/framework/src/audit/src/auditctl-llist.c b/framework/src/audit/src/auditctl-llist.c
deleted file mode 100644
index 175310d7..00000000
--- a/framework/src/audit/src/auditctl-llist.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-* ausearch-llist.c - Minimal linked list library
-* Copyright (c) 2005 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include "auditctl-llist.h"
-
-void list_create(llist *l)
-{
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-void list_first(llist *l)
-{
- l->cur = l->head;
-}
-
-void list_last(llist *l)
-{
- register lnode* window;
-
- if (l->head == NULL)
- return;
-
- window = l->head;
- while (window->next)
- window = window->next;
- l->cur = window;
-}
-
-lnode *list_next(llist *l)
-{
- if (l->cur == NULL)
- return NULL;
- l->cur = l->cur->next;
- return l->cur;
-}
-
-void list_append(llist *l, struct audit_rule_data *r, size_t sz)
-{
- lnode* newnode;
-
- newnode = malloc(sizeof(lnode));
-
- if (r) {
- void *rr = malloc(sz);
- if (rr)
- memcpy(rr, r, sz);
- newnode->r = rr;
- } else
- newnode->r = NULL;
-
- newnode->size = sz;
- newnode->next = 0;
-
- // if we are at top, fix this up
- if (l->head == NULL)
- l->head = newnode;
- else // Otherwise add pointer to newnode
- l->cur->next = newnode;
-
- // make newnode current
- l->cur = newnode;
- l->cnt++;
-}
-
-void list_clear(llist* l)
-{
- lnode* nextnode;
- register lnode* current;
-
- current = l->head;
- while (current) {
- nextnode=current->next;
- free(current->r);
- free(current);
- current=nextnode;
- }
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
diff --git a/framework/src/audit/src/auditctl-llist.h b/framework/src/audit/src/auditctl-llist.h
deleted file mode 100644
index 371d0d7e..00000000
--- a/framework/src/audit/src/auditctl-llist.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-* auditctl-llist.h - Header file for ausearch-llist.c
-* Copyright (c) 2005 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef CTLLIST_HEADER
-#define CTLLIST_HEADER
-
-#include "config.h"
-#include <sys/types.h>
-#include "libaudit.h"
-
-/* This is the node of the linked list. message & item are the only elements
- * at this time. Any data elements that are per item goes here. */
-typedef struct _lnode{
- struct audit_rule_data *r; // The rule from the kernel
- size_t size; // Size of the rule struct
- struct _lnode *next; // Next node pointer
-} lnode;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- lnode *head; // List head
- lnode *cur; // Pointer to current node
- unsigned int cnt; // How many items in this list
-} llist;
-
-void list_create(llist *l);
-void list_first(llist *l);
-void list_last(llist *l);
-lnode *list_next(llist *l);
-static inline lnode *list_get_cur(llist *l) { return l->cur; }
-void list_append(llist *l, struct audit_rule_data *r, size_t sz);
-void list_clear(llist* l);
-
-#endif
-
diff --git a/framework/src/audit/src/auditctl.c b/framework/src/audit/src/auditctl.c
deleted file mode 100644
index 334f8021..00000000
--- a/framework/src/audit/src/auditctl.c
+++ /dev/null
@@ -1,1472 +0,0 @@
-/* auditctl.c --
- * Copyright 2004-2015 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- * Rickard E. (Rik) Faith <faith@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h> /* strdup needs xopen define */
-#include <getopt.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <sys/utsname.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <libgen.h> /* For basename */
-#include <limits.h> /* PATH_MAX */
-#include "libaudit.h"
-#include "auditctl-listing.h"
-#include "private.h"
-
-/* This define controls the size of the line that we will request when
- * reading in rules from a file.
- */
-#define LINE_SIZE 6144
-
-
-/* Global functions */
-static int handle_request(int status);
-static void get_reply(void);
-extern int delete_all_rules(int fd);
-
-/* Global vars */
-int list_requested = 0, interpret = 0;
-char key[AUDIT_MAX_KEY_LEN+1];
-const char key_sep[2] = { AUDIT_KEY_SEPARATOR, 0 };
-static int keylen;
-static int fd = -1;
-static int add = AUDIT_FILTER_UNSET, del = AUDIT_FILTER_UNSET, action = -1;
-static int ignore = 0, continue_error = 0;
-static int exclude = 0;
-static int multiple = 0;
-static struct audit_rule_data *rule_new = NULL;
-
-/*
- * This function will reset everything used for each loop when loading
- * a ruleset from a file.
- */
-static int reset_vars(void)
-{
- list_requested = 0;
- _audit_syscalladded = 0;
- _audit_permadded = 0;
- _audit_archadded = 0;
- _audit_elf = 0;
- add = AUDIT_FILTER_UNSET;
- del = AUDIT_FILTER_UNSET;
- action = -1;
- exclude = 0;
- multiple = 0;
-
- free(rule_new);
- rule_new = malloc(sizeof(struct audit_rule_data));
- memset(rule_new, 0, sizeof(struct audit_rule_data));
- if (fd < 0) {
- if ((fd = audit_open()) < 0) {
- audit_msg(LOG_ERR, "Cannot open netlink audit socket");
- return 1;
- }
- }
- return 0;
-}
-
-static void usage(void)
-{
- printf(
- "usage: auditctl [options]\n"
- " -a <l,a> Append rule to end of <l>ist with <a>ction\n"
- " -A <l,a> Add rule at beginning of <l>ist with <a>ction\n"
- " -b <backlog> Set max number of outstanding audit buffers\n"
- " allowed Default=64\n"
- " -c Continue through errors in rules\n"
- " -C f=f Compare collected fields if available:\n"
- " Field name, operator(=,!=), field name\n"
- " -d <l,a> Delete rule from <l>ist with <a>ction\n"
- " l=task,exit,user,exclude\n"
- " a=never,always\n"
- " -D Delete all rules and watches\n"
- " -e [0..2] Set enabled flag\n"
- " -f [0..2] Set failure flag\n"
- " 0=silent 1=printk 2=panic\n"
- " -F f=v Build rule: field name, operator(=,!=,<,>,<=,\n"
- " >=,&,&=) value\n"
- " -h Help\n"
- " -i Ignore errors when reading rules from file\n"
- " -k <key> Set filter key on audit rule\n"
- " -l List rules\n"
- " -m text Send a user-space message\n"
- " -p [r|w|x|a] Set permissions filter on watch\n"
- " r=read, w=write, x=execute, a=attribute\n"
- " -q <mount,subtree> make subtree part of mount point's dir watches\n"
- " -r <rate> Set limit in messages/sec (0=none)\n"
- " -R <file> read rules from file\n"
- " -s Report status\n"
- " -S syscall Build rule: syscall name or number\n"
- " -t Trim directory watches\n"
- " -v Version\n"
- " -w <path> Insert watch at <path>\n"
- " -W <path> Remove watch at <path>\n"
- " --loginuid-immutable Make loginuids unchangeable once set\n"
- " --backlog_wait_time Set the kernel backlog_wait_time\n"
- );
-}
-
-static int lookup_filter(const char *str, int *filter)
-{
- if (strcmp(str, "task") == 0)
- *filter = AUDIT_FILTER_TASK;
- else if (strcmp(str, "entry") == 0)
- *filter = AUDIT_FILTER_ENTRY;
- else if (strcmp(str, "exit") == 0)
- *filter = AUDIT_FILTER_EXIT;
- else if (strcmp(str, "user") == 0)
- *filter = AUDIT_FILTER_USER;
- else if (strcmp(str, "exclude") == 0) {
- *filter = AUDIT_FILTER_EXCLUDE;
- exclude = 1;
- } else
- return 2;
- return 0;
-}
-
-static int lookup_action(const char *str, int *act)
-{
- if (strcmp(str, "never") == 0)
- *act = AUDIT_NEVER;
- else if (strcmp(str, "possible") == 0)
- return 1;
- else if (strcmp(str, "always") == 0)
- *act = AUDIT_ALWAYS;
- else
- return 2;
- return 0;
-}
-
-/*
- * Returns 0 ok, 1 deprecated action, 2 rule error,
- * 3 multiple rule insert/delete
- */
-static int audit_rule_setup(char *opt, int *filter, int *act, int lineno)
-{
- int rc;
- char *p;
-
- if (++multiple != 1)
- return 3;
-
- p = strchr(opt, ',');
- if (p == NULL || strchr(p+1, ','))
- return 2;
- *p = 0;
-
- /* Try opt both ways */
- if (lookup_filter(opt, filter) == 2) {
- rc = lookup_action(opt, act);
- if (rc != 0) {
- *p = ',';
- return rc;
- }
- }
-
- /* Repair the string */
- *p = ',';
- opt = p+1;
-
- /* If flags are empty, p+1 must be the filter */
- if (*filter == AUDIT_FILTER_UNSET)
- lookup_filter(opt, filter);
- else {
- rc = lookup_action(opt, act);
- if (rc != 0)
- return rc;
- }
-
- /* Make sure we set both */
- if (*filter == AUDIT_FILTER_UNSET || *act == -1)
- return 2;
-
- /* Consolidate rules on exit filter */
- if (*filter == AUDIT_FILTER_ENTRY) {
- *filter = AUDIT_FILTER_EXIT;
- if (lineno)
- audit_msg(LOG_INFO, "Warning - entry rules deprecated, changing to exit rule in line %d", lineno);
- else
- audit_msg(LOG_INFO,
- "Warning - entry rules deprecated, changing to exit rule");
- }
-
- return 0;
-}
-
-/*
- * This function will check the path before accepting it. It returns
- * 1 on error and 0 on success.
- */
-static int check_path(const char *path)
-{
- char *ptr, *base;
- size_t nlen;
- size_t plen = strlen(path);
- if (plen >= PATH_MAX) {
- audit_msg(LOG_ERR, "The path passed for the watch is too big");
- return 1;
- }
- if (path[0] != '/') {
- audit_msg(LOG_ERR, "The path must start with '/'");
- return 1;
- }
- ptr = strdup(path);
- base = basename(ptr);
- nlen = strlen(base);
- free(ptr);
- if (nlen > NAME_MAX) {
- audit_msg(LOG_ERR, "The base name of the path is too big");
- return 1;
- }
-
- /* These are warnings, not errors */
- if (strstr(path, ".."))
- audit_msg(LOG_WARNING,
- "Warning - relative path notation is not supported");
- if (strchr(path, '*') || strchr(path, '?'))
- audit_msg(LOG_WARNING,
- "Warning - wildcard notation is not supported");
-
- return 0;
-}
-
-/*
- * Setup a watch. The "name" of the watch in userspace will be the <path> to
- * the watch. When this potential watch reaches the kernel, it will resolve
- * down to <name> (of terminating file or directory).
- * Returns a 1 on success & -1 on failure.
- */
-static int audit_setup_watch_name(struct audit_rule_data **rulep, char *path)
-{
- int type = AUDIT_WATCH;
- size_t len;
- struct stat buf;
-
- if (check_path(path))
- return -1;
-
- // Trim trailing '/' should they exist
- len = strlen(path);
- if (len > 2 && path[len-1] == '/') {
- while (path[len-1] == '/' && len > 1) {
- path[len-1] = 0;
- len--;
- }
- }
- if (stat(path, &buf) == 0) {
- if (S_ISDIR(buf.st_mode))
- type = AUDIT_DIR;
- }
- /* FIXME: might want to check to see that rule is empty */
- if (audit_add_watch_dir(type, rulep, path))
- return -1;
-
- return 1;
-}
-
-/*
- * Setup a watch permissions.
- * Returns a 1 on success & -1 on failure.
- */
-static int audit_setup_perms(struct audit_rule_data *rule, const char *opt)
-{
- unsigned int i, len, val = 0;
-
- len = strlen(opt);
- if (len > 4)
- return -1;
-
- for (i = 0; i < len; i++) {
- switch (tolower(opt[i])) {
- case 'r':
- val |= AUDIT_PERM_READ;
- break;
- case 'w':
- val |= AUDIT_PERM_WRITE;
- break;
- case 'x':
- val |= AUDIT_PERM_EXEC;
- break;
- case 'a':
- val |= AUDIT_PERM_ATTR;
- break;
- default:
- audit_msg(LOG_ERR,
- "Permission %c isn't supported",
- opt[i]);
- return -1;
- }
- }
-
- if (audit_update_watch_perms(rule_new, val) == 0) {
- _audit_permadded = 1;
- return 1;
- }
- return -1;
-}
-
-/* 0 success, -1 failure */
-static int lookup_itype(const char *kind)
-{
- if (strcmp(kind, "sys") == 0)
- return 0;
- if (strcmp(kind, "file") == 0)
- return 0;
- if (strcmp(kind, "exec") == 0)
- return 0;
- if (strcmp(kind, "mkexe") == 0)
- return 0;
- return -1;
-}
-
-/* 0 success, -1 failure */
-static int lookup_iseverity(const char *severity)
-{
- if (strncmp(severity, "inf", 3) == 0)
- return 0;
- if (strncmp(severity, "low", 3) == 0)
- return 0;
- if (strncmp(severity, "med", 3) == 0)
- return 0;
- if (strncmp(severity, "hi", 2) == 0)
- return 0;
- return -1;
-}
-
-/* 0 success, -1 failure */
-static int check_ids_key(const char *k)
-{
- char *ptr, *kindptr, *ratingptr;
- char keyptr[AUDIT_MAX_KEY_LEN+1];
-
- if (strlen(k) > AUDIT_MAX_KEY_LEN)
- goto fail_exit;
-
- strncpy(keyptr, k, sizeof(keyptr));
- keyptr[AUDIT_MAX_KEY_LEN] = 0;
- ptr = strchr(keyptr, '-'); // There has to be a - because strncmp
- kindptr = ptr + 1;
- if (*kindptr == 0)
- goto fail_exit;
-
- ptr = strchr(kindptr, '-');
- if (ptr) {
- *ptr = 0;
- ratingptr = ptr +1;
- } else // The rules are misconfigured
- goto fail_exit;
- if (*ratingptr == 0)
- goto fail_exit;
-
- if (lookup_itype(kindptr)) {
- audit_msg(LOG_ERR, "ids key type is bad");
- return -1;
- }
- if (lookup_iseverity(ratingptr)) {
- audit_msg(LOG_ERR, "ids key severity is bad");
- return -1;
- }
- return 0;
-
-fail_exit:
- audit_msg(LOG_ERR, "ids key is bad");
- return -1;
-}
-
-static int equiv_parse(char *optarg, char **mp, char **sub)
-{
- char *ptr = strchr(optarg, ',');
- if (ptr == NULL)
- return -1; // no comma
- *ptr = 0;
- ptr++;
- if (*ptr == 0)
- return -1; // ends with comma
- *mp = optarg;
- *sub = ptr;
- if (strchr(*sub, ','))
- return -1; // too many commas
- return 0;
-}
-
-int audit_request_rule_list(int fd)
-{
- if (audit_request_rules_list_data(fd) > 0) {
- list_requested = 1;
- get_reply();
- return 1;
- }
- return 0;
-}
-
-void check_rule_mismatch(int lineno, const char *option)
-{
- struct audit_rule_data tmprule;
- unsigned int old_audit_elf = _audit_elf;
- int rc = 0;
-
- switch (_audit_elf)
- {
- case AUDIT_ARCH_X86_64:
- _audit_elf = AUDIT_ARCH_I386;
- break;
- case AUDIT_ARCH_PPC64:
- _audit_elf = AUDIT_ARCH_PPC;
- break;
- case AUDIT_ARCH_S390X:
- _audit_elf = AUDIT_ARCH_S390;
- break;
- }
- memset(&tmprule, 0, sizeof(struct audit_rule_data));
- audit_rule_syscallbyname_data(&tmprule, option);
- if (memcmp(tmprule.mask, rule_new->mask, AUDIT_BITMASK_SIZE))
- rc = 1;
- _audit_elf = old_audit_elf;
- if (rc) {
- if (lineno)
- audit_msg(LOG_WARNING, "WARNING - 32/64 bit syscall mismatch in line %d, you should specify an arch", lineno);
- else
- audit_msg(LOG_WARNING, "WARNING - 32/64 bit syscall mismatch, you should specify an arch");
- }
-}
-
-int report_status(int fd)
-{
- int retval;
-
- retval = audit_request_status(fd);
- if (retval == -1) {
- if (errno == ECONNREFUSED)
- fprintf(stderr, "The audit system is disabled\n");
- return -1;
- }
- get_reply();
- retval = audit_request_features(fd);
- if (retval == -1) {
- // errno is EINVAL if the kernel does support features API
- if (errno == EINVAL)
- return -2;
- return -1;
- }
- get_reply();
- return -2;
-}
-
-int parse_syscall(struct audit_rule_data *rule_new, const char *optarg)
-{
- int retval = 0;
- char *saved;
-
- if (strchr(optarg, ',')) {
- char *ptr, *tmp = strdup(optarg);
- if (tmp == NULL)
- return -1;
- ptr = strtok_r(tmp, ",", &saved);
- while (ptr) {
- retval = audit_rule_syscallbyname_data(rule_new, ptr);
- if (retval != 0) {
- if (retval == -1) {
- audit_msg(LOG_ERR,
- "Syscall name unknown: %s",
- ptr);
- retval = -3; // error reported
- }
- break;
- }
- ptr = strtok_r(NULL, ",", &saved);
- }
- free(tmp);
- return retval;
- }
-
- return audit_rule_syscallbyname_data(rule_new, optarg);
-}
-
-struct option long_opts[] =
-{
- {"loginuid-immutable", 0, NULL, 1},
- {"backlog_wait_time", 1, NULL, 2},
- {NULL, 0, NULL, 0}
-};
-
-// FIXME: Change these to enums
-/*
- * returns: -3 deprecated, -2 success - no reply, -1 error - noreply,
- * 0 success - reply, > 0 success - rule
- */
-static int setopt(int count, int lineno, char *vars[])
-{
- int c;
- int retval = 0, rc;
-
- optind = 0;
- opterr = 0;
- key[0] = 0;
- keylen = AUDIT_MAX_KEY_LEN;
-
- while ((retval >= 0) && (c = getopt_long(count, vars,
- "hicslDvtC:e:f:r:b:a:A:d:S:F:m:R:w:W:k:p:q:",
- long_opts, NULL)) != EOF) {
- int flags = AUDIT_FILTER_UNSET;
- rc = 10; // Init to something impossible to see if unused.
- switch (c) {
- case 'h':
- usage();
- retval = -1;
- break;
- case 'i':
- ignore = 1;
- retval = -2;
- break;
- case 'c':
- ignore = 1;
- continue_error = 1;
- retval = -2;
- break;
- case 's':
- if (count > 3) {
- audit_msg(LOG_ERR,
- "Too many options for status command");
- retval = -1;
- break;
- } else if (optind == 2 && count == 3) {
- if (strcmp(vars[optind], "-i") == 0) {
- interpret = 1;
- count -= 1;
- } else {
- audit_msg(LOG_ERR,
- "Only -i option is allowed");
- retval = -1;
- break;
- }
- }
- retval = report_status(fd);
- break;
- case 'e':
- if (optarg && ((strcmp(optarg, "0") == 0) ||
- (strcmp(optarg, "1") == 0) ||
- (strcmp(optarg, "2") == 0))) {
- if (audit_set_enabled(fd, strtoul(optarg,NULL,0)) > 0)
- audit_request_status(fd);
- else
- retval = -1;
- } else {
- audit_msg(LOG_ERR, "Enable must be 0, 1, or 2 was %s",
- optarg);
- retval = -1;
- }
- break;
- case 'f':
- if (optarg && ((strcmp(optarg, "0") == 0) ||
- (strcmp(optarg, "1") == 0) ||
- (strcmp(optarg, "2") == 0))) {
- if (audit_set_failure(fd, strtoul(optarg,NULL,0)) > 0)
- audit_request_status(fd);
- else
- return -1;
- } else {
- audit_msg(LOG_ERR, "Failure must be 0, 1, or 2 was %s",
- optarg);
- retval = -1;
- }
- break;
- case 'r':
- if (optarg && isdigit(optarg[0])) {
- uint32_t rate;
- errno = 0;
- rate = strtoul(optarg,NULL,0);
- if (errno) {
- audit_msg(LOG_ERR, "Error converting rate");
- return -1;
- }
- if (audit_set_rate_limit(fd, rate) > 0)
- audit_request_status(fd);
- else
- return -1;
- } else {
- audit_msg(LOG_ERR,"Rate must be a numeric value was %s",
- optarg);
- retval = -1;
- }
- break;
- case 'b':
- if (optarg && isdigit(optarg[0])) {
- uint32_t limit;
- errno = 0;
- limit = strtoul(optarg,NULL,0);
- if (errno) {
- audit_msg(LOG_ERR, "Error converting backlog");
- return -1;
- }
- if (audit_set_backlog_limit(fd, limit) > 0)
- audit_request_status(fd);
- else
- return -1;
- } else {
- audit_msg(LOG_ERR,
- "Backlog must be a numeric value was %s",
- optarg);
- retval = -1;
- }
- break;
- case 'l':
- if (count > 4) {
- audit_msg(LOG_ERR,
- "Wrong number of options for list request");
- retval = -1;
- break;
- }
- if (count == 3) {
- if (strcmp(vars[optind], "-i") == 0) {
- interpret = 1;
- count -= 1;
- } else {
- audit_msg(LOG_ERR,
- "Only -k or -i options are allowed");
- retval = -1;
- }
- } else if (count == 4) {
- if (vars[optind] && strcmp(vars[optind], "-k") == 0) {
- strncat(key, vars[3], keylen);
- count -= 2;
- } else {
- audit_msg(LOG_ERR,
- "Only -k or -i options are allowed");
- retval = -1;
- break;
- }
- }
- if (audit_request_rule_list(fd)) {
- list_requested = 1;
- retval = -2;
- } else
- retval = -1;
- break;
- case 'a':
- if (strstr(optarg, "task") && _audit_syscalladded) {
- audit_msg(LOG_ERR,
- "Syscall auditing requested for task list");
- retval = -1;
- } else {
- rc = audit_rule_setup(optarg, &add, &action, lineno);
- if (rc == 3) {
- audit_msg(LOG_ERR,
- "Multiple rule insert/delete operations are not allowed\n");
- retval = -1;
- } else if (rc == 2) {
- audit_msg(LOG_ERR,
- "Append rule - bad keyword %s",
- optarg);
- retval = -1;
- } else if (rc == 1) {
- audit_msg(LOG_ERR,
- "Append rule - possible is deprecated");
- return -3; /* deprecated - eat it */
- } else
- retval = 1; /* success - please send */
- }
- break;
- case 'A':
- if (strstr(optarg, "task") && _audit_syscalladded) {
- audit_msg(LOG_ERR,
- "Error: syscall auditing requested for task list");
- retval = -1;
- } else {
- rc = audit_rule_setup(optarg, &add, &action, lineno);
- if (rc == 3) {
- audit_msg(LOG_ERR,
- "Multiple rule insert/delete operations are not allowed");
- retval = -1;
- } else if (rc == 2) {
- audit_msg(LOG_ERR,
- "Add rule - bad keyword %s", optarg);
- retval = -1;
- } else if (rc == 1) {
- audit_msg(LOG_WARNING,
- "Append rule - possible is deprecated");
- return -3; /* deprecated - eat it */
- } else {
- add |= AUDIT_FILTER_PREPEND;
- retval = 1; /* success - please send */
- }
- }
- break;
- case 'd':
- rc = audit_rule_setup(optarg, &del, &action, lineno);
- if (rc == 3) {
- audit_msg(LOG_ERR,
- "Multiple rule insert/delete operations are not allowed");
- retval = -1;
- } else if (rc == 2) {
- audit_msg(LOG_ERR, "Delete rule - bad keyword %s",
- optarg);
- retval = -1;
- } else if (rc == 1) {
- audit_msg(LOG_INFO,
- "Delete rule - possible is deprecated");
- return -3; /* deprecated - eat it */
- } else
- retval = 1; /* success - please send */
- break;
- case 'S': {
- int unknown_arch = !_audit_elf;
- /* Do some checking to make sure that we are not adding a
- * syscall rule to a list that does not make sense. */
- if (((add & (AUDIT_FILTER_MASK|AUDIT_FILTER_UNSET)) ==
- AUDIT_FILTER_TASK || (del &
- (AUDIT_FILTER_MASK|AUDIT_FILTER_UNSET)) ==
- AUDIT_FILTER_TASK)) {
- audit_msg(LOG_ERR,
- "Error: syscall auditing being added to task list");
- return -1;
- } else if (((add & (AUDIT_FILTER_MASK|AUDIT_FILTER_UNSET)) ==
- AUDIT_FILTER_USER || (del &
- (AUDIT_FILTER_MASK|AUDIT_FILTER_UNSET)) ==
- AUDIT_FILTER_USER)) {
- audit_msg(LOG_ERR,
- "Error: syscall auditing being added to user list");
- return -1;
- } else if (exclude) {
- audit_msg(LOG_ERR,
- "Error: syscall auditing cannot be put on exclude list");
- return -1;
- } else {
- if (unknown_arch) {
- int machine;
- unsigned int elf;
- machine = audit_detect_machine();
- if (machine < 0) {
- audit_msg(LOG_ERR,
- "Error detecting machine type");
- return -1;
- }
- elf = audit_machine_to_elf(machine);
- if (elf == 0) {
- audit_msg(LOG_ERR,
- "Error looking up elf type %d",
- machine);
- return -1;
- }
- _audit_elf = elf;
- }
- }
- rc = parse_syscall(rule_new, optarg);
- switch (rc)
- {
- case 0:
- _audit_syscalladded = 1;
- if (unknown_arch && add != AUDIT_FILTER_UNSET)
- check_rule_mismatch(lineno, optarg);
- break;
- case -1:
- audit_msg(LOG_ERR, "Syscall name unknown: %s",
- optarg);
- retval = -1;
- break;
- case -2:
- audit_msg(LOG_ERR, "Elf type unknown: 0x%x",
- _audit_elf);
- retval = -1;
- break;
- case -3: // Error reported - do nothing here
- retval = -1;
- break;
- }}
- break;
- case 'F':
- if (add != AUDIT_FILTER_UNSET)
- flags = add & AUDIT_FILTER_MASK;
- else if (del != AUDIT_FILTER_UNSET)
- flags = del & AUDIT_FILTER_MASK;
- // if the field is arch & there is a -t option...we
- // can allow it
- else if ((optind >= count) || (strstr(optarg, "arch=") == NULL)
- || (strcmp(vars[optind], "-t") != 0)) {
- audit_msg(LOG_ERR, "List must be given before field");
- retval = -1;
- break;
- }
-
- rc = audit_rule_fieldpair_data(&rule_new,optarg,flags);
- if (rc != 0) {
- audit_number_to_errmsg(rc, optarg);
- retval = -1;
- } else {
- if (rule_new->fields[rule_new->field_count-1] ==
- AUDIT_PERM)
- _audit_permadded = 1;
- }
-
- break;
- case 'C':
- if (add != AUDIT_FILTER_UNSET)
- flags = add & AUDIT_FILTER_MASK;
- else if (del != AUDIT_FILTER_UNSET)
- flags = del & AUDIT_FILTER_MASK;
-
- rc = audit_rule_interfield_comp_data(&rule_new, optarg, flags);
- if (rc != 0) {
- audit_number_to_errmsg(rc, optarg);
- retval = -1;
- } else {
- if (rule_new->fields[rule_new->field_count - 1] ==
- AUDIT_PERM)
- _audit_permadded = 1;
- }
- break;
- case 'm':
- if (count > 3) {
- audit_msg(LOG_ERR,
- "The -m option must be only the only option and takes 1 parameter");
- retval = -1;
- } else {
- const char*s = optarg;
- while (*s) {
- if (*s < 32) {
- audit_msg(LOG_ERR,
- "Illegal character in audit event");
- return -1;
- }
- s++;
- }
- if (audit_log_user_message( fd, AUDIT_USER,
- optarg, NULL, NULL, NULL, 1) <= 0)
- retval = -1;
- else
- return -2; // success - no reply for this
- }
- break;
- case 'R':
- audit_msg(LOG_ERR, "Error - nested rule files not supported");
- retval = -1;
- break;
- case 'D':
- if (count > 4 || count == 3) {
- audit_msg(LOG_ERR,
- "Wrong number of options for Delete all request");
- retval = -1;
- break;
- }
- if (count == 4) {
- if (strcmp(vars[optind], "-k") == 0) {
- strncat(key, vars[3], keylen);
- count -= 2;
- } else {
- audit_msg(LOG_ERR,
- "Only the -k option is allowed");
- retval = -1;
- break;
- }
- }
- retval = delete_all_rules(fd);
- if (retval == 0) {
- (void)audit_request_rule_list(fd);
- key[0] = 0;
- retval = -2;
- }
- break;
- case 'w':
- if (add != AUDIT_FILTER_UNSET ||
- del != AUDIT_FILTER_UNSET) {
- audit_msg(LOG_ERR,
- "watch option can't be given with a syscall");
- retval = -1;
- } else if (optarg) {
- add = AUDIT_FILTER_EXIT;
- action = AUDIT_ALWAYS;
- _audit_syscalladded = 1;
- retval = audit_setup_watch_name(&rule_new, optarg);
- } else {
- audit_msg(LOG_ERR, "watch option needs a path");
- retval = -1;
- }
- break;
- case 'W':
- if (optarg) {
- del = AUDIT_FILTER_EXIT;
- action = AUDIT_ALWAYS;
- _audit_syscalladded = 1;
- retval = audit_setup_watch_name(&rule_new, optarg);
- } else {
- audit_msg(LOG_ERR, "watch option needs a path");
- retval = -1;
- }
- break;
- case 'k':
- if (!(_audit_syscalladded || _audit_permadded ) ||
- (add==AUDIT_FILTER_UNSET &&
- del==AUDIT_FILTER_UNSET)) {
- audit_msg(LOG_ERR,
- "key option needs a watch or syscall given prior to it");
- retval = -1;
- } else if (!optarg) {
- audit_msg(LOG_ERR, "key option needs a value");
- retval = -1;
- } else if ((strlen(optarg)+strlen(key)+(!!key[0])) >
- AUDIT_MAX_KEY_LEN) {
- audit_msg(LOG_ERR, "key option exceeds size limit");
- retval = -1;
- } else {
- if (strncmp(optarg, "ids-", 4) == 0) {
- if (check_ids_key(optarg)) {
- retval = -1;
- break;
- }
- }
- if (strchr(optarg, AUDIT_KEY_SEPARATOR))
- audit_msg(LOG_ERR,
- "key %s has illegal character", optarg);
- if (key[0]) { // Add the separator if we need to
- strcat(key, key_sep);
- keylen--;
- }
- strncat(key, optarg, keylen);
- keylen = AUDIT_MAX_KEY_LEN - strlen(key);
- }
- break;
- case 'p':
- if (!add && !del) {
- audit_msg(LOG_ERR,
- "permission option needs a watch given prior to it");
- retval = -1;
- } else if (!optarg) {
- audit_msg(LOG_ERR, "permission option needs a filter");
- retval = -1;
- } else
- retval = audit_setup_perms(rule_new, optarg);
- break;
- case 'q':
- if (_audit_syscalladded) {
- audit_msg(LOG_ERR,
- "Syscall auditing requested for make equivalent");
- retval = -1;
- } else {
- char *mp, *sub;
- retval = equiv_parse(optarg, &mp, &sub);
- if (retval < 0) {
- audit_msg(LOG_ERR,
- "Error parsing equivalent parts");
- retval = -1;
- } else {
- retval = audit_make_equivalent(fd, mp, sub);
- if (retval <= 0) {
- retval = -1;
- } else
- return -2; // success - no reply needed
- }
- }
- break;
- case 't':
- retval = audit_trim_subtrees(fd);
- if (retval <= 0)
- retval = -1;
- else
- return -2; // success - no reply for this
- break;
- case 'v':
- printf("auditctl version %s\n", VERSION);
- retval = -2;
- break;
- // Now the long options
- case 1:
- retval = audit_set_loginuid_immutable(fd);
- if (retval <= 0)
- retval = -1;
- else
- return -2; // success - no reply for this
- break;
- case 2:
-#if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME
- if (optarg && isdigit(optarg[0])) {
- uint32_t bwt;
- errno = 0;
- bwt = strtoul(optarg,NULL,0);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting backlog_wait_time");
- return -1;
- }
- if (audit_set_backlog_wait_time(fd, bwt) > 0)
- audit_request_status(fd);
- else
- return -1;
- } else {
- audit_msg(LOG_ERR,
- "Backlog_wait_time must be a numeric value was %s",
- optarg);
- retval = -1;
- }
-#else
- audit_msg(LOG_ERR,
- "backlog_wait_time is not supported on your kernel");
- retval = -1;
-#endif
- break;
- default:
- usage();
- retval = -1;
- break;
- }
- }
- /* catch extra args or errors where the user types "- s" */
- if (optind == 1)
- retval = -1;
- else if ((optind < count) && (retval != -1)) {
- audit_msg(LOG_ERR, "parameter passed without an option given");
- retval = -1;
- }
-
- /* See if we were adding a key */
- if (key[0] && list_requested == 0) {
- int flags = 0;
- char *cmd=NULL;
-
- /* Get the flag */
- if (add != AUDIT_FILTER_UNSET)
- flags = add & AUDIT_FILTER_MASK;
- else if (del != AUDIT_FILTER_UNSET)
- flags = del & AUDIT_FILTER_MASK;
-
- /* Build the command */
- if (asprintf(&cmd, "key=%s", key) < 0) {
- cmd = NULL;
- audit_msg(LOG_ERR, "Out of memory adding key");
- retval = -1;
- } else {
- /* Add this to the rule */
- int ret = audit_rule_fieldpair_data(&rule_new, cmd, flags);
- if (ret < 0)
- retval = -1;
- free(cmd);
- }
- }
- if (retval == -1 && errno == ECONNREFUSED)
- audit_msg(LOG_ERR, "The audit system is disabled");
- return retval;
-}
-
-static char *get_line(FILE *f, char *buf)
-{
- if (fgets_unlocked(buf, LINE_SIZE, f)) {
- /* remove newline */
- char *ptr = strchr(buf, 0x0a);
- if (ptr)
- *ptr = 0;
- return buf;
- }
- return NULL;
-}
-
-
-void preprocess(char *buf)
-{
- unsigned int i = 0;
- bool esc_ctx = false;
-
- while (buf[i]) {
- if (buf[i] == '\\' && esc_ctx == false)
- esc_ctx = true;
- else {
- if (esc_ctx == true) {
- if (buf[i] == ' ') {
- buf[i] = 0x07;
- buf[i - 1] = 0x07;
- } else if (buf[i] == '\\') {
- buf[i] = 0x04;
- buf[i - 1] = 0x04;
- }
-
- esc_ctx = false;
- }
- }
-
- i++;
- }
-}
-
-
-void postprocess(char *buf)
-{
- char *str = strdup(buf);
- char *pos1 = str;
- char *pos2 = buf;
-
- if (!str)
- return;
-
- while (*pos1) {
- if (*pos1 == 0x07) {
- *pos2 = ' ';
- pos1 += 2;
- pos2++;
- continue;
- } else if (*pos1 == 0x04) {
- *pos2 = '\\';
- pos1 += 2;
- pos2++;
- continue;
- }
-
- *pos2 = *pos1;
- pos2++;
- pos1++;
- }
-
- *pos2 = 0;
- free(str);
-}
-
-
-/*
- * This function reads the given file line by line and executes the rule.
- * It returns 0 if everything went OK, 1 if there are problems before reading
- * the file and -1 on error conditions after executing some of the rules.
- * It will abort reading the file if it encounters any problems.
- */
-static int fileopt(const char *file)
-{
- int i, tfd, rc, lineno = 1;
- struct stat st;
- FILE *f;
- char buf[LINE_SIZE];
-
- /* Does the file exist? */
- rc = open(file, O_RDONLY);
- if (rc < 0) {
- if (errno != ENOENT) {
- audit_msg(LOG_ERR,"Error opening %s (%s)",
- file, strerror(errno));
- return 1;
- }
- audit_msg(LOG_INFO, "file %s doesn't exist, skipping", file);
- return 0;
- }
- tfd = rc;
-
- /* Is the file permissions sane? */
- if (fstat(tfd, &st) < 0) {
- audit_msg(LOG_ERR, "Error fstat'ing %s (%s)",
- file, strerror(errno));
- close(tfd);
- return 1;
- }
- if (st.st_uid != 0) {
- audit_msg(LOG_ERR, "Error - %s isn't owned by root", file);
- close(tfd);
- return 1;
- }
- if ((st.st_mode & S_IWOTH) == S_IWOTH) {
- audit_msg(LOG_ERR, "Error - %s is world writable", file);
- close(tfd);
- return 1;
- }
- if (!S_ISREG(st.st_mode)) {
- audit_msg(LOG_ERR, "Error - %s is not a regular file", file);
- close(tfd);
- return 1;
- }
-
- f = fdopen(tfd, "rm");
- if (f == NULL) {
- audit_msg(LOG_ERR, "Error - fdopen failed (%s)",
- strerror(errno));
- close(tfd);
- return 1;
- }
-
- /* Read until eof, lineno starts as 1 */
- while (get_line(f, buf)) {
- char *ptr, **fields;
- int idx=0, nf = (strlen(buf)/3) + 3;
-
- /* Weed out blank lines */
- while (buf[idx] == ' ')
- idx++;
- if (buf[idx] == 0) {
- lineno++;
- continue;
- }
-
- preprocess(buf);
- ptr = audit_strsplit(buf);
- if (ptr == NULL)
- break;
-
- /* allow comments */
- if (ptr[0] == '#') {
- lineno++;
- continue;
- }
- i = 0;
- fields = malloc(nf * sizeof(char *));
- fields[i++] = "auditctl";
- fields[i++] = ptr;
- while( (ptr=audit_strsplit(NULL)) && (i < nf-1)) {
- postprocess(ptr);
- fields[i++] = ptr;
- }
-
- fields[i] = NULL;
-
- /* Parse it */
- if (reset_vars()) {
- free(fields);
- fclose(f);
- return -1;
- }
- rc = setopt(i, lineno, fields);
- free(fields);
-
- /* handle reply or send rule */
- if (rc != -3) {
- if (handle_request(rc) == -1) {
- if (errno != ECONNREFUSED)
- audit_msg(LOG_ERR,
- "There was an error in line %d of %s",
- lineno, file);
- else {
- audit_msg(LOG_ERR,
- "The audit system is disabled");
- fclose(f);
- return 0;
- }
- if (ignore == 0) {
- fclose(f);
- return -1;
- }
- if (continue_error)
- continue_error = -1;
- }
- }
- lineno++;
- }
- fclose(f);
- return 0;
-}
-
-/* Return 1 if ready, 0 otherwise */
-static int is_ready(int fd)
-{
- if (audit_is_enabled(fd) == 2) {
- audit_msg(LOG_ERR, "The audit system is in immutable mode,"
- " no rule changes allowed");
- return 0;
- } else if (errno == ECONNREFUSED) {
- audit_msg(LOG_ERR, "The audit system is disabled");
- return 0;
- }
- return 1;
-}
-
-int main(int argc, char *argv[])
-{
- int retval = 1;
-
- set_aumessage_mode(MSG_STDERR, DBG_NO);
-
- if (argc == 1) {
- usage();
- return 1;
- }
-#ifndef DEBUG
- /* Make sure we are root if we do anything except help */
- if (!(argc == 2 && (strcmp(argv[1], "--help")==0 ||
- strcmp(argv[1], "-h") == 0)) && (geteuid() != 0)) {
- audit_msg(LOG_WARNING, "You must be root to run this program.");
- return 4;
- }
-#endif
- /* Check where the rules are coming from: commandline or file */
- if ((argc == 3) && (strcmp(argv[1], "-R") == 0)) {
- // If reading a file, its most likely start up. Send problems
- // to syslog where they will persist for later review
- set_aumessage_mode(MSG_SYSLOG, DBG_NO);
- fd = audit_open();
- if (is_ready(fd) == 0)
- return 0;
- else if (fileopt(argv[2])) {
- free(rule_new);
- return 1;
- } else {
- free(rule_new);
- if (continue_error < 0)
- return 1;
- return 0;
- }
- } else {
- if (reset_vars()) {
- free(rule_new);
- return 1;
- }
- retval = setopt(argc, 0, argv);
- if (retval == -3) {
- free(rule_new);
- return 0;
- }
- }
-
- if (add != AUDIT_FILTER_UNSET || del != AUDIT_FILTER_UNSET) {
- fd = audit_open();
- if (is_ready(fd) == 0) {
- free(rule_new);
- return 0;
- }
- }
- retval = handle_request(retval);
- free(rule_new);
- return retval;
-}
-
-/*
- * This function is called after setopt to handle the return code.
- * On entry, status = 0 means just get the reply. Greater than 0 means we
- * are adding or deleting a rule or watch. -1 means an error occurred.
- * -2 means everything is OK and no reply needed. Even if there's an
- * error, we need to call this routine to close up the audit fd.
- * The return code from this function is 0 success and -1 error.
- */
-static int handle_request(int status)
-{
- if (status == 0) {
- if (_audit_syscalladded) {
- audit_msg(LOG_ERR, "Error - no list specified");
- return -1;
- }
- get_reply();
- } else if (status == -2)
- status = 0; // report success
- else if (status > 0) {
- int rc;
- if (add != AUDIT_FILTER_UNSET) {
- // if !task add syscall any if not specified
- if ((add & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK &&
- _audit_syscalladded != 1) {
- audit_rule_syscallbyname_data(
- rule_new, "all");
- }
- set_aumessage_mode(MSG_QUIET, DBG_NO);
- rc = audit_add_rule_data(fd, rule_new, add, action);
- set_aumessage_mode(MSG_STDERR, DBG_NO);
- /* Retry for legacy kernels */
- if (rc < 0) {
- if (errno == EINVAL &&
- rule_new->fields[0] == AUDIT_DIR) {
- rule_new->fields[0] = AUDIT_WATCH;
- rc = audit_add_rule_data(fd, rule_new,
- add, action);
- } else {
- audit_msg(LOG_ERR,
- "Error sending add rule data request (%s)",
- errno == EEXIST ?
- "Rule exists" : strerror(-rc));
- }
- }
- }
- else if (del != AUDIT_FILTER_UNSET) {
- if ((del & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK &&
- _audit_syscalladded != 1) {
- audit_rule_syscallbyname_data(
- rule_new, "all");
- }
- set_aumessage_mode(MSG_QUIET, DBG_NO);
- rc = audit_delete_rule_data(fd, rule_new,
- del, action);
- set_aumessage_mode(MSG_STDERR, DBG_NO);
- /* Retry for legacy kernels */
- if (rc < 0) {
- if (errno == EINVAL &&
- rule_new->fields[0] == AUDIT_DIR) {
- rule_new->fields[0] = AUDIT_WATCH;
- rc = audit_delete_rule_data(fd,rule_new,
- del, action);
- } else {
- audit_msg(LOG_ERR,
- "Error sending delete rule data request (%s)",
- errno == EEXIST ?
- "Rule exists" : strerror(-rc));
- }
- }
- } else {
- usage();
- audit_close(fd);
- exit(1);
- }
- if (rc <= 0)
- status = -1;
- else
- status = 0;
- } else
- status = -1;
-
- if (!list_requested)
- audit_close(fd);
- fd = -1;
- return status;
-}
-
-/*
- * A reply from the kernel is expected. Get and display it.
- */
-static void get_reply(void)
-{
- int i, retval;
- int timeout = 40; /* loop has delay of .1 - so this is 4 seconds */
- struct audit_reply rep;
- fd_set read_mask;
- FD_ZERO(&read_mask);
- FD_SET(fd, &read_mask);
-
- // Reset printing counter
- audit_print_init();
-
- for (i = 0; i < timeout; i++) {
- struct timeval t;
-
- t.tv_sec = 0;
- t.tv_usec = 100000; /* .1 second */
- do {
- retval=select(fd+1, &read_mask, NULL, NULL, &t);
- } while (retval < 0 && errno == EINTR);
- // We'll try to read just in case
- retval = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
- if (retval > 0) {
- if (rep.type == NLMSG_ERROR && rep.error->error == 0) {
- i = 0; /* reset timeout */
- continue; /* This was an ack */
- }
-
- if ((retval = audit_print_reply(&rep, fd)) == 0)
- break;
- else
- i = 0; /* If getting more, reset timeout */
- }
- }
-}
-
diff --git a/framework/src/audit/src/auditd-config.c b/framework/src/audit/src/auditd-config.c
deleted file mode 100644
index 0a99ffe0..00000000
--- a/framework/src/audit/src/auditd-config.c
+++ /dev/null
@@ -1,1744 +0,0 @@
-/* auditd-config.c --
- * Copyright 2004-2011,2013-14 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <fcntl.h> /* O_NOFOLLOW needs gnu defined */
-#include <libgen.h>
-#include <arpa/inet.h>
-#include <limits.h> /* INT_MAX */
-#include "auditd-config.h"
-#include "libaudit.h"
-#include "private.h"
-
-#define TCP_PORT_MAX 65535
-
-/* Local prototypes */
-struct nv_pair
-{
- const char *name;
- const char *value;
- const char *option;
-};
-
-struct kw_pair
-{
- const char *name;
- int (*parser)(struct nv_pair *, int, struct daemon_conf *);
- int max_options;
-};
-
-struct nv_list
-{
- const char *name;
- int option;
-};
-
-static char *get_line(FILE *f, char *buf, unsigned size, int *lineno,
- const char *file);
-static int nv_split(char *buf, struct nv_pair *nv);
-static const struct kw_pair *kw_lookup(const char *val);
-static int log_file_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int num_logs_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int log_group_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int qos_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int dispatch_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int name_format_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int name_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int max_log_size_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int max_log_size_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int log_format_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int flush_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int freq_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int space_left_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int space_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int action_mail_acct_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int admin_space_left_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int admin_space_left_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int disk_full_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int disk_error_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int priority_boost_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int tcp_listen_port_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int tcp_listen_queue_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int tcp_max_per_addr_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int use_libwrap_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int tcp_client_ports_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int tcp_client_max_idle_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int enable_krb5_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int krb5_principal_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int krb5_key_file_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config);
-static int sanity_check(struct daemon_conf *config);
-
-static const struct kw_pair keywords[] =
-{
- {"log_file", log_file_parser, 0 },
- {"log_format", log_format_parser, 0 },
- {"log_group", log_group_parser, 0 },
- {"flush", flush_parser, 0 },
- {"freq", freq_parser, 0 },
- {"num_logs", num_logs_parser, 0 },
- {"dispatcher", dispatch_parser, 0 },
- {"name_format", name_format_parser, 0 },
- {"name", name_parser, 0 },
- {"disp_qos", qos_parser, 0 },
- {"max_log_file", max_log_size_parser, 0 },
- {"max_log_file_action", max_log_size_action_parser, 0 },
- {"space_left", space_left_parser, 0 },
- {"space_left_action", space_action_parser, 1 },
- {"action_mail_acct", action_mail_acct_parser, 0 },
- {"admin_space_left", admin_space_left_parser, 0 },
- {"admin_space_left_action", admin_space_left_action_parser, 1 },
- {"disk_full_action", disk_full_action_parser, 1 },
- {"disk_error_action", disk_error_action_parser, 1 },
- {"priority_boost", priority_boost_parser, 0 },
- {"tcp_listen_port", tcp_listen_port_parser, 0 },
- {"tcp_listen_queue", tcp_listen_queue_parser, 0 },
- {"tcp_max_per_addr", tcp_max_per_addr_parser, 0 },
- {"use_libwrap", use_libwrap_parser, 0 },
- {"tcp_client_ports", tcp_client_ports_parser, 0 },
- {"tcp_client_max_idle", tcp_client_max_idle_parser, 0 },
- {"enable_krb5", enable_krb5_parser, 0 },
- {"krb5_principal", krb5_principal_parser, 0 },
- {"krb5_key_file", krb5_key_file_parser, 0 },
- { NULL, NULL }
-};
-
-static const struct nv_list log_formats[] =
-{
- {"raw", LF_RAW },
- {"nolog", LF_NOLOG },
- { NULL, 0 }
-};
-
-static const struct nv_list flush_techniques[] =
-{
- {"none", FT_NONE },
- {"incremental", FT_INCREMENTAL },
- {"data", FT_DATA },
- {"sync", FT_SYNC },
- { NULL, 0 }
-};
-
-static const struct nv_list failure_actions[] =
-{
- {"ignore", FA_IGNORE },
- {"syslog", FA_SYSLOG },
- {"rotate", FA_ROTATE },
- {"email", FA_EMAIL },
- {"exec", FA_EXEC },
- {"suspend", FA_SUSPEND },
- {"single", FA_SINGLE },
- {"halt", FA_HALT },
- { NULL, 0 }
-};
-
-// Future ideas: e-mail, run command
-static const struct nv_list size_actions[] =
-{
- {"ignore", SZ_IGNORE },
- {"syslog", SZ_SYSLOG },
- {"suspend", SZ_SUSPEND },
- {"rotate", SZ_ROTATE },
- {"keep_logs", SZ_KEEP_LOGS},
- { NULL, 0 }
-};
-
-static const struct nv_list qos_options[] =
-{
- {"lossy", QOS_NON_BLOCKING },
- {"lossless", QOS_BLOCKING },
- { NULL, 0 }
-};
-
-static const struct nv_list node_name_formats[] =
-{
- {"none", N_NONE },
- {"hostname", N_HOSTNAME },
- {"fqd", N_FQD },
- {"numeric", N_NUMERIC },
- {"user", N_USER },
- { NULL, 0 }
-};
-
-static const struct nv_list yes_no_values[] =
-{
- {"yes", 1 },
- {"no", 0 },
- { NULL, 0 }
-};
-
-const char *email_command = "/usr/lib/sendmail";
-static int allow_links = 0;
-
-
-void set_allow_links(int allow)
-{
- allow_links = allow;
-}
-
-/*
- * Set everything to its default value
-*/
-void clear_config(struct daemon_conf *config)
-{
- config->qos = QOS_NON_BLOCKING;
- config->sender_uid = 0;
- config->sender_pid = 0;
- config->sender_ctx = NULL;
- config->log_file = strdup("/var/log/audit/audit.log");
- config->log_format = LF_RAW;
- config->log_group = 0;
- config->priority_boost = 4;
- config->flush = FT_NONE;
- config->freq = 0;
- config->num_logs = 0L;
- config->dispatcher = NULL;
- config->node_name_format = N_NONE;
- config->node_name = NULL;
- config->max_log_size = 0L;
- config->max_log_size_action = SZ_IGNORE;
- config->space_left = 0L;
- config->space_left_action = FA_IGNORE;
- config->space_left_exe = NULL;
- config->action_mail_acct = strdup("root");
- config->admin_space_left= 0L;
- config->admin_space_left_action = FA_IGNORE;
- config->admin_space_left_exe = NULL;
- config->disk_full_action = FA_IGNORE;
- config->disk_full_exe = NULL;
- config->disk_error_action = FA_SYSLOG;
- config->disk_error_exe = NULL;
- config->tcp_listen_port = 0;
- config->tcp_listen_queue = 5;
- config->tcp_max_per_addr = 1;
- config->use_libwrap = 1;
- config->tcp_client_min_port = 0;
- config->tcp_client_max_port = TCP_PORT_MAX;
- config->tcp_client_max_idle = 0;
- config->enable_krb5 = 0;
- config->krb5_principal = NULL;
- config->krb5_key_file = NULL;
-}
-
-static log_test_t log_test = TEST_AUDITD;
-int load_config(struct daemon_conf *config, log_test_t lt)
-{
- int fd, rc, mode, lineno = 1;
- struct stat st;
- FILE *f;
- char buf[160];
-
- clear_config(config);
- log_test = lt;
-
- /* open the file */
- mode = O_RDONLY;
- if (allow_links == 0)
- mode |= O_NOFOLLOW;
- rc = open(CONFIG_FILE, mode);
- if (rc < 0) {
- if (errno != ENOENT) {
- audit_msg(LOG_ERR, "Error opening config file (%s)",
- strerror(errno));
- return 1;
- }
- audit_msg(LOG_WARNING,
- "Config file %s doesn't exist, skipping", CONFIG_FILE);
- return 0;
- }
- fd = rc;
-
- /* check the file's permissions: owned by root, not world writable,
- * not symlink.
- */
- audit_msg(LOG_DEBUG, "Config file %s opened for parsing",
- CONFIG_FILE);
- if (fstat(fd, &st) < 0) {
- audit_msg(LOG_ERR, "Error fstat'ing config file (%s)",
- strerror(errno));
- close(fd);
- return 1;
- }
- if (st.st_uid != 0) {
- audit_msg(LOG_ERR, "Error - %s isn't owned by root",
- CONFIG_FILE);
- close(fd);
- return 1;
- }
- if ((st.st_mode & S_IWOTH) == S_IWOTH) {
- audit_msg(LOG_ERR, "Error - %s is world writable",
- CONFIG_FILE);
- close(fd);
- return 1;
- }
- if (!S_ISREG(st.st_mode)) {
- audit_msg(LOG_ERR, "Error - %s is not a regular file",
- CONFIG_FILE);
- close(fd);
- return 1;
- }
-
- /* it's ok, read line by line */
- f = fdopen(fd, "rm");
- if (f == NULL) {
- audit_msg(LOG_ERR, "Error - fdopen failed (%s)",
- strerror(errno));
- close(fd);
- return 1;
- }
-
- while (get_line(f, buf, sizeof(buf), &lineno, CONFIG_FILE)) {
- // convert line into name-value pair
- const struct kw_pair *kw;
- struct nv_pair nv;
- rc = nv_split(buf, &nv);
- switch (rc) {
- case 0: // fine
- break;
- case 1: // not the right number of tokens.
- audit_msg(LOG_ERR,
- "Wrong number of arguments for line %d in %s",
- lineno, CONFIG_FILE);
- break;
- case 2: // no '=' sign
- audit_msg(LOG_ERR,
- "Missing equal sign for line %d in %s",
- lineno, CONFIG_FILE);
- break;
- default: // something else went wrong...
- audit_msg(LOG_ERR,
- "Unknown error for line %d in %s",
- lineno, CONFIG_FILE);
- break;
- }
- if (nv.name == NULL) {
- lineno++;
- continue;
- }
- if (nv.value == NULL) {
- fclose(f);
- audit_msg(LOG_ERR,
- "Not processing any more lines in %s",
- CONFIG_FILE);
- return 1;
- }
-
- /* identify keyword or error */
- kw = kw_lookup(nv.name);
- if (kw->name == NULL) {
- audit_msg(LOG_ERR,
- "Unknown keyword \"%s\" in line %d of %s",
- nv.name, lineno, CONFIG_FILE);
- fclose(f);
- return 1;
- }
-
- /* Check number of options */
- if (kw->max_options == 0 && nv.option != NULL) {
- audit_msg(LOG_ERR,
- "Keyword \"%s\" has invalid option "
- "\"%s\" in line %d of %s",
- nv.name, nv.option, lineno, CONFIG_FILE);
- fclose(f);
- return 1;
- }
-
- /* dispatch to keyword's local parser */
- rc = kw->parser(&nv, lineno, config);
- if (rc != 0) {
- fclose(f);
- return 1; // local parser puts message out
- }
-
- lineno++;
- }
-
- fclose(f);
- if (lineno > 1)
- return sanity_check(config);
- return 0;
-}
-
-static char *get_line(FILE *f, char *buf, unsigned size, int *lineno,
- const char *file)
-{
- int too_long = 0;
-
- while (fgets_unlocked(buf, size, f)) {
- /* remove newline */
- char *ptr = strchr(buf, 0x0a);
- if (ptr) {
- if (!too_long) {
- *ptr = 0;
- return buf;
- }
- // Reset and start with the next line
- too_long = 0;
- *lineno = *lineno + 1;
- } else {
- // If a line is too long skip it.
- // Only output 1 warning
- if (!too_long)
- audit_msg(LOG_ERR,
- "Skipping line %d in %s: too long",
- *lineno, file);
- too_long = 1;
- }
- }
- return NULL;
-}
-
-static int nv_split(char *buf, struct nv_pair *nv)
-{
- /* Get the name part */
- char *ptr;
-
- nv->name = NULL;
- nv->value = NULL;
- nv->option = NULL;
- ptr = audit_strsplit(buf);
- if (ptr == NULL)
- return 0; /* If there's nothing, go to next line */
- if (ptr[0] == '#')
- return 0; /* If there's a comment, go to next line */
- nv->name = ptr;
-
- /* Check for a '=' */
- ptr = audit_strsplit(NULL);
- if (ptr == NULL)
- return 1;
- if (strcmp(ptr, "=") != 0)
- return 2;
-
- /* get the value */
- ptr = audit_strsplit(NULL);
- if (ptr == NULL)
- return 1;
- nv->value = ptr;
-
- /* See if there's an option */
- ptr = audit_strsplit(NULL);
- if (ptr) {
- nv->option = ptr;
-
- /* Make sure there's nothing else */
- ptr = audit_strsplit(NULL);
- if (ptr)
- return 1;
- }
-
- /* Everything is OK */
- return 0;
-}
-
-static const struct kw_pair *kw_lookup(const char *val)
-{
- int i = 0;
- while (keywords[i].name != NULL) {
- if (strcasecmp(keywords[i].name, val) == 0)
- break;
- i++;
- }
- return &keywords[i];
-}
-
-static int log_file_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- char *dir = NULL, *tdir;
- DIR *d;
- int fd, mode;
- struct stat buf;
-
- audit_msg(LOG_DEBUG, "log_file_parser called with: %s", nv->value);
-
- /* get dir from name. */
- tdir = strdup(nv->value);
- if (tdir)
- dir = dirname(tdir);
- if (dir == NULL || strlen(dir) < 4) { // '/var' is shortest dirname
- audit_msg(LOG_ERR,
- "The directory name: %s is too short - line %d",
- dir, line);
- free((void *)tdir);
- return 1;
- }
-
- /* verify the directory path exists */
- d = opendir(dir);
- if (d == NULL) {
- audit_msg(LOG_ERR, "Could not open dir %s (%s)", dir,
- strerror(errno));
- free((void *)tdir);
- return 1;
- }
- free((void *)tdir);
- closedir(d);
-
- /* if the file exists, see that its regular, owned by root,
- * and not world anything */
- if (log_test == TEST_AUDITD)
- mode = O_APPEND;
- else
- mode = O_RDONLY;
-
- fd = open(nv->value, mode);
- if (fd < 0) {
- if (errno == ENOENT) {
- fd = create_log_file(nv->value);
- if (fd < 0)
- return 1;
- } else {
- audit_msg(LOG_ERR, "Unable to open %s (%s)", nv->value,
- strerror(errno));
- return 1;
- }
- }
- if (fstat(fd, &buf) < 0) {
- audit_msg(LOG_ERR, "Unable to stat %s (%s)",
- nv->value, strerror(errno));
- close(fd);
- return 1;
- }
- close(fd);
- if (!S_ISREG(buf.st_mode)) {
- audit_msg(LOG_ERR, "%s is not a regular file", nv->value);
- return 1;
- }
- if (buf.st_uid != 0) {
- audit_msg(LOG_ERR, "%s is not owned by root", nv->value);
- return 1;
- }
- if ( (buf.st_mode & (S_IXUSR|S_IWGRP|S_IXGRP|S_IRWXO)) ) {
- audit_msg(LOG_ERR, "%s permissions should be 0600 or 0640",
- nv->value);
- return 1;
- }
- if ( !(buf.st_mode & S_IWUSR) ) {
- audit_msg(LOG_ERR, "audit log is not writable by owner");
- return 1;
- }
-
- free((void *)config->log_file);
- config->log_file = strdup(nv->value);
- if (config->log_file == NULL)
- return 1;
- return 0;
-}
-
-static int num_logs_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "num_logs_parser called with: %s", nv->value);
-
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned long */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- if (i > 99) {
- audit_msg(LOG_ERR, "num_logs must be 99 or less");
- return 1;
- }
- config->num_logs = i;
- return 0;
-}
-
-static int qos_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "qos_parser called with: %s", nv->value);
- for (i=0; qos_options[i].name != NULL; i++) {
- if (strcasecmp(nv->value, qos_options[i].name) == 0) {
- config->qos = qos_options[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int dispatch_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- char *dir = NULL, *tdir;
- int fd;
- struct stat buf;
-
- audit_msg(LOG_DEBUG, "dispatch_parser called with: %s", nv->value);
- if (nv->value == NULL) {
- config->dispatcher = NULL;
- return 0;
- }
-
- /* get dir from name. */
- tdir = strdup(nv->value);
- if (tdir)
- dir = dirname(tdir);
- if (dir == NULL || strlen(dir) < 4) { // '/var' is shortest dirname
- audit_msg(LOG_ERR,
- "The directory name: %s is too short - line %d",
- dir, line);
- free(tdir);
- return 1;
- }
-
- free((void *)tdir);
-
- /* Bypass the perms check if group is not root since
- * this will fail under normal circumstances */
- if ((config->log_group != 0 && getuid() != 0) ||
- (log_test == TEST_SEARCH))
- goto bypass;
-
- /* if the file exists, see that its regular, owned by root,
- * and not world anything */
- fd = open(nv->value, O_RDONLY);
- if (fd < 0) {
- audit_msg(LOG_ERR, "Unable to open %s (%s)", nv->value,
- strerror(errno));
- return 1;
- }
- if (fstat(fd, &buf) < 0) {
- audit_msg(LOG_ERR, "Unable to stat %s (%s)", nv->value,
- strerror(errno));
- close(fd);
- return 1;
- }
- close(fd);
- if (!S_ISREG(buf.st_mode)) {
- audit_msg(LOG_ERR, "%s is not a regular file", nv->value);
- return 1;
- }
- if (buf.st_uid != 0) {
- audit_msg(LOG_ERR, "%s is not owned by root", nv->value);
- return 1;
- }
- if ((buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
- (S_IRWXU|S_IRGRP|S_IXGRP) &&
- (buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
- (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) {
- audit_msg(LOG_ERR, "%s permissions should be 0750 or 0755",
- nv->value);
- return 1;
- }
-bypass:
- free((void *)config->dispatcher);
- config->dispatcher = strdup(nv->value);
- if (config->dispatcher == NULL)
- return 1;
- return 0;
-}
-
-static int name_format_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "name_format_parser called with: %s", nv->value);
- for (i=0; node_name_formats[i].name != NULL; i++) {
- if (strcasecmp(nv->value, node_name_formats[i].name) == 0) {
- config->node_name_format = node_name_formats[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int name_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- audit_msg(LOG_DEBUG, "name_parser called with: %s", nv->value);
- if (nv->value == NULL)
- config->node_name = NULL;
- else
- config->node_name = strdup(nv->value);
- return 0;
-}
-
-static int max_log_size_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "max_log_size_parser called with: %s", nv->value);
-
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned long */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- config->max_log_size = i;
- return 0;
-}
-
-static int max_log_size_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "max_log_size_action_parser called with: %s",
- nv->value);
- for (i=0; size_actions[i].name != NULL; i++) {
- if (strcasecmp(nv->value, size_actions[i].name) == 0) {
- config->max_log_size_action = size_actions[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int log_format_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "log_format_parser called with: %s", nv->value);
- for (i=0; log_formats[i].name != NULL; i++) {
- if (strcasecmp(nv->value, log_formats[i].name) == 0) {
- config->log_format = log_formats[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int log_group_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- gid_t gid = 0;
-
- audit_msg(LOG_DEBUG, "log_group_parser called with: %s",
- nv->value);
- if (isdigit(nv->value[0])) {
- errno = 0;
- gid = strtoul(nv->value,NULL,10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Numeric group ID conversion error (%s) for %s - line %d\n",
- strerror(errno), nv->value, line);
- return 1;
- }
- } else {
- struct group *gr ;
-
- gr = getgrnam(nv->value);
- if (gr == NULL) {
- audit_msg(LOG_ERR,
- "Group ID is non-numeric and unknown (%s) - line %d\n",
- nv->value, line);
- return 1;
- }
- gid = gr->gr_gid;
- }
- config->log_group = gid;
- return 0;
-}
-
-static int flush_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "flush_parser called with: %s", nv->value);
- for (i=0; flush_techniques[i].name != NULL; i++) {
- if (strcasecmp(nv->value, flush_techniques[i].name) == 0) {
- config->flush = flush_techniques[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int freq_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "freq_parser called with: %s", nv->value);
-
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- /* Check its range */
- if (i > INT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too large - line %d",
- nv->value, line);
- return 1;
- }
- config->freq = (unsigned int)i;
- return 0;
-}
-
-static int space_left_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "space_left_parser called with: %s", nv->value);
-
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned long */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- config->space_left = i;
- return 0;
-}
-
-static int check_exe_name(const char *val, int line)
-{
- struct stat buf;
-
- if (val == NULL) {
- audit_msg(LOG_ERR, "Executable path needed for line %d", line);
- return -1;
- }
-
- if (*val != '/') {
- audit_msg(LOG_ERR, "Absolute path needed for %s - line %d",
- val, line);
- return -1;
- }
-
- if (stat(val, &buf) < 0) {
- audit_msg(LOG_ERR, "Unable to stat %s (%s) - line %d", val,
- strerror(errno), line);
- return -1;
- }
- if (!S_ISREG(buf.st_mode)) {
- audit_msg(LOG_ERR, "%s is not a regular file - line %d", val,
- line);
- return -1;
- }
- if (buf.st_uid != 0) {
- audit_msg(LOG_ERR, "%s is not owned by root - line %d", val,
- line);
- return -1;
- }
- if ((buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
- (S_IRWXU|S_IRGRP|S_IXGRP) &&
- (buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
- (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) {
- audit_msg(LOG_ERR,
- "%s permissions should be 0750 or 0755 - line %d",
- val, line);
- return -1;
- }
- return 0;
-}
-
-static int space_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "space_action_parser called with: %s", nv->value);
- for (i=0; failure_actions[i].name != NULL; i++) {
- if (strcasecmp(nv->value, failure_actions[i].name) == 0) {
- if (failure_actions[i].option == FA_EMAIL) {
- if (access(email_command, X_OK)) {
- audit_msg(LOG_ERR,
- "Email option is specified but %s doesn't seem executable.",
- email_command);
- }
- } else if (failure_actions[i].option == FA_EXEC) {
- if (check_exe_name(nv->option, line))
- return 1;
- config->space_left_exe = strdup(nv->option);
- }
- config->space_left_action = failure_actions[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-// returns 0 if OK, 1 on temp error, 2 on permanent error
-static int validate_email(const char *acct)
-{
- int i, len;
- char *ptr1;
-
- if (acct == NULL)
- return 2;
-
- len = strlen(acct);
- if (len < 2) {
- audit_msg(LOG_ERR,
- "email: %s is too short, expecting at least 2 characters",
- acct);
- return 2;
- }
-
- // look for illegal char
- for (i=0; i<len; i++) {
- if (! (isalnum(acct[i]) || (acct[i] == '@') ||
- (acct[i]=='.') || (acct[i]=='-') ||
- (acct[i] == '_')) ) {
- audit_msg(LOG_ERR, "email: %s has illegal character",
- acct);
- return 2;
- }
- }
-
- if ((ptr1 = strchr(acct, '@'))) {
- char *ptr2;
- struct hostent *t_addr;
-
- ptr2 = strrchr(acct, '.'); // get last dot - sb after @
- if ((ptr2 == NULL) || (ptr1 > ptr2)) {
- audit_msg(LOG_ERR, "email: %s should have . after @",
- acct);
- return 2;
- }
-
- t_addr = gethostbyname(ptr1+1);
- if (t_addr == 0) {
- if ((h_errno == HOST_NOT_FOUND) ||
- (h_errno == NO_RECOVERY)) {
- audit_msg(LOG_ERR,
- "validate_email: failed looking up host for %s",
- ptr1+1);
- // FIXME: gethostbyname is having trouble
- // telling when we have a temporary vs permanent
- // dns failure. So, for now, treat all as temp
- return 1;
- }
- else if (h_errno == TRY_AGAIN)
- audit_msg(LOG_DEBUG,
- "validate_email: temporary failure looking up domain for %s",
- ptr1+1);
- return 1;
- }
- }
- return 0;
-}
-
-static int action_mail_acct_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- char *tmail;
-
- audit_msg(LOG_DEBUG, "action_mail_acct_parser called with: %s",
- nv->value);
- tmail = strdup(nv->value);
- if (tmail == NULL)
- return 1;
-
- if (validate_email(tmail) > 1) {
- free(tmail);
- return 1;
- }
-
-
- if (config->action_mail_acct)
- free((void *)config->action_mail_acct);
- config->action_mail_acct = tmail;
- return 0;
-}
-
-static int admin_space_left_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "admin_space_left_parser called with: %s",
- nv->value);
-
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned long */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- config->admin_space_left = i;
- return 0;
-}
-
-static int admin_space_left_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "admin_space_left_action_parser called with: %s",
- nv->value);
- for (i=0; failure_actions[i].name != NULL; i++) {
- if (strcasecmp(nv->value, failure_actions[i].name) == 0) {
- if (failure_actions[i].option == FA_EMAIL) {
- if (access(email_command, X_OK)) {
- audit_msg(LOG_ERR,
- "Email option is specified but %s doesn't seem executable.",
- email_command);
- }
- } else if (failure_actions[i].option == FA_EXEC) {
- if (check_exe_name(nv->option, line))
- return 1;
- config->admin_space_left_exe =
- strdup(nv->option);
- }
- config->admin_space_left_action =
- failure_actions[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int disk_full_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "disk_full_action_parser called with: %s",
- nv->value);
- for (i=0; failure_actions[i].name != NULL; i++) {
- if (strcasecmp(nv->value, failure_actions[i].name) == 0) {
- if (failure_actions[i].option == FA_EMAIL) {
- audit_msg(LOG_ERR,
- "Illegal option %s for disk_full_action - line %d",
- nv->value, line);
- return 1;
- } else if (failure_actions[i].option == FA_EXEC) {
- if (check_exe_name(nv->option, line))
- return 1;
- config->disk_full_exe = strdup(nv->option);
- }
- config->disk_full_action = failure_actions[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int disk_error_action_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- int i;
-
- audit_msg(LOG_DEBUG, "disk_error_action_parser called with: %s",
- nv->value);
- for (i=0; failure_actions[i].name != NULL; i++) {
- if (strcasecmp(nv->value, failure_actions[i].name) == 0) {
- if (failure_actions[i].option == FA_EMAIL ||
- failure_actions[i].option == FA_ROTATE) {
- audit_msg(LOG_ERR,
- "Illegal option %s for disk_error_action - line %d",
- nv->value, line);
- return 1;
- } else if (failure_actions[i].option == FA_EXEC) {
- if (check_exe_name(nv->option, line))
- return 1;
- config->disk_error_exe = strdup(nv->option);
- }
- config->disk_error_action = failure_actions[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int priority_boost_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "priority_boost_parser called with: %s",
- nv->value);
-
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- /* Check its range */
- if (i > INT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too large - line %d",
- nv->value, line);
- return 1;
- }
- config->priority_boost = (unsigned int)i;
- return 0;
-}
-
-static int tcp_listen_port_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "tcp_listen_port_parser called with: %s",
- nv->value);
-
-#ifndef USE_LISTENER
- audit_msg(LOG_DEBUG,
- "Listener support is not enabled, ignoring value at line %d",
- line);
- return 0;
-#else
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- /* Check its range */
- if (i > TCP_PORT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too large - line %d",
- nv->value, line);
- return 1;
- }
- if (i < 1) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too small - line %d",
- nv->value, line);
- return 1;
- }
- config->tcp_listen_port = (unsigned int)i;
- return 0;
-#endif
-}
-
-static int tcp_listen_queue_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "tcp_listen_queue_parser called with: %s",
- nv->value);
-
-#ifndef USE_LISTENER
- audit_msg(LOG_DEBUG,
- "Listener support is not enabled, ignoring value at line %d",
- line);
- return 0;
-#else
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- /* Check its range. While this value is technically
- unlimited, it's limited by the kernel, and we limit it here
- for sanity. */
- if (i > TCP_PORT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too large - line %d",
- nv->value, line);
- return 1;
- }
- if (i < 1) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too small - line %d",
- nv->value, line);
- return 1;
- }
- config->tcp_listen_queue = (unsigned int)i;
- return 0;
-#endif
-}
-
-
-static int tcp_max_per_addr_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "tcp_max_per_addr_parser called with: %s",
- nv->value);
-
-#ifndef USE_LISTENER
- audit_msg(LOG_DEBUG,
- "Listener support is not enabled, ignoring value at line %d",
- line);
- return 0;
-#else
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- /* Check its range. While this value is technically
- unlimited, it's limited by the kernel, and we limit it here
- for sanity. */
- if (i > 1024) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too large - line %d",
- nv->value, line);
- return 1;
- }
- if (i < 1) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too small - line %d",
- nv->value, line);
- return 1;
- }
- config->tcp_max_per_addr = (unsigned int)i;
- return 0;
-#endif
-}
-
-static int use_libwrap_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "use_libwrap_parser called with: %s",
- nv->value);
-
- for (i=0; yes_no_values[i].name != NULL; i++) {
- if (strcasecmp(nv->value, yes_no_values[i].name) == 0) {
- config->use_libwrap = yes_no_values[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-}
-
-static int tcp_client_ports_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i, minv, maxv;
- const char *saw_dash = NULL;
-
- audit_msg(LOG_DEBUG, "tcp_listen_queue_parser called with: %s",
- nv->value);
-
-#ifndef USE_LISTENER
- audit_msg(LOG_DEBUG,
- "Listener support is not enabled, ignoring value at line %d",
- line);
- return 0;
-#else
- /* check that all chars are numbers, with an optional inclusive '-'. */
- for (i=0; ptr[i]; i++) {
- if (i > 0 && ptr[i] == '-' && ptr[i+1] != '\0') {
- saw_dash = ptr + i;
- continue;
- }
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers, or "
- "two numbers separated by a dash - line %d",
- nv->value, line);
- return 1;
- }
- }
- for (; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers, or "
- "two numbers separated by a dash - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- maxv = minv = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- if (saw_dash) {
- maxv = strtoul(saw_dash + 1, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- }
- /* Check their ranges. */
- if (minv > TCP_PORT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%ld) is too large - line %d",
- minv, line);
- return 1;
- }
- if (maxv > TCP_PORT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%ld) is too large - line %d",
- maxv, line);
- return 1;
- }
- if (minv > maxv) {
- audit_msg(LOG_ERR,
- "Error - converted range (%ld-%ld) is reversed - line %d",
- minv, maxv, line);
- return 1;
- }
- config->tcp_client_min_port = (unsigned int)minv;
- config->tcp_client_max_port = (unsigned int)maxv;
- return 0;
-#endif
-}
-
-static int tcp_client_max_idle_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- const char *ptr = nv->value;
- unsigned long i;
-
- audit_msg(LOG_DEBUG, "tcp_client_max_idle_parser called with: %s",
- nv->value);
-
-#ifndef USE_LISTENER
- audit_msg(LOG_DEBUG,
- "Listener support is not enabled, ignoring value at line %d",
- line);
- return 0;
-#else
- /* check that all chars are numbers */
- for (i=0; ptr[i]; i++) {
- if (!isdigit(ptr[i])) {
- audit_msg(LOG_ERR,
- "Value %s should only be numbers - line %d",
- nv->value, line);
- return 1;
- }
- }
-
- /* convert to unsigned int */
- errno = 0;
- i = strtoul(nv->value, NULL, 10);
- if (errno) {
- audit_msg(LOG_ERR,
- "Error converting string to a number (%s) - line %d",
- strerror(errno), line);
- return 1;
- }
- /* Check its range. While this value is technically
- unlimited, it's limited by the kernel, and we limit it here
- for sanity. */
- if (i > INT_MAX) {
- audit_msg(LOG_ERR,
- "Error - converted number (%s) is too large - line %d",
- nv->value, line);
- return 1;
- }
- config->tcp_client_max_idle = (unsigned int)i;
- return 0;
-#endif
-}
-
-static int enable_krb5_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- audit_msg(LOG_DEBUG, "enable_krb5_parser called with: %s",
- nv->value);
-
-#ifndef USE_GSSAPI
- audit_msg(LOG_DEBUG,
- "GSSAPI support is not enabled, ignoring value at line %d",
- line);
- return 0;
-#else
- unsigned long i;
-
- for (i=0; yes_no_values[i].name != NULL; i++) {
- if (strcasecmp(nv->value, yes_no_values[i].name) == 0) {
- config->enable_krb5 = yes_no_values[i].option;
- return 0;
- }
- }
- audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
- return 1;
-#endif
-}
-
-static int krb5_principal_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- audit_msg(LOG_DEBUG,"krb5_principal_parser called with: %s",nv->value);
-#ifndef USE_GSSAPI
- audit_msg(LOG_DEBUG,
- "GSSAPI support is not enabled, ignoring value at line %d",
- line);
-#else
- config->krb5_principal = strdup(nv->value);
-#endif
- return 0;
-}
-
-static int krb5_key_file_parser(struct nv_pair *nv, int line,
- struct daemon_conf *config)
-{
- audit_msg(LOG_DEBUG, "krb5_key_file_parser called with: %s", nv->value);
-#ifndef USE_GSSAPI
- audit_msg(LOG_DEBUG,
- "GSSAPI support is not enabled, ignoring value at line %d",
- line);
-#else
- config->krb5_key_file = strdup(nv->value);
-#endif
- return 0;
-}
-
-/*
- * This function is where we do the integrated check of the audit config
- * options. At this point, all fields have been read. Returns 0 if no
- * problems and 1 if problems detected.
- */
-static int sanity_check(struct daemon_conf *config)
-{
- /* Error checking */
- if (config->space_left <= config->admin_space_left) {
- audit_msg(LOG_ERR,
- "Error - space_left(%lu) must be larger than admin_space_left(%lu)",
- config->space_left, config->admin_space_left);
- return 1;
- }
- if (config->flush == FT_INCREMENTAL && config->freq == 0) {
- audit_msg(LOG_ERR,
- "Error - incremental flushing chosen, but 0 selected for freq");
- return 1;
- }
- /* Warnings */
- if (config->flush > FT_INCREMENTAL && config->freq != 0) {
- audit_msg(LOG_WARNING,
- "Warning - freq is non-zero and incremental flushing not selected.");
- }
- return 0;
-}
-
-const char *audit_lookup_format(int fmt)
-{
- int i;
-
- for (i=0; log_formats[i].name != NULL; i++) {
- if (log_formats[i].option == fmt)
- return log_formats[i].name;
- }
- return NULL;
-}
-
-int create_log_file(const char *val)
-{
- int fd;
-
- umask(S_IRWXO);
- fd = open(val, O_CREAT|O_EXCL|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
- if (fd < 0)
- audit_msg(LOG_ERR, "Unable to create %s (%s)", val,
- strerror(errno));
- return fd;
-}
-
-void free_config(struct daemon_conf *config)
-{
- free((void *)config->sender_ctx);
- free((void *)config->log_file);
- free((void *)config->dispatcher);
- free((void *)config->node_name);
- free((void *)config->action_mail_acct);
- free((void *)config->space_left_exe);
- free((void *)config->admin_space_left_exe);
- free((void *)config->disk_full_exe);
- free((void *)config->disk_error_exe);
- free((void *)config->krb5_principal);
- free((void *)config->krb5_key_file);
-}
-
-int resolve_node(struct daemon_conf *config)
-{
- int rc = 0;
- char tmp_name[255];
-
- /* Get the host name representation */
- switch (config->node_name_format)
- {
- case N_NONE:
- break;
- case N_HOSTNAME:
- if (gethostname(tmp_name, sizeof(tmp_name))) {
- audit_msg(LOG_ERR,
- "Unable to get machine name");
- rc = -1;
- } else
- config->node_name = strdup(tmp_name);
- break;
- case N_USER:
- if (config->node_name == NULL) {
- audit_msg(LOG_ERR, "User defined name missing");
- rc = -1;
- }
- break;
- case N_FQD:
- if (gethostname(tmp_name, sizeof(tmp_name))) {
- audit_msg(LOG_ERR,
- "Unable to get machine name");
- rc = -1;
- } else {
- int rc2;
- struct addrinfo *ai;
- struct addrinfo hints;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
- hints.ai_socktype = SOCK_STREAM;
-
- rc2 = getaddrinfo(tmp_name, NULL, &hints, &ai);
- if (rc2 != 0) {
- audit_msg(LOG_ERR,
- "Cannot resolve hostname %s (%s)",
- tmp_name, gai_strerror(rc));
- rc = -1;
- break;
- }
- config->node_name = strdup(ai->ai_canonname);
- freeaddrinfo(ai);
- }
- break;
- case N_NUMERIC:
- if (gethostname(tmp_name, sizeof(tmp_name))) {
- audit_msg(LOG_ERR,
- "Unable to get machine name");
- rc = -1;
- } else {
- int rc2;
- struct addrinfo *ai;
- struct addrinfo hints;
-
- audit_msg(LOG_DEBUG,
- "Resolving numeric address for %s",
- tmp_name);
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
- hints.ai_socktype = SOCK_STREAM;
-
- rc2 = getaddrinfo(tmp_name, NULL, &hints, &ai);
- if (rc2) {
- audit_msg(LOG_ERR,
- "Cannot resolve hostname %s (%s)",
- tmp_name, gai_strerror(rc2));
- rc = -1;
- break;
- }
- inet_ntop(ai->ai_family,
- ai->ai_family == AF_INET ?
- (void *) &((struct sockaddr_in *)ai->ai_addr)->sin_addr :
- (void *) &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
- tmp_name, INET6_ADDRSTRLEN);
- freeaddrinfo(ai);
- config->node_name = strdup(tmp_name);
- }
- break;
- }
- if (rc == 0 && config->node_name)
- audit_msg(LOG_DEBUG, "Resolved node name: %s",
- config->node_name);
- return rc;
-}
-
diff --git a/framework/src/audit/src/auditd-config.h b/framework/src/audit/src/auditd-config.h
deleted file mode 100644
index 5a3eb6bb..00000000
--- a/framework/src/audit/src/auditd-config.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* auditd-config.h --
- * Copyright 2004-2009,2014 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#ifndef AUDITD_CONFIG_H
-#define AUDITD_CONFIG_H
-
-#include "libaudit.h"
-#include <grp.h>
-#define CONFIG_FILE "/etc/audit/auditd.conf"
-#define MEGABYTE 1048576UL
-
-typedef enum { D_FOREGROUND, D_BACKGROUND } daemon_t;
-typedef enum { LF_RAW, LF_NOLOG } logging_formats;
-typedef enum { FT_NONE, FT_INCREMENTAL, FT_DATA, FT_SYNC } flush_technique;
-typedef enum { FA_IGNORE, FA_SYSLOG, FA_ROTATE, FA_EMAIL, FA_EXEC, FA_SUSPEND,
- FA_SINGLE, FA_HALT } failure_action_t;
-typedef enum { SZ_IGNORE, SZ_SYSLOG, SZ_SUSPEND, SZ_ROTATE,
- SZ_KEEP_LOGS } size_action;
-typedef enum { QOS_NON_BLOCKING, QOS_BLOCKING } qos_t;
-typedef enum { TEST_AUDITD, TEST_SEARCH } log_test_t;
-typedef enum { N_NONE, N_HOSTNAME, N_FQD, N_NUMERIC, N_USER } node_t;
-
-struct daemon_conf
-{
- daemon_t daemonize;
- qos_t qos; /* use blocking/non-blocking sockets */
- uid_t sender_uid; /* the uid for sender of sighup */
- pid_t sender_pid; /* the pid for sender of sighup */
- const char *sender_ctx; /* the context for the sender of sighup */
- const char *log_file;
- logging_formats log_format;
- gid_t log_group;
- unsigned int priority_boost;
- flush_technique flush;
- unsigned int freq;
- unsigned int num_logs;
- const char *dispatcher;
- node_t node_name_format;
- const char *node_name;
- unsigned long max_log_size;
- size_action max_log_size_action;
- unsigned long space_left;
- failure_action_t space_left_action;
- const char *space_left_exe;
- const char *action_mail_acct;
- unsigned long admin_space_left;
- failure_action_t admin_space_left_action;
- const char *admin_space_left_exe;
- failure_action_t disk_full_action;
- const char *disk_full_exe;
- failure_action_t disk_error_action;
- const char *disk_error_exe;
- unsigned long tcp_listen_port;
- unsigned long tcp_listen_queue;
- unsigned long tcp_max_per_addr;
- int use_libwrap;
- unsigned long tcp_client_min_port;
- unsigned long tcp_client_max_port;
- unsigned long tcp_client_max_idle;
- int enable_krb5;
- const char *krb5_principal;
- const char *krb5_key_file;
-};
-
-void set_allow_links(int allow);
-int load_config(struct daemon_conf *config, log_test_t lt);
-void clear_config(struct daemon_conf *config);
-const char *audit_lookup_format(int fmt);
-int create_log_file(const char *val);
-int resolve_node(struct daemon_conf *config);
-
-void init_config_manager(void);
-#ifdef AUDITD_EVENT_H
-int start_config_manager(struct auditd_reply_list *rep);
-#endif
-void shutdown_config(void);
-void free_config(struct daemon_conf *config);
-
-#endif
-
diff --git a/framework/src/audit/src/auditd-dispatch.c b/framework/src/audit/src/auditd-dispatch.c
deleted file mode 100644
index 02681f03..00000000
--- a/framework/src/audit/src/auditd-dispatch.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* auditd-dispatch.c --
- * Copyright 2005-07,2013 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- * Junji Kanemaru <junji.kanemaru@linuon.com>
- */
-
-#include "config.h"
-#include <unistd.h>
-#include <sys/uio.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "libaudit.h"
-#include "private.h"
-#include "auditd-dispatch.h"
-
-/* This is the communications channel between auditd & the dispatcher */
-static int disp_pipe[2] = {-1, -1};
-static pid_t pid = 0;
-static int n_errs = 0;
-#define REPORT_LIMIT 10
-
-int dispatcher_pid(void)
-{
- return pid;
-}
-
-void dispatcher_reaped(void)
-{
- audit_msg(LOG_INFO, "dispatcher %d reaped\n", pid);
- pid = 0;
- shutdown_dispatcher();
-}
-
-/* set_flags: to set flags to file desc */
-static int set_flags(int fn, int flags)
-{
- int fl;
-
- if ((fl = fcntl(fn, F_GETFL, 0)) < 0) {
- audit_msg(LOG_ERR, "fcntl failed. Cannot get flags (%s)\n",
- strerror(errno));
- return fl;
- }
-
- fl |= flags;
-
- return fcntl(fn, F_SETFL, fl);
-}
-
-/* This function returns 1 on error & 0 on success */
-int init_dispatcher(const struct daemon_conf *config)
-{
- struct sigaction sa;
-
- if (config->dispatcher == NULL)
- return 0;
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, disp_pipe)) {
- audit_msg(LOG_ERR, "Failed creating disp_pipe");
- return 1;
- }
-
- /* Make both disp_pipe non-blocking */
- if (config->qos == QOS_NON_BLOCKING) {
- if (set_flags(disp_pipe[0], O_NONBLOCK) < 0 ||
- set_flags(disp_pipe[1], O_NONBLOCK) < 0) {
- audit_msg(LOG_ERR, "Failed to set O_NONBLOCK flag");
- return 1;
- }
- }
-
- // do the fork
- pid = fork();
- switch(pid) {
- case 0: // child
- dup2(disp_pipe[0], 0);
- close(disp_pipe[0]);
- close(disp_pipe[1]);
- sigfillset (&sa.sa_mask);
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
- setsid();
- execl(config->dispatcher, config->dispatcher, NULL);
- audit_msg(LOG_ERR, "exec() failed");
- exit(1);
- break;
- case -1: // error
- return 1;
- break;
- default: // parent
- close(disp_pipe[0]);
- disp_pipe[0] = -1;
- /* Avoid leaking this */
- if (fcntl(disp_pipe[1], F_SETFD, FD_CLOEXEC) < 0) {
- audit_msg(LOG_ERR,
- "Failed to set FD_CLOEXEC flag");
- return 1;
- }
- audit_msg(LOG_INFO, "Started dispatcher: %s pid: %u",
- config->dispatcher, pid);
- break;
- }
-
- return 0;
-}
-
-void shutdown_dispatcher(void)
-{
- // kill child
- if (pid)
- kill(pid, SIGTERM);
- // wait for term
- // if not in time, send sigkill
- pid = 0;
-
- // cleanup comm pipe
- if (disp_pipe[0] >= 0) {
- close(disp_pipe[0]);
- disp_pipe[0] = -1;
- }
- if (disp_pipe[1] >= 0) {
- close(disp_pipe[1]);
- disp_pipe[1] = -1;
- }
-}
-
-void reconfigure_dispatcher(const struct daemon_conf *config)
-{
- // signal child or start it so it can see if config changed
- if (pid)
- kill(pid, SIGHUP);
- else
- init_dispatcher(config);
-}
-
-/* Returns -1 on err, 0 on success, and 1 if eagain occurred and not an err */
-int dispatch_event(const struct audit_reply *rep, int is_err)
-{
- int rc, count = 0;
- struct iovec vec[2];
- struct audit_dispatcher_header hdr;
-
- if (disp_pipe[1] == -1)
- return 0;
-
- // Don't send reconfig or rotate as they are purely internal to daemon
- if (rep->type == AUDIT_DAEMON_RECONFIG ||
- rep->type == AUDIT_DAEMON_ROTATE)
- return 0;
-
- hdr.ver = AUDISP_PROTOCOL_VER; /* Hard-coded to current protocol */
- hdr.hlen = sizeof(struct audit_dispatcher_header);
- hdr.type = rep->type;
- hdr.size = rep->len;
-
- vec[0].iov_base = (void*)&hdr;
- vec[0].iov_len = sizeof(hdr);
- vec[1].iov_base = (void*)rep->message;
- vec[1].iov_len = rep->len;
-
- do {
- rc = writev(disp_pipe[1], vec, 2);
- } while (rc < 0 && errno == EAGAIN && count++ < 8);
-
- // close pipe if no child or peer has been lost
- if (rc <= 0) {
- if (errno == EPIPE) {
- shutdown_dispatcher();
- n_errs = 0;
- } else if (errno == EAGAIN && !is_err) {
- return 1;
- } else {
- if (n_errs <= REPORT_LIMIT) {
- audit_msg(LOG_ERR,
- "dispatch err (%s) event lost",
- errno == EAGAIN ? "pipe full" :
- strerror(errno));
- n_errs++;
- }
- if (n_errs == REPORT_LIMIT) {
- audit_msg(LOG_ERR,
- "dispatch error reporting limit"
- " reached - ending report"
- " notification.");
- n_errs++;
- }
- return -1;
- }
- } else
- n_errs = 0;
- return 0;
-}
-
diff --git a/framework/src/audit/src/auditd-dispatch.h b/framework/src/audit/src/auditd-dispatch.h
deleted file mode 100644
index 25d32352..00000000
--- a/framework/src/audit/src/auditd-dispatch.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* auditd-dispatch.h --
- * Copyright 2005,2007,2013 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#ifndef AUDITD_DISPATCH_H
-#define AUDITD_DISPATCH_H
-
-#include "auditd-config.h"
-
-int dispatcher_pid(void);
-void dispatcher_reaped(void);
-int init_dispatcher(const struct daemon_conf *config);
-void shutdown_dispatcher(void);
-void reconfigure_dispatcher(const struct daemon_conf *config);
-int dispatch_event(const struct audit_reply *rep, int is_err);
-
-#endif
-
diff --git a/framework/src/audit/src/auditd-event.c b/framework/src/audit/src/auditd-event.c
deleted file mode 100644
index ed0272e2..00000000
--- a/framework/src/audit/src/auditd-event.c
+++ /dev/null
@@ -1,1407 +0,0 @@
-/* auditd-event.c --
- * Copyright 2004-08,2011,2013 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <signal.h>
-#include <fcntl.h> /* O_NOFOLLOW needs gnu defined */
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/vfs.h>
-#include <limits.h> /* POSIX_HOST_NAME_MAX */
-#include "auditd-event.h"
-#include "auditd-dispatch.h"
-#include "auditd-listen.h"
-#include "libaudit.h"
-#include "private.h"
-
-/* This is defined in auditd.c */
-extern volatile int stop;
-
-struct auditd_consumer_data {
- struct daemon_conf *config;
- pthread_mutex_t queue_lock;
- pthread_cond_t queue_nonempty;
- struct auditd_reply_list *head;
- struct auditd_reply_list *tail;
- int log_fd;
- FILE *log_file;
-};
-
-/* Local function prototypes */
-static void *event_thread_main(void *arg);
-static void handle_event(struct auditd_consumer_data *data);
-static void write_to_log(const char *buf, struct auditd_consumer_data *data);
-static void check_log_file_size(struct auditd_consumer_data *data);
-static void check_space_left(int lfd, struct auditd_consumer_data *data);
-static void do_space_left_action(struct auditd_consumer_data *data, int admin);
-static void do_disk_full_action(struct auditd_consumer_data *data);
-static void do_disk_error_action(const char *func, struct daemon_conf *config,
- int err);
-static void check_excess_logs(struct auditd_consumer_data *data);
-static void rotate_logs_now(struct auditd_consumer_data *data);
-static void rotate_logs(struct auditd_consumer_data *data,
- unsigned int num_logs);
-static void shift_logs(struct auditd_consumer_data *data);
-static int open_audit_log(struct auditd_consumer_data *data);
-static void change_runlevel(const char *level);
-static void safe_exec(const char *exe);
-static char *format_raw(const struct audit_reply *rep,
- struct daemon_conf *config);
-static void reconfigure(struct auditd_consumer_data *data);
-
-
-/* Local Data */
-static struct auditd_consumer_data consumer_data;
-static pthread_t event_thread;
-static unsigned int disk_err_warning = 0;
-static int fs_space_warning = 0;
-static int fs_admin_space_warning = 0;
-static int fs_space_left = 1;
-static int logging_suspended = 0;
-static const char *SINGLE = "1";
-static const char *HALT = "0";
-static char *format_buf = NULL;
-static off_t log_size = 0;
-
-
-void shutdown_events(void)
-{
- /* Give it 5 seconds to clear the queue */
- alarm(5);
- pthread_join(event_thread, NULL);
- free((void *)format_buf);
- fclose(consumer_data.log_file);
-}
-
-int init_event(struct daemon_conf *config)
-{
- /* Store the netlink descriptor and config info away */
- consumer_data.config = config;
- consumer_data.log_fd = -1;
-
- /* Setup IPC mechanisms */
- pthread_mutex_init(&consumer_data.queue_lock, NULL);
- pthread_cond_init(&consumer_data.queue_nonempty, NULL);
-
- /* Reset the queue */
- consumer_data.head = consumer_data.tail = NULL;
-
- /* Now open the log */
- if (config->daemonize == D_BACKGROUND) {
- if (open_audit_log(&consumer_data))
- return 1;
- } else {
- consumer_data.log_fd = 1; // stdout
- consumer_data.log_file = fdopen(consumer_data.log_fd, "a");
- if (consumer_data.log_file == NULL) {
- audit_msg(LOG_ERR,
- "Error setting up stdout descriptor (%s)",
- strerror(errno));
- return 1;
- }
- /* Set it to line buffering */
- setlinebuf(consumer_data.log_file);
- }
-
- /* Create the worker thread */
- if (pthread_create(&event_thread, NULL,
- event_thread_main, &consumer_data) < 0) {
- audit_msg(LOG_ERR, "Couldn't create event thread, exiting");
- fclose(consumer_data.log_file);
- return 1;
- }
-
- if (config->daemonize == D_BACKGROUND) {
- check_log_file_size(&consumer_data);
- check_excess_logs(&consumer_data);
- check_space_left(consumer_data.log_fd, &consumer_data);
- }
- format_buf = (char *)malloc(MAX_AUDIT_MESSAGE_LENGTH +
- _POSIX_HOST_NAME_MAX);
- if (format_buf == NULL) {
- audit_msg(LOG_ERR, "No memory for formatting, exiting");
- fclose(consumer_data.log_file);
- return 1;
- }
- return 0;
-}
-
-/* This function takes a malloc'd rep and places it on the queue. The
- dequeue'r is responsible for freeing the memory. */
-void enqueue_event(struct auditd_reply_list *rep)
-{
- char *buf = NULL;
- int len;
-
- rep->ack_func = 0;
- rep->ack_data = 0;
- rep->sequence_id = 0;
-
- if (rep->reply.type != AUDIT_DAEMON_RECONFIG) {
- switch (consumer_data.config->log_format)
- {
- case LF_RAW:
- buf = format_raw(&rep->reply, consumer_data.config);
- break;
- case LF_NOLOG:
- // We need the rotate event to get enqueued
- if (rep->reply.type != AUDIT_DAEMON_ROTATE ) {
- // Internal DAEMON messages should be free'd
- if (rep->reply.type >= AUDIT_FIRST_DAEMON &&
- rep->reply.type <= AUDIT_LAST_DAEMON)
- free((void *)rep->reply.message);
- free(rep);
- return;
- }
- break;
- default:
- audit_msg(LOG_ERR,
- "Illegal log format detected %d",
- consumer_data.config->log_format);
- // Internal DAEMON messages should be free'd
- if (rep->reply.type >= AUDIT_FIRST_DAEMON &&
- rep->reply.type <= AUDIT_LAST_DAEMON)
- free((void *)rep->reply.message);
- free(rep);
- return;
- }
-
- if (buf) {
- len = strlen(buf);
- if (len < MAX_AUDIT_MESSAGE_LENGTH - 1)
- memcpy(rep->reply.msg.data, buf, len+1);
- else {
- // FIXME: is truncation the right thing to do?
- memcpy(rep->reply.msg.data, buf,
- MAX_AUDIT_MESSAGE_LENGTH-1);
- rep->reply.msg.data[MAX_AUDIT_MESSAGE_LENGTH-1] = 0;
- }
- }
- }
-
- rep->next = NULL; /* new packet goes at end - so zero this */
-
- pthread_mutex_lock(&consumer_data.queue_lock);
- if (consumer_data.head == NULL) {
- consumer_data.head = consumer_data.tail = rep;
- pthread_cond_signal(&consumer_data.queue_nonempty);
- } else {
- /* FIXME: wait for room on the queue */
-
- /* OK there's room...add it in */
- consumer_data.tail->next = rep; /* link in at end */
- consumer_data.tail = rep; /* move end to newest */
- }
- pthread_mutex_unlock(&consumer_data.queue_lock);
-}
-
-/* This function takes a preformatted message and places it on the
- queue. The dequeue'r is responsible for freeing the memory. */
-void enqueue_formatted_event(char *msg, ack_func_type ack_func, void *ack_data, uint32_t sequence_id)
-{
- int len;
- struct auditd_reply_list *rep;
-
- rep = (struct auditd_reply_list *) calloc (1, sizeof (*rep));
- if (rep == NULL) {
- audit_msg(LOG_ERR, "Cannot allocate audit reply");
- return;
- }
-
- rep->ack_func = ack_func;
- rep->ack_data = ack_data;
- rep->sequence_id = sequence_id;
-
- len = strlen (msg);
- if (len < MAX_AUDIT_MESSAGE_LENGTH - 1)
- memcpy (rep->reply.msg.data, msg, len+1);
- else {
- /* FIXME: is truncation the right thing to do? */
- memcpy (rep->reply.msg.data, msg, MAX_AUDIT_MESSAGE_LENGTH-1);
- rep->reply.msg.data[MAX_AUDIT_MESSAGE_LENGTH-1] = 0;
- }
-
- pthread_mutex_lock(&consumer_data.queue_lock);
- if (consumer_data.head == NULL) {
- consumer_data.head = consumer_data.tail = rep;
- pthread_cond_signal(&consumer_data.queue_nonempty);
- } else {
- /* FIXME: wait for room on the queue */
-
- /* OK there's room...add it in */
- consumer_data.tail->next = rep; /* link in at end */
- consumer_data.tail = rep; /* move end to newest */
- }
- pthread_mutex_unlock(&consumer_data.queue_lock);
-}
-
-void resume_logging(void)
-{
- logging_suspended = 0;
- fs_space_left = 1;
- disk_err_warning = 0;
- fs_space_warning = 0;
- fs_admin_space_warning = 0;
- audit_msg(LOG_ERR, "Audit daemon is attempting to resume logging.");
-}
-
-static void *event_thread_main(void *arg)
-{
- struct auditd_consumer_data *data = arg;
- sigset_t sigs;
-
- /* This is a worker thread. Don't handle signals. */
- sigemptyset(&sigs);
- sigaddset(&sigs, SIGALRM);
- sigaddset(&sigs, SIGTERM);
- sigaddset(&sigs, SIGHUP);
- sigaddset(&sigs, SIGUSR1);
- sigaddset(&sigs, SIGUSR2);
- pthread_sigmask(SIG_SETMASK, &sigs, NULL);
-
- while (1) {
- struct auditd_reply_list *cur;
- int stop_req = 0;
-// FIXME: wait for data
- pthread_mutex_lock(&data->queue_lock);
- while (data->head == NULL) {
- pthread_cond_wait(&data->queue_nonempty,
- &data->queue_lock);
- }
-// FIXME: at this point we can use data->head unlocked since it won't change.
- handle_event(data);
- cur = data->head;
-// FIXME: relock at this point
- if (data->tail == data->head)
- data->tail = NULL;
- data->head = data->head->next;
- if (data->head == NULL && stop &&
- ( cur->reply.type == AUDIT_DAEMON_END ||
- cur->reply.type == AUDIT_DAEMON_ABORT) )
- stop_req = 1;
- pthread_mutex_unlock(&data->queue_lock);
-
- /* Internal DAEMON messages should be free'd */
- if (cur->reply.type >= AUDIT_FIRST_DAEMON &&
- cur->reply.type <= AUDIT_LAST_DAEMON) {
- free((void *)cur->reply.message);
- }
- free(cur);
- if (stop_req)
- break;
- }
- return NULL;
-}
-
-
-/* This function takes the newly dequeued event and handles it. */
-static unsigned int count = 0L;
-static void handle_event(struct auditd_consumer_data *data)
-{
- char *buf = data->head->reply.msg.data;
-
- if (data->head->reply.type == AUDIT_DAEMON_RECONFIG) {
- reconfigure(data);
- switch (consumer_data.config->log_format)
- {
- case LF_RAW:
- buf = format_raw(&data->head->reply, consumer_data.config);
- break;
- case LF_NOLOG:
- return;
- default:
- audit_msg(LOG_ERR,
- "Illegal log format detected %d",
- consumer_data.config->log_format);
- return;
- }
- } else if (data->head->reply.type == AUDIT_DAEMON_ROTATE) {
- rotate_logs_now(data);
- if (consumer_data.config->log_format == LF_NOLOG)
- return;
- }
- if (!logging_suspended) {
-
- write_to_log(buf, data);
-
- /* See if we need to flush to disk manually */
- if (data->config->flush == FT_INCREMENTAL) {
- count++;
- if ((count % data->config->freq) == 0) {
- int rc;
- errno = 0;
- do {
- rc = fflush(data->log_file);
- } while (rc < 0 && errno == EINTR);
- if (errno) {
- if (errno == ENOSPC &&
- fs_space_left == 1) {
- fs_space_left = 0;
- do_disk_full_action(data);
- } else
- //EIO is only likely failure mode
- do_disk_error_action("flush",
- data->config, errno);
- }
-
- /* EIO is only likely failure mode */
- if ((data->config->daemonize == D_BACKGROUND)&&
- (fsync(data->log_fd) != 0)) {
- do_disk_error_action("fsync",
- data->config, errno);
- }
- }
- }
- }
-}
-
-static void send_ack(struct auditd_consumer_data *data, int ack_type,
- const char *msg)
-{
- if (data->head->ack_func) {
- unsigned char header[AUDIT_RMW_HEADER_SIZE];
-
- AUDIT_RMW_PACK_HEADER(header, 0, ack_type, strlen(msg),
- data->head->sequence_id);
-
- data->head->ack_func(data->head->ack_data, header, msg);
- }
-}
-
-/* This function writes the given buf to the current log file */
-static void write_to_log(const char *buf, struct auditd_consumer_data *data)
-{
- int rc;
- FILE *f = data->log_file;
- struct daemon_conf *config = data->config;
- int ack_type = AUDIT_RMW_TYPE_ACK;
- const char *msg = "";
-
- /* write it to disk */
- rc = fprintf(f, "%s\n", buf);
-
- /* error? Handle it */
- if (rc < 0) {
- if (errno == ENOSPC) {
- ack_type = AUDIT_RMW_TYPE_DISKFULL;
- msg = "disk full";
- send_ack(data, ack_type, msg);
- if (fs_space_left == 1) {
- fs_space_left = 0;
- do_disk_full_action(data);
- }
- } else {
- int saved_errno = errno;
- ack_type = AUDIT_RMW_TYPE_DISKERROR;
- msg = "disk write error";
- send_ack(data, ack_type, msg);
- do_disk_error_action("write", config, saved_errno);
- }
- } else {
- /* check log file size & space left on partition */
- if (config->daemonize == D_BACKGROUND) {
- // If either of these fail, I consider it an
- // inconvenience as opposed to something that is
- // actionable. There may be some temporary condition
- // that the system recovers from. The real error
- // occurs on write.
- log_size += rc;
- check_log_file_size(data);
- check_space_left(data->log_fd, data);
- }
-
- if (fs_space_warning)
- ack_type = AUDIT_RMW_TYPE_DISKLOW;
- send_ack(data, ack_type, msg);
- disk_err_warning = 0;
- }
-}
-
-static void check_log_file_size(struct auditd_consumer_data *data)
-{
- struct daemon_conf *config = data->config;
-
- /* did we cross the size limit? */
- off_t sz = log_size / MEGABYTE;
-
- if (sz >= config->max_log_size && (config->daemonize == D_BACKGROUND)) {
- switch (config->max_log_size_action)
- {
- case SZ_IGNORE:
- break;
- case SZ_SYSLOG:
- audit_msg(LOG_ERR,
- "Audit daemon log file is larger than max size");
- break;
- case SZ_SUSPEND:
- audit_msg(LOG_ERR,
- "Audit daemon is suspending logging due to logfile size.");
- logging_suspended = 1;
- break;
- case SZ_ROTATE:
- if (data->config->num_logs > 1) {
- audit_msg(LOG_NOTICE,
- "Audit daemon rotating log files");
- rotate_logs(data, 0);
- }
- break;
- case SZ_KEEP_LOGS:
- audit_msg(LOG_NOTICE,
- "Audit daemon rotating log files with keep option");
- shift_logs(data);
- break;
- default:
- audit_msg(LOG_ALERT,
- "Audit daemon log file is larger than max size and unknown action requested");
- break;
- }
- }
-}
-
-static void check_space_left(int lfd, struct auditd_consumer_data *data)
-{
- int rc;
- struct statfs buf;
- struct daemon_conf *config = data->config;
-
- rc = fstatfs(lfd, &buf);
- if (rc == 0) {
- if (buf.f_bavail < 5) {
- /* we won't consume the last 5 blocks */
- fs_space_left = 0;
- do_disk_full_action(data);
- } else {
- unsigned long blocks;
- unsigned long block_size = buf.f_bsize;
- blocks = config->space_left * (MEGABYTE/block_size);
- if (buf.f_bavail < blocks) {
- if (fs_space_warning == 0) {
- do_space_left_action(data, 0);
- fs_space_warning = 1;
- }
- } else if (fs_space_warning &&
- config->space_left_action == FA_SYSLOG){
- // Auto reset only if failure action is syslog
- fs_space_warning = 0;
- }
- blocks=config->admin_space_left * (MEGABYTE/block_size);
- if (buf.f_bavail < blocks) {
- if (fs_admin_space_warning == 0) {
- do_space_left_action(data, 1);
- fs_admin_space_warning = 1;
- }
- } else if (fs_admin_space_warning &&
- config->admin_space_left_action == FA_SYSLOG) {
- // Auto reset only if failure action is syslog
- fs_admin_space_warning = 0;
- }
- }
- }
- else audit_msg(LOG_DEBUG, "fstatfs returned:%d, %s", rc,
- strerror(errno));
-}
-
-extern int sendmail(const char *subject, const char *content,
- const char *mail_acct);
-static void do_space_left_action(struct auditd_consumer_data *data, int admin)
-{
- int action;
- struct daemon_conf *config = data->config;
-
- if (admin)
- action = config->admin_space_left_action;
- else
- action = config->space_left_action;
-
- switch (action)
- {
- case FA_IGNORE:
- break;
- case FA_SYSLOG:
- audit_msg(LOG_ALERT,
- "Audit daemon is low on disk space for logging");
- break;
- case FA_ROTATE:
- if (config->num_logs > 1) {
- audit_msg(LOG_NOTICE,
- "Audit daemon rotating log files");
- rotate_logs(data, 0);
- }
- break;
- case FA_EMAIL:
- if (admin == 0) {
- sendmail("Audit Disk Space Alert",
- "The audit daemon is low on disk space for logging! Please take action\nto ensure no loss of service.",
- config->action_mail_acct);
- audit_msg(LOG_ALERT,
- "Audit daemon is low on disk space for logging");
- } else {
- sendmail("Audit Admin Space Alert",
- "The audit daemon is very low on disk space for logging! Immediate action\nis required to ensure no loss of service.",
- config->action_mail_acct);
- audit_msg(LOG_ALERT,
- "Audit daemon is very low on disk space for logging");
- }
- break;
- case FA_EXEC:
- if (admin)
- safe_exec(config->admin_space_left_exe);
- else
- safe_exec(config->space_left_exe);
- break;
- case FA_SUSPEND:
- audit_msg(LOG_ALERT,
- "Audit daemon is suspending logging due to low disk space.");
- logging_suspended = 1;
- break;
- case FA_SINGLE:
- audit_msg(LOG_ALERT,
- "The audit daemon is now changing the system to single user mode");
- change_runlevel(SINGLE);
- break;
- case FA_HALT:
- audit_msg(LOG_ALERT,
- "The audit daemon is now halting the system");
- change_runlevel(HALT);
- break;
- default:
- audit_msg(LOG_ALERT,
- "Audit daemon is low on disk space for logging and unknown action requested");
- break;
- }
-}
-
-static void do_disk_full_action(struct auditd_consumer_data *data)
-{
- struct daemon_conf *config = data->config;
-
- audit_msg(LOG_ALERT,
- "Audit daemon has no space left on logging partition");
- switch (config->disk_full_action)
- {
- case FA_IGNORE:
- case FA_SYSLOG: /* Message is syslogged above */
- break;
- case FA_ROTATE:
- if (config->num_logs > 1) {
- audit_msg(LOG_NOTICE,
- "Audit daemon rotating log files");
- rotate_logs(data, 0);
- }
- break;
- case FA_EXEC:
- safe_exec(config->disk_full_exe);
- break;
- case FA_SUSPEND:
- audit_msg(LOG_ALERT,
- "Audit daemon is suspending logging due to no space left on logging partition.");
- logging_suspended = 1;
- break;
- case FA_SINGLE:
- audit_msg(LOG_ALERT,
- "The audit daemon is now changing the system to single user mode due to no space left on logging partition");
- change_runlevel(SINGLE);
- break;
- case FA_HALT:
- audit_msg(LOG_ALERT,
- "The audit daemon is now halting the system due to no space left on logging partition");
- change_runlevel(HALT);
- break;
- default:
- audit_msg(LOG_ALERT, "Unknown disk full action requested");
- break;
- }
-}
-
-static void do_disk_error_action(const char * func, struct daemon_conf *config,
- int err)
-{
- char text[128];
-
- switch (config->disk_error_action)
- {
- case FA_IGNORE:
- break;
- case FA_SYSLOG:
- if (disk_err_warning < 5) {
- snprintf(text, sizeof(text),
- "%s: Audit daemon detected an error writing an event to disk (%s)",
- func, strerror(err));
- audit_msg(LOG_ALERT, "%s", text);
- disk_err_warning++;
- }
- break;
- case FA_EXEC:
- safe_exec(config->disk_error_exe);
- break;
- case FA_SUSPEND:
- audit_msg(LOG_ALERT,
- "Audit daemon is suspending logging due to previously mentioned write error");
- logging_suspended = 1;
- break;
- case FA_SINGLE:
- audit_msg(LOG_ALERT,
- "The audit daemon is now changing the system to single user mode due to previously mentioned write error");
- change_runlevel(SINGLE);
- break;
- case FA_HALT:
- audit_msg(LOG_ALERT,
- "The audit daemon is now halting the system due to previously mentioned write error.");
- change_runlevel(HALT);
- break;
- default:
- audit_msg(LOG_ALERT,
- "Unknown disk error action requested");
- break;
- }
-}
-
-static void rotate_logs_now(struct auditd_consumer_data *data)
-{
- struct daemon_conf *config = data->config;
-
- if (config->max_log_size_action == SZ_KEEP_LOGS)
- shift_logs(data);
- else
- rotate_logs(data, 0);
-}
-
-/* Check for and remove excess logs so that we don't run out of room */
-static void check_excess_logs(struct auditd_consumer_data *data)
-{
- int rc;
- unsigned int i, len;
- char *name;
-
- // Only do this if rotate is the log size action
- // and we actually have a limit
- if (data->config->max_log_size_action != SZ_ROTATE ||
- data->config->num_logs < 2)
- return;
-
- len = strlen(data->config->log_file) + 16;
- name = (char *)malloc(len);
- if (name == NULL) { /* Not fatal - just messy */
- audit_msg(LOG_ERR, "No memory checking excess logs");
- return;
- }
-
- // We want 1 beyond the normal logs
- i=data->config->num_logs;
- rc=0;
- while (rc == 0) {
- snprintf(name, len, "%s.%d", data->config->log_file, i++);
- rc=unlink(name);
- if (rc == 0)
- audit_msg(LOG_NOTICE,
- "Log %s removed as it exceeds num_logs parameter",
- name);
- }
- free(name);
-}
-
-static void rotate_logs(struct auditd_consumer_data *data,
- unsigned int num_logs)
-{
- int rc;
- unsigned int len, i;
- char *oldname, *newname;
-
- if (data->config->max_log_size_action == SZ_ROTATE &&
- data->config->num_logs < 2)
- return;
-
- /* Close audit file. fchmod and fchown errors are not fatal because we
- * already adjusted log file permissions and ownership when opening the
- * log file. */
- if (fchmod(data->log_fd, data->config->log_group ? S_IRUSR|S_IRGRP :
- S_IRUSR) < 0) {
- audit_msg(LOG_NOTICE, "Couldn't change permissions while "
- "rotating log file (%s)", strerror(errno));
- }
- if (fchown(data->log_fd, 0, data->config->log_group) < 0) {
- audit_msg(LOG_NOTICE, "Couldn't change ownership while "
- "rotating log file (%s)", strerror(errno));
- }
- fclose(data->log_file);
-
- /* Rotate */
- len = strlen(data->config->log_file) + 16;
- oldname = (char *)malloc(len);
- if (oldname == NULL) { /* Not fatal - just messy */
- audit_msg(LOG_ERR, "No memory rotating logs");
- logging_suspended = 1;
- return;
- }
- newname = (char *)malloc(len);
- if (newname == NULL) { /* Not fatal - just messy */
- audit_msg(LOG_ERR, "No memory rotating logs");
- free(oldname);
- logging_suspended = 1;
- return;
- }
-
- /* If we are rotating, get number from config */
- if (num_logs == 0)
- num_logs = data->config->num_logs;
-
- /* Handle this case first since it will not enter the for loop */
- if (num_logs == 2)
- snprintf(oldname, len, "%s.1", data->config->log_file);
-
- for (i=num_logs - 1; i>1; i--) {
- snprintf(oldname, len, "%s.%d", data->config->log_file, i-1);
- snprintf(newname, len, "%s.%d", data->config->log_file, i);
- /* if the old file exists */
- rc = rename(oldname, newname);
- if (rc == -1 && errno != ENOENT) {
- // Likely errors: ENOSPC, ENOMEM, EBUSY
- int saved_errno = errno;
- audit_msg(LOG_ERR,
- "Error rotating logs from %s to %s (%s)",
- oldname, newname, strerror(errno));
- if (saved_errno == ENOSPC && fs_space_left == 1) {
- fs_space_left = 0;
- do_disk_full_action(data);
- } else
- do_disk_error_action("rotate", data->config,
- saved_errno);
- }
- }
- free(newname);
-
- /* At this point, oldname should point to lowest number - use it */
- newname = oldname;
- rc = rename(data->config->log_file, newname);
- if (rc == -1 && errno != ENOENT) {
- // Likely errors: ENOSPC, ENOMEM, EBUSY
- int saved_errno = errno;
- audit_msg(LOG_ERR, "Error rotating logs from %s to %s (%s)",
- data->config->log_file, newname, strerror(errno));
- if (saved_errno == ENOSPC && fs_space_left == 1) {
- fs_space_left = 0;
- do_disk_full_action(data);
- } else
- do_disk_error_action("rotate2", data->config,
- saved_errno);
-
- /* At this point, we've failed to rotate the original log.
- * So, let's make the old log writable and try again next
- * time */
- chmod(data->config->log_file,
- data->config->log_group ? S_IWUSR|S_IRUSR|S_IRGRP :
- S_IWUSR|S_IRUSR);
- }
- free(newname);
-
- /* open new audit file */
- if (open_audit_log(data)) {
- int saved_errno = errno;
- audit_msg(LOG_NOTICE,
- "Could not reopen a log after rotating.");
- logging_suspended = 1;
- do_disk_error_action("reopen", data->config, saved_errno);
- }
-}
-
-static int last_log = 1;
-static void shift_logs(struct auditd_consumer_data *data)
-{
- // The way this has to work is to start scanning from .1 up until
- // no file is found. Then do the rotate algorithm using that number
- // instead of log_max.
- unsigned int num_logs, len;
- char *name;
-
- len = strlen(data->config->log_file) + 16;
- name = (char *)malloc(len);
- if (name == NULL) { /* Not fatal - just messy */
- audit_msg(LOG_ERR, "No memory shifting logs");
- return;
- }
-
- // Find last log
- num_logs = last_log;
- while (num_logs) {
- snprintf(name, len, "%s.%d", data->config->log_file,
- num_logs);
- if (access(name, R_OK) != 0)
- break;
- num_logs++;
- }
-
- /* Our last known file disappeared, start over... */
- if (num_logs <= last_log && last_log > 1) {
- audit_msg(LOG_WARNING, "Last known log disappeared (%s)", name);
- num_logs = last_log = 1;
- while (num_logs) {
- snprintf(name, len, "%s.%d", data->config->log_file,
- num_logs);
- if (access(name, R_OK) != 0)
- break;
- num_logs++;
- }
- audit_msg(LOG_INFO, "Next log to use will be %s", name);
- }
- last_log = num_logs;
- rotate_logs(data, num_logs+1);
- free(name);
-}
-
-/*
- * This function handles opening a descriptor for the audit log
- * file and ensuring the correct options are applied to the descriptor.
- * It returns 0 on success and 1 on failure.
- */
-static int open_audit_log(struct auditd_consumer_data *data)
-{
- int flags, lfd;
-
- // Likely errors for open: Almost anything
- // Likely errors on rotate: ENFILE, ENOMEM, ENOSPC
-retry:
- lfd = open(data->config->log_file, O_WRONLY|O_APPEND|O_NOFOLLOW);
- if (lfd < 0) {
- if (errno == ENOENT) {
- lfd = create_log_file(data->config->log_file);
- if (lfd < 0) {
- audit_msg(LOG_ERR,
- "Couldn't create log file %s (%s)",
- data->config->log_file,
- strerror(errno));
- return 1;
- }
- close(lfd);
- lfd = open(data->config->log_file,
- O_WRONLY|O_APPEND|O_NOFOLLOW);
- log_size = 0;
- } else if (errno == ENFILE) {
- // All system descriptors used, try again...
- goto retry;
- }
- if (lfd < 0) {
- audit_msg(LOG_ERR, "Couldn't open log file %s (%s)",
- data->config->log_file, strerror(errno));
- return 1;
- }
- } else {
- // Get initial size
- struct stat st;
-
- int rc = fstat(lfd, &st);
- if (rc == 0)
- log_size = st.st_size;
- else {
- close(lfd);
- return 1;
- }
- }
-
- if (fcntl(lfd, F_SETFD, FD_CLOEXEC) == -1) {
- close(lfd);
- audit_msg(LOG_ERR, "Error setting log file CLOEXEC flag (%s)",
- strerror(errno));
- return 1;
- }
- if (data->config->flush == FT_DATA) {
- flags = fcntl(lfd, F_GETFL);
- if (flags < 0) {
- audit_msg(LOG_ERR, "Couldn't get log file flags (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
- if (fcntl(lfd, F_SETFL, flags|O_DSYNC) < 0) {
- audit_msg(LOG_ERR,
- "Couldn't set data sync mode on log file (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
- }
- else if (data->config->flush == FT_SYNC){
- flags = fcntl(lfd, F_GETFL);
- if (flags < 0) {
- audit_msg(LOG_ERR, "Couldn't get log file flags (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
- if (fcntl(lfd, F_SETFL, flags|O_SYNC) < 0) {
- audit_msg(LOG_ERR,
- "Couldn't set sync mode on log file (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
- }
- if (fchmod(lfd, data->config->log_group ? S_IRUSR|S_IWUSR|S_IRGRP :
- S_IRUSR|S_IWUSR) < 0) {
- audit_msg(LOG_ERR,
- "Couldn't change permissions of log file (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
- if (fchown(lfd, 0, data->config->log_group) < 0) {
- audit_msg(LOG_ERR, "Couldn't change ownership of log file (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
-
- data->log_fd = lfd;
- data->log_file = fdopen(lfd, "a");
- if (data->log_file == NULL) {
- audit_msg(LOG_ERR, "Error setting up log descriptor (%s)",
- strerror(errno));
- close(lfd);
- return 1;
- }
-
- /* Set it to line buffering */
- setlinebuf(consumer_data.log_file);
- return 0;
-}
-
-static void change_runlevel(const char *level)
-{
- char *argv[3];
- int pid;
- struct sigaction sa;
- static const char *init_pgm = "/sbin/init";
-
- pid = fork();
- if (pid < 0) {
- audit_msg(LOG_ALERT,
- "Audit daemon failed to fork switching runlevels");
- return;
- }
- if (pid) /* Parent */
- return;
- /* Child */
- sigfillset (&sa.sa_mask);
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
-
- argv[0] = (char *)init_pgm;
- argv[1] = (char *)level;
- argv[2] = NULL;
- execve(init_pgm, argv, NULL);
- audit_msg(LOG_ALERT, "Audit daemon failed to exec %s", init_pgm);
- exit(1);
-}
-
-static void safe_exec(const char *exe)
-{
- char *argv[2];
- int pid;
- struct sigaction sa;
-
- if (exe == NULL) {
- audit_msg(LOG_ALERT,
- "Safe_exec passed NULL for program to execute");
- return;
- }
-
- pid = fork();
- if (pid < 0) {
- audit_msg(LOG_ALERT,
- "Audit daemon failed to fork doing safe_exec");
- return;
- }
- if (pid) /* Parent */
- return;
- /* Child */
- sigfillset (&sa.sa_mask);
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
-
- argv[0] = (char *)exe;
- argv[1] = NULL;
- execve(exe, argv, NULL);
- audit_msg(LOG_ALERT, "Audit daemon failed to exec %s", exe);
- exit(1);
-}
-
-/*
-* This function will take an audit structure and return a
-* text buffer that's unformatted for writing to disk. If there
-* is an error the return value is NULL.
-*/
-static char *format_raw(const struct audit_reply *rep,
- struct daemon_conf *config)
-{
- char *ptr;
-
- if (rep==NULL) {
- if (config->node_name_format != N_NONE)
- snprintf(format_buf, MAX_AUDIT_MESSAGE_LENGTH +
- _POSIX_HOST_NAME_MAX - 32,
- "node=%s type=DAEMON msg=NULL reply",
- config->node_name);
- else
- snprintf(format_buf, MAX_AUDIT_MESSAGE_LENGTH,
- "type=DAEMON msg=NULL reply");
- } else {
- int len, nlen;
- const char *type, *message;
- char unknown[32];
- type = audit_msg_type_to_name(rep->type);
- if (type == NULL) {
- snprintf(unknown, sizeof(unknown),
- "UNKNOWN[%d]", rep->type);
- type = unknown;
- }
- if (rep->message == NULL) {
- message = "msg lost";
- len = 8;
- } else {
- message = rep->message;
- len = rep->len;
- }
-
- // Note: This can truncate messages if
- // MAX_AUDIT_MESSAGE_LENGTH is too small
- if (config->node_name_format != N_NONE)
- nlen = snprintf(format_buf, MAX_AUDIT_MESSAGE_LENGTH +
- _POSIX_HOST_NAME_MAX - 32,
- "node=%s type=%s msg=%.*s\n",
- config->node_name, type, len, message);
- else
- nlen = snprintf(format_buf,
- MAX_AUDIT_MESSAGE_LENGTH - 32,
- "type=%s msg=%.*s", type, len, message);
-
- /* Replace \n with space so it looks nicer. */
- ptr = format_buf;
- while ((ptr = strchr(ptr, 0x0A)) != NULL)
- *ptr = ' ';
-
- /* Trim trailing space off since it wastes space */
- if (format_buf[nlen-1] == ' ')
- format_buf[nlen-1] = 0;
- }
- return format_buf;
-}
-
-static void reconfigure(struct auditd_consumer_data *data)
-{
- struct daemon_conf *nconf = data->head->reply.conf;
- struct daemon_conf *oconf = data->config;
- uid_t uid = nconf->sender_uid;
- pid_t pid = nconf->sender_pid;
- const char *ctx = nconf->sender_ctx;
- struct timeval tv;
- char txt[MAX_AUDIT_MESSAGE_LENGTH];
- char date[40];
- unsigned int seq_num;
- int need_size_check = 0, need_reopen = 0, need_space_check = 0;
-
- snprintf(txt, sizeof(txt),
- "config change requested by pid=%d auid=%u subj=%s",
- pid, uid, ctx);
- audit_msg(LOG_NOTICE, "%s", txt);
-
- /* Do the reconfiguring. These are done in a specific
- * order from least invasive to most invasive. We will
- * start with general system parameters. */
-
- // start with disk error action.
- oconf->disk_error_action = nconf->disk_error_action;
- free((char *)oconf->disk_error_exe);
- oconf->disk_error_exe = nconf->disk_error_exe;
- disk_err_warning = 0;
-
- // numlogs is next
- oconf->num_logs = nconf->num_logs;
-
- // flush freq
- oconf->freq = nconf->freq;
-
- // priority boost
- if (oconf->priority_boost != nconf->priority_boost) {
- int rc;
-
- oconf->priority_boost = nconf->priority_boost;
- errno = 0;
- rc = nice(-oconf->priority_boost);
- if (rc == -1 && errno)
- audit_msg(LOG_NOTICE, "Cannot change priority in "
- "reconfigure (%s)", strerror(errno));
- }
-
- // log format
- oconf->log_format = nconf->log_format;
-
- // action_mail_acct
- if (strcmp(oconf->action_mail_acct, nconf->action_mail_acct)) {
- free((void *)oconf->action_mail_acct);
- oconf->action_mail_acct = nconf->action_mail_acct;
- } else
- free((void *)nconf->action_mail_acct);
-
- // node_name
- if (oconf->node_name_format != nconf->node_name_format ||
- (oconf->node_name && nconf->node_name &&
- strcmp(oconf->node_name, nconf->node_name) != 0)) {
- oconf->node_name_format = nconf->node_name_format;
- free((char *)oconf->node_name);
- oconf->node_name = nconf->node_name;
- }
-
- /* Now look at audit dispatcher changes */
- oconf->qos = nconf->qos; // dispatcher qos
-
- // do the dispatcher app change
- if (oconf->dispatcher || nconf->dispatcher) {
- // none before, start new one
- if (oconf->dispatcher == NULL) {
- oconf->dispatcher = strdup(nconf->dispatcher);
- if (oconf->dispatcher == NULL) {
- int saved_errno = errno;
- audit_msg(LOG_NOTICE,
- "Could not allocate dispatcher memory"
- " in reconfigure");
- // Likely errors: ENOMEM
- do_disk_error_action("reconfig", data->config,
- saved_errno);
- }
- if(init_dispatcher(oconf)) {// dispatcher & qos is used
- int saved_errno = errno;
- audit_msg(LOG_NOTICE,
- "Could not start dispatcher %s"
- " in reconfigure", oconf->dispatcher);
- // Likely errors: Socketpairs or exec perms
- do_disk_error_action("reconfig", data->config,
- saved_errno);
- }
- }
- // have one, but none after this
- else if (nconf->dispatcher == NULL) {
- shutdown_dispatcher();
- free((char *)oconf->dispatcher);
- oconf->dispatcher = NULL;
- }
- // they are different apps
- else if (strcmp(oconf->dispatcher, nconf->dispatcher)) {
- shutdown_dispatcher();
- free((char *)oconf->dispatcher);
- oconf->dispatcher = strdup(nconf->dispatcher);
- if (oconf->dispatcher == NULL) {
- int saved_errno = errno;
- audit_msg(LOG_NOTICE,
- "Could not allocate dispatcher memory"
- " in reconfigure");
- // Likely errors: ENOMEM
- do_disk_error_action("reconfig", data->config,
- saved_errno);
- }
- if(init_dispatcher(oconf)) {// dispatcher & qos is used
- int saved_errno = errno;
- audit_msg(LOG_NOTICE,
- "Could not start dispatcher %s"
- " in reconfigure", oconf->dispatcher);
- // Likely errors: Socketpairs or exec perms
- do_disk_error_action("reconfig", data->config,
- saved_errno);
- }
- }
- // they are the same app - just signal it
- else {
- reconfigure_dispatcher(oconf);
- free((char *)nconf->dispatcher);
- nconf->dispatcher = NULL;
- }
- }
-
- // network listener
- auditd_tcp_listen_reconfigure(nconf, oconf);
-
- /* At this point we will work on the items that are related to
- * a single log file. */
-
- // max logfile action
- if (oconf->max_log_size_action != nconf->max_log_size_action) {
- oconf->max_log_size_action = nconf->max_log_size_action;
- need_size_check = 1;
- }
-
- // max log size
- if (oconf->max_log_size != nconf->max_log_size) {
- oconf->max_log_size = nconf->max_log_size;
- need_size_check = 1;
- }
-
- if (need_size_check) {
- logging_suspended = 0;
- check_log_file_size(data);
- }
-
- // flush technique
- if (oconf->flush != nconf->flush) {
- oconf->flush = nconf->flush;
- need_reopen = 1;
- }
-
- // logfile
- if (strcmp(oconf->log_file, nconf->log_file)) {
- free((void *)oconf->log_file);
- oconf->log_file = nconf->log_file;
- need_reopen = 1;
- need_space_check = 1; // might be on new partition
- } else
- free((void *)nconf->log_file);
-
- if (need_reopen) {
- fclose(data->log_file);
- if (open_audit_log(data)) {
- int saved_errno = errno;
- audit_msg(LOG_NOTICE,
- "Could not reopen a log after reconfigure");
- logging_suspended = 1;
- // Likely errors: ENOMEM, ENOSPC
- do_disk_error_action("reconfig", data->config,
- saved_errno);
- } else {
- logging_suspended = 0;
- check_log_file_size(data);
- }
- }
-
- /* At this point we will start working on items that are
- * related to the amount of space on the partition. */
-
- // space left
- if (oconf->space_left != nconf->space_left) {
- oconf->space_left = nconf->space_left;
- need_space_check = 1;
- }
-
- // space left action
- if (oconf->space_left_action != nconf->space_left_action) {
- oconf->space_left_action = nconf->space_left_action;
- need_space_check = 1;
- }
-
- // space left exe
- if (oconf->space_left_exe || nconf->space_left_exe) {
- if (nconf->space_left_exe == NULL)
- ; /* do nothing if new one is blank */
- else if (oconf->space_left_exe == NULL && nconf->space_left_exe)
- need_space_check = 1;
- else if (strcmp(oconf->space_left_exe, nconf->space_left_exe))
- need_space_check = 1;
- free((char *)oconf->space_left_exe);
- oconf->space_left_exe = nconf->space_left_exe;
- }
-
- // admin space left
- if (oconf->admin_space_left != nconf->admin_space_left) {
- oconf->admin_space_left = nconf->admin_space_left;
- need_space_check = 1;
- }
-
- // admin space action
- if (oconf->admin_space_left_action != nconf->admin_space_left_action) {
- oconf->admin_space_left_action = nconf->admin_space_left_action;
- need_space_check = 1;
- }
-
- // admin space left exe
- if (oconf->admin_space_left_exe || nconf->admin_space_left_exe) {
- if (nconf->admin_space_left_exe == NULL)
- ; /* do nothing if new one is blank */
- else if (oconf->admin_space_left_exe == NULL &&
- nconf->admin_space_left_exe)
- need_space_check = 1;
- else if (strcmp(oconf->admin_space_left_exe,
- nconf->admin_space_left_exe))
- need_space_check = 1;
- free((char *)oconf->admin_space_left_exe);
- oconf->admin_space_left_exe = nconf->admin_space_left_exe;
- }
- // disk full action
- if (oconf->disk_full_action != nconf->disk_full_action) {
- oconf->disk_full_action = nconf->disk_full_action;
- need_space_check = 1;
- }
-
- // disk full exe
- if (oconf->disk_full_exe || nconf->disk_full_exe) {
- if (nconf->disk_full_exe == NULL)
- ; /* do nothing if new one is blank */
- else if (oconf->disk_full_exe == NULL && nconf->disk_full_exe)
- need_space_check = 1;
- else if (strcmp(oconf->disk_full_exe, nconf->disk_full_exe))
- need_space_check = 1;
- free((char *)oconf->disk_full_exe);
- oconf->disk_full_exe = nconf->disk_full_exe;
- }
-
- if (need_space_check) {
- /* note save suspended flag, then do space_left. If suspended
- * is still 0, then copy saved suspended back. This avoids
- * having to call check_log_file_size to restore it. */
- int saved_suspend = logging_suspended;
-
- fs_space_warning = 0;
- fs_admin_space_warning = 0;
- fs_space_left = 1;
- logging_suspended = 0;
- check_excess_logs(data);
- check_space_left(data->log_fd, data);
- if (logging_suspended == 0)
- logging_suspended = saved_suspend;
- }
-
- // Next document the results
- srand(time(NULL));
- seq_num = rand()%10000;
- if (gettimeofday(&tv, NULL) == 0) {
- snprintf(date, sizeof(date), "audit(%lu.%03u:%u)", tv.tv_sec,
- (unsigned)(tv.tv_usec/1000), seq_num);
- } else {
- snprintf(date, sizeof(date),
- "audit(%lu.%03u:%u)", (unsigned long)time(NULL),
- 0, seq_num);
- }
-
- data->head->reply.len = snprintf(txt, sizeof(txt),
- "%s config changed, auid=%u pid=%d subj=%s res=success", date,
- uid, pid, ctx );
- audit_msg(LOG_NOTICE, "%s", txt);
- data->head->reply.type = AUDIT_DAEMON_CONFIG;
- data->head->reply.message = strdup(txt);
- if (!data->head->reply.message) {
- data->head->reply.len = 0;
- audit_msg(LOG_ERR, "Cannot allocate config message");
- // FIXME: Should call some error handler
- }
- free((char *)ctx);
-}
-
diff --git a/framework/src/audit/src/auditd-event.h b/framework/src/audit/src/auditd-event.h
deleted file mode 100644
index 71678259..00000000
--- a/framework/src/audit/src/auditd-event.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* auditd-event.h --
- * Copyright 2004, 2005, 2008 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#ifndef AUDITD_EVENT_H
-#define AUDITD_EVENT_H
-
-#include "libaudit.h"
-
-typedef void (*ack_func_type)(void *ack_data, const unsigned char *header, const char *msg);
-
-struct auditd_reply_list {
- struct audit_reply reply;
- struct auditd_reply_list *next;
- ack_func_type ack_func;
- void *ack_data;
- unsigned long sequence_id;
-};
-
-#include "auditd-config.h"
-
-void shutdown_events(void);
-int init_event(struct daemon_conf *config);
-void resume_logging(void);
-void enqueue_event(struct auditd_reply_list *rep);
-void enqueue_formatted_event(char *msg, ack_func_type ack_func, void *ack_data, uint32_t sequence_id);
-void *consumer_thread_main(void *arg);
-
-#endif
-
diff --git a/framework/src/audit/src/auditd-listen.c b/framework/src/audit/src/auditd-listen.c
deleted file mode 100644
index d1977c63..00000000
--- a/framework/src/audit/src/auditd-listen.c
+++ /dev/null
@@ -1,1065 +0,0 @@
-/* auditd-listen.c --
- * Copyright 2008,2009,2011 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * DJ Delorie <dj@redhat.com>
- *
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <fcntl.h> /* O_NOFOLLOW needs gnu defined */
-#include <libgen.h>
-#include <arpa/inet.h>
-#include <limits.h> /* INT_MAX */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#ifdef HAVE_LIBWRAP
-#include <tcpd.h>
-#endif
-#ifdef USE_GSSAPI
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-#include <krb5.h>
-#endif
-#include "libaudit.h"
-#include "auditd-event.h"
-#include "auditd-config.h"
-#include "private.h"
-
-#include "ev.h"
-
-extern volatile int stop;
-extern int send_audit_event(int type, const char *str);
-#define DEFAULT_BUF_SZ 192
-
-typedef struct ev_tcp {
- struct ev_io io;
- struct sockaddr_in addr;
- struct ev_tcp *next, *prev;
- unsigned int bufptr;
- int client_active;
-#ifdef USE_GSSAPI
- /* This holds the negotiated security context for this client. */
- gss_ctx_id_t gss_context;
- char *remote_name;
- int remote_name_len;
-#endif
- unsigned char buffer [MAX_AUDIT_MESSAGE_LENGTH + 17];
-} ev_tcp;
-
-static int listen_socket;
-static struct ev_io tcp_listen_watcher;
-static struct ev_periodic periodic_watcher;
-static int min_port, max_port, max_per_addr;
-static int use_libwrap = 1;
-#ifdef USE_GSSAPI
-/* This is used to hold our own private key. */
-static gss_cred_id_t server_creds;
-static char *my_service_name, *my_gss_realm;
-static int use_gss = 0;
-static char msgbuf[MAX_AUDIT_MESSAGE_LENGTH + 1];
-#endif
-
-static struct ev_tcp *client_chain = NULL;
-
-static char *sockaddr_to_ipv4(struct sockaddr_in *addr)
-{
- unsigned char *uaddr = (unsigned char *)&(addr->sin_addr);
- static char buf[40];
-
- snprintf(buf, sizeof(buf), "%u.%u.%u.%u",
- uaddr[0], uaddr[1], uaddr[2], uaddr[3]);
- return buf;
-}
-
-static char *sockaddr_to_addr4(struct sockaddr_in *addr)
-{
- unsigned char *uaddr = (unsigned char *)&(addr->sin_addr);
- static char buf[40];
-
- snprintf(buf, sizeof(buf), "%u.%u.%u.%u:%u",
- uaddr[0], uaddr[1], uaddr[2], uaddr[3],
- ntohs (addr->sin_port));
- return buf;
-}
-
-static void set_close_on_exec (int fd)
-{
- int flags = fcntl (fd, F_GETFD);
- if (flags == -1)
- flags = 0;
- flags |= FD_CLOEXEC;
- fcntl (fd, F_SETFD, flags);
-}
-
-static void release_client(struct ev_tcp *client)
-{
- char emsg[DEFAULT_BUF_SZ];
-
- snprintf(emsg, sizeof(emsg), "addr=%s port=%d res=success",
- sockaddr_to_ipv4(&client->addr), ntohs (client->addr.sin_port));
- send_audit_event(AUDIT_DAEMON_CLOSE, emsg);
-#ifdef USE_GSSAPI
- if (client->remote_name)
- free (client->remote_name);
-#endif
- shutdown(client->io.fd, SHUT_RDWR);
- close(client->io.fd);
- if (client_chain == client)
- client_chain = client->next;
- if (client->next)
- client->next->prev = client->prev;
- if (client->prev)
- client->prev->next = client->next;
-}
-
-static void close_client(struct ev_tcp *client)
-{
- release_client (client);
- free (client);
-}
-
-static int ar_write (int sock, const void *buf, int len)
-{
- int rc = 0, w;
- while (len > 0) {
- do {
- w = write(sock, buf, len);
- } while (w < 0 && errno == EINTR);
- if (w < 0)
- return w;
- if (w == 0)
- break;
- rc += w;
- len -= w;
- buf = (const void *)((const char *)buf + w);
- }
- return rc;
-}
-
-#ifdef USE_GSSAPI
-static int ar_read (int sock, void *buf, int len)
-{
- int rc = 0, r;
- while (len > 0) {
- do {
- r = read(sock, buf, len);
- } while (r < 0 && errno == EINTR);
- if (r < 0)
- return r;
- if (r == 0)
- break;
- rc += r;
- len -= r;
- buf = (void *)((char *)buf + r);
- }
- return rc;
-}
-
-
-/* Communications under GSS is done by token exchanges. Each "token"
- may contain a message, perhaps signed, perhaps encrypted. The
- messages within are what we're interested in, but the network sees
- the tokens. The protocol we use for transferring tokens is to send
- the length first, four bytes MSB first, then the token data. We
- return nonzero on error. */
-static int recv_token (int s, gss_buffer_t tok)
-{
- int ret;
- unsigned char lenbuf[4];
- unsigned int len;
-
- ret = ar_read(s, (char *) lenbuf, 4);
- if (ret < 0) {
- audit_msg(LOG_ERR, "GSS-API error reading token length");
- return -1;
- } else if (!ret) {
- return 0;
- } else if (ret != 4) {
- audit_msg(LOG_ERR, "GSS-API error reading token length");
- return -1;
- }
-
- len = ((lenbuf[0] << 24)
- | (lenbuf[1] << 16)
- | (lenbuf[2] << 8)
- | lenbuf[3]);
- if (len > MAX_AUDIT_MESSAGE_LENGTH) {
- audit_msg(LOG_ERR,
- "GSS-API error: event length excedes MAX_AUDIT_LENGTH");
- return -1;
- }
- tok->length = len;
-
- tok->value = (char *) malloc(tok->length ? tok->length : 1);
- if (tok->length && tok->value == NULL) {
- audit_msg(LOG_ERR, "Out of memory allocating token data");
- return -1;
- }
-
- ret = ar_read(s, (char *) tok->value, tok->length);
- if (ret < 0) {
- audit_msg(LOG_ERR, "GSS-API error reading token data");
- free(tok->value);
- return -1;
- } else if (ret != (int) tok->length) {
- audit_msg(LOG_ERR, "GSS-API error reading token data");
- free(tok->value);
- return -1;
- }
-
- return 1;
-}
-
-/* Same here. */
-int send_token(int s, gss_buffer_t tok)
-{
- int ret;
- unsigned char lenbuf[4];
- unsigned int len;
-
- if (tok->length > 0xffffffffUL)
- return -1;
- len = tok->length;
- lenbuf[0] = (len >> 24) & 0xff;
- lenbuf[1] = (len >> 16) & 0xff;
- lenbuf[2] = (len >> 8) & 0xff;
- lenbuf[3] = len & 0xff;
-
- ret = ar_write(s, (char *) lenbuf, 4);
- if (ret < 0) {
- audit_msg(LOG_ERR, "GSS-API error sending token length");
- return -1;
- } else if (ret != 4) {
- audit_msg(LOG_ERR, "GSS-API error sending token length");
- return -1;
- }
-
- ret = ar_write(s, tok->value, tok->length);
- if (ret < 0) {
- audit_msg(LOG_ERR, "GSS-API error sending token data");
- return -1;
- } else if (ret != (int) tok->length) {
- audit_msg(LOG_ERR, "GSS-API error sending token data");
- return -1;
- }
-
- return 0;
-}
-
-
-static void gss_failure_2 (const char *msg, int status, int type)
-{
- OM_uint32 message_context = 0;
- OM_uint32 min_status = 0;
- gss_buffer_desc status_string;
-
- do {
- gss_display_status (&min_status,
- status,
- type,
- GSS_C_NO_OID,
- &message_context,
- &status_string);
-
- audit_msg (LOG_ERR, "GSS error: %s: %s",
- msg, (char *)status_string.value);
-
- gss_release_buffer(&min_status, &status_string);
- } while (message_context != 0);
-}
-
-static void gss_failure (const char *msg, int major_status, int minor_status)
-{
- gss_failure_2 (msg, major_status, GSS_C_GSS_CODE);
- if (minor_status)
- gss_failure_2 (msg, minor_status, GSS_C_MECH_CODE);
-}
-
-#define KCHECK(x,f) if (x) { \
- const char *kstr = krb5_get_error_message(kcontext, x); \
- audit_msg(LOG_ERR, "krb5 error: %s in %s\n", kstr, f); \
- krb5_free_error_message(kcontext, kstr); \
- return -1; }
-
-/* These are our private credentials, which come from a key file on
- our server. They are aquired once, at program start. */
-static int server_acquire_creds(const char *service_name,
- gss_cred_id_t *server_creds)
-{
- gss_buffer_desc name_buf;
- gss_name_t server_name;
- OM_uint32 major_status, minor_status;
-
- krb5_context kcontext = NULL;
- int krberr;
-
- my_service_name = strdup (service_name);
- name_buf.value = (char *)service_name;
- name_buf.length = strlen(name_buf.value) + 1;
- major_status = gss_import_name(&minor_status, &name_buf,
- (gss_OID) gss_nt_service_name,
- &server_name);
- if (major_status != GSS_S_COMPLETE) {
- gss_failure("importing name", major_status, minor_status);
- return -1;
- }
-
- major_status = gss_acquire_cred(&minor_status,
- server_name, GSS_C_INDEFINITE,
- GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
- server_creds, NULL, NULL);
- if (major_status != GSS_S_COMPLETE) {
- gss_failure("acquiring credentials",
- major_status, minor_status);
- return -1;
- }
-
- (void) gss_release_name(&minor_status, &server_name);
-
- krberr = krb5_init_context (&kcontext);
- KCHECK (krberr, "krb5_init_context");
- krberr = krb5_get_default_realm (kcontext, &my_gss_realm);
- KCHECK (krberr, "krb5_get_default_realm");
-
- audit_msg(LOG_DEBUG, "GSS creds for %s acquired", service_name);
-
- return 0;
-}
-
-/* This is where we negotiate a security context with the client. In
- the case of Kerberos, this is where the key exchange happens.
- FIXME: While everything else is strictly nonblocking, this
- negotiation blocks. */
-static int negotiate_credentials (ev_tcp *io)
-{
- gss_buffer_desc send_tok, recv_tok;
- gss_name_t client;
- OM_uint32 maj_stat, min_stat, acc_sec_min_stat;
- gss_ctx_id_t *context;
- OM_uint32 sess_flags;
- char *slashptr, *atptr;
-
- context = & io->gss_context;
- *context = GSS_C_NO_CONTEXT;
-
- maj_stat = GSS_S_CONTINUE_NEEDED;
- do {
- /* STEP 1 - get a token from the client. */
-
- if (recv_token(io->io.fd, &recv_tok) <= 0) {
- audit_msg(LOG_ERR,
- "TCP session from %s will be closed, error ignored",
- sockaddr_to_addr4(&io->addr));
- return -1;
- }
- if (recv_tok.length == 0)
- continue;
-
- /* STEP 2 - let GSS process that token. */
-
- maj_stat = gss_accept_sec_context(&acc_sec_min_stat,
- context, server_creds,
- &recv_tok,
- GSS_C_NO_CHANNEL_BINDINGS, &client,
- NULL, &send_tok, &sess_flags,
- NULL, NULL);
- if (recv_tok.value) {
- free(recv_tok.value);
- recv_tok.value = NULL;
- }
- if (maj_stat != GSS_S_COMPLETE
- && maj_stat != GSS_S_CONTINUE_NEEDED) {
- gss_release_buffer(&min_stat, &send_tok);
- if (*context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&min_stat, context,
- GSS_C_NO_BUFFER);
- gss_failure("accepting context", maj_stat,
- acc_sec_min_stat);
- return -1;
- }
-
- /* STEP 3 - send any tokens to the client that GSS may
- ask us to send. */
-
- if (send_tok.length != 0) {
- if (send_token(io->io.fd, &send_tok) < 0) {
- gss_release_buffer(&min_stat, &send_tok);
- audit_msg(LOG_ERR,
- "TCP session from %s will be closed, error ignored",
- sockaddr_to_addr4(&io->addr));
- if (*context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&min_stat,
- context, GSS_C_NO_BUFFER);
- return -1;
- }
- gss_release_buffer(&min_stat, &send_tok);
- }
- } while (maj_stat == GSS_S_CONTINUE_NEEDED);
-
- maj_stat = gss_display_name(&min_stat, client, &recv_tok, NULL);
- gss_release_name(&min_stat, &client);
-
- if (maj_stat != GSS_S_COMPLETE) {
- gss_failure("displaying name", maj_stat, min_stat);
- return -1;
- }
-
- audit_msg(LOG_INFO, "GSS-API Accepted connection from: %s",
- (char *)recv_tok.value);
- io->remote_name = strdup (recv_tok.value);
- io->remote_name_len = strlen (recv_tok.value);
- gss_release_buffer(&min_stat, &recv_tok);
-
- slashptr = strchr (io->remote_name, '/');
- atptr = strchr (io->remote_name, '@');
-
- if (!slashptr || !atptr) {
- audit_msg(LOG_ERR, "Invalid GSS name from remote client: %s",
- io->remote_name);
- return -1;
- }
-
- *slashptr = 0;
- if (strcmp (io->remote_name, my_service_name)) {
- audit_msg(LOG_ERR, "Unauthorized GSS client name: %s (not %s)",
- io->remote_name, my_service_name);
- return -1;
- }
- *slashptr = '/';
-
- if (strcmp (atptr+1, my_gss_realm)) {
- audit_msg(LOG_ERR, "Unauthorized GSS client realm: %s (not %s)",
- atptr+1, my_gss_realm);
- return -1;
- }
-
- return 0;
-}
-#endif /* USE_GSSAPI */
-
-/* This is called from auditd-event after the message has been logged.
- The header is already filled in. */
-static void client_ack (void *ack_data, const unsigned char *header,
- const char *msg)
-{
- ev_tcp *io = (ev_tcp *)ack_data;
-#ifdef USE_GSSAPI
- if (use_gss) {
- OM_uint32 major_status, minor_status;
- gss_buffer_desc utok, etok;
- int rc, mlen;
-
- mlen = strlen (msg);
- utok.length = AUDIT_RMW_HEADER_SIZE + mlen;
- utok.value = malloc (utok.length + 1);
-
- memcpy (utok.value, header, AUDIT_RMW_HEADER_SIZE);
- memcpy (utok.value+AUDIT_RMW_HEADER_SIZE, msg, mlen);
-
- /* Wrapping the message creates a token for the
- client. Then we just have to worry about sending
- the token. */
-
- major_status = gss_wrap (&minor_status,
- io->gss_context,
- 1,
- GSS_C_QOP_DEFAULT,
- &utok,
- NULL,
- &etok);
- if (major_status != GSS_S_COMPLETE) {
- gss_failure("encrypting message", major_status,
- minor_status);
- free (utok.value);
- return;
- }
- // FIXME: What were we going to do with rc?
- rc = send_token (io->io.fd, &etok);
- free (utok.value);
- (void) gss_release_buffer(&minor_status, &etok);
-
- return;
- }
-#endif
- // Send the header and a text error message if it exists
- ar_write (io->io.fd, header, AUDIT_RMW_HEADER_SIZE);
- if (msg[0])
- ar_write (io->io.fd, msg, strlen(msg));
-}
-
-static void client_message (struct ev_tcp *io, unsigned int length,
- unsigned char *header)
-{
- unsigned char ch;
- uint32_t type, mlen, seq;
- int hver, mver;
-
- if (AUDIT_RMW_IS_MAGIC (header, length)) {
- AUDIT_RMW_UNPACK_HEADER (header, hver, mver, type, mlen, seq)
-
- ch = header[length];
- header[length] = 0;
- if (length > 1 && header[length-1] == '\n')
- header[length-1] = 0;
- if (type == AUDIT_RMW_TYPE_HEARTBEAT) {
- unsigned char ack[AUDIT_RMW_HEADER_SIZE];
- AUDIT_RMW_PACK_HEADER (ack, 0, AUDIT_RMW_TYPE_ACK,
- 0, seq);
- client_ack (io, ack, "");
- } else
- enqueue_formatted_event(header+AUDIT_RMW_HEADER_SIZE,
- client_ack, io, seq);
- header[length] = ch;
- } else {
- header[length] = 0;
- if (length > 1 && header[length-1] == '\n')
- header[length-1] = 0;
- enqueue_formatted_event (header, NULL, NULL, 0);
- }
-}
-
-static void auditd_tcp_client_handler( struct ev_loop *loop,
- struct ev_io *_io, int revents )
-{
- struct ev_tcp *io = (struct ev_tcp *) _io;
- int i, r;
- int total_this_call = 0;
-
- io->client_active = 1;
-
- /* The socket is non-blocking, but we have a limited buffer
- size. In the event that we get a packet that's bigger than
- our buffer, we need to read it in multiple parts. Thus, we
- keep reading/parsing/processing until we run out of ready
- data. */
-read_more:
- r = read (io->io.fd,
- io->buffer + io->bufptr,
- MAX_AUDIT_MESSAGE_LENGTH - io->bufptr);
-
- if (r < 0 && errno == EAGAIN)
- r = 0;
-
- /* We need to keep track of the difference between "no data
- * because it's closed" and "no data because we've read it
- * all". */
- if (r == 0 && total_this_call > 0) {
- return;
- }
-
- /* If the connection is gracefully closed, the first read we
- try will return zero. If the connection times out or
- otherwise fails, the read will return -1. */
- if (r <= 0) {
- if (r < 0)
- audit_msg (LOG_WARNING,
- "client %s socket closed unexpectedly",
- sockaddr_to_addr4(&io->addr));
-
- /* There may have been a final message without a LF. */
- if (io->bufptr) {
- client_message (io, io->bufptr, io->buffer);
-
- }
-
- ev_io_stop (loop, _io);
- close_client (io);
- return;
- }
-
- total_this_call += r;
-
-more_messages:
-#ifdef USE_GSSAPI
- /* If we're using GSS at all, everything will be encrypted,
- one record per token. */
- if (use_gss) {
- gss_buffer_desc utok, etok;
- io->bufptr += r;
- uint32_t len;
- OM_uint32 major_status, minor_status;
-
- /* We need at least four bytes to test the length. If
- we have more than four bytes, we can tell if we
- have a whole token (or more). */
-
- if (io->bufptr < 4)
- return;
-
- len = ( ((uint32_t)(io->buffer[0] & 0xFF) << 24)
- | ((uint32_t)(io->buffer[1] & 0xFF) << 16)
- | ((uint32_t)(io->buffer[2] & 0xFF) << 8)
- | (uint32_t)(io->buffer[3] & 0xFF));
-
- /* Make sure we got something big enough and not too big */
- if (io->bufptr < 4 + len || len > MAX_AUDIT_MESSAGE_LENGTH)
- return;
- i = len + 4;
-
- etok.length = len;
- etok.value = io->buffer + 4;
-
- /* Unwrapping the token gives us the original message,
- which we know is already a single record. */
- major_status = gss_unwrap (&minor_status, io->gss_context,
- &etok, &utok, NULL, NULL);
-
- if (major_status != GSS_S_COMPLETE) {
- gss_failure("decrypting message", major_status,
- minor_status);
- } else {
- /* client_message() wants to NUL terminate it,
- so copy it to a bigger buffer. Plus, we
- want to add our own tag. */
- memcpy (msgbuf, utok.value, utok.length);
- while (utok.length > 0 && msgbuf[utok.length-1] == '\n')
- utok.length --;
- snprintf (msgbuf + utok.length,
- MAX_AUDIT_MESSAGE_LENGTH - utok.length,
- " krb5=%s", io->remote_name);
- utok.length += 6 + io->remote_name_len;
- client_message (io, utok.length, msgbuf);
- gss_release_buffer(&minor_status, &utok);
- }
- } else
-#endif
- if (AUDIT_RMW_IS_MAGIC (io->buffer, (io->bufptr+r))) {
- uint32_t type, len, seq;
- int hver, mver;
- unsigned char *header = (unsigned char *)io->buffer;
-
- io->bufptr += r;
-
- if (io->bufptr < AUDIT_RMW_HEADER_SIZE)
- return;
-
- AUDIT_RMW_UNPACK_HEADER (header, hver, mver, type, len, seq);
-
- /* Make sure len is not too big */
- if (len > MAX_AUDIT_MESSAGE_LENGTH)
- return;
-
- i = len;
- i += AUDIT_RMW_HEADER_SIZE;
-
- /* See if we have enough bytes to extract the whole message. */
- if (io->bufptr < i)
- return;
-
- /* We have an I-byte message in buffer. Send ACK */
- client_message (io, i, io->buffer);
-
- } else {
- /* At this point, the buffer has IO->BUFPTR+R bytes in it.
- The first IO->BUFPTR bytes do not have a LF in them (we've
- already checked), we must check the R new bytes. */
-
- for (i = io->bufptr; i < io->bufptr + r; i ++)
- if (io->buffer [i] == '\n')
- break;
-
- io->bufptr += r;
-
- /* Check for a partial message, with no LF yet. */
- if (i == io->bufptr)
- return;
-
- i++;
-
- /* We have an I-byte message in buffer. Send ACK */
- client_message (io, i, io->buffer);
- }
-
- /* Now copy any remaining bytes to the beginning of the
- buffer. */
- memmove(io->buffer, io->buffer + i, io->bufptr - i);
- io->bufptr -= i;
-
- /* See if this packet had more than one message in it. */
- if (io->bufptr > 0) {
- r = io->bufptr;
- io->bufptr = 0;
- goto more_messages;
- }
-
- /* Go back and see if there's more data to read. */
- goto read_more;
-}
-
-#ifndef HAVE_LIBWRAP
-#define auditd_tcpd_check(s) ({ 0; })
-#else
-int allow_severity = LOG_INFO, deny_severity = LOG_NOTICE;
-static int auditd_tcpd_check(int sock)
-{
- struct request_info request;
-
- request_init(&request, RQ_DAEMON, "auditd", RQ_FILE, sock, 0);
- fromhost(&request);
- if (! hosts_access(&request))
- return 1;
- return 0;
-}
-#endif
-
-/*
- * This function counts the number of concurrent connections and returns
- * a 1 if there are too many and a 0 otherwise. It assumes the incoming
- * connection has not been added to the linked list yet.
- */
-static int check_num_connections(struct sockaddr_in *aaddr)
-{
- int num = 0;
- struct ev_tcp *client = client_chain;
-
- while (client) {
- if (memcmp(&aaddr->sin_addr, &client->addr.sin_addr,
- sizeof(struct in_addr)) == 0) {
- num++;
- if (num >= max_per_addr)
- return 1;
- }
- client = client->next;
- }
- return 0;
-}
-
-static void auditd_tcp_listen_handler( struct ev_loop *loop,
- struct ev_io *_io, int revents )
-{
- int one=1;
- int afd;
- socklen_t aaddrlen;
- struct sockaddr_in aaddr;
- struct ev_tcp *client;
- char emsg[DEFAULT_BUF_SZ];
-
- /* Accept the connection and see where it's coming from. */
- aaddrlen = sizeof(aaddr);
- afd = accept (listen_socket, (struct sockaddr *)&aaddr, &aaddrlen);
- if (afd == -1) {
- audit_msg(LOG_ERR, "Unable to accept TCP connection");
- return;
- }
-
- if (use_libwrap) {
- if (auditd_tcpd_check(afd)) {
- shutdown(afd, SHUT_RDWR);
- close(afd);
- audit_msg(LOG_ERR, "TCP connection from %s rejected",
- sockaddr_to_addr4(&aaddr));
- snprintf(emsg, sizeof(emsg),
- "op=wrap addr=%s port=%d res=no",
- sockaddr_to_ipv4(&aaddr),
- ntohs (aaddr.sin_port));
- send_audit_event(AUDIT_DAEMON_ACCEPT, emsg);
- return;
- }
- }
-
- /* Verify it's coming from an authorized port. We assume the firewall
- * will block attempts from unauthorized machines. */
- if (min_port > ntohs (aaddr.sin_port) ||
- ntohs (aaddr.sin_port) > max_port) {
- audit_msg(LOG_ERR, "TCP connection from %s rejected",
- sockaddr_to_addr4(&aaddr));
- snprintf(emsg, sizeof(emsg),
- "op=port addr=%s port=%d res=no",
- sockaddr_to_ipv4(&aaddr),
- ntohs (aaddr.sin_port));
- send_audit_event(AUDIT_DAEMON_ACCEPT, emsg);
- shutdown(afd, SHUT_RDWR);
- close(afd);
- return;
- }
-
- /* Make sure we don't have too many connections */
- if (check_num_connections(&aaddr)) {
- audit_msg(LOG_ERR, "Too many connections from %s - rejected",
- sockaddr_to_addr4(&aaddr));
- snprintf(emsg, sizeof(emsg),
- "op=dup addr=%s port=%d res=no",
- sockaddr_to_ipv4(&aaddr),
- ntohs (aaddr.sin_port));
- send_audit_event(AUDIT_DAEMON_ACCEPT, emsg);
- shutdown(afd, SHUT_RDWR);
- close(afd);
- return;
- }
-
- /* Connection is accepted...start setting it up */
- setsockopt(afd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (int));
- setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sizeof (int));
- setsockopt(afd, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof (int));
- set_close_on_exec (afd);
-
- /* Make the client data structure */
- client = (struct ev_tcp *) malloc (sizeof (struct ev_tcp));
- if (client == NULL) {
- audit_msg(LOG_CRIT, "Unable to allocate TCP client data");
- snprintf(emsg, sizeof(emsg),
- "op=alloc addr=%s port=%d res=no",
- sockaddr_to_ipv4(&aaddr),
- ntohs (aaddr.sin_port));
- send_audit_event(AUDIT_DAEMON_ACCEPT, emsg);
- shutdown(afd, SHUT_RDWR);
- close(afd);
- return;
- }
-
- memset (client, 0, sizeof (struct ev_tcp));
- client->client_active = 1;
-
- // Was watching for EV_ERROR, but libev 3.48 took it away
- ev_io_init (&(client->io), auditd_tcp_client_handler, afd, EV_READ);
-
- memcpy (&client->addr, &aaddr, sizeof (struct sockaddr_in));
-
-#ifdef USE_GSSAPI
- if (use_gss && negotiate_credentials (client)) {
- shutdown(afd, SHUT_RDWR);
- close(afd);
- free(client);
- return;
- }
-#endif
-
- fcntl(afd, F_SETFL, O_NONBLOCK | O_NDELAY);
- ev_io_start (loop, &(client->io));
-
- /* Add the new connection to a linked list of active clients. */
- client->next = client_chain;
- if (client->next)
- client->next->prev = client;
- client_chain = client;
-
- /* And finally log that we accepted the connection */
- snprintf(emsg, sizeof(emsg),
- "addr=%s port=%d res=success", sockaddr_to_ipv4(&aaddr),
- ntohs (aaddr.sin_port));
- send_audit_event(AUDIT_DAEMON_ACCEPT, emsg);
-}
-
-static void auditd_set_ports(int minp, int maxp, int max_p_addr)
-{
- min_port = minp;
- max_port = maxp;
- max_per_addr = max_p_addr;
-}
-
-static void periodic_handler(struct ev_loop *loop, struct ev_periodic *per,
- int revents )
-{
- struct daemon_conf *config = (struct daemon_conf *) per->data;
- struct ev_tcp *ev, *next = NULL;
- int active;
-
- if (!config->tcp_client_max_idle)
- return;
-
- for (ev = client_chain; ev; ev = next) {
- active = ev->client_active;
- ev->client_active = 0;
- if (active)
- continue;
-
- audit_msg(LOG_NOTICE,
- "client %s idle too long - closing connection\n",
- sockaddr_to_addr4(&(ev->addr)));
- ev_io_stop (loop, &ev->io);
- release_client(ev);
- next = ev->next;
- free(ev);
- }
-}
-
-int auditd_tcp_listen_init ( struct ev_loop *loop, struct daemon_conf *config )
-{
- struct sockaddr_in address;
- int one = 1;
-
- ev_periodic_init (&periodic_watcher, periodic_handler,
- 0, config->tcp_client_max_idle, NULL);
- periodic_watcher.data = config;
- if (config->tcp_client_max_idle)
- ev_periodic_start (loop, &periodic_watcher);
-
- /* If the port is not set, that means we aren't going to
- listen for connections. */
- if (config->tcp_listen_port == 0)
- return 0;
-
- listen_socket = socket (AF_INET, SOCK_STREAM, 0);
- if (listen_socket < 0) {
- audit_msg(LOG_ERR, "Cannot create tcp listener socket");
- return 1;
- }
-
- set_close_on_exec (listen_socket);
- setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR,
- (char *)&one, sizeof (int));
-
- memset (&address, 0, sizeof(address));
- address.sin_family = AF_INET;
- address.sin_port = htons(config->tcp_listen_port);
- address.sin_addr.s_addr = htonl(INADDR_ANY);
-
- /* This avoids problems if auditd needs to be restarted. */
- setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR,
- (char *)&one, sizeof (int));
-
- if (bind(listen_socket, (struct sockaddr *)&address, sizeof(address))){
- audit_msg(LOG_ERR,
- "Cannot bind tcp listener socket to port %ld",
- config->tcp_listen_port);
- close(listen_socket);
- return 1;
- }
-
- listen(listen_socket, config->tcp_listen_queue);
-
- audit_msg(LOG_DEBUG, "Listening on TCP port %ld",
- config->tcp_listen_port);
-
- ev_io_init (&tcp_listen_watcher, auditd_tcp_listen_handler,
- listen_socket, EV_READ);
- ev_io_start (loop, &tcp_listen_watcher);
-
- use_libwrap = config->use_libwrap;
- auditd_set_ports(config->tcp_client_min_port,
- config->tcp_client_max_port,
- config->tcp_max_per_addr);
-
-#ifdef USE_GSSAPI
- if (config->enable_krb5) {
- const char *princ = config->krb5_principal;
- const char *key_file;
- struct stat st;
-
- if (!princ)
- princ = "auditd";
- use_gss = 1;
- /* This may fail, but we don't care. */
- unsetenv ("KRB5_KTNAME");
- if (config->krb5_key_file)
- key_file = config->krb5_key_file;
- else
- key_file = "/etc/audit/audit.key";
- setenv ("KRB5_KTNAME", key_file, 1);
-
- if (stat (key_file, &st) == 0) {
- if ((st.st_mode & 07777) != 0400) {
- audit_msg (LOG_ERR,
- "%s is not mode 0400 (it's %#o) - compromised key?",
- key_file, st.st_mode & 07777);
- return -1;
- }
- if (st.st_uid != 0) {
- audit_msg (LOG_ERR,
- "%s is not owned by root (it's %d) - compromised key?",
- key_file, st.st_uid);
- return -1;
- }
- }
-
- server_acquire_creds(princ, &server_creds);
- }
-#endif
-
- return 0;
-}
-
-void auditd_tcp_listen_uninit ( struct ev_loop *loop,
- struct daemon_conf *config )
-{
-#ifdef USE_GSSAPI
- OM_uint32 status;
-#endif
-
- ev_io_stop ( loop, &tcp_listen_watcher );
- close ( listen_socket );
-
-#ifdef USE_GSSAPI
- if (use_gss) {
- use_gss = 0;
- gss_release_cred(&status, &server_creds);
- }
-#endif
-
- while (client_chain) {
- unsigned char ack[AUDIT_RMW_HEADER_SIZE];
-
- AUDIT_RMW_PACK_HEADER (ack, 0, AUDIT_RMW_TYPE_ENDING, 0, 0);
- client_ack (client_chain, ack, "");
- ev_io_stop (loop, &client_chain->io);
- close_client (client_chain);
- }
-
- if (config->tcp_client_max_idle)
- ev_periodic_stop (loop, &periodic_watcher);
-}
-
-static void periodic_reconfigure(struct daemon_conf *config)
-{
- struct ev_loop *loop = ev_default_loop (EVFLAG_AUTO);
- if (config->tcp_client_max_idle) {
- ev_periodic_set (&periodic_watcher, ev_now (loop),
- config->tcp_client_max_idle, NULL);
- ev_periodic_start (loop, &periodic_watcher);
- } else {
- ev_periodic_stop (loop, &periodic_watcher);
- }
-}
-
-void auditd_tcp_listen_reconfigure ( struct daemon_conf *nconf,
- struct daemon_conf *oconf )
-{
- /* Look at network things that do not need restarting */
- if (oconf->tcp_client_min_port != nconf->tcp_client_min_port ||
- oconf->tcp_client_max_port != nconf->tcp_client_max_port ||
- oconf->tcp_max_per_addr != nconf->tcp_max_per_addr) {
- oconf->tcp_client_min_port = nconf->tcp_client_min_port;
- oconf->tcp_client_max_port = nconf->tcp_client_max_port;
- oconf->tcp_max_per_addr = nconf->tcp_max_per_addr;
- auditd_set_ports(oconf->tcp_client_min_port,
- oconf->tcp_client_max_port,
- oconf->tcp_max_per_addr);
- }
- if (oconf->tcp_client_max_idle != nconf->tcp_client_max_idle) {
- oconf->tcp_client_max_idle = nconf->tcp_client_max_idle;
- periodic_reconfigure(oconf);
- }
- if (oconf->tcp_listen_port != nconf->tcp_listen_port ||
- oconf->tcp_listen_queue != nconf->tcp_listen_queue) {
- oconf->tcp_listen_port = nconf->tcp_listen_port;
- oconf->tcp_listen_queue = nconf->tcp_listen_queue;
- // FIXME: need to restart the network stuff
- }
-}
diff --git a/framework/src/audit/src/auditd-listen.h b/framework/src/audit/src/auditd-listen.h
deleted file mode 100644
index 69f9310a..00000000
--- a/framework/src/audit/src/auditd-listen.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* auditd-config.h --
- * Copyright 2004-2007 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * DJ Delorie <dj@redhat.com>
- *
- */
-
-#ifndef AUDITD_LISTEN_H
-#define AUDITD_LISTEN_H
-
-#include "ev.h"
-
-#ifdef USE_LISTENER
-int auditd_tcp_listen_init ( struct ev_loop *loop, struct daemon_conf *config );
-void auditd_tcp_listen_uninit ( struct ev_loop *loop,
- struct daemon_conf *config );
-void auditd_tcp_listen_reconfigure ( struct daemon_conf *nconf,
- struct daemon_conf *oconf );
-#else
-static inline int auditd_tcp_listen_init ( struct ev_loop *loop,
- struct daemon_conf *config )
-{
- return 0;
-}
-
-static inline void auditd_tcp_listen_uninit ( struct ev_loop *loop,
- struct daemon_conf *config )
-{
- return;
-}
-
-static inline void auditd_tcp_listen_reconfigure ( struct daemon_conf *nconf,
- struct daemon_conf *oconf )
-{
- return;
-}
-#endif /* USE_LISTENER */
-
-#endif
diff --git a/framework/src/audit/src/auditd-reconfig.c b/framework/src/audit/src/auditd-reconfig.c
deleted file mode 100644
index ac3bd030..00000000
--- a/framework/src/audit/src/auditd-reconfig.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* auditd-reconfig.c --
- * Copyright 2005 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#include "config.h"
-#include <pthread.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "libaudit.h"
-#include "auditd-event.h"
-#include "auditd-config.h"
-#include "private.h"
-
-/* This is the configuration manager code */
-static pthread_t config_thread;
-static pthread_mutex_t config_lock;
-static void *config_thread_main(void *arg);
-
-void init_config_manager(void)
-{
- pthread_mutex_init(&config_lock, NULL);
- audit_msg(LOG_DEBUG, "config_manager init complete");
-}
-
-int start_config_manager(struct auditd_reply_list *rep)
-{
- int retval, rc = 0;
-
- retval = pthread_mutex_trylock(&config_lock);
- if (retval == 0) {
- pthread_attr_t detached;
-
- pthread_attr_init(&detached);
- pthread_attr_setdetachstate(&detached,
- PTHREAD_CREATE_DETACHED);
-
- if (pthread_create(&config_thread, &detached,
- config_thread_main, rep) < 0) {
- audit_msg(LOG_ERR,
- "Couldn't create config thread, no config changes");
- free(rep);
- pthread_mutex_unlock(&config_lock);
- rc = 1;
- }
- pthread_attr_destroy(&detached);
- } else {
- audit_msg(LOG_ERR,
- "Config thread already running, no config changes");
- free(rep);
- rc = 1;
- }
- return rc;
-}
-
-void shutdown_config(void)
-{
- pthread_cancel(config_thread);
-}
-
-static void *config_thread_main(void *arg)
-{
- sigset_t sigs;
- struct auditd_reply_list *rep = (struct auditd_reply_list *)arg;
- struct daemon_conf new_config;
- extern int send_audit_event(int type, const char *str);
-
- /* This is a worker thread. Don't handle signals. */
- sigemptyset(&sigs);
- sigaddset(&sigs, SIGALRM);
- sigaddset(&sigs, SIGTERM);
- sigaddset(&sigs, SIGHUP);
- sigaddset(&sigs, SIGUSR1);
- sigaddset(&sigs, SIGUSR2);
- pthread_sigmask(SIG_SETMASK, &sigs, NULL);
-
- if (load_config(&new_config, TEST_AUDITD) == 0) {
- /* We will re-use the current reply */
- new_config.sender_uid = rep->reply.signal_info->uid;
- new_config.sender_pid = rep->reply.signal_info->pid;
- if (rep->reply.len > 24)
- new_config.sender_ctx =
- strdup(rep->reply.signal_info->ctx);
- else
- new_config.sender_ctx = strdup("?");
- memcpy(rep->reply.msg.data, &new_config, sizeof(new_config));
- rep->reply.conf = (struct daemon_conf *)rep->reply.msg.data;
- rep->reply.type = AUDIT_DAEMON_RECONFIG;
- enqueue_event(rep);
- } else {
- // need to send a failed event message
- char txt[MAX_AUDIT_MESSAGE_LENGTH];
- snprintf(txt, sizeof(txt),
- "reconfig aborted, sending auid=%u pid=%d subj=%s res=failed",
- rep->reply.signal_info->uid,
- rep->reply.signal_info->pid,
- (rep->reply.len > 24) ?
- rep->reply.signal_info->ctx : "?");
- send_audit_event(AUDIT_DAEMON_CONFIG, txt);
- free_config(&new_config);
- free(rep);
- }
-
- pthread_mutex_unlock(&config_lock);
- return NULL;
-}
-
diff --git a/framework/src/audit/src/auditd-sendmail.c b/framework/src/audit/src/auditd-sendmail.c
deleted file mode 100644
index ab0b901f..00000000
--- a/framework/src/audit/src/auditd-sendmail.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* auditd-sendmail.c --
- * Copyright 2005 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <unistd.h> // for access()
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-#include "libaudit.h"
-#include "private.h"
-#include "auditd-config.h"
-
-extern const char *email_command;
-static int safe_popen(pid_t *pid, const char *mail_acct);
-
-// returns 1 on error & 0 if OK
-int sendmail(const char *subject, const char *content, const char *mail_acct)
-{
- pid_t pid;
-
- if (access(email_command, 01) == 0)
- {
- FILE *mail;
- int fd;
-
- fd = safe_popen(&pid, mail_acct);
- if (fd < 0)
- return 1;
- mail = fdopen(fd, "w");
- if (mail == NULL) {
- kill(pid, SIGKILL);
- close(fd);
- audit_msg(LOG_ERR, "Error - starting mail");
- return 1;
- }
-
- fprintf(mail, "To: %s\n", mail_acct);
- fprintf(mail, "From: root\n");
-// fprintf(mail, "X-Sender: %s\n", mail_acct);
- fprintf(mail, "Subject: %s\n\n", subject); // End of Header
- fprintf(mail, "%s\n", content);
- fprintf(mail, ".\n\n"); // Close it up...
- fclose(mail);
- return 0;
- } else
- audit_msg(LOG_ERR, "Error - %s isn't executable",
- email_command);
- return 1;
-}
-
-static int safe_popen(pid_t *pid, const char *mail_acct)
-{
- char *argv[4];
- char acct[256];
- int pipe_fd[2];
- struct sigaction sa;
-
- if (pipe(pipe_fd)) {
- audit_msg(LOG_ALERT,
- "Audit daemon failed to create pipe while sending email alert");
- return -1;
- }
-
- *pid = fork();
- if (*pid < 0) {
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- audit_msg(LOG_ALERT,
- "Audit daemon failed to fork while sending email alert");
- return -1;
- }
- if (*pid) { /* Parent */
- close(pipe_fd[0]); // adjust pipe
- return pipe_fd[1];
- }
- /* Child */
- sigfillset (&sa.sa_mask);
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
-
- close(pipe_fd[1]); // adjust pipe
- dup2(pipe_fd[0], 0);
-
- /* Make email acct param */
- snprintf(acct, sizeof(acct), "-f%s", mail_acct);
-
- /* Stuff arg list */
- argv[0] = (char *)email_command;
- argv[1] = (char *)"-t";
- argv[2] = acct;
- argv[3] = NULL;
- execve(email_command, argv, NULL);
- audit_msg(LOG_ALERT, "Audit daemon failed to exec %s", email_command);
- exit(1);
-}
-
diff --git a/framework/src/audit/src/auditd.c b/framework/src/audit/src/auditd.c
deleted file mode 100644
index 5afebac2..00000000
--- a/framework/src/audit/src/auditd.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/* auditd.c --
- * Copyright 2004-09,2011,2013 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- * Rickard E. (Rik) Faith <faith@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <sys/utsname.h>
-#include <getopt.h>
-
-#include "libaudit.h"
-#include "auditd-event.h"
-#include "auditd-config.h"
-#include "auditd-dispatch.h"
-#include "auditd-listen.h"
-#include "private.h"
-
-#include "ev.h"
-
-#define EV_STOP() ev_unloop (ev_default_loop (EVFLAG_AUTO), EVUNLOOP_ALL), stop = 1;
-
-#define DEFAULT_BUF_SZ 448
-#define DMSG_SIZE (DEFAULT_BUF_SZ + 48)
-#define SUCCESS 0
-#define FAILURE 1
-#define SUBJ_LEN 4097
-
-/* Global Data */
-volatile int stop = 0;
-
-/* Local data */
-static int fd = -1;
-static struct daemon_conf config;
-static const char *pidfile = "/var/run/auditd.pid";
-static int init_pipe[2];
-static int do_fork = 1;
-static struct auditd_reply_list *rep = NULL;
-static int hup_info_requested = 0;
-static int usr1_info_requested = 0, usr2_info_requested = 0;
-static char subj[SUBJ_LEN];
-
-/* Local function prototypes */
-int send_audit_event(int type, const char *str);
-static void close_down(void);
-static void clean_exit(void);
-static int get_reply(int fd, struct audit_reply *rep, int seq);
-static char *getsubj(char *subj);
-
-enum startup_state {startup_disable=0, startup_enable, startup_nochange,
- startup_INVALID};
-static const char *startup_states[] = {"disable", "enable", "nochange"};
-
-/*
- * Output a usage message
- */
-static void usage(void)
-{
- fprintf(stderr, "Usage: auditd [-f] [-l] [-n] [-s %s|%s|%s]\n",
- startup_states[startup_disable],
- startup_states[startup_enable],
- startup_states[startup_nochange]);
-
- exit(2);
-}
-
-
-/*
- * SIGTERM handler
- */
-static void term_handler(struct ev_loop *loop, struct ev_signal *sig,
- int revents)
-{
- EV_STOP ();
-}
-
-/*
- * Used with sigalrm to force exit
- */
-static void thread_killer( int sig )
-{
- exit(0);
-}
-
-/*
- * Used with sigalrm to force exit
- */
-static void hup_handler( struct ev_loop *loop, struct ev_signal *sig, int revents )
-{
- int rc;
-
- rc = audit_request_signal_info(fd);
- if (rc < 0)
- send_audit_event(AUDIT_DAEMON_CONFIG,
- "auditd error getting hup info - no change, sending auid=? pid=? subj=? res=failed");
- else
- hup_info_requested = 1;
-}
-
-/*
- * Used to force log rotation
- */
-static void user1_handler(struct ev_loop *loop, struct ev_signal *sig,
- int revents)
-{
- int rc;
-
- rc = audit_request_signal_info(fd);
- if (rc < 0)
- send_audit_event(AUDIT_DAEMON_ROTATE,
- "auditd error getting usr1 info - no change, sending auid=? pid=? subj=? res=failed");
- else
- usr1_info_requested = 1;
-}
-
-/*
- * Used to resume logging
- */
-static void user2_handler( struct ev_loop *loop, struct ev_signal *sig, int revents )
-{
- int rc;
-
- rc = audit_request_signal_info(fd);
- if (rc < 0) {
- resume_logging();
- send_audit_event(AUDIT_DAEMON_RESUME,
- "auditd resuming logging, sending auid=? pid=? subj=? res=success");
- } else
- usr2_info_requested = 1;
-}
-
-/*
- * Used with email alerts to cleanup
- */
-static void child_handler(struct ev_loop *loop, struct ev_signal *sig,
- int revents)
-{
- int pid;
-
- while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
- if (pid == dispatcher_pid())
- dispatcher_reaped();
- }
-}
-
-static void distribute_event(struct auditd_reply_list *rep)
-{
- int attempt = 0;
-
- /* Make first attempt to send to plugins */
- if (dispatch_event(&rep->reply, attempt) == 1)
- attempt++; /* Failed sending, retry after writing to disk */
-
- /* End of Event is for realtime interface - skip local logging of it */
- if (rep->reply.type != AUDIT_EOE) {
- int yield = rep->reply.type <= AUDIT_LAST_DAEMON &&
- rep->reply.type >= AUDIT_FIRST_DAEMON ? 1 : 0;
- /* Write to local disk */
- enqueue_event(rep);
- if (yield) {
- struct timespec ts;
- ts.tv_sec = 0;
- ts.tv_nsec = 2 * 1000 * 1000; // 2 milliseconds
- nanosleep(&ts, NULL); // Let other thread try to log it
- }
- } else
- free(rep); // This function takes custody of the memory
-
- // FIXME: This is commented out since it fails to work. The
- // problem is that the logger thread free's the buffer. Probably
- // need a way to flag in the buffer if logger thread should free or
- // move the free to this function.
-
- /* Last chance to send...maybe the pipe is empty now. */
-// if (attempt)
-// dispatch_event(&rep->reply, attempt);
-}
-
-/*
- * This function is used to send start, stop, and abort messages
- * to the audit log.
- */
-static unsigned seq_num = 0;
-int send_audit_event(int type, const char *str)
-{
- struct auditd_reply_list *rep;
- struct timeval tv;
-
- if ((rep = malloc(sizeof(*rep))) == NULL) {
- audit_msg(LOG_ERR, "Cannot allocate audit reply");
- return 1;
- }
-
- rep->reply.type = type;
- rep->reply.message = (char *)malloc(DMSG_SIZE);
- if (rep->reply.message == NULL) {
- free(rep);
- audit_msg(LOG_ERR, "Cannot allocate local event message");
- return 1;
- }
- if (seq_num == 0) {
- srand(time(NULL));
- seq_num = rand()%10000;
- } else
- seq_num++;
- if (gettimeofday(&tv, NULL) == 0) {
- rep->reply.len = snprintf((char *)rep->reply.message,
- DMSG_SIZE, "audit(%lu.%03u:%u): %s",
- tv.tv_sec, (unsigned)(tv.tv_usec/1000), seq_num, str);
- } else {
- rep->reply.len = snprintf((char *)rep->reply.message,
- DMSG_SIZE, "audit(%lu.%03u:%u): %s",
- (unsigned long)time(NULL), 0, seq_num, str);
- }
- if (rep->reply.len > DMSG_SIZE)
- rep->reply.len = DMSG_SIZE;
-
- distribute_event(rep);
- return 0;
-}
-
-static int write_pid_file(void)
-{
- int pidfd, len;
- char val[16];
-
- len = snprintf(val, sizeof(val), "%u\n", getpid());
- if (len <= 0) {
- audit_msg(LOG_ERR, "Pid error (%s)", strerror(errno));
- pidfile = 0;
- return 1;
- }
- pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
- if (pidfd < 0) {
- audit_msg(LOG_ERR, "Unable to set pidfile (%s)",
- strerror(errno));
- pidfile = 0;
- return 1;
- }
- if (write(pidfd, val, (unsigned int)len) != len) {
- audit_msg(LOG_ERR, "Unable to write pidfile (%s)",
- strerror(errno));
- close(pidfd);
- pidfile = 0;
- return 1;
- }
- close(pidfd);
- return 0;
-}
-
-static void avoid_oom_killer(void)
-{
- int oomfd, len, rc;
- char *score = NULL;
-
- /* New kernels use different technique */
- if ((oomfd = open("/proc/self/oom_score_adj",
- O_NOFOLLOW | O_WRONLY)) >= 0) {
- score = "-1000";
- } else if ((oomfd = open("/proc/self/oom_adj",
- O_NOFOLLOW | O_WRONLY)) >= 0) {
- score = "-17";
- } else {
- audit_msg(LOG_NOTICE, "Cannot open out of memory adjuster");
- return;
- }
-
- len = strlen(score);
- rc = write(oomfd, score, len);
- if (rc != len)
- audit_msg(LOG_NOTICE, "Unable to adjust out of memory score");
-
- close(oomfd);
-}
-
-/*
- * This function will take care of becoming a daemon. The parent
- * will wait until the child notifies it by writing into a special
- * pipe to signify that it successfully initialized. This prevents
- * a race in the init script where rules get loaded before the daemon
- * is ready and they wind up in syslog. The child returns 0 on success
- * and nonzero on failure. The parent returns nonzero on failure. On
- * success, the parent calls _exit with 0.
- */
-static int become_daemon(void)
-{
- int fd, rc;
- pid_t pid;
- int status;
-
- if (do_fork) {
- if (pipe(init_pipe) ||
- fcntl(init_pipe[0], F_SETFD, FD_CLOEXEC) ||
- fcntl(init_pipe[0], F_SETFD, FD_CLOEXEC))
- return -1;
- pid = fork();
- } else
- pid = 0;
-
- switch (pid)
- {
- case 0:
- /* No longer need this... */
- if (do_fork)
- close(init_pipe[0]);
-
- /* Open stdin,out,err to /dev/null */
- fd = open("/dev/null", O_RDWR);
- if (fd < 0) {
- audit_msg(LOG_ERR, "Cannot open /dev/null");
- return -1;
- }
- if ((dup2(fd, 0) < 0) || (dup2(fd, 1) < 0) ||
- (dup2(fd, 2) < 0)) {
- audit_msg(LOG_ERR,
- "Cannot reassign descriptors to /dev/null");
- close(fd);
- return -1;
- }
- close(fd);
-
- /* Change to '/' */
- rc = chdir("/");
- if (rc < 0) {
- audit_msg(LOG_ERR,
- "Cannot change working directory to /");
- return -1;
- }
-
- /* Become session/process group leader */
- setsid();
- break;
- case -1:
- return -1;
- break;
- default:
- /* Wait for the child to say its done */
- rc = read(init_pipe[0], &status, sizeof(status));
- if (rc < 0)
- return -1;
-
- /* Success - die a happy death */
- if (status == SUCCESS)
- _exit(0);
- else
- return -1;
- break;
- }
-
- return 0;
-}
-
-static void tell_parent(int status)
-{
- int rc;
-
- if (config.daemonize != D_BACKGROUND || do_fork == 0)
- return;
- do {
- rc = write(init_pipe[1], &status, sizeof(status));
- } while (rc < 0 && errno == EINTR);
-}
-
-static void netlink_handler(struct ev_loop *loop, struct ev_io *io,
- int revents)
-{
- if (rep == NULL) {
- if ((rep = malloc(sizeof(*rep))) == NULL) {
- char emsg[DEFAULT_BUF_SZ];
- if (*subj)
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d subj=%s res=failed",
- audit_getloginuid(), getpid(), subj);
- else
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d res=failed",
- audit_getloginuid(), getpid());
- EV_STOP ();
- send_audit_event(AUDIT_DAEMON_ABORT, emsg);
- audit_msg(LOG_ERR,
- "Cannot allocate audit reply, exiting");
- close_down();
- if (pidfile)
- unlink(pidfile);
- shutdown_dispatcher();
- return;
- }
- }
- if (audit_get_reply(fd, &rep->reply,
- GET_REPLY_NONBLOCKING, 0) > 0) {
- switch (rep->reply.type)
- { /* For now dont process these */
- case NLMSG_NOOP:
- case NLMSG_DONE:
- case NLMSG_ERROR:
- case AUDIT_GET: /* Or these */
- case AUDIT_LIST_RULES:
- case AUDIT_FIRST_DAEMON...AUDIT_LAST_DAEMON:
- break;
- case AUDIT_SIGNAL_INFO:
- if (hup_info_requested) {
- audit_msg(LOG_DEBUG,
- "HUP detected, starting config manager");
- if (start_config_manager(rep)) {
- send_audit_event(
- AUDIT_DAEMON_CONFIG,
- "auditd error getting hup info - no change,"
- " sending auid=? pid=? subj=? res=failed");
- }
- rep = NULL;
- hup_info_requested = 0;
- } else if (usr1_info_requested) {
- char usr1[MAX_AUDIT_MESSAGE_LENGTH];
- if (rep->reply.len == 24) {
- snprintf(usr1, sizeof(usr1),
- "auditd sending auid=? pid=? subj=?");
- } else {
- snprintf(usr1, sizeof(usr1),
- "auditd sending auid=%u pid=%d subj=%s",
- rep->reply.signal_info->uid,
- rep->reply.signal_info->pid,
- rep->reply.signal_info->ctx);
- }
- send_audit_event(AUDIT_DAEMON_ROTATE, usr1);
- usr1_info_requested = 0;
- } else if (usr2_info_requested) {
- char usr2[MAX_AUDIT_MESSAGE_LENGTH];
- if (rep->reply.len == 24) {
- snprintf(usr2, sizeof(usr2),
- "auditd resuming logging, "
- "sending auid=? pid=? subj=? "
- "res=success");
- } else {
- snprintf(usr2, sizeof(usr2),
- "auditd resuming logging, "
- "sending auid=%u pid=%d subj=%s res=success",
- rep->reply.signal_info->uid,
- rep->reply.signal_info->pid,
- rep->reply.signal_info->ctx);
- }
- resume_logging();
- send_audit_event(AUDIT_DAEMON_RESUME, usr2);
- usr2_info_requested = 0;
- }
- break;
- default:
- distribute_event(rep);
- rep = NULL;
- break;
- }
- } else {
- if (errno == EFBIG) {
- // FIXME do err action
- }
- }
-}
-
-int main(int argc, char *argv[])
-{
- struct sigaction sa;
- struct rlimit limit;
- int i, c, rc;
- int opt_foreground = 0, opt_allow_links = 0;
- enum startup_state opt_startup = startup_enable;
- extern char *optarg;
- extern int optind;
- struct ev_loop *loop;
- struct ev_io netlink_watcher;
- struct ev_signal sigterm_watcher;
- struct ev_signal sighup_watcher;
- struct ev_signal sigusr1_watcher;
- struct ev_signal sigusr2_watcher;
- struct ev_signal sigchld_watcher;
-
- /* Get params && set mode */
- while ((c = getopt(argc, argv, "flns:")) != -1) {
- switch (c) {
- case 'f':
- opt_foreground = 1;
- break;
- case 'l':
- opt_allow_links=1;
- break;
- case 'n':
- do_fork = 0;
- break;
- case 's':
- for (i=0; i<startup_INVALID; i++) {
- if (strncmp(optarg, startup_states[i],
- strlen(optarg)) == 0) {
- opt_startup = i;
- break;
- }
- }
- if (i == startup_INVALID) {
- fprintf(stderr, "unknown startup mode '%s'\n",
- optarg);
- usage();
- }
- break;
- default:
- usage();
- }
- }
-
- /* check for trailing command line following options */
- if (optind < argc) {
- usage();
- }
-
- if (opt_allow_links)
- set_allow_links(1);
-
- if (opt_foreground) {
- config.daemonize = D_FOREGROUND;
- set_aumessage_mode(MSG_STDERR, DBG_YES);
- } else {
- config.daemonize = D_BACKGROUND;
- set_aumessage_mode(MSG_SYSLOG, DBG_NO);
- (void) umask( umask( 077 ) | 022 );
- }
-
-#ifndef DEBUG
- /* Make sure we are root */
- if (getuid() != 0) {
- fprintf(stderr, "You must be root to run this program.\n");
- return 4;
- }
-#endif
-
- /* Register sighandlers */
- sa.sa_flags = 0 ;
- sigemptyset( &sa.sa_mask ) ;
- /* Ignore all signals by default */
- sa.sa_handler = SIG_IGN;
- for (i=1; i<NSIG; i++)
- sigaction( i, &sa, NULL );
-
- atexit(clean_exit);
-
- /* Raise the rlimits in case we're being started from a shell
- * with restrictions. Not a fatal error. */
- limit.rlim_cur = RLIM_INFINITY;
- limit.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_FSIZE, &limit);
- setrlimit(RLIMIT_CPU, &limit);
-
- /* Load the Configuration File */
- if (load_config(&config, TEST_AUDITD))
- return 6;
-
- if (config.priority_boost != 0) {
- errno = 0;
- rc = nice((int)-config.priority_boost);
- if (rc == -1 && errno) {
- audit_msg(LOG_ERR, "Cannot change priority (%s)",
- strerror(errno));
- return 1;
- }
- }
-
- /* Daemonize or stay in foreground for debugging */
- if (config.daemonize == D_BACKGROUND) {
- if (become_daemon() != 0) {
- audit_msg(LOG_ERR, "Cannot daemonize (%s)",
- strerror(errno));
- tell_parent(FAILURE);
- return 1;
- }
- openlog("auditd", LOG_PID, LOG_DAEMON);
- }
-
- /* Init netlink */
- if ((fd = audit_open()) < 0) {
- audit_msg(LOG_ERR, "Cannot open netlink audit socket");
- tell_parent(FAILURE);
- return 1;
- }
-
- /* Init the event handler thread */
- write_pid_file();
- if (init_event(&config)) {
- if (pidfile)
- unlink(pidfile);
- tell_parent(FAILURE);
- return 1;
- }
-
- if (init_dispatcher(&config)) {
- if (pidfile)
- unlink(pidfile);
- tell_parent(FAILURE);
- return 1;
- }
-
- /* Get machine name ready for use */
- if (resolve_node(&config)) {
- if (pidfile)
- unlink(pidfile);
- tell_parent(FAILURE);
- return 1;
- }
-
- /* Write message to log that we are alive */
- {
- struct utsname ubuf;
- char start[DEFAULT_BUF_SZ];
- const char *fmt = audit_lookup_format((int)config.log_format);
- if (fmt == NULL)
- fmt = "UNKNOWN";
- if (uname(&ubuf) != 0) {
- if (pidfile)
- unlink(pidfile);
- tell_parent(FAILURE);
- return 1;
- }
- if (getsubj(subj))
- snprintf(start, sizeof(start),
- "auditd start, ver=%s format=%s "
- "kernel=%.56s auid=%u pid=%d subj=%s res=success",
- VERSION, fmt, ubuf.release,
- audit_getloginuid(), getpid(), subj);
- else
- snprintf(start, sizeof(start),
- "auditd start, ver=%s format=%s "
- "kernel=%.56s auid=%u pid=%d res=success",
- VERSION, fmt, ubuf.release,
- audit_getloginuid(), getpid());
- if (send_audit_event(AUDIT_DAEMON_START, start)) {
- audit_msg(LOG_ERR, "Cannot send start message");
- if (pidfile)
- unlink(pidfile);
- shutdown_dispatcher();
- tell_parent(FAILURE);
- return 1;
- }
- }
-
- /* Tell kernel not to kill us */
- avoid_oom_killer();
-
- /* let config manager init */
- init_config_manager();
-
- if (opt_startup != startup_nochange && (audit_is_enabled(fd) < 2) &&
- audit_set_enabled(fd, (int)opt_startup) < 0) {
- char emsg[DEFAULT_BUF_SZ];
- if (*subj)
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d subj=%s res=failed",
- audit_getloginuid(), getpid(), subj);
- else
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d res=failed",
- audit_getloginuid(), getpid());
- stop = 1;
- send_audit_event(AUDIT_DAEMON_ABORT, emsg);
- audit_msg(LOG_ERR,
- "Unable to set initial audit startup state to '%s', exiting",
- startup_states[opt_startup]);
- close_down();
- if (pidfile)
- unlink(pidfile);
- shutdown_dispatcher();
- tell_parent(FAILURE);
- return 1;
- }
-
- /* Tell the kernel we are alive */
- if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) {
- char emsg[DEFAULT_BUF_SZ];
- if (*subj)
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d subj=%s res=failed",
- audit_getloginuid(), getpid(), subj);
- else
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d res=failed",
- audit_getloginuid(), getpid());
- stop = 1;
- send_audit_event(AUDIT_DAEMON_ABORT, emsg);
- audit_msg(LOG_ERR, "Unable to set audit pid, exiting");
- close_down();
- if (pidfile)
- unlink(pidfile);
- shutdown_dispatcher();
- tell_parent(FAILURE);
- return 1;
- }
-
- /* Depending on value of opt_startup (-s) set initial audit state */
- loop = ev_default_loop (EVFLAG_NOENV);
-
- ev_io_init (&netlink_watcher, netlink_handler, fd, EV_READ);
- ev_io_start (loop, &netlink_watcher);
-
- ev_signal_init (&sigterm_watcher, term_handler, SIGTERM);
- ev_signal_start (loop, &sigterm_watcher);
-
- ev_signal_init (&sighup_watcher, hup_handler, SIGHUP);
- ev_signal_start (loop, &sighup_watcher);
-
- ev_signal_init (&sigusr1_watcher, user1_handler, SIGUSR1);
- ev_signal_start (loop, &sigusr1_watcher);
-
- ev_signal_init (&sigusr2_watcher, user2_handler, SIGUSR2);
- ev_signal_start (loop, &sigusr2_watcher);
-
- ev_signal_init (&sigchld_watcher, child_handler, SIGCHLD);
- ev_signal_start (loop, &sigchld_watcher);
-
- if (auditd_tcp_listen_init (loop, &config)) {
- char emsg[DEFAULT_BUF_SZ];
- if (*subj)
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d subj=%s res=failed",
- audit_getloginuid(), getpid(), subj);
- else
- snprintf(emsg, sizeof(emsg),
- "auditd error halt, auid=%u pid=%d res=failed",
- audit_getloginuid(), getpid());
- stop = 1;
- send_audit_event(AUDIT_DAEMON_ABORT, emsg);
- tell_parent(FAILURE);
- } else {
- /* Now tell parent that everything went OK */
- tell_parent(SUCCESS);
- audit_msg(LOG_NOTICE,
- "Init complete, auditd %s listening for events (startup state %s)",
- VERSION,
- startup_states[opt_startup]);
- }
-
- /* Parent should be gone by now... */
- if (do_fork)
- close(init_pipe[1]);
-
- // Init complete, start event loop
- if (!stop)
- ev_loop (loop, 0);
-
- auditd_tcp_listen_uninit (loop, &config);
-
- // Tear down IO watchers Part 1
- ev_signal_stop (loop, &sighup_watcher);
- ev_signal_stop (loop, &sigusr1_watcher);
- ev_signal_stop (loop, &sigusr2_watcher);
- ev_signal_stop (loop, &sigterm_watcher);
-
- /* Write message to log that we are going down */
- rc = audit_request_signal_info(fd);
- if (rc > 0) {
- struct audit_reply trep;
-
- rc = get_reply(fd, &trep, rc);
- if (rc > 0) {
- char txt[MAX_AUDIT_MESSAGE_LENGTH];
- snprintf(txt, sizeof(txt),
- "auditd normal halt, sending auid=%u "
- "pid=%d subj=%s res=success",
- trep.signal_info->uid,
- trep.signal_info->pid,
- trep.signal_info->ctx);
- send_audit_event(AUDIT_DAEMON_END, txt);
- }
- }
- if (rc <= 0)
- send_audit_event(AUDIT_DAEMON_END,
- "auditd normal halt, sending auid=? "
- "pid=? subj=? res=success");
- free(rep);
-
- // Tear down IO watchers Part 2
- ev_io_stop (loop, &netlink_watcher);
-
- // Give DAEMON_END event a little time to be sent in case
- // of remote logging
- usleep(10000); // 10 milliseconds
- shutdown_dispatcher();
-
- // Tear down IO watchers Part 3
- ev_signal_stop (loop, &sigchld_watcher);
-
- close_down();
- free_config(&config);
- ev_default_destroy();
-
- return 0;
-}
-
-static void close_down(void)
-{
- struct sigaction sa;
-
- /* We are going down. Give the event thread a chance to shutdown.
- Just in case it hangs, set a timer to get us out of trouble. */
- sa.sa_flags = 0 ;
- sigemptyset( &sa.sa_mask ) ;
- sa.sa_handler = thread_killer;
- sigaction( SIGALRM, &sa, NULL );
- shutdown_events();
-}
-
-
-/*
- * A clean exit means :
- * 1) we log that we are going down
- * 2) deregister with kernel
- * 3) close the netlink socket
- */
-static void clean_exit(void)
-{
- audit_msg(LOG_INFO, "The audit daemon is exiting.");
- if (fd >= 0) {
- audit_set_pid(fd, 0, WAIT_NO);
- audit_close(fd);
- }
- if (pidfile)
- unlink(pidfile);
- closelog();
-}
-
-/*
- * This function is used to get the reply for term info.
- * Returns 1 on success & -1 on failure.
- */
-static int get_reply(int fd, struct audit_reply *rep, int seq)
-{
- int rc, i;
- int timeout = 30; /* tenths of seconds */
-
- for (i = 0; i < timeout; i++) {
- struct timeval t;
- fd_set read_mask;
-
- t.tv_sec = 0;
- t.tv_usec = 100000; /* .1 second */
- FD_ZERO(&read_mask);
- FD_SET(fd, &read_mask);
- do {
- rc = select(fd+1, &read_mask, NULL, NULL, &t);
- } while (rc < 0 && errno == EINTR);
- rc = audit_get_reply(fd, rep,
- GET_REPLY_NONBLOCKING, 0);
- if (rc > 0) {
- /* Don't make decisions based on wrong packet */
- if (rep->nlh->nlmsg_seq != seq)
- continue;
-
- /* If its not what we are expecting, keep looping */
- if (rep->type == AUDIT_SIGNAL_INFO)
- return 1;
-
- /* If we get done or error, break out */
- if (rep->type == NLMSG_DONE || rep->type == NLMSG_ERROR)
- break;
- }
- }
- return -1;
-}
-
-//get the subj of the daemon
-static char *getsubj(char *subj)
-{
- pid_t pid = getpid();
- char filename[48];
- ssize_t num_read;
- int fd;
-
- snprintf(filename, sizeof(filename), "/proc/%u/attr/current", pid);
- fd = open(filename, O_RDONLY);
- if(fd == -1) {
- subj[0] = 0;
- return NULL;
- }
- do {
- num_read = read(fd, subj, SUBJ_LEN-1);
- } while (num_read < 0 && errno == EINTR);
- close(fd);
- if(num_read <= 0) {
- subj[0] = 0;
- return NULL;
- }
- subj[num_read] = '\0';
- return subj;
-}
-
diff --git a/framework/src/audit/src/aureport-options.c b/framework/src/audit/src/aureport-options.c
deleted file mode 100644
index 7508417f..00000000
--- a/framework/src/audit/src/aureport-options.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/* aureport-options.c - parse commandline options and configure aureport
- * Copyright 2005-08,2010-11,2014 Red Hat Inc., Durham, North Carolina.
- * Copyright (c) 2011 IBM Corp.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- * Marcelo Henrique Cerri <mhcerri@br.ibm.com>
- */
-
-#include "config.h"
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
-#include <time.h>
-#include "aureport-options.h"
-#include "ausearch-time.h"
-#include "libaudit.h"
-
-
-/* Global vars that will be accessed by the main program */
-char *user_file = NULL;
-int force_logs = 0;
-int no_config = 0;
-
-/* These are for compatibility with parser */
-unsigned int event_id = -1;
-uid_t event_uid = -1, event_loginuid = -2, event_euid = -1;
-gid_t event_gid = -1, event_egid = -1;
-slist *event_node_list = NULL;
-const char *event_key = NULL;
-const char *event_filename = NULL;
-const char *event_exe = NULL;
-const char *event_comm = NULL;
-const char *event_hostname = NULL;
-const char *event_terminal = NULL;
-const char *event_subject = NULL;
-const char *event_object = NULL;
-const char *event_uuid = NULL;
-const char *event_vmname = NULL;
-long long event_exit = 0;
-int event_exit_is_set = 0;
-int event_ppid = -1, event_session_id = -2;
-int event_debug = 0, event_machine = -1;
-
-/* These are used by aureport */
-const char *dummy = "dummy";
-report_type_t report_type = RPT_UNSET;
-report_det_t report_detail = D_UNSET;
-report_t report_format = RPT_DEFAULT;
-failed_t event_failed = F_BOTH;
-conf_act_t event_conf_act = C_NEITHER;
-success_t event_success = S_SUCCESS;
-int event_pid = 0;
-
-struct nv_pair {
- int value;
- const char *name;
-};
-
-enum { R_INFILE, R_TIME_END, R_TIME_START, R_VERSION, R_SUMMARY, R_LOG_TIMES,
- R_CONFIGS, R_LOGINS, R_USERS, R_TERMINALS, R_HOSTS, R_EXES, R_FILES,
- R_AVCS, R_SYSCALLS, R_PIDS, R_EVENTS, R_ACCT_MODS,
- R_INTERPRET, R_HELP, R_ANOMALY, R_RESPONSE, R_SUMMARY_DET, R_CRYPTO,
- R_MAC, R_FAILED, R_SUCCESS, R_ADD, R_DEL, R_AUTH, R_NODE, R_IN_LOGS,
- R_KEYS, R_TTY, R_NO_CONFIG, R_COMM, R_VIRT, R_INTEG };
-
-static struct nv_pair optiontab[] = {
- { R_AUTH, "-au" },
- { R_AUTH, "--auth" },
- { R_AVCS, "-a" },
- { R_AVCS, "--avc" },
- { R_ADD, "--add" },
- { R_CONFIGS, "-c" },
- { R_COMM, "--comm" },
- { R_CONFIGS, "--config" },
- { R_CRYPTO, "-cr" },
- { R_CRYPTO, "--crypto" },
- { R_DEL, "--delete" },
- { R_EVENTS, "-e" },
- { R_EVENTS, "--event" },
- { R_FILES, "-f" },
- { R_FILES, "--file" },
- { R_FAILED, "--failed" },
- { R_HOSTS, "-h" },
- { R_HOSTS, "--host" },
- { R_HELP, "--help" },
- { R_INTERPRET, "-i" },
- { R_INTERPRET, "--interpret" },
- { R_INFILE, "-if" },
- { R_INFILE, "--input" },
- { R_IN_LOGS, "--input-logs" },
- { R_INTEG, "--integrity" },
- { R_KEYS, "-k" },
- { R_KEYS, "--key" },
- { R_LOGINS, "-l" },
- { R_LOGINS, "--login" },
- { R_ACCT_MODS, "-m" },
- { R_ACCT_MODS, "--mods" },
- { R_MAC, "-ma" },
- { R_MAC, "--mac" },
- { R_NODE, "--node" },
- { R_NO_CONFIG, "-nc" },
- { R_NO_CONFIG, "--no-config" },
- { R_ANOMALY, "-n" },
- { R_ANOMALY, "--anomaly" },
- { R_PIDS, "-p" },
- { R_PIDS, "--pid" },
- { R_RESPONSE, "-r" },
- { R_RESPONSE, "--response" },
- { R_SYSCALLS, "-s" },
- { R_SYSCALLS, "--syscall" },
- { R_SUCCESS, "--success" },
- { R_SUMMARY_DET, "--summary" },
- { R_LOG_TIMES, "-t" },
- { R_LOG_TIMES, "--log" },
- { R_TIME_END, "-te"},
- { R_TIME_END, "--end"},
- { R_TERMINALS, "-tm"}, // don't like this
- { R_TERMINALS, "--terminal"}, // don't like this
- { R_TIME_START, "-ts" },
- { R_TTY, "--tty" },
- { R_TIME_START, "--start" },
- { R_USERS, "-u" },
- { R_USERS, "--user" },
- { R_VERSION, "-v" },
- { R_VERSION, "--version" },
- { R_EXES, "-x" },
- { R_EXES, "--executable" },
- { R_VIRT, "--virt" }
-};
-#define OPTION_NAMES (sizeof(optiontab)/sizeof(optiontab[0]))
-
-
-static int audit_lookup_option(const char *name)
-{
- int i;
-
- for (i = 0; i < OPTION_NAMES; i++)
- if (!strcmp(optiontab[i].name, name))
- return optiontab[i].value;
- return -1;
-}
-
-static void usage(void)
-{
- printf("usage: aureport [options]\n"
- "\t-a,--avc\t\t\tAvc report\n"
- "\t-au,--auth\t\t\tAuthentication report\n"
- "\t--comm\t\t\t\tCommands run report\n"
- "\t-c,--config\t\t\tConfig change report\n"
- "\t-cr,--crypto\t\t\tCrypto report\n"
- "\t-e,--event\t\t\tEvent report\n"
- "\t-f,--file\t\t\tFile name report\n"
- "\t--failed\t\t\tonly failed events in report\n"
- "\t-h,--host\t\t\tRemote Host name report\n"
- "\t--help\t\t\t\thelp\n"
- "\t-i,--interpret\t\t\tInterpretive mode\n"
- "\t-if,--input <Input File name>\tuse this file as input\n"
- "\t--input-logs\t\t\tUse the logs even if stdin is a pipe\n"
- "\t--integrity\t\t\tIntegrity event report\n"
- "\t-l,--login\t\t\tLogin report\n"
- "\t-k,--key\t\t\tKey report\n"
- "\t-m,--mods\t\t\tModification to accounts report\n"
- "\t-ma,--mac\t\t\tMandatory Access Control (MAC) report\n"
- "\t-n,--anomaly\t\t\taNomaly report\n"
- "\t-nc,--no-config\t\t\tDon't include config events\n"
- "\t--node <node name>\t\tOnly events from a specific node\n"
- "\t-p,--pid\t\t\tPid report\n"
- "\t-r,--response\t\t\tResponse to anomaly report\n"
- "\t-s,--syscall\t\t\tSyscall report\n"
- "\t--success\t\t\tonly success events in report\n"
- "\t--summary\t\t\tsorted totals for main object in report\n"
- "\t-t,--log\t\t\tLog time range report\n"
- "\t-te,--end [end date] [end time]\tending date & time for reports\n"
- "\t-tm,--terminal\t\t\tTerMinal name report\n"
- "\t-ts,--start [start date] [start time]\tstarting data & time for reports\n"
- "\t--tty\t\t\t\tReport about tty keystrokes\n"
- "\t-u,--user\t\t\tUser name report\n"
- "\t-v,--version\t\t\tVersion\n"
- "\t--virt\t\t\t\tVirtualization report\n"
- "\t-x,--executable\t\t\teXecutable name report\n"
- "\tIf no report is given, the summary report will be displayed\n"
- );
-}
-
-static int set_report(report_type_t r)
-{
- if (report_type == RPT_UNSET) {
- report_type = r;
- return 0;
- } else {
- fprintf(stderr, "Error - only one report can be specified");
- return 1;
- }
-}
-
-static int set_detail(report_det_t d)
-{
- if (report_detail == D_UNSET) {
- report_detail = d;
- return 0;
- } else if (d == D_SUM) {
- report_detail = d;
- return 0;
- } else {
- return 1;
- }
-}
-
-/*
- * This function examines the commandline parameters and sets various
- * search options. It returns a 0 on success and < 0 on failure
- */
-int check_params(int count, char *vars[])
-{
- int c = 1;
- int retval = 0;
- const char *optarg;
-
- while (c < count && retval == 0) {
- // Go ahead and point to the next argument
- if (c+1 < count) {
- if (vars[c+1][0] != '-')
- optarg = vars[c+1];
- else
- optarg = NULL;
- } else
- optarg = NULL;
-
- switch (audit_lookup_option(vars[c])) {
- case R_INFILE:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- user_file = strdup(optarg);
- if (user_file == NULL)
- retval = -1;
- c++;
- }
- break;
- case R_LOG_TIMES:
- if (set_report(RPT_TIME))
- retval = -1;
- else
- set_detail(D_DETAILED);
- break;
- case R_AVCS:
- if (set_report(RPT_AVC))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_comm = dummy;
- event_subject = dummy;
- event_object = dummy;
- }
- break;
- case R_AUTH:
- if (set_report(RPT_AUTH))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_exe = dummy;
- event_hostname = dummy;
- event_terminal = dummy;
- event_uid = 1;
- }
- break;
- case R_MAC:
- if (set_report(RPT_MAC))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_loginuid = 1;
- }
- break;
- case R_INTEG:
- if (set_report(RPT_INTEG))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_loginuid = 1;
- }
- break;
- case R_VIRT:
- if (set_report(RPT_VIRT))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- }
- break;
- case R_CONFIGS:
- if (set_report(RPT_CONFIG))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_loginuid = 1;
- }
- break;
- case R_CRYPTO:
- if (set_report(RPT_CRYPTO))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_loginuid = 1;
- }
- break;
- case R_LOGINS:
- if (set_report(RPT_LOGIN))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_exe = dummy;
- event_hostname = dummy;
- event_terminal = dummy;
- event_loginuid = 1;
- }
- break;
- case R_ACCT_MODS:
- if (set_report(RPT_ACCT_MOD))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_exe = dummy;
- event_hostname = dummy;
- event_terminal = dummy;
- event_loginuid = 1;
- }
- break;
- case R_EVENTS:
- if (set_report(RPT_EVENT))
- retval = -1;
- else {
-// if (!optarg) {
- set_detail(D_DETAILED);
- event_loginuid = 1;
-// } else {
-// UNIMPLEMENTED;
-// set_detail(D_SPECIFIC);
-// if (isdigit(optarg[0])) {
-// errno = 0;
-// event_id = strtoul(optarg,
-// NULL, 10);
-// if (errno) {
-// fprintf(stderr,
-// "Illegal value for audit event ID");
-// retval = -1;
-// }
-// c++;
-// } else {
-// fprintf(stderr,
-// "Audit event id must be a numeric value, was %s\n",
-// optarg);
-// retval = -1;
-// }
-// }
- }
- break;
- case R_FILES:
- if (set_report(RPT_FILE))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_filename = dummy;
- event_exe = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_HOSTS:
- if (set_report(RPT_HOST))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_hostname = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_INTERPRET:
- report_format = RPT_INTERP;
- if (optarg) {
- fprintf(stderr,
- "Argument is NOT required for %s\n",
- vars[c]);
- retval = -1;
- }
- break;
- case R_PIDS:
- if (set_report(RPT_PID))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_exe = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_SYSCALLS:
- if (set_report(RPT_SYSCALL))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_comm = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_TERMINALS:
- if (set_report(RPT_TERM))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_terminal = dummy;
- event_hostname = dummy;
- event_exe = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_USERS:
- if (set_report(RPT_USER))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_terminal = dummy;
- event_hostname = dummy;
- event_exe = dummy;
- event_uid = 1;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_EXES:
- if (set_report(RPT_EXE))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_terminal = dummy;
- event_hostname = dummy;
- event_exe = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_COMM:
- if (set_report(RPT_COMM))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_terminal = dummy;
- event_hostname = dummy;
- event_comm = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_ANOMALY:
- if (set_report(RPT_ANOMALY))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_terminal = dummy;
- event_hostname = dummy;
- event_exe = dummy;
- event_comm = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_RESPONSE:
- if (set_report(RPT_RESPONSE))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_KEYS:
- if (set_report(RPT_KEY))
- retval = -1;
- else {
- if (!optarg) {
- set_detail(D_DETAILED);
- event_exe = dummy;
- event_key = dummy;
- event_loginuid = 1;
- } else {
- UNIMPLEMENTED;
- }
- }
- break;
- case R_TTY:
- if (set_report(RPT_TTY))
- retval = -1;
- else {
- set_detail(D_DETAILED);
- event_session_id = 1;
- event_loginuid = 1;
- event_terminal = dummy;
- event_comm = dummy;
- }
- break;
- case R_TIME_END:
- if (optarg) {
- if ( (c+2 < count) && vars[c+2] &&
- (vars[c+2][0] != '-') ) {
- /* Have both date and time - check order*/
- if (strchr(optarg, ':')) {
- if (ausearch_time_end(vars[c+2],
- optarg) != 0)
- retval = -1;
- } else {
- if (ausearch_time_end(optarg,
- vars[c+2]) != 0)
- retval = -1;
- }
- c++;
- } else {
- // Check against recognized words
- int t = lookup_time(optarg);
- if (t >= 0) {
- if (ausearch_time_end(optarg,
- NULL) != 0)
- retval = -1;
- } else if ( (strchr(optarg, ':')) == NULL) {
- /* Only have date */
- if (ausearch_time_end(optarg,
- NULL) != 0)
- retval = -1;
- } else {
- /* Only have time */
- if (ausearch_time_end(NULL,
- optarg) != 0)
- retval = -1;
- }
- }
- c++;
- break;
- }
- fprintf(stderr,
- "%s requires either date and/or time\n",
- vars[c]);
- retval = -1;
- break;
- case R_TIME_START:
- if (optarg) {
- if ( (c+2 < count) && vars[c+2] &&
- (vars[c+2][0] != '-') ) {
- /* Have both date and time - check order */
- if (strchr(optarg, ':')) {
- if (ausearch_time_start(
- vars[c+2], optarg) != 0)
- retval = -1;
- } else {
- if (ausearch_time_start(optarg,
- vars[c+2]) != 0)
- retval = -1;
- }
- c++;
- } else {
- // Check against recognized words
- int t = lookup_time(optarg);
- if (t >= 0) {
- if (ausearch_time_start(optarg,
- "00:00:00") != 0)
- retval = -1;
- } else if ( strchr(optarg, ':') == NULL) {
- /* Only have date */
- if (ausearch_time_start(optarg,
- "00:00:00") != 0)
- retval = -1;
- } else {
- /* Only have time */
- if (ausearch_time_start(NULL,
- optarg) != 0)
- retval = -1;
- }
- }
- c++;
- break;
- }
- fprintf(stderr,
- "%s requires either date and/or time\n",
- vars[c]);
- retval = -1;
- break;
- case R_NODE:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- snode sn;
- c++;
-
- if (!event_node_list) {
- event_node_list = malloc(sizeof (slist));
- if (!event_node_list) {
- retval = -1;
- break;
- }
- slist_create(event_node_list);
- }
-
- sn.str = strdup(optarg);
- sn.key = NULL;
- sn.hits=0;
- slist_append(event_node_list, &sn);
- }
- break;
- case R_SUMMARY_DET:
- set_detail(D_SUM);
- break;
- case R_FAILED:
- event_failed = F_FAILED;
- break;
- case R_SUCCESS:
- event_failed = F_SUCCESS;
- break;
- case R_ADD:
- event_conf_act = C_ADD;
- break;
- case R_DEL:
- event_conf_act = C_DEL;
- break;
- case R_IN_LOGS:
- force_logs = 1;
- break;
- case R_NO_CONFIG:
- no_config = 1;
- break;
- case R_VERSION:
- printf("aureport version %s\n", VERSION);
- exit(0);
- break;
- case R_HELP:
- usage();
- exit(0);
- break;
- default:
- fprintf(stderr, "%s is an unsupported option\n",
- vars[c]);
- retval = -1;
- break;
- }
- c++;
- }
-
- if (retval >= 0) {
- if (report_type == RPT_UNSET) {
- if (set_report(RPT_SUMMARY))
- retval = -1;
- else {
- set_detail(D_SUM);
- event_filename = dummy;
- event_hostname = dummy;
- event_terminal = dummy;
- event_exe = dummy;
- event_comm = dummy;
- event_key = dummy;
- event_loginuid = 1;
- }
- }
- } else
- usage();
-
- return retval;
-}
-
diff --git a/framework/src/audit/src/aureport-options.h b/framework/src/audit/src/aureport-options.h
deleted file mode 100644
index a559f645..00000000
--- a/framework/src/audit/src/aureport-options.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* aureport-options.h --
- * Copyright 2005-06, 2008,2014 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#ifndef AUREPORT_OPTIONS_H
-#define AUREPORT_OPTIONS_H
-
-#include <time.h>
-#include <sys/types.h>
-#include "ausearch-common.h"
-
-/* Global variables that describe what search is to be performed */
-extern const char *event_context;
-
-typedef enum { RPT_UNSET, RPT_TIME, RPT_SUMMARY, RPT_AVC, RPT_MAC,
- RPT_CONFIG, RPT_EVENT, RPT_FILE, RPT_HOST, RPT_LOGIN,
- RPT_ACCT_MOD, RPT_PID, RPT_SYSCALL, RPT_TERM, RPT_USER,
- RPT_EXE, RPT_ANOMALY, RPT_RESPONSE, RPT_CRYPTO,
- RPT_AUTH, RPT_KEY, RPT_TTY, RPT_COMM, RPT_VIRT,
- RPT_INTEG } report_type_t;
-
-typedef enum { D_UNSET, D_SUM, D_DETAILED, D_SPECIFIC } report_det_t;
-
-extern report_type_t report_type;
-extern report_det_t report_detail;
-extern report_t report_format;
-
-
-/* Function to process commandline options */
-extern int check_params(int count, char *vars[]);
-
-#include <stdlib.h>
-#define UNIMPLEMENTED { fprintf(stderr,"Unimplemented option\n"); exit(1); }
-
-#endif
-
diff --git a/framework/src/audit/src/aureport-output.c b/framework/src/audit/src/aureport-output.c
deleted file mode 100644
index 9125d5ff..00000000
--- a/framework/src/audit/src/aureport-output.c
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
-* aureport-output.c - Print the report
-* Copyright (c) 2005-06,2008,2014 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "aureport-scan.h"
-#include "aureport-options.h"
-#include "ausearch-lookup.h"
-
-/* Locale functions */
-static void print_title_summary(void);
-static void print_title_detailed(void);
-static void do_summary_output(void);
-static void do_file_summary_output(slist *sptr);
-static void do_string_summary_output(slist *sptr);
-static void do_user_summary_output(slist *sptr);
-static void do_int_summary_output(ilist *sptr);
-static void do_syscall_summary_output(ilist *sptr);
-static void do_type_summary_output(ilist *sptr);
-
-/* Local Data */
-unsigned int line_item;
-
-
-void print_title(void)
-{
- line_item = 0U;
- printf("\n");
- switch (report_detail)
- {
- case D_SUM:
- print_title_summary();
- break;
- case D_DETAILED:
- print_title_detailed();
- break;
- case D_SPECIFIC:
- default:
- break;
- }
-}
-
-static void print_title_summary(void)
-{
- if (event_failed == F_FAILED) printf("Failed ");
- if (event_failed == F_SUCCESS) printf("Success ");
- switch (report_type)
- {
- case RPT_SUMMARY:
- printf("Summary Report\n");
- printf("======================\n");
- break;
- case RPT_AVC:
- printf("Avc Object Summary Report\n");
- printf("=================================\n");
- printf("total obj\n");
- printf("=================================\n");
- break;
- case RPT_MAC:
- printf("MAC Summary Report\n");
- printf("==================\n");
- printf("total type\n");
- printf("==================\n");
- break;
- case RPT_INTEG:
- printf("Integrity Summary Report\n");
- printf("========================\n");
- printf("total type\n");
- printf("========================\n");
- break;
- case RPT_VIRT:
- printf("Virtualization Summary Report\n");
- printf("=============================\n");
- printf("total type\n");
- printf("=============================\n");
- break;
- case RPT_CONFIG:
- printf("Config Change Summary Report\n");
- printf("============================\n");
- printf("total type\n");
- printf("============================\n");
- break;
- case RPT_AUTH:
- printf("Authentication Summary Report\n");
- printf("=============================\n");
- printf("total acct\n");
- printf("=============================\n");
- break;
- case RPT_LOGIN:
- printf("Login Summary Report\n");
- printf("============================\n");
- printf("total auid\n");
- printf("============================\n");
- break;
- case RPT_ACCT_MOD:
- printf("Acct Modification Summary Report\n");
- printf("================================\n");
- printf("total type\n");
- printf("================================\n");
- break;
- case RPT_TIME:
- UNIMPLEMENTED;
- break;
- case RPT_EVENT:
- printf("Event Summary Report\n");
- printf("======================\n");
- printf("total type\n");
- printf("======================\n");
- break;
- case RPT_FILE:
- printf("File Summary Report\n");
- printf("===========================\n");
- printf("total file\n");
- printf("===========================\n");
- break;
- case RPT_HOST:
- printf("Host Summary Report\n");
- printf("===========================\n");
- printf("total host\n");
- printf("===========================\n");
- break;
- case RPT_PID:
- printf("Pid Summary Report\n");
- printf("==========================\n");
- printf("total pid\n");
- printf("==========================\n");
- break;
- case RPT_SYSCALL:
- printf("Syscall Summary Report\n");
- printf("==========================\n");
- printf("total syscall\n");
- printf("==========================\n");
- break;
- case RPT_TERM:
- printf("Terminal Summary Report\n");
- printf("===============================\n");
- printf("total terminal\n");
- printf("===============================\n");
- break;
- case RPT_USER:
- printf("User Summary Report\n");
- printf("===========================\n");
- printf("total auid\n");
- printf("===========================\n");
- break;
- case RPT_EXE:
- printf("Executable Summary Report\n");
- printf("=================================\n");
- printf("total file\n");
- printf("=================================\n");
- break;
- case RPT_COMM:
- printf("Command Summary Report\n");
- printf("=================================\n");
- printf("total command\n");
- printf("=================================\n");
- break;
- case RPT_ANOMALY:
- printf("Anomaly Summary Report\n");
- printf("======================\n");
- printf("total type\n");
- printf("======================\n");
- break;
- case RPT_RESPONSE:
- printf("Anomaly Response Summary Report\n");
- printf("===============================\n");
- printf("total type\n");
- printf("===============================\n");
- break;
- case RPT_CRYPTO:
- printf("Crypto Summary Report\n");
- printf("=====================\n");
- printf("total type\n");
- printf("=====================\n");
- break;
- case RPT_KEY:
- printf("Key Summary Report\n");
- printf("===========================\n");
- printf("total key\n");
- printf("===========================\n");
- break;
- case RPT_TTY:
- UNIMPLEMENTED;
- break;
- default:
- break;
- }
-}
-
-static void print_title_detailed(void)
-{
- switch (report_type)
- {
- case RPT_AVC:
- printf("AVC Report\n");
- printf(
- "========================================================\n");
- printf(
- "# date time comm subj syscall class permission obj event\n");
- printf(
- "========================================================\n");
- break;
- case RPT_CONFIG:
- printf("Config Change Report\n");
- printf("===================================\n");
- printf("# date time type auid success event\n");
- printf("===================================\n");
- break;
- case RPT_AUTH:
- printf("Authentication Report\n");
- printf(
- "============================================\n");
- printf(
- "# date time acct host term exe success event\n");
- printf(
- "============================================\n");
- break;
- case RPT_LOGIN:
- printf("Login Report\n");
- printf(
- "============================================\n");
- printf(
- "# date time auid host term exe success event\n");
- printf(
- "============================================\n");
- break;
- case RPT_ACCT_MOD:
- printf("Account Modifications Report\n");
- printf(
- "=================================================\n");
- printf(
- "# date time auid addr term exe acct success event\n");
- printf(
- "=================================================\n");
- break;
- case RPT_TIME:
- printf("Log Time Range Report\n");
- printf("=====================\n");
- break;
- case RPT_EVENT:
- if (report_detail == D_DETAILED) {
- printf("Event Report\n");
- printf("===================================\n");
- printf("# date time event type auid success\n");
- printf("===================================\n");
- } else {
- printf("Specific Event Report\n");
- printf("=====================\n");
- }
- break;
- case RPT_FILE:
- if (report_detail == D_DETAILED) {
- printf("File Report\n");
- printf(
- "===============================================\n");
- printf(
- "# date time file syscall success exe auid event\n");
- printf(
- "===============================================\n");
- } else {
- printf("Specific File Report\n");
- printf("====================\n");
- }
- break;
- case RPT_HOST:
- if (report_detail == D_DETAILED) {
- printf("Host Report\n");
- printf("===================================\n");
- printf("# date time host syscall auid event\n");
- printf("===================================\n");
- } else {
- printf("Specific Host Report\n");
- printf("====================\n");
- }
- break;
- case RPT_PID:
- if (report_detail == D_DETAILED) {
- printf("Process ID Report\n");
- printf(
- "======================================\n");
- printf(
- "# date time pid exe syscall auid event\n");
- printf(
- "======================================\n");
- } else {
- printf("Specific Process ID Report\n");
- printf("==========================\n");
- }
- break;
- case RPT_SYSCALL:
- if (report_detail == D_DETAILED) {
- printf("Syscall Report\n");
- printf(
- "=======================================\n");
- printf(
- "# date time syscall pid comm auid event\n");
- printf(
- "=======================================\n");
- } else {
- printf("Specific Syscall Report\n");
- printf("=======================\n");
- }
- break;
- case RPT_TERM:
- if (report_detail == D_DETAILED) {
- printf("Terminal Report\n");
- printf(
- "====================================\n");
- printf(
- "# date time term host exe auid event\n");
- printf(
- "====================================\n");
- } else {
- printf("Specific Terminal Report\n");
- printf("========================\n");
- }
- break;
- case RPT_USER:
- if (report_detail == D_DETAILED) {
- printf("User ID Report\n");
- printf(
- "====================================\n");
- printf(
- "# date time auid term host exe event\n");
- printf(
- "====================================\n");
- } else {
- printf("Specific User ID Report\n");
- printf("=======================\n");
- }
- break;
- case RPT_EXE:
- if (report_detail == D_DETAILED) {
- printf("Executable Report\n");
- printf(
- "====================================\n");
- printf(
- "# date time exe term host auid event\n");
- printf(
- "====================================\n");
- } else {
- printf("Specific Executable Report\n");
- printf("==========================\n");
- }
- break;
- case RPT_COMM:
- if (report_detail == D_DETAILED) {
- printf("Command Report\n");
- printf(
- "====================================\n");
- printf(
- "# date time comm term host auid event\n");
- printf(
- "=====================================\n");
- } else {
- printf("Specific command Report\n");
- printf("=======================\n");
- }
- break;
- case RPT_ANOMALY:
- if (report_detail == D_DETAILED) {
- printf("Anomaly Report\n");
- printf(
- "=========================================\n");
- printf(
- "# date time type exe term host auid event\n");
- printf(
- "=========================================\n");
- } else {
- printf("Specific Anomaly Report\n");
- printf("=======================\n");
- }
- break;
- case RPT_RESPONSE:
- if (report_detail == D_DETAILED) {
- printf("Response to Anomaly Report\n");
- printf("==============================\n");
- printf("# date time type success event\n");
- printf("==============================\n");
- } else {
- printf("Specific Response to Anomaly Report\n");
- printf("===================================\n");
- }
- break;
- case RPT_MAC:
- if (report_detail == D_DETAILED) {
- printf("MAC Report\n");
- printf("===================================\n");
- printf("# date time auid type success event\n");
- printf("===================================\n");
- } else {
- printf("Specific Mandatory Access Control (MAC) Report\n");
- printf("===================================\n");
- }
- break;
- case RPT_INTEG:
- if (report_detail == D_DETAILED) {
- printf("Integrity Report\n");
- printf("==============================\n");
- printf("# date time type success event\n");
- printf("==============================\n");
- } else {
- printf("Specific Integrity Report\n");
- printf("==============================\n");
- }
- break;
- case RPT_VIRT:
- if (report_detail == D_DETAILED) {
- printf("Virtualization Report\n");
- printf("==============================\n");
- printf("# date time type success event\n");
- printf("==============================\n");
- } else {
- printf("Specific Virtualization Report\n");
- printf("==============================\n");
- }
- break;
- case RPT_CRYPTO:
- if (report_detail == D_DETAILED) {
- printf("Crypto Report\n");
- printf("===================================\n");
- printf("# date time auid type success event\n");
- printf("===================================\n");
- } else {
- printf("Specific Crypto Report\n");
- printf("===================================\n");
- }
- break;
- case RPT_KEY:
- if (report_detail == D_DETAILED) {
- printf("Key Report\n");
- printf(
- "===============================================\n");
- printf(
- "# date time key success exe auid event\n");
- printf(
- "===============================================\n");
- } else {
- printf("Specific Key Report\n");
- printf("====================\n");
- }
- break;
- case RPT_TTY:
- if (report_detail == D_DETAILED) {
- printf("TTY Report\n");
- printf(
- "===============================================\n");
- printf(
- "# date time event auid term sess comm data\n");
- printf(
- "===============================================\n");
- } else {
- printf("Specific TTY Report\n");
- printf("====================\n");
- }
- break;
- default:
- break;
- }
-}
-
-void print_per_event_item(llist *l)
-{
- char buf[128];
- char name[64];
- char date[32];
- struct tm *tv;
-
- // The beginning is common to all reports
- tv = localtime(&l->e.sec);
- strftime(date, sizeof(date), "%x %T", tv);
- if (report_type != RPT_AVC) {
- line_item++;
- printf("%u. %s ", line_item, date);
- }
-
- switch (report_type)
- {
- case RPT_AVC:
- alist_find_avc(l->s.avc);
- do {
- anode *an = l->s.avc->cur;
- line_item++;
- printf("%u. %s ", line_item, date);
- // command subject syscall action obj res event
- safe_print_string(l->s.comm ? l->s.comm : "?", 0);
- printf(" %s %s %s %s %s %s %lu\n",
- an->scontext,
- aulookup_syscall(l, buf,sizeof(buf)),
- an->avc_class, an->avc_perm,
- an->tcontext, aulookup_result(an->avc_result),
- l->e.serial);
-//printf("items:%d\n", l->s.avc->cnt);
- } while (alist_next_avc(l->s.avc));
- break;
- case RPT_CONFIG:
- // FIXME:who, action, what, outcome, event
- // NOW: type auid success event
- printf("%s %s %s %lu\n",
- audit_msg_type_to_name(l->head->type),
- aulookup_uid(l->s.loginuid, name, sizeof(name)),
- aulookup_success(l->s.success), l->e.serial);
- break;
- case RPT_AUTH:
- // who, addr, terminal, exe, success, event
- // Special note...uid is used here because that is
- // the way that the message works. This is because
- // on failed logins, loginuid is not set.
- safe_print_string(l->s.acct ? l->s.acct :
- aulookup_uid(l->s.uid, name, sizeof(name)), 0);
- printf(" %s %s %s %s %lu\n",
- l->s.hostname, l->s.terminal,
- l->s.exe, aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_LOGIN:
- // who, addr, terminal, exe, success, event
- // Special note...uid is used here because that is
- // the way that the message works. This is because
- // on failed logins, loginuid is not set.
- safe_print_string(((l->s.success == S_FAILED) &&
- l->s.acct) ? l->s.acct :
- aulookup_uid(l->s.uid, name, sizeof(name)), 0);
- printf(" %s %s %s %s %lu\n",
- l->s.hostname, l->s.terminal,
- l->s.exe, aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_ACCT_MOD:
- // who, addr, terminal, exe, success, event
- safe_print_string(
- aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %s %s %s %s %s %lu\n",
- l->s.hostname ? l->s.hostname : "?",
- l->s.terminal ? l->s.terminal : "?",
- l->s.exe ? l->s.exe : "?",
- l->s.acct ? l->s.acct : "?",
- aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_EVENT: // report_detail == D_DETAILED
- // event, type, who, success
- printf("%lu %s ",
- l->e.serial,
- audit_msg_type_to_name(l->head->type));
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %s\n", aulookup_success(l->s.success));
- break;
- case RPT_FILE: // report_detail == D_DETAILED
- // file, syscall, success, exe, who, event
- slist_first(l->s.filename);
- safe_print_string(l->s.filename->cur->str,0);
- printf(" %s %s ",
- aulookup_syscall(l,buf,sizeof(buf)),
- aulookup_success(l->s.success));
- safe_print_string(l->s.exe ? l->s.exe : "?", 0);
- putchar(' ');
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_HOST: // report_detail == D_DETAILED
- // host, syscall, who, event
- printf("%s %s ",
- l->s.hostname,
- aulookup_syscall(l,buf,sizeof(buf)));
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_PID: // report_detail == D_DETAILED
- // pid, exe, syscall, who, event
- printf("%u ", l->s.pid);
- safe_print_string(l->s.exe ? l->s.exe : "?", 0);
- printf(" %s ", aulookup_syscall(l,buf,sizeof(buf)));
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_SYSCALL: // report_detail == D_DETAILED
- // syscall, pid, comm, who, event
- printf("%s %u ", aulookup_syscall(l,buf,sizeof(buf)),
- l->s.pid);
- safe_print_string(l->s.comm ? l->s.comm : "?", 0);
- putchar(' ');
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_TERM: // report_detail == D_DETAILED
- // terminal, host, exe, who, event
- printf("%s %s ",
- l->s.terminal, l->s.hostname);
- safe_print_string(l->s.exe, 0);
- putchar(' ');
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_USER: // report_detail == D_DETAILED
- // who, terminal, host, exe, event
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %s %s ",
- l->s.terminal ? l->s.terminal : "?",
- l->s.hostname ? l->s.hostname : "?");
- safe_print_string(l->s.exe ? l->s.exe : "?", 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_EXE: // report_detail == D_DETAILED
- // exe, terminal, host, who, event
- safe_print_string(l->s.exe ? l->s.exe : "?", 0);
- printf(" %s %s ",
- l->s.terminal ? l->s.terminal : "?",
- l->s.hostname ? l->s.hostname : "?");
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_COMM: // report_detail == D_DETAILED
- // comm, terminal, host, who, event
- safe_print_string(l->s.comm ? l->s.comm : "?", 0);
- printf(" %s %s ",
- l->s.terminal ? l->s.terminal : "?",
- l->s.hostname ? l->s.hostname : "?");
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_ANOMALY: // report_detail == D_DETAILED
- // type exe term host auid event
- printf("%s ", audit_msg_type_to_name(l->head->type));
- safe_print_string(l->s.exe ? l->s.exe :
- l->s.comm ? l->s.comm: "?", 0);
- printf(" %s %s ",
- l->s.terminal ? l->s.terminal : "?",
- l->s.hostname ? l->s.hostname : "?");
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_RESPONSE: // report_detail == D_DETAILED
- // type success event
- printf("%s %s %lu\n",
- audit_msg_type_to_name(l->head->type),
- aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_MAC:
- // auid type success event
- printf("%s %s %s %lu\n",
- aulookup_uid(l->s.loginuid, name, sizeof(name)),
- audit_msg_type_to_name(l->head->type),
- aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_INTEG:
- // type success event
- printf("%s %s %lu\n",
- audit_msg_type_to_name(l->head->type),
- aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_VIRT:
- // type success event
- printf("%s %s %lu\n",
- audit_msg_type_to_name(l->head->type),
- aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_CRYPTO:
- // auid type success event
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %s %s %lu\n",
- audit_msg_type_to_name(l->head->type),
- aulookup_success(l->s.success),
- l->e.serial);
- break;
- case RPT_KEY: // report_detail == D_DETAILED
- // key, success, exe, who, event
- slist_first(l->s.key);
- printf("%s %s ", l->s.key->cur->str,
- aulookup_success(l->s.success));
- safe_print_string(l->s.exe ? l->s.exe : "?", 0);
- putchar(' ');
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %lu\n", l->e.serial);
- break;
- case RPT_TTY: {
- char *ch, *ptr = strstr(l->head->message, "data=");
- if (!ptr)
- break;
- ptr += 5;
- ch = strrchr(ptr, ' ');
- if (ch)
- *ch = 0;
- // event who term sess data
- printf("%lu ", l->e.serial);
- safe_print_string(aulookup_uid(l->s.loginuid, name,
- sizeof(name)), 0);
- printf(" %s %u ",
- l->s.terminal ? l->s.terminal : "?",
- l->s.session_id);
- safe_print_string(l->s.comm ? l->s.comm: "?", 0);
- putchar(' ');
- print_tty_data(ptr);
- printf("\n");
- }
- break;
- default:
- break;
- }
-}
-
-void print_wrap_up(void)
-{
- if (report_detail != D_SUM)
- return;
-
- switch (report_type)
- {
- case RPT_SUMMARY:
- do_summary_output();
- break;
- case RPT_AVC:
- slist_sort_by_hits(&sd.avc_objs);
- do_string_summary_output(&sd.avc_objs);
- break;
- case RPT_CONFIG: /* We will borrow the pid list */
- ilist_sort_by_hits(&sd.pids);
- do_type_summary_output(&sd.pids);
- break;
- case RPT_AUTH:
- slist_sort_by_hits(&sd.users);
- do_user_summary_output(&sd.users);
- break;
- case RPT_LOGIN:
- slist_sort_by_hits(&sd.users);
- do_user_summary_output(&sd.users);
- break;
- case RPT_ACCT_MOD: /* We will borrow the pid list */
- ilist_sort_by_hits(&sd.pids);
- do_type_summary_output(&sd.pids);
- break;
- case RPT_EVENT: /* We will borrow the pid list */
- ilist_sort_by_hits(&sd.pids);
- do_type_summary_output(&sd.pids);
- break;
- case RPT_FILE:
- slist_sort_by_hits(&sd.files);
- do_file_summary_output(&sd.files);
- break;
- case RPT_HOST:
- slist_sort_by_hits(&sd.hosts);
- do_string_summary_output(&sd.hosts);
- break;
- case RPT_PID:
- ilist_sort_by_hits(&sd.pids);
- do_int_summary_output(&sd.pids);
- break;
- case RPT_SYSCALL:
- ilist_sort_by_hits(&sd.sys_list);
- do_syscall_summary_output(&sd.sys_list);
- break;
- case RPT_TERM:
- slist_sort_by_hits(&sd.terms);
- do_string_summary_output(&sd.terms);
- break;
- case RPT_USER:
- slist_sort_by_hits(&sd.users);
- do_user_summary_output(&sd.users);
- break;
- case RPT_EXE:
- slist_sort_by_hits(&sd.exes);
- do_file_summary_output(&sd.exes);
- break;
- case RPT_COMM:
- slist_sort_by_hits(&sd.comms);
- do_file_summary_output(&sd.comms);
- break;
- case RPT_ANOMALY:
- ilist_sort_by_hits(&sd.anom_list);
- do_type_summary_output(&sd.anom_list);
- break;
- case RPT_RESPONSE:
- ilist_sort_by_hits(&sd.resp_list);
- do_type_summary_output(&sd.resp_list);
- break;
- case RPT_MAC:
- ilist_sort_by_hits(&sd.mac_list);
- do_type_summary_output(&sd.mac_list);
- break;
- case RPT_INTEG:
- ilist_sort_by_hits(&sd.integ_list);
- do_type_summary_output(&sd.integ_list);
- break;
- case RPT_VIRT:
- ilist_sort_by_hits(&sd.virt_list);
- do_type_summary_output(&sd.virt_list);
- break;
- case RPT_CRYPTO:
- ilist_sort_by_hits(&sd.crypto_list);
- do_type_summary_output(&sd.crypto_list);
- break;
- case RPT_KEY:
- slist_sort_by_hits(&sd.keys);
- do_file_summary_output(&sd.keys);
- break;
- default:
- break;
- }
-}
-
-static void do_summary_output(void)
-{
- extern event very_first_event;
- extern event very_last_event;
-
- printf("Range of time in logs: ");
- {
- struct tm *btm;
- char tmp[48];
-
- btm = localtime(&very_first_event.sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- printf("%s.%03d - ", tmp, very_first_event.milli);
- btm = localtime(&very_last_event.sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- printf("%s.%03d\n", tmp, very_last_event.milli);
- }
- printf("Selected time for report: ");
- {
- struct tm *btm;
- char tmp[48];
-
- if (start_time)
- btm = localtime(&start_time);
- else
- btm = localtime(&very_first_event.sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- printf("%s - ", tmp);
- if (end_time)
- btm = localtime(&end_time);
- else
- btm = localtime(&very_last_event.sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- if (end_time)
- printf("%s\n", tmp);
- else
- printf("%s.%03d\n", tmp, very_last_event.milli);
- }
- printf("Number of changes in configuration: %lu\n", sd.changes);
- printf("Number of changes to accounts, groups, or roles: %lu\n",
- sd.acct_changes);
- printf("Number of logins: %lu\n", sd.good_logins);
- printf("Number of failed logins: %lu\n", sd.bad_logins);
- printf("Number of authentications: %lu\n", sd.good_auth);
- printf("Number of failed authentications: %lu\n", sd.bad_auth);
- printf("Number of users: %u\n", sd.users.cnt);
- printf("Number of terminals: %u\n", sd.terms.cnt);
- printf("Number of host names: %u\n", sd.hosts.cnt);
- printf("Number of executables: %u\n", sd.exes.cnt);
- printf("Number of commands: %u\n", sd.comms.cnt);
- printf("Number of files: %u\n", sd.files.cnt);
- printf("Number of AVC's: %lu\n", sd.avcs);
- printf("Number of MAC events: %lu\n", sd.mac);
- printf("Number of failed syscalls: %lu\n", sd.failed_syscalls);
- printf("Number of anomaly events: %lu\n", sd.anomalies);
- printf("Number of responses to anomaly events: %lu\n", sd.responses);
- printf("Number of crypto events: %lu\n", sd.crypto);
- printf("Number of integrity events: %lu\n", sd.integ);
- printf("Number of virt events: %lu\n", sd.virt);
- printf("Number of keys: %u\n", sd.keys.cnt);
- printf("Number of process IDs: %u\n", sd.pids.cnt);
- printf("Number of events: %lu\n", sd.events);
- printf("\n");
-}
-
-static void do_file_summary_output(slist *sptr)
-{
- const snode *sn;
-
- if (sptr->cnt == 0) {
- printf("<no events of interest were found>\n\n");
- return;
- }
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- printf("%u ", sn->hits);
- safe_print_string(sn->str, 1);
- sn=slist_next(sptr);
- }
-}
-
-static void do_string_summary_output(slist *sptr)
-{
- const snode *sn;
-
- if (sptr->cnt == 0) {
- printf("<no events of interest were found>\n\n");
- return;
- }
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- printf("%u %s\n", sn->hits, sn->str);
- sn=slist_next(sptr);
- }
-}
-
-static void do_user_summary_output(slist *sptr)
-{
- const snode *sn;
-
- if (sptr->cnt == 0) {
- printf("<no events of interest were found>\n\n");
- return;
- }
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- long uid;
- char name[64];
-
- if (sn->str[0] == '-' || isdigit(sn->str[0])) {
- uid = strtol(sn->str, NULL, 10);
- printf("%u ", sn->hits);
- safe_print_string(aulookup_uid(uid, name,
- sizeof(name)), 1);
- } else {
- printf("%u ", sn->hits);
- safe_print_string(sn->str, 1);
- }
- sn=slist_next(sptr);
- }
-}
-
-static void do_int_summary_output(ilist *sptr)
-{
- const int_node *in;
-
- if (sptr->cnt == 0) {
- printf("<no events of interest were found>\n\n");
- return;
- }
- ilist_first(sptr);
- in=ilist_get_cur(sptr);
- while (in) {
- printf("%u %d\n", in->hits, in->num);
- in=ilist_next(sptr);
- }
-}
-
-static void do_syscall_summary_output(ilist *sptr)
-{
- const int_node *in;
-
- if (sptr->cnt == 0) {
- printf("<no events of interest were found>\n\n");
- return;
- }
- ilist_first(sptr);
- in=ilist_get_cur(sptr);
- while (in) {
- const char *sys = NULL;
- int machine = audit_elf_to_machine(in->aux1);
- if (machine >= 0)
- sys = audit_syscall_to_name(in->num, machine);
- if (sys)
- printf("%u %s\n", in->hits, sys);
- else
- printf("%u %d\n", in->hits, in->num);
- in=ilist_next(sptr);
- }
-}
-
-static void do_type_summary_output(ilist *sptr)
-{
- const int_node *in;
-
- if (sptr->cnt == 0) {
- printf("<no events of interest were found>\n\n");
- return;
- }
- ilist_first(sptr);
- in=ilist_get_cur(sptr);
- while (in) {
- const char *name = audit_msg_type_to_name(in->num);
- if (report_format == RPT_DEFAULT)
- printf("%u %d\n", in->hits, in->num);
- else
- printf("%u %s\n", in->hits, name);
- in=ilist_next(sptr);
- }
-}
-
diff --git a/framework/src/audit/src/aureport-scan.c b/framework/src/audit/src/aureport-scan.c
deleted file mode 100644
index 6b2f5ee6..00000000
--- a/framework/src/audit/src/aureport-scan.c
+++ /dev/null
@@ -1,974 +0,0 @@
-/*
-* aureport-scan.c - Extract interesting fields and check for match
-* Copyright (c) 2005-06,2008,2011,2014-15 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <string.h>
-#include <stdio.h>
-#include <pwd.h>
-#include "libaudit.h"
-#include "aureport-options.h"
-#include "ausearch-parse.h"
-#include "ausearch-string.h"
-#include "ausearch-lookup.h"
-#include "aureport-scan.h"
-
-static void do_summary_total(llist *l);
-static int per_event_summary(llist *l);
-static int per_event_detailed(llist *l);
-
-summary_data sd;
-
-/* This function inits the counters */
-void reset_counters(void)
-{
- sd.changes = 0UL;
- sd.crypto = 0UL;
- sd.acct_changes = 0UL;
- sd.good_logins = 0UL;
- sd.bad_logins = 0UL;
- sd.good_auth = 0UL;
- sd.bad_auth = 0UL;
- sd.events = 0UL;
- sd.avcs = 0UL;
- sd.mac = 0UL;
- sd.failed_syscalls = 0UL;
- sd.anomalies = 0UL;
- sd.responses = 0UL;
- sd.virt = 0UL;
- sd.integ = 0UL;
- slist_create(&sd.users);
- slist_create(&sd.terms);
- slist_create(&sd.files);
- slist_create(&sd.hosts);
- slist_create(&sd.exes);
- slist_create(&sd.comms);
- slist_create(&sd.avc_objs);
- slist_create(&sd.keys);
- ilist_create(&sd.pids);
- ilist_create(&sd.sys_list);
- ilist_create(&sd.anom_list);
- ilist_create(&sd.mac_list);
- ilist_create(&sd.resp_list);
- ilist_create(&sd.crypto_list);
- ilist_create(&sd.virt_list);
- ilist_create(&sd.integ_list);
-}
-
-/* This function inits the counters */
-void destroy_counters(void)
-{
- sd.changes = 0UL;
- sd.crypto = 0UL;
- sd.acct_changes = 0UL;
- sd.good_logins = 0UL;
- sd.bad_logins = 0UL;
- sd.good_auth = 0UL;
- sd.bad_auth = 0UL;
- sd.events = 0UL;
- sd.avcs = 0UL;
- sd.mac = 0UL;
- sd.failed_syscalls = 0UL;
- sd.anomalies = 0UL;
- sd.responses = 0UL;
- sd.virt = 0UL;
- sd.integ = 0UL;
- slist_clear(&sd.users);
- slist_clear(&sd.terms);
- slist_clear(&sd.files);
- slist_clear(&sd.hosts);
- slist_clear(&sd.exes);
- slist_clear(&sd.comms);
- slist_clear(&sd.avc_objs);
- slist_clear(&sd.keys);
- ilist_clear(&sd.pids);
- ilist_clear(&sd.sys_list);
- ilist_clear(&sd.anom_list);
- ilist_create(&sd.mac_list);
- ilist_clear(&sd.resp_list);
- ilist_create(&sd.crypto_list);
- ilist_create(&sd.virt_list);
- ilist_create(&sd.integ_list);
-}
-
-/* This function will return 0 on no match and 1 on match */
-int classify_success(const llist *l)
-{
-//printf("%d,succ=%d:%d\n", l->head->type, event_failed, l->s.success);
- // If match only failed...
- if (event_failed == F_FAILED)
- return l->s.success == S_FAILED ? 1 : 0;
- // If match only success...
- if (event_failed == F_SUCCESS)
- return l->s.success == S_SUCCESS ? 1 : 0;
- // Otherwise...we don't care so pretend it matched
- return 1;
-}
-
-/* This function will return 0 on no match and 1 on match */
-int classify_conf(const llist *l)
-{
- int rc = 1;
- extern int no_config;
-
- switch (l->head->type)
- {
- case AUDIT_CONFIG_CHANGE:
- if (no_config)
- rc = 0;
- break;
- case AUDIT_USYS_CONFIG:
- break;
- case AUDIT_ADD_USER:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_DEL_USER:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- case AUDIT_ADD_GROUP:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_DEL_GROUP:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- case AUDIT_MAC_CIPSOV4_ADD:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_MAC_CIPSOV4_DEL:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- case AUDIT_MAC_MAP_ADD:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_MAC_MAP_DEL:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- case AUDIT_MAC_IPSEC_ADDSA:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_MAC_IPSEC_DELSA:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- case AUDIT_MAC_IPSEC_ADDSPD:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_MAC_IPSEC_DELSPD:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- case AUDIT_MAC_UNLBL_STCADD:
- if (event_conf_act == C_DEL)
- rc = 0;
- break;
- case AUDIT_MAC_UNLBL_STCDEL:
- if (event_conf_act == C_ADD)
- rc = 0;
- break;
- default:
- break;
- }
-//printf("conf=%d:%d\n", l->head->type, rc);
- return rc;
-}
-
-/*
- * This function performs that matching of search params with the record.
- * It returns 1 on a match, and 0 if no match.
- */
-int scan(llist *l)
-{
- // Are we within time range?
- if (start_time == 0 || l->e.sec >= start_time) {
- if (end_time == 0 || l->e.sec <= end_time) {
- // OK - do the heavier checking
- int rc = extract_search_items(l);
- if (rc == 0) {
- if (event_node_list) {
- const snode *sn;
- int found=0;
- slist *sptr = event_node_list;
-
- if (l->e.node == NULL)
- return 0;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn && !found) {
- if (sn->str && (!strcmp(sn->str, l->e.node)))
- found++;
- else
- sn=slist_next(sptr);
- }
-
- if (!found)
- return 0;
- }
- if (classify_success(l) && classify_conf(l))
- return 1;
- return 0;
- }
- }
- }
- return 0;
-}
-
-int per_event_processing(llist *l)
-{
- int rc;
-
- switch (report_detail)
- {
- case D_SUM:
- rc = per_event_summary(l);
- break;
- case D_DETAILED:
- rc = per_event_detailed(l);
- break;
- case D_SPECIFIC:
- default:
- rc = 0;
- break;
- }
- return rc;
-}
-
-static int per_event_summary(llist *l)
-{
- int rc = 0;
-
- switch (report_type)
- {
- case RPT_SUMMARY:
- do_summary_total(l);
- rc = 1;
- break;
- case RPT_AVC:
- if (list_find_msg(l, AUDIT_AVC)) {
- if (alist_find_avc(l->s.avc)) {
- do {
- slist_add_if_uniq(&sd.avc_objs,
- l->s.avc->cur->tcontext);
- } while (alist_next_avc(l->s.avc));
- }
- } else {
- if (list_find_msg(l, AUDIT_USER_AVC)) {
- if (alist_find_avc(l->s.avc)) {
- do {
- slist_add_if_uniq(
- &sd.avc_objs,
- l->s.avc->cur->tcontext);
- } while (alist_next_avc(
- l->s.avc));
- }
- }
- }
- break;
- case RPT_MAC:
- if (list_find_msg_range(l, AUDIT_MAC_POLICY_LOAD,
- AUDIT_MAC_MAP_DEL)) {
- ilist_add_if_uniq(&sd.mac_list,
- l->head->type, 0);
- } else {
- if (list_find_msg_range(l,
- AUDIT_FIRST_USER_LSPP_MSG,
- AUDIT_LAST_USER_LSPP_MSG)) {
- ilist_add_if_uniq(&sd.mac_list,
- l->head->type, 0);
- }
- }
- break;
- case RPT_INTEG:
- if (list_find_msg_range(l,
- AUDIT_INTEGRITY_FIRST_MSG,
- AUDIT_INTEGRITY_LAST_MSG)) {
- ilist_add_if_uniq(&sd.integ_list,
- l->head->type, 0);
- }
- break;
- case RPT_VIRT:
- if (list_find_msg_range(l,
- AUDIT_FIRST_VIRT_MSG,
- AUDIT_LAST_VIRT_MSG)) {
- ilist_add_if_uniq(&sd.virt_list,
- l->head->type, 0);
- }
- break;
- case RPT_CONFIG: /* We will borrow the pid list */
- if (list_find_msg(l, AUDIT_CONFIG_CHANGE) ||
- list_find_msg(l, AUDIT_DAEMON_CONFIG) ||
- list_find_msg(l, AUDIT_USYS_CONFIG) ||
- list_find_msg(l, AUDIT_NETFILTER_CFG) ||
- list_find_msg(l, AUDIT_FEATURE_CHANGE) ||
- list_find_msg(l, AUDIT_USER_MAC_CONFIG_CHANGE)||
- list_find_msg_range(l,
- AUDIT_MAC_POLICY_LOAD,
- AUDIT_MAC_UNLBL_STCDEL)) {
- ilist_add_if_uniq(&sd.pids, l->head->type, 0);
- }
- break;
- case RPT_AUTH:
- if (list_find_msg(l, AUDIT_USER_AUTH)) {
- if (l->s.loginuid == -2 && l->s.acct)
- slist_add_if_uniq(&sd.users, l->s.acct);
- else {
- char name[64];
-
- slist_add_if_uniq(&sd.users,
- aulookup_uid(l->s.loginuid,
- name,
- sizeof(name))
- );
- }
- } else if (list_find_msg(l, AUDIT_USER_MGMT)) {
- // Only count the failures
- if (l->s.success == S_FAILED) {
- if (l->s.loginuid == -2 &&
- l->s.acct != NULL)
- slist_add_if_uniq(&sd.users, l->s.acct);
- else {
- char name[64];
-
- slist_add_if_uniq(&sd.users,
- aulookup_uid(
- l->s.loginuid,
- name,
- sizeof(name))
- );
- }
- }
- }
- break;
- case RPT_LOGIN:
- if (list_find_msg(l, AUDIT_USER_LOGIN)) {
- if ((int)l->s.loginuid < 0 && l->s.acct)
- slist_add_if_uniq(&sd.users, l->s.acct);
- else {
- char name[64];
-
- slist_add_if_uniq(&sd.users,
- aulookup_uid(l->s.loginuid,
- name,
- sizeof(name))
- );
- }
- }
- break;
- case RPT_ACCT_MOD: /* We will borrow the pid list */
- if (list_find_msg(l, AUDIT_USER_CHAUTHTOK) ||
- list_find_msg_range(l,
- AUDIT_ADD_USER, AUDIT_DEL_GROUP) ||
- list_find_msg(l, AUDIT_USER_MGMT) ||
- list_find_msg(l, AUDIT_GRP_MGMT) ||
- list_find_msg_range(l,
- AUDIT_ROLE_ASSIGN,
- AUDIT_ROLE_REMOVE)) {
- ilist_add_if_uniq(&sd.pids, l->head->type, 0);
- }
- break;
- case RPT_EVENT: /* We will borrow the pid list */
- if (l->head->type != -1) {
- ilist_add_if_uniq(&sd.pids, l->head->type, 0);
- }
- break;
- case RPT_FILE:
- if (l->s.filename) {
- const snode *sn;
- slist *sptr = l->s.filename;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- if (sn->str)
- slist_add_if_uniq(&sd.files,
- sn->str);
- sn=slist_next(sptr);
- }
- }
- break;
- case RPT_HOST:
- if (l->s.hostname)
- slist_add_if_uniq(&sd.hosts, l->s.hostname);
- break;
- case RPT_PID:
- if (l->s.pid != -1) {
- ilist_add_if_uniq(&sd.pids, l->s.pid, 0);
- }
- break;
- case RPT_SYSCALL:
- if (l->s.syscall > 0) {
- ilist_add_if_uniq(&sd.sys_list,
- l->s.syscall, l->s.arch);
- }
- break;
- case RPT_TERM:
- if (l->s.terminal)
- slist_add_if_uniq(&sd.terms, l->s.terminal);
- break;
- case RPT_USER:
- if (l->s.loginuid != -2) {
- char tmp[32];
- snprintf(tmp, sizeof(tmp), "%d", l->s.loginuid);
- slist_add_if_uniq(&sd.users, tmp);
- }
- break;
- case RPT_EXE:
- if (l->s.exe)
- slist_add_if_uniq(&sd.exes, l->s.exe);
- break;
- case RPT_COMM:
- if (l->s.comm)
- slist_add_if_uniq(&sd.comms, l->s.comm);
- break;
- case RPT_ANOMALY:
- if (list_find_msg_range(l, AUDIT_FIRST_ANOM_MSG,
- AUDIT_LAST_ANOM_MSG)) {
- ilist_add_if_uniq(&sd.anom_list,
- l->head->type, 0);
- } else {
- if (list_find_msg_range(l,
- AUDIT_FIRST_KERN_ANOM_MSG,
- AUDIT_LAST_KERN_ANOM_MSG)) {
- ilist_add_if_uniq(&sd.anom_list,
- l->head->type, 0);
- }
- }
- break;
- case RPT_RESPONSE:
- if (list_find_msg_range(l, AUDIT_FIRST_ANOM_RESP,
- AUDIT_LAST_ANOM_RESP)) {
- ilist_add_if_uniq(&sd.resp_list,
- l->head->type, 0);
- }
- break;
- case RPT_CRYPTO:
- if (list_find_msg_range(l, AUDIT_FIRST_KERN_CRYPTO_MSG,
- AUDIT_LAST_KERN_CRYPTO_MSG)) {
- ilist_add_if_uniq(&sd.crypto_list,
- l->head->type, 0);
- } else {
- if (list_find_msg_range(l,
- AUDIT_FIRST_CRYPTO_MSG,
- AUDIT_LAST_CRYPTO_MSG)) {
- ilist_add_if_uniq(&sd.crypto_list,
- l->head->type, 0);
- }
- }
- break;
- case RPT_KEY:
- if (l->s.key) {
- const snode *sn;
- slist *sptr = l->s.key;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- if (sn->str &&
- strcmp(sn->str, "(null)"))
- slist_add_if_uniq(&sd.keys,
- sn->str);
- sn=slist_next(sptr);
- }
- }
- break;
- case RPT_TTY:
- UNIMPLEMENTED;
- break;
- default:
- break;
- }
- return rc;
-}
-
-static int per_event_detailed(llist *l)
-{
- int rc = 0;
-
- switch (report_type)
- {
- case RPT_AVC:
- if (list_find_msg(l, AUDIT_AVC)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_USER_AVC)) {
- print_per_event_item(l);
- rc = 1;
- }
- break;
- case RPT_MAC:
- if (report_detail == D_DETAILED) {
- if (list_find_msg_range(l,
- AUDIT_MAC_POLICY_LOAD,
- AUDIT_MAC_UNLBL_STCDEL)) {
- print_per_event_item(l);
- rc = 1;
- } else {
- if (list_find_msg_range(l,
- AUDIT_FIRST_USER_LSPP_MSG,
- AUDIT_LAST_USER_LSPP_MSG)) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- }
- break;
- case RPT_INTEG:
- if (report_detail == D_DETAILED) {
- if (list_find_msg_range(l,
- AUDIT_INTEGRITY_FIRST_MSG,
- AUDIT_INTEGRITY_LAST_MSG)) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- break;
- case RPT_VIRT:
- if (report_detail == D_DETAILED) {
- if (list_find_msg_range(l,
- AUDIT_FIRST_VIRT_MSG,
- AUDIT_LAST_VIRT_MSG)) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- break;
- case RPT_CONFIG:
- if (list_find_msg(l, AUDIT_CONFIG_CHANGE)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_DAEMON_CONFIG)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_USYS_CONFIG)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_NETFILTER_CFG)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_FEATURE_CHANGE)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l,
- AUDIT_USER_MAC_CONFIG_CHANGE)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg_range(l,
- AUDIT_MAC_POLICY_LOAD,
- AUDIT_MAC_UNLBL_STCDEL)) {
- print_per_event_item(l);
- rc = 1;
- }
- break;
- case RPT_AUTH:
- if (list_find_msg(l, AUDIT_USER_AUTH)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_USER_MGMT)) {
- // Only count the failed acct
- if (l->s.success == S_FAILED) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- break;
- case RPT_LOGIN:
- if (list_find_msg(l, AUDIT_USER_LOGIN)) {
- print_per_event_item(l);
- rc = 1;
- }
- break;
- case RPT_ACCT_MOD:
- if (list_find_msg(l, AUDIT_USER_CHAUTHTOK)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg_range(l,
- AUDIT_ADD_USER, AUDIT_DEL_GROUP)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_USER_MGMT)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg(l, AUDIT_GRP_MGMT)) {
- print_per_event_item(l);
- rc = 1;
- } else if (list_find_msg_range(l,
- AUDIT_ROLE_ASSIGN,
- AUDIT_ROLE_REMOVE)) {
- print_per_event_item(l);
- rc = 1;
- }
- break;
- case RPT_EVENT:
- list_first(l);
- if (report_detail == D_DETAILED) {
- print_per_event_item(l);
- rc = 1;
- } else { // specific event report
- UNIMPLEMENTED;
- }
- break;
- case RPT_FILE:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.filename) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific file report
- UNIMPLEMENTED;
- }
- break;
- case RPT_HOST:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.hostname) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific host report
- UNIMPLEMENTED;
- }
- break;
- case RPT_PID:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.pid >= 0) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific pid report
- UNIMPLEMENTED;
- }
- break;
- case RPT_SYSCALL:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.syscall) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific syscall report
- UNIMPLEMENTED;
- }
- break;
- case RPT_TERM:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.terminal) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific terminal report
- UNIMPLEMENTED;
- }
- break;
- case RPT_USER:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.uid != -1) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific user report
- UNIMPLEMENTED;
- }
- break;
- case RPT_EXE:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.exe) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific exe report
- UNIMPLEMENTED;
- }
- break;
- case RPT_COMM:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.comm) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // specific exe report
- UNIMPLEMENTED;
- }
- break;
- case RPT_ANOMALY:
- if (report_detail == D_DETAILED) {
- if (list_find_msg_range(l,
- AUDIT_FIRST_ANOM_MSG,
- AUDIT_LAST_ANOM_MSG)) {
- print_per_event_item(l);
- rc = 1;
- } else {
- if (list_find_msg_range(l,
- AUDIT_FIRST_KERN_ANOM_MSG,
- AUDIT_LAST_KERN_ANOM_MSG)) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- } else { // FIXME: specific anom report
- UNIMPLEMENTED;
- }
- break;
- case RPT_RESPONSE:
- if (report_detail == D_DETAILED) {
- if (list_find_msg_range(l,
- AUDIT_FIRST_ANOM_RESP,
- AUDIT_LAST_ANOM_RESP)) {
- print_per_event_item(l);
- rc = 1;
- }
- } else { // FIXME: specific resp report
- UNIMPLEMENTED;
- }
- break;
- case RPT_CRYPTO:
- if (report_detail == D_DETAILED) {
- if (list_find_msg_range(l,
- AUDIT_FIRST_KERN_CRYPTO_MSG,
- AUDIT_LAST_KERN_CRYPTO_MSG)) {
- print_per_event_item(l);
- rc = 1;
- } else {
- if (list_find_msg_range(l,
- AUDIT_FIRST_CRYPTO_MSG,
- AUDIT_LAST_CRYPTO_MSG)) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- } else { // FIXME: specific crypto report
- UNIMPLEMENTED;
- }
- break;
- case RPT_KEY:
- list_first(l);
- if (report_detail == D_DETAILED) {
- if (l->s.key) {
- slist_first(l->s.key);
- if (strcmp(l->s.key->cur->str,
- "(null)")) {
- print_per_event_item(l);
- rc = 1;
- }
- }
- } else { // specific key report
- UNIMPLEMENTED;
- }
- break;
- case RPT_TTY:
- if (l->head->type == AUDIT_TTY ||
- l->head->type == AUDIT_USER_TTY) {
- print_per_event_item(l);
- rc = 1;
- }
- break;
- default:
- break;
- }
- return rc;
-}
-
-static void do_summary_total(llist *l)
-{
- // add events
- sd.events++;
-
- // add config changes
- if (list_find_msg(l, AUDIT_CONFIG_CHANGE))
- sd.changes++;
- if (list_find_msg(l, AUDIT_DAEMON_CONFIG))
- sd.changes++;
- if (list_find_msg(l, AUDIT_USYS_CONFIG))
- sd.changes++;
- if (list_find_msg(l, AUDIT_NETFILTER_CFG))
- sd.changes++;
- if (list_find_msg(l, AUDIT_FEATURE_CHANGE))
- sd.changes++;
- if (list_find_msg(l, AUDIT_USER_MAC_CONFIG_CHANGE))
- sd.changes++;
- list_first(l);
- if (list_find_msg_range(l, AUDIT_MAC_POLICY_LOAD,
- AUDIT_MAC_UNLBL_STCDEL))
- sd.changes++;
-
- // add acct changes
- if (list_find_msg(l, AUDIT_USER_CHAUTHTOK))
- sd.acct_changes++;
- if (list_find_msg_range(l, AUDIT_ADD_USER, AUDIT_DEL_GROUP))
- sd.acct_changes++;
- if (list_find_msg(l, AUDIT_USER_MGMT))
- sd.acct_changes++;
- if (list_find_msg(l, AUDIT_GRP_MGMT))
- sd.acct_changes++;
- list_first(l);
- if (list_find_msg_range(l, AUDIT_ROLE_ASSIGN, AUDIT_ROLE_REMOVE))
- sd.acct_changes++;
-
- // Crypto
- list_first(l);
- if (list_find_msg_range(l, AUDIT_FIRST_KERN_CRYPTO_MSG,
- AUDIT_LAST_KERN_CRYPTO_MSG))
- sd.crypto++;
- if (list_find_msg_range(l, AUDIT_FIRST_CRYPTO_MSG,
- AUDIT_LAST_CRYPTO_MSG))
- sd.crypto++;
-
- // add logins
- if (list_find_msg(l, AUDIT_USER_LOGIN)) {
- if (l->s.success == S_SUCCESS)
- sd.good_logins++;
- else if (l->s.success == S_FAILED)
- sd.bad_logins++;
- }
-
- // add use of auth
- if (list_find_msg(l, AUDIT_USER_AUTH)) {
- if (l->s.success == S_SUCCESS)
- sd.good_auth++;
- else if (l->s.success == S_FAILED)
- sd.bad_auth++;
- } else if (list_find_msg(l, AUDIT_USER_MGMT)) {
- // Only count the failures
- if (l->s.success == S_FAILED)
- sd.bad_auth++;
- } else if (list_find_msg(l, AUDIT_GRP_AUTH)) {
- if (l->s.success == S_SUCCESS)
- sd.good_auth++;
- else if (l->s.success == S_FAILED)
- sd.bad_auth++;
- }
-
- // add users
- if (l->s.loginuid != -2) {
- char tmp[32];
- snprintf(tmp, sizeof(tmp), "%d", l->s.loginuid);
- slist_add_if_uniq(&sd.users, tmp);
- }
-
- // add terminals
- if (l->s.terminal)
- slist_add_if_uniq(&sd.terms, l->s.terminal);
-
- // add hosts
- if (l->s.hostname)
- slist_add_if_uniq(&sd.hosts, l->s.hostname);
-
- // add execs
- if (l->s.exe)
- slist_add_if_uniq(&sd.exes, l->s.exe);
-
- // add comms
- if (l->s.comm)
- slist_add_if_uniq(&sd.comms, l->s.comm);
-
- // add files
- if (l->s.filename) {
- const snode *sn;
- slist *sptr = l->s.filename;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- if (sn->str)
- slist_add_if_uniq(&sd.files, sn->str);
- sn=slist_next(sptr);
- }
- }
-
- // add avcs
- if (list_find_msg(l, AUDIT_AVC))
- sd.avcs++;
- else if (list_find_msg(l, AUDIT_USER_AVC))
- sd.avcs++;
-
- // MAC
- list_first(l);
- if (list_find_msg_range(l, AUDIT_MAC_POLICY_LOAD,
- AUDIT_MAC_UNLBL_STCDEL))
- sd.mac++;
- if (list_find_msg_range(l, AUDIT_FIRST_USER_LSPP_MSG,
- AUDIT_LAST_USER_LSPP_MSG))
- sd.mac++;
-
- // Virt
- list_first(l);
- if (list_find_msg_range(l, AUDIT_FIRST_VIRT_MSG,
- AUDIT_LAST_VIRT_MSG))
- sd.virt++;
-
- // Integrity
- list_first(l);
- if (list_find_msg_range(l, AUDIT_INTEGRITY_FIRST_MSG,
- AUDIT_INTEGRITY_LAST_MSG))
- sd.integ++;
-
- // add failed syscalls
- if (l->s.success == S_FAILED && l->s.syscall > 0)
- sd.failed_syscalls++;
-
- // add pids
- if (l->s.pid != -1) {
- ilist_add_if_uniq(&sd.pids, l->s.pid, 0);
- }
-
- // add anomalies
- if (list_find_msg_range(l, AUDIT_FIRST_ANOM_MSG, AUDIT_LAST_ANOM_MSG))
- sd.anomalies++;
- if (list_find_msg_range(l, AUDIT_FIRST_KERN_ANOM_MSG,
- AUDIT_LAST_KERN_ANOM_MSG))
- sd.anomalies++;
-
- // add response to anomalies
- if (list_find_msg_range(l, AUDIT_FIRST_ANOM_RESP, AUDIT_LAST_ANOM_RESP))
- sd.responses++;
-
- // add keys
- if (l->s.key) {
- const snode *sn;
- slist *sptr = l->s.key;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn) {
- if (sn->str && strcmp(sn->str, "(null)")) {
- slist_add_if_uniq(&sd.keys, sn->str);
- }
- sn=slist_next(sptr);
- }
- }
-}
-
diff --git a/framework/src/audit/src/aureport-scan.h b/framework/src/audit/src/aureport-scan.h
deleted file mode 100644
index 5044d96d..00000000
--- a/framework/src/audit/src/aureport-scan.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* aureport-scan.h --
- * Copyright 2005-06,2008,2014 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#ifndef AUREPORT_SCAN_H
-#define AUREPORT_SCAN_H
-
-#include "ausearch-llist.h"
-#include "ausearch-int.h"
-
-typedef struct sdata {
- slist users;
- slist terms;
- slist files;
- slist hosts;
- slist exes;
- slist comms;
- slist avc_objs;
- slist keys;
- ilist pids;
- ilist sys_list;
- ilist anom_list;
- ilist resp_list;
- ilist mac_list;
- ilist crypto_list;
- ilist virt_list;
- ilist integ_list;
- unsigned long changes;
- unsigned long crypto;
- unsigned long acct_changes;
- unsigned long good_logins;
- unsigned long bad_logins;
- unsigned long good_auth;
- unsigned long bad_auth;
- unsigned long events;
- unsigned long avcs;
- unsigned long mac;
- unsigned long failed_syscalls;
- unsigned long anomalies;
- unsigned long responses;
- unsigned long virt;
- unsigned long integ;
-} summary_data;
-
-void reset_counters(void);
-void destroy_counters(void);
-int scan(llist *l);
-int per_event_processing(llist *l);
-
-void print_title(void);
-void print_per_event_item(llist *l);
-void print_wrap_up(void);
-
-extern summary_data sd;
-
-#endif
-
diff --git a/framework/src/audit/src/aureport.c b/framework/src/audit/src/aureport.c
deleted file mode 100644
index 98511e01..00000000
--- a/framework/src/audit/src/aureport.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * aureport.c - main file for aureport utility
- * Copyright 2005-08, 2010,11,2013 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <locale.h>
-#include <sys/param.h>
-#include "libaudit.h"
-#include "auditd-config.h"
-#include "aureport-options.h"
-#include "aureport-scan.h"
-#include "ausearch-lol.h"
-#include "ausearch-lookup.h"
-
-
-event very_first_event, very_last_event;
-static FILE *log_fd = NULL;
-static lol lo;
-static int found = 0;
-static int files_to_process = 0; // Logs left when processing multiple
-static int userfile_is_dir = 0;
-static int process_logs(void);
-static int process_log_fd(const char *filename);
-static int process_stdin(void);
-static int process_file(char *filename);
-static int get_record(llist **);
-
-extern char *user_file;
-extern int force_logs;
-
-
-static int is_pipe(int fd)
-{
- struct stat st;
-
- if (fstat(fd, &st) == 0) {
- if (S_ISFIFO(st.st_mode))
- return 1;
- }
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- struct rlimit limit;
- int rc;
-
- /* Check params and build regexpr */
- setlocale (LC_ALL, "");
- if (check_params(argc, argv))
- return 1;
-
- /* Raise the rlimits in case we're being started from a shell
- * with restrictions. Not a fatal error. */
- limit.rlim_cur = RLIM_INFINITY;
- limit.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_FSIZE, &limit);
- setrlimit(RLIMIT_CPU, &limit);
- set_aumessage_mode(MSG_STDERR, DBG_NO);
- (void) umask( umask( 077 ) | 027 );
- very_first_event.sec = 0;
- reset_counters();
-
- print_title();
- lol_create(&lo);
- if (user_file) {
- struct stat sb;
- if (stat(user_file, &sb) == -1) {
- perror("stat");
- return 1;
- } else {
- switch (sb.st_mode & S_IFMT) {
- case S_IFDIR:
- userfile_is_dir = 1;
- rc = process_logs();
- break;
- case S_IFREG:
- default:
- rc = process_file(user_file);
- break;
- }
- }
- } else if (force_logs)
- rc = process_logs();
- else if (is_pipe(0))
- rc = process_stdin();
- else
- rc = process_logs();
- lol_clear(&lo);
- if (rc)
- return rc;
-
- if (!found && report_detail == D_DETAILED && report_type != RPT_TIME) {
- printf("<no events of interest were found>\n\n");
- destroy_counters();
- aulookup_destroy_uid_list();
- aulookup_destroy_gid_list();
- return 1;
- } else
- print_wrap_up();
- destroy_counters();
- aulookup_destroy_uid_list();
- aulookup_destroy_gid_list();
- free(user_file);
- return 0;
-}
-
-static int process_logs(void)
-{
- struct daemon_conf config;
- char *filename;
- int len, num = 0;
-
- if (user_file && userfile_is_dir) {
- char dirname[MAXPATHLEN];
- clear_config (&config);
-
- strcpy(dirname, user_file);
- if (dirname[strlen(dirname)-1] != '/')
- strcat(dirname, "/");
- strcat (dirname, "audit.log");
- free((void *)config.log_file);
- config.log_file=strdup(dirname);
- fprintf(stderr, "NOTE - using logs in %s\n", config.log_file);
- } else {
- /* Load config so we know where logs are */
- if (load_config(&config, TEST_SEARCH))
- fprintf(stderr, "NOTE - using built-in logs: %s\n",
- config.log_file);
- }
-
- /* for each file */
- len = strlen(config.log_file) + 16;
- filename = malloc(len);
- if (!filename) {
- fprintf(stderr, "No memory\n");
- free_config(&config);
- return 1;
- }
- /* Find oldest log file */
- snprintf(filename, len, "%s", config.log_file);
- do {
- if (access(filename, R_OK) != 0)
- break;
-// FIXME: do a time check and put them on linked list for later
- num++;
- snprintf(filename, len, "%s.%d", config.log_file, num);
- } while (1);
- num--;
- /*
- * We note how many files we need to process
- */
- files_to_process = num;
-
- /* Got it, now process logs from last to first */
- if (num > 0)
- snprintf(filename, len, "%s.%d", config.log_file, num);
- else
- snprintf(filename, len, "%s", config.log_file);
- do {
- int ret;
- if ((ret = process_file(filename))) {
- free(filename);
- free_config(&config);
- return ret;
- }
-
- /* Get next log file */
- files_to_process--; /* one less file to process */
- num--;
- if (num > 0)
- snprintf(filename, len, "%s.%d", config.log_file, num);
- else if (num == 0)
- snprintf(filename, len, "%s", config.log_file);
- else
- break;
- } while (1);
- free(filename);
- free_config(&config);
- return 0;
-}
-
-static int process_log_fd(const char *filename)
-{
- llist *entries; // entries in a record
- int ret;
- int first = 0;
- event first_event, last_event;
-
- last_event.sec = 0;
- last_event.milli = 0;
-
- /* For each record in file */
- do {
- ret = get_record(&entries);
- if ((ret != 0)||(entries->cnt == 0))
- break;
- // If report is RPT_TIME or RPT_SUMMARY, get
- if (report_type <= RPT_SUMMARY) {
- if (first == 0) {
- list_get_event(entries, &first_event);
- first = 1;
- if (very_first_event.sec == 0)
- list_get_event(entries,
- &very_first_event);
- }
- list_get_event(entries, &last_event);
- }
- if (scan(entries)) {
- // This is the per entry action item
- if (per_event_processing(entries))
- found = 1;
- }
- list_clear(entries);
- free(entries);
- } while (ret == 0);
- fclose(log_fd);
- // This is the per file action items
- very_last_event.sec = last_event.sec;
- very_last_event.milli = last_event.milli;
- if (report_type == RPT_TIME) {
- if (first == 0) {
- printf("%s: no records\n", filename);
- } else {
- struct tm *btm;
- char tmp[32];
-
- printf("%s: ", filename);
- btm = localtime(&first_event.sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- printf("%s.%03d - ", tmp, first_event.milli);
- btm = localtime(&last_event.sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- printf("%s.%03d\n", tmp, last_event.milli);
- }
- }
-
- return 0;
-}
-
-static int process_stdin(void)
-{
- log_fd = stdin;
-
- return process_log_fd("stdin");
-}
-
-static int process_file(char *filename)
-{
- log_fd = fopen(filename, "rm");
- if (log_fd == NULL) {
- fprintf(stderr, "Error opening %s (%s)\n", filename,
- strerror(errno));
- return 1;
- }
-
- __fsetlocking(log_fd, FSETLOCKING_BYCALLER);
- return process_log_fd(filename);
-}
-
-/*
- * This function returns a malloc'd buffer of the next record in the audit
- * logs. It returns 0 on success, 1 on eof, -1 on error.
- */
-static int get_record(llist **l)
-{
- char *rc;
- char *buff = NULL;
-
- *l = get_ready_event(&lo);
- if (*l)
- return 0;
-
- while (1) {
- if (!buff) {
- buff = malloc(MAX_AUDIT_MESSAGE_LENGTH);
- if (!buff)
- return -1;
- }
- rc = fgets_unlocked(buff, MAX_AUDIT_MESSAGE_LENGTH,
- log_fd);
- if (rc) {
- if (lol_add_record(&lo, buff)) {
- *l = get_ready_event(&lo);
- if (*l)
- break;
- }
- } else {
- free(buff);
- if (feof_unlocked(log_fd)) {
- // Only mark all events complete if this is
- // the last file.
- if (files_to_process == 0) {
- terminate_all_events(&lo);
- }
- *l = get_ready_event(&lo);
- if (*l)
- return 0;
- else
- return 1;
- } else
- return -1;
- }
- }
- free(buff);
- return 0;
-}
-
diff --git a/framework/src/audit/src/ausearch-avc.c b/framework/src/audit/src/ausearch-avc.c
deleted file mode 100644
index 2d3b3199..00000000
--- a/framework/src/audit/src/ausearch-avc.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-* ausearch-avc.c - Minimal linked list library for avcs
-* Copyright (c) 2006,2008,2014 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-#include "ausearch-avc.h"
-
-
-void alist_create(alist *l)
-{
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-anode *alist_next(alist *l)
-{
- if (l->cur == NULL)
- return NULL;
- l->cur = l->cur->next;
- return l->cur;
-}
-
-static void alist_last(alist *l)
-{
- register anode* cur;
-
- if (l->head == NULL)
- return;
-
- // Start with cur in hopes that we don't start at beginning
- if (l->cur)
- cur = l->cur;
- else
- cur = l->head;
-
- // Loop until no next value
- while (cur->next)
- cur = cur->next;
- l->cur = cur;
-}
-
-void alist_append(alist *l, anode *node)
-{
- anode* newnode;
-
- newnode = malloc(sizeof(anode));
-
- if (node->scontext)
- newnode->scontext = node->scontext;
- else
- newnode->scontext = NULL;
-
- if (node->tcontext)
- newnode->tcontext = node->tcontext;
- else
- newnode->tcontext = NULL;
-
- newnode->avc_result = node->avc_result;
-
- if (node->avc_perm)
- newnode->avc_perm = node->avc_perm;
- else
- newnode->avc_perm = NULL;
-
- if (node->avc_class)
- newnode->avc_class = node->avc_class;
- else
- newnode->avc_class = NULL;
-
- newnode->next = NULL;
-
- // Make sure cursor is at the end
- alist_last(l);
-
- // if we are at top, fix this up
- if (l->head == NULL)
- l->head = newnode;
- else // Otherwise add pointer to newnode
- l->cur->next = newnode;
-
- // make newnode current
- l->cur = newnode;
- l->cnt++;
-}
-
-int alist_find_subj(alist *l)
-{
- register anode* window = l->head;
-
- while (window) {
- if (window->scontext) {
- l->cur = window;
- return 1;
- }
- else
- window = window->next;
- }
- return 0;
-}
-
-anode *alist_next_subj(alist *l)
-{
- if (l->cur == NULL)
- return NULL;
- while (l->cur->next) {
- l->cur=l->cur->next;
- if (l->cur->scontext)
- return l->cur;
- }
- return NULL;
-}
-
-int alist_find_obj(alist *l)
-{
- register anode* window = l->head;
-
- while (window) {
- if (window->tcontext) {
- l->cur = window;
- return 1;
- }
- else
- window = window->next;
- }
- return 0;
-}
-
-anode *alist_next_obj(alist *l)
-{
- if (l->cur == NULL)
- return NULL;
- while (l->cur->next) {
- l->cur=l->cur->next;
- if (l->cur->tcontext)
- return l->cur;
- }
- return NULL;
-}
-
-int alist_find_avc(alist *l)
-{
- register anode* window = l->head;
-
- while (window) {
- if (window->avc_result != AVC_UNSET) {
- l->cur = window;
- return 1;
- }
- else
- window = window->next;
- }
- return 0;
-}
-
-anode *alist_next_avc(alist *l)
-{
- if (l->cur == NULL)
- return NULL;
- while (l->cur->next) {
- l->cur=l->cur->next;
- if (l->cur->avc_result != AVC_UNSET)
- return l->cur;
- }
- return NULL;
-}
-
-void alist_clear(alist* l)
-{
- anode* nextnode;
- register anode* current;
-
- current = l->head;
- while (current) {
- nextnode=current->next;
- anode_clear(current);
- free(current);
- current=nextnode;
- }
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-void anode_init(anode *an)
-{
- an->scontext = NULL;
- an->tcontext = NULL;
- an->avc_result = AVC_UNSET;
- an->avc_perm = NULL;
- an->avc_class = NULL;
-}
-
-void anode_clear(anode *an)
-{
- free(an->scontext);
- free(an->tcontext);
- free(an->avc_perm);
- free(an->avc_class);
-}
-
diff --git a/framework/src/audit/src/ausearch-avc.h b/framework/src/audit/src/ausearch-avc.h
deleted file mode 100644
index c31293e1..00000000
--- a/framework/src/audit/src/ausearch-avc.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-* ausearch-avc.h - Header file for ausearch-string.c
-* Copyright (c) 2006,2008 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AU_AVC_HEADER
-#define AU_AVC_HEADER
-
-#include "config.h"
-#include <sys/types.h>
-#include "libaudit.h"
-
-typedef enum { AVC_UNSET, AVC_DENIED, AVC_GRANTED } avc_t;
-
-/* This is the node of the linked list. message & item are the only elements
- * at this time. Any data elements that are per item goes here. */
-typedef struct _anode{
- char *scontext; // se linux subject context
- char *tcontext; // se linux object context
- avc_t avc_result; // se linux avc denied/granted
- char *avc_perm; // se linux avc permission mentioned
- char *avc_class; // se linux class mentioned
- struct _anode* next; // Next string node pointer
-} anode;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- anode *head; // List head
- anode *cur; // Pointer to current node
- unsigned int cnt; // How many items in this list
-} alist;
-
-void alist_create(alist *l);
-static inline void alist_first(alist *l) { l->cur = l->head; }
-anode *alist_next(alist *l);
-static inline anode *alist_get_cur(alist *l) { return l->cur; }
-void alist_append(alist *l, anode *node);
-void anode_init(anode *an);
-void anode_clear(anode *an);
-void alist_clear(alist* l);
-
-/* See if any subj exists in list */
-int alist_find_subj(alist *l);
-anode *alist_next_subj(alist *l);
-/* See if any obj exists in list */
-int alist_find_obj(alist *l);
-anode *alist_next_obj(alist *l);
-/* See if any avc exists in list */
-int alist_find_avc(alist *l);
-anode *alist_next_avc(alist *l);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-checkpt.c b/framework/src/audit/src/ausearch-checkpt.c
deleted file mode 100644
index e0d0022c..00000000
--- a/framework/src/audit/src/ausearch-checkpt.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * ausearch-checkpt.c - ausearch checkpointing feature
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "ausearch-checkpt.h"
-
-#define DBG 0 /* set to non-zero for debug */
-
-/* Remember why we failed */
-unsigned checkpt_failure = 0;
-
-/*
- * Remember the file we were processing when we had incomplete events.
- * We remember this via it's dev and inode
- */
-static dev_t checkpt_dev = (dev_t)NULL;
-static ino_t checkpt_ino = (ino_t)NULL;
-
-/* Remember the last event output */
-static event last_event = {0, 0, 0, NULL, 0};
-
-/* Loaded values from a given checkpoint file */
-dev_t chkpt_input_dev = (dev_t)NULL;
-ino_t chkpt_input_ino = (ino_t)NULL;
-event chkpt_input_levent = {0, 0, 0, NULL, 0};
-
-/*
- * Record the dev_t and ino_t of the given file
- *
- * Returns:
- * 1 Failed to get status
- * 0 OK
- */
-int set_ChkPtFileDetails(const char *fn)
-{
- struct stat sbuf;
-
- if (stat(fn, &sbuf) != 0) {
- fprintf(stderr, "Cannot stat audit file for checkpoint "
- "details - %s: %s\n", fn, strerror(errno));
- checkpt_failure |= CP_STATFAILED;
- return 1;
- }
- checkpt_dev = sbuf.st_dev;
- checkpt_ino = sbuf.st_ino;
-
- return 0;
-}
-
-/*
- * Save the given event in the last_event record
- * Returns:
- * 1 no memory
- * 0 OK
- */
-int set_ChkPtLastEvent(const event *e)
-{
- /* Set the event node if necessary */
- if (e->node) {
- if (last_event.node) {
- if (strcmp(e->node, last_event.node) != 0) {
- free((void *)last_event.node);
- last_event.node = strdup(e->node);
- }
- } else
- last_event.node = strdup(e->node);
- if (last_event.node == NULL) {
- fprintf(stderr, "No memory to allocate "
- "checkpoint last event node name\n");
- return 1;
- }
- } else {
- if (last_event.node)
- free((void *)last_event.node);
- last_event.node = NULL;
- }
- last_event.sec = e->sec;
- last_event.milli = e->milli;
- last_event.serial = e->serial;
- last_event.type = e->type;
-
- return 0;
-}
-
-/* Free all checkpoint memory */
-void free_ChkPtMemory(void)
-{
- if (last_event.node)
- (void)free((void *)last_event.node);
- last_event.node = NULL;
- if (chkpt_input_levent.node)
- (void)free((void *)chkpt_input_levent.node);
- chkpt_input_levent.node = NULL;
-}
-
-/*
- * Save the checkpoint to the given file
- * Returns:
- * 1 io error
- * 0 OK
- */
-void save_ChkPt(const char *fn)
-{
- FILE *fd;
-
- if ((fd = fopen(fn, "w")) == NULL) {
- fprintf(stderr, "Cannot open checkpoint file - %s: %s\n",
- fn, strerror(errno));
- checkpt_failure |= CP_STATUSIO;
- return;
- }
- fprintf(fd, "dev=0x%X\ninode=0x%X\n",
- (unsigned int)checkpt_dev, (unsigned int)checkpt_ino);
- fprintf(fd, "output=%s %lu.%03u:%lu 0x%X\n",
- last_event.node ? last_event.node : "-",
- (long unsigned int)last_event.sec, last_event.milli,
- last_event.serial, last_event.type);
- fclose(fd);
-}
-
-/*
- * Parse a checkpoint file "output=" record
- * Returns
- * 1 failed to parse or no memory
- * 0 parsed OK
- */
-static int parse_checkpt_event(char *lbuf, int ndix, event *e)
-{
- char *rest;
-
- /*
- * Find the space after the node, then make it '\0' so
- * we terminate the node value. We leave 'rest' at the start
- * of the event time/serial element
- */
- rest = strchr(&lbuf[ndix], ' ');
- if (rest == NULL) {
- fprintf(stderr, "Malformed output/event checkpoint line "
- "near node - [%s]\n", lbuf);
- checkpt_failure |= CP_STATUSBAD;
- return 1;
- }
- *rest++ = '\0';
-
- if (lbuf[ndix] == '-')
- e->node = NULL;
- else {
- e->node = strdup(&lbuf[ndix]);
- if (e->node == NULL) {
- fprintf(stderr, "No memory for node when loading "
- "checkpoint line - [%s]\n", lbuf);
- checkpt_failure |= CP_NOMEM;
- return 1;
- }
- }
- if (sscanf(rest, "%lu.%03u:%lu 0x%X", &e->sec, &e->milli,
- &e->serial, &e->type) != 4) {
- fprintf(stderr, "Malformed output/event checkpoint line "
- "after node - [%s]\n", lbuf);
- checkpt_failure |= CP_STATUSBAD;
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Load the checkpoint from the given file
- * Returns:
- * < -1 error
- * == -1 no file present
- * == 0 loaded data
- */
-int load_ChkPt(const char *fn)
-{
-#define MAX_LN 1023
- FILE *fd;
- char lbuf[MAX_LN];
-
- if ((fd = fopen(fn, "r")) == NULL) {
- if (errno == ENOENT)
- return -1;
- fprintf(stderr, "Cannot open checkpoint file - %s: %s\n",
- fn, strerror(errno));
- return -2;
- }
- while (fgets(lbuf, MAX_LN, fd) != NULL) {
- size_t len = strlen(lbuf);
-
- if (len && lbuf[len - 1] == '\n') /* drop the newline */
- lbuf[len - 1] = '\0';
-
- if (strncmp(lbuf, "dev=", 4) == 0) {
- errno = 0;
- chkpt_input_dev = strtoul(&lbuf[4], NULL, 16);
- if (errno) {
- fprintf(stderr, "Malformed dev checkpoint "
- "line - [%s]\n", lbuf);
- checkpt_failure |= CP_STATUSBAD;
- break;
- }
- } else if (strncmp(lbuf, "inode=", 6) == 0) {
- errno = 0;
- chkpt_input_ino = strtoul(&lbuf[6], NULL, 16);
- if (errno) {
- fprintf(stderr, "Malformed inode checkpoint "
- "line - [%s]\n", lbuf);
- checkpt_failure |= CP_STATUSBAD;
- break;
- }
- } else if (strncmp(lbuf, "output=", 7) == 0) {
- if (parse_checkpt_event(lbuf, 7, &chkpt_input_levent))
- break;
- } else {
- fprintf(stderr, "Unknown checkpoint line - [%s]\n",
- lbuf);
- checkpt_failure |= CP_STATUSBAD;
- break;
- }
- }
- if ( (chkpt_input_ino == (ino_t)NULL) ||
- (chkpt_input_dev == (dev_t)NULL) ) {
- fprintf(stderr, "Missing dev/inode lines from checkpoint "
- "file %s\n", fn);
- checkpt_failure |= CP_STATUSBAD;
- }
- fclose(fd);
-
- if (checkpt_failure)
- return -3;
-
-#if DBG
- {
- fprintf(stderr, "Loaded %s - dev: 0x%X, ino: 0x%X\n",
- fn, chkpt_input_dev, chkpt_input_ino);
- fprintf(stderr, "output:%s %d.%03d:%lu 0x%X\n",
- chkpt_input_levent.node ? chkpt_input_levent.node : "-",
- chkpt_input_levent.sec, chkpt_input_levent.milli,
- chkpt_input_levent.serial, chkpt_input_levent.type);
- }
-#endif /* DBG */
- return 0;
-}
-
diff --git a/framework/src/audit/src/ausearch-checkpt.h b/framework/src/audit/src/ausearch-checkpt.h
deleted file mode 100644
index db66c254..00000000
--- a/framework/src/audit/src/ausearch-checkpt.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * ausearch-checkpt.h - ausearch checkpointing feature header file
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CHECKPT_HEADER
-#define CHECKPT_HEADER
-
-#include <sys/types.h>
-#include "ausearch-llist.h"
-
-int set_ChkPtFileDetails(const char *fn);
-int set_ChkPtLastEvent(const event *e);
-void free_ChkPtMemory(void);
-void save_ChkPt(const char *fn);
-int load_ChkPt(const char *fn);
-
-#define CP_NOMEM 0x0001 /* no memory when creating checkpoint list */
-#define CP_STATFAILED 0x0002 /* stat() call on last log file failed */
-#define CP_STATUSIO 0x0004 /* cannot open/read/write checkpoint file */
-#define CP_STATUSBAD 0x0008 /* malformed status checkpoint entries */
-#define CP_CORRUPTED 0x0010 /* corrupted times in checkpoint file */
-
-extern unsigned checkpt_failure;
-
-extern dev_t chkpt_input_dev;
-extern ino_t chkpt_input_ino;
-extern event chkpt_input_levent;
-
-#endif /* CHECKPT_HEADER */
diff --git a/framework/src/audit/src/ausearch-common.h b/framework/src/audit/src/ausearch-common.h
deleted file mode 100644
index 96b59c85..00000000
--- a/framework/src/audit/src/ausearch-common.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* ausearch-common.h --
- * Copyright 2006-08,2010,2014 Red Hat Inc., Durham, North Carolina.
- * Copyright (c) 2011 IBM Corp.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- * Marcelo Henrique Cerri <mhcerri@br.ibm.com>
- *
- */
-
-#ifndef AUREPORT_COMMON_H
-#define AUREPORT_COMMON_H
-
-#include "ausearch-string.h"
-
-/*
- * MAX_EVENT_DELTA_SECS is the maximum number of seconds it would take for
- * auditd and the kernel to emit all of an events' records. Thus, when scanning
- * a list of audit records without any End of Event marker, we can determine if
- * all an event's records have been collected if we compare that event's time
- * with the time of the event we are currently scanning. If
- * MAX_EVENT_DELTA_SECS have passed, then the event is deamed to be complete
- * and we have all it's records.
- */
-#define MAX_EVENT_DELTA_SECS 2
-
-/* Global variables that describe what search is to be performed */
-extern time_t start_time, end_time;
-extern unsigned int event_id;
-extern gid_t event_gid, event_egid;
-extern pid_t event_pid;
-extern int event_exact_match;
-extern uid_t event_uid, event_euid, event_loginuid;
-slist *event_node_list;
-extern const char *event_comm;
-extern const char *event_filename;
-extern const char *event_hostname;
-extern const char *event_terminal;
-extern int event_syscall;
-extern int event_machine;
-extern const char *event_exe;
-extern int event_ua, event_ga;
-extern long long event_exit;
-extern int event_exit_is_set;
-extern const char *event_uuid;
-extern const char *event_vmname;
-
-typedef enum { F_BOTH, F_FAILED, F_SUCCESS } failed_t;
-typedef enum { C_NEITHER, C_ADD, C_DEL } conf_act_t;
-typedef enum { S_UNSET=-1, S_FAILED, S_SUCCESS } success_t;
-typedef enum { RPT_RAW, RPT_DEFAULT, RPT_INTERP, RPT_PRETTY } report_t;
-
-extern failed_t event_failed;
-extern conf_act_t event_conf_act;
-extern success_t event_success;
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-int.c b/framework/src/audit/src/ausearch-int.c
deleted file mode 100644
index a6bf8eb4..00000000
--- a/framework/src/audit/src/ausearch-int.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-* ausearch-int.c - Minimal linked list library for integers
-* Copyright (c) 2005,2008 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-#include "ausearch-int.h"
-
-void ilist_create(ilist *l)
-{
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-int_node *ilist_next(ilist *l)
-{
- if (l->cur == NULL)
- return NULL;
- l->cur = l->cur->next;
- return l->cur;
-}
-
-void ilist_append(ilist *l, int num, unsigned int hits, int aux)
-{
- int_node* newnode;
-
- newnode = malloc(sizeof(int_node));
-
- newnode->num = num;
- newnode->hits = hits;
- newnode->aux1 = aux;
- newnode->next = NULL;
-
- // if we are at top, fix this up
- if (l->head == NULL)
- l->head = newnode;
- else // Otherwise add pointer to newnode
- l->cur->next = newnode;
-
- // make newnode current
- l->cur = newnode;
- l->cnt++;
-}
-
-void ilist_clear(ilist* l)
-{
- int_node* nextnode;
- register int_node* current;
-
- if (l == NULL)
- return;
-
- current = l->head;
- while (current) {
- nextnode=current->next;
- free(current);
- current=nextnode;
- }
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-int ilist_add_if_uniq(ilist *l, int num, int aux)
-{
- register int_node *cur, *prev;
-
- prev = cur = l->head;
- while (cur) {
- if (cur->num == num) {
- cur->hits++;
- return 0;
- } else if (num > cur->num) {
- prev = cur;
- cur = cur->next;
- } else {
- int head = 0;
-
- // Insert so list is from low to high
- if (cur == l->head) {
- l->head = NULL;
- head = 1;
- } else
- l->cur = prev;
- ilist_append(l, num, 1, aux);
- if (head)
- l->cur->next = prev;
- else
- l->cur->next = cur;
- return 1;
- }
- }
-
- if (prev)
- l->cur = prev;
-
- /* No matches, append to the end */
- ilist_append(l, num, 1, aux);
- return 1;
-}
-
-// If lprev would be NULL, use l->head
-static void swap_nodes(int_node *lprev, int_node *left, int_node *right)
-{
- int_node *t = right->next;
- if (lprev)
- lprev->next = right;
- right->next = left;
- left->next = t;
-}
-
-// This will sort the list from most hits to least
-void ilist_sort_by_hits(ilist *l)
-{
- register int_node* cur, *prev;
-
- if (l->cnt <= 1)
- return;
-
- prev = cur = l->head;
- while (cur && cur->next) {
- /* If the next node is bigger */
- if (cur->hits < cur->next->hits) {
- if (cur == l->head) {
- // Update the actual list head
- l->head = cur->next;
- prev = NULL;
- }
- swap_nodes(prev, cur, cur->next);
-
- // start over
- prev = cur = l->head;
- continue;
- }
- prev = cur;
- cur = cur->next;
- }
- // End with cur pointing at first record
- l->cur = l->head;
-}
-
diff --git a/framework/src/audit/src/ausearch-int.h b/framework/src/audit/src/ausearch-int.h
deleted file mode 100644
index bc2c51fc..00000000
--- a/framework/src/audit/src/ausearch-int.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* ausearch-int.h - Header file for ausearch-int.c
-* Copyright (c) 2005,2008 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AUINT_HEADER
-#define AUINT_HEADER
-
-#include "config.h"
-
-/* This is the node of the linked list. Number & item are the only elements
- * at this time. Any data elements that are per item goes here. */
-typedef struct _int_node{
- int num; // The number
- unsigned int hits; // The number of times this was attempted to be added
- int aux1; // Extra spot for data
- struct _int_node* next; // Next string node pointer
-} int_node;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- int_node *head; // List head
- int_node *cur; // Pointer to current node
- unsigned int cnt; // How many items in this list
-} ilist;
-
-void ilist_create(ilist *l);
-static inline void ilist_first(ilist *l) { l->cur = l->head; }
-int_node *ilist_next(ilist *l);
-static inline int_node *ilist_get_cur(ilist *l) { return l->cur; }
-void ilist_append(ilist *l, int num, unsigned int hits, int aux);
-void ilist_clear(ilist* l);
-
-/* append a number if its not already on the list */
-int ilist_add_if_uniq(ilist *l, int num, int aux);
-void ilist_sort_by_hits(ilist *l);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-llist.c b/framework/src/audit/src/ausearch-llist.c
deleted file mode 100644
index 973941c5..00000000
--- a/framework/src/audit/src/ausearch-llist.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-* ausearch-llist.c - Minimal linked list library
-* Copyright (c) 2005-2008, 2011 Red Hat Inc., Durham, North Carolina.
-* Copyright (c) 2011 IBM Corp.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-* Marcelo Henrique Cerri <mhcerri@br.ibm.com>
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include "ausearch-llist.h"
-
-void list_create(llist *l)
-{
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
- l->e.milli = 0L;
- l->e.sec = 0L;
- l->e.serial = 0L;
- l->e.node = NULL;
- l->e.type = 0;
- l->s.gid = -1;
- l->s.egid = -1;
- l->s.ppid = -1;
- l->s.pid = -1;
- l->s.success = S_UNSET;
- l->s.uid = -1;
- l->s.euid = -1;
- l->s.loginuid = -2;
- l->s.hostname = NULL;
- l->s.filename = NULL;
- l->s.terminal = NULL;
- l->s.cwd = NULL;
- l->s.exe = NULL;
- l->s.key = NULL;
- l->s.comm = NULL;
- l->s.avc = NULL;
- l->s.acct = NULL;
- l->s.arch = 0;
- l->s.syscall = 0;
- l->s.session_id = -2;
- l->s.uuid = NULL;
- l->s.vmname = NULL;
- l->s.exit = 0;
- l->s.exit_is_set = 0;
-}
-
-void list_last(llist *l)
-{
- register lnode* window;
-
- if (l->head == NULL)
- return;
-
- window = l->head;
- while (window->next)
- window = window->next;
- l->cur = window;
-}
-
-lnode *list_next(llist *l)
-{
- if (l->cur == NULL)
- return NULL;
- l->cur = l->cur->next;
- return l->cur;
-}
-
-lnode *list_prev(llist *l)
-{
- if (l->cur == NULL)
- return NULL;
-
- if (l->cur->item == 0)
- return NULL;
-
- list_find_item(l, l->cur->item-1);
- return l->cur;
-}
-
-void list_append(llist *l, lnode *node)
-{
- lnode* newnode;
-
- newnode = malloc(sizeof(lnode));
-
- if (node->message)
- newnode->message = node->message;
- else
- newnode->message = NULL;
-
- newnode->mlen = node->mlen;
- newnode->type = node->type;
- newnode->a0 = node->a0;
- newnode->a1 = node->a1;
- newnode->item = l->cnt;
- newnode->next = NULL;
-
- // if we are at top, fix this up
- if (l->head == NULL)
- l->head = newnode;
- else // Otherwise add pointer to newnode
- l->cur->next = newnode;
-
- // make newnode current
- l->cur = newnode;
- l->cnt++;
-}
-
-int list_find_item(llist *l, unsigned int i)
-{
- register lnode* window;
-
- if (l->cur && (l->cur->item <= i))
- window = l->cur; /* Try to use where we are */
- else
- window = l->head; /* Can't, start over */
-
- while (window) {
- if (window->item == i) {
- l->cur = window;
- return 1;
- } else
- window = window->next;
- }
- return 0;
-}
-
-void list_clear(llist* l)
-{
- lnode* nextnode;
- register lnode* current;
-
- current = l->head;
- while (current) {
- nextnode=current->next;
- free(current->message);
- free(current);
- current=nextnode;
- }
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
- l->e.milli = 0L;
- l->e.sec = 0L;
- l->e.serial = 0L;
- free((char *)l->e.node);
- l->e.node = NULL;
- l->e.type = 0;
- l->s.gid = -1;
- l->s.egid = -1;
- l->s.ppid = -1;
- l->s.pid = -1;
- l->s.success = S_UNSET;
- l->s.uid = -1;
- l->s.euid = -1;
- l->s.loginuid = -2;
- free(l->s.hostname);
- l->s.hostname = NULL;
- if (l->s.filename) {
- slist_clear(l->s.filename);
- free(l->s.filename);
- l->s.filename = NULL;
- }
- free(l->s.terminal);
- l->s.terminal = NULL;
- free(l->s.cwd);
- l->s.cwd = NULL;
- free(l->s.exe);
- l->s.exe = NULL;
- if (l->s.key) {
- slist_clear(l->s.key);
- free(l->s.key);
- l->s.key = NULL;
- }
- free(l->s.comm);
- l->s.comm = NULL;
- if (l->s.avc) {
- alist_clear(l->s.avc);
- free(l->s.avc);
- l->s.avc = NULL;
- }
- free(l->s.acct);
- l->s.acct = NULL;
- l->s.arch = 0;
- l->s.syscall = 0;
- l->s.session_id = -2;
- free(l->s.uuid);
- l->s.uuid = NULL;
- free(l->s.vmname);
- l->s.vmname = NULL;
- l->s.exit = 0;
- l->s.exit_is_set = 0;
-}
-
-int list_get_event(llist* l, event *e)
-{
- if (l == NULL || e == NULL)
- return 0;
-
- e->sec = l->e.sec;
- e->milli = l->e.milli;
- e->serial = l->e.serial;
- return 1;
-}
-
-lnode *list_find_msg(llist *l, int i)
-{
- register lnode* window;
-
- window = l->head; /* start at the beginning */
- while (window) {
- if (window->type == i) {
- l->cur = window;
- return window;
- } else
- window = window->next;
- }
- return NULL;
-}
-
-lnode *list_find_msg_range(llist *l, int low, int high)
-{
- register lnode* window;
-
- if (high <= low)
- return NULL;
-
- window = l->head; /* Start at the beginning */
- while (window) {
- if (window->type >= low && window->type <= high) {
- l->cur = window;
- return window;
- } else
- window = window->next;
- }
- return NULL;
-}
-
diff --git a/framework/src/audit/src/ausearch-llist.h b/framework/src/audit/src/ausearch-llist.h
deleted file mode 100644
index ada8ec81..00000000
--- a/framework/src/audit/src/ausearch-llist.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-* ausearch-llist.h - Header file for ausearch-llist.c
-* Copyright (c) 2005-2008, 2013-14 Red Hat Inc., Durham, North Carolina.
-* Copyright (c) 2011 IBM Corp.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-* Marcelo Henrique Cerri <mhcerri@br.ibm.com>
-*/
-
-#ifndef AULIST_HEADER
-#define AULIST_HEADER
-
-#include "config.h"
-#include <sys/types.h>
-#include "ausearch-string.h"
-#include "ausearch-avc.h"
-#include "ausearch-common.h"
-
-
-typedef struct
-{
- time_t sec; // Event seconds
- unsigned int milli; // millisecond of the timestamp
- unsigned long serial; // Serial number of the event
- const char *node; // Machine's node name
- int type; // type of first event
-} event;
-
-typedef struct
-{
- pid_t ppid; // parent process ID
- pid_t pid; // process ID
- uid_t uid; // user ID
- uid_t euid; // effective user ID
- uid_t loginuid; // login user ID
- gid_t gid; // group ID
- gid_t egid; // effective group ID
- success_t success; // success flag, 1 = yes, 0 = no, -1 = unset
- int arch; // arch
- int syscall; // syscall
- uint32_t session_id; // Login session id
- long long exit; // Syscall exit code
- int exit_is_set; // Syscall exit code is valid
- char *hostname; // remote hostname
- slist *filename; // filename list
- char *cwd; // current working dir
- char *exe; // executable
- slist *key; // key field
- char *terminal; // terminal
- char *comm; // comm name
- alist *avc; // avcs for the event
- char *acct; // account used when uid is invalid
- char *uuid; // virtual machine unique universal identifier
- char *vmname; // virtual machine name
-} search_items;
-
-/* This is the node of the linked list. Any data elements that are per
- * record goes here. */
-typedef struct _lnode{
- char *message; // The whole unparsed message
- unsigned mlen; // Length of the message
- int type; // message type (KERNEL, USER, LOGIN, etc)
- unsigned long long a0; // argv 0
- unsigned long long a1; // argv 1
- unsigned int item; // Which item of the same event
- struct _lnode* next; // Next node pointer
-} lnode;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- lnode *head; // List head
- lnode *cur; // Pointer to current node
- unsigned int cnt; // How many items in this list
-
- // Data we add as 1 per event
- event e; // event - time & serial number
- search_items s; // items in master rec that are searchable
-} llist;
-
-void list_create(llist *l);
-static inline void list_first(llist *l) { l->cur = l->head; }
-void list_last(llist *l);
-lnode *list_next(llist *l);
-lnode *list_prev(llist *l);
-static inline lnode *list_get_cur(llist *l) { return l->cur; }
-void list_append(llist *l, lnode *node);
-void list_clear(llist* l);
-int list_get_event(llist* l, event *e);
-
-/* Given a numeric index, find that record. */
-int list_find_item(llist *l, unsigned int i);
-
-/* Given a message type, find the matching node */
-lnode *list_find_msg(llist *l, int i);
-
-/* Given two message types, find the first matching node */
-lnode *list_find_msg_range(llist *l, int low, int high);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-lol.c b/framework/src/audit/src/ausearch-lol.c
deleted file mode 100644
index 48005126..00000000
--- a/framework/src/audit/src/ausearch-lol.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
-* ausearch-lol.c - linked list of linked lists library
-* Copyright (c) 2008,2010,2014 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "ausearch-lol.h"
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include "ausearch-common.h"
-#include "private.h"
-
-#define ARRAY_LIMIT 80
-static int ready = 0;
-
-void lol_create(lol *lo)
-{
- int size = ARRAY_LIMIT * sizeof(lolnode);
-
- lo->maxi = -1;
- lo->limit = ARRAY_LIMIT;
- lo->array = (lolnode *)malloc(size);
- memset(lo->array, 0, size);
-}
-
-void lol_clear(lol *lo)
-{
- int i;
-
- for (i=0; i<=lo->maxi; i++) {
- if (lo->array[i].status) {
- list_clear(lo->array[i].l);
- free(lo->array[i].l);
- }
- }
- free(lo->array);
- lo->array = NULL;
- lo->maxi = -1;
-}
-
-static void lol_append(lol *lo, llist *l)
-{
- int i;
- size_t new_size;
- lolnode *ptr;
-
- for(i=0; i<lo->limit; i++) {
- lolnode *cur = &lo->array[i];
- if (cur->status == L_EMPTY) {
- cur->l = l;
- cur->status = L_BUILDING;
- if (i > lo->maxi)
- lo->maxi = i;
- return;
- }
- }
- // Overran the array...lets make it bigger
- new_size = sizeof(lolnode) * (lo->limit + ARRAY_LIMIT);
- ptr = realloc(lo->array, new_size);
- if (ptr) {
- lo->array = ptr;
- memset(&lo->array[lo->limit], 0, sizeof(lolnode) * ARRAY_LIMIT);
- lo->array[i].l = l;
- lo->array[i].status = L_BUILDING;
- lo->maxi = i;
- lo->limit += ARRAY_LIMIT;
- }
-}
-
-static int str2event(char *s, event *e)
-{
- char *ptr;
-
- errno = 0;
- ptr = strchr(s+10, ':');
- if (ptr) {
- e->serial = strtoul(ptr+1, NULL, 10);
- *ptr = 0;
- if (errno)
- return -1;
- } else
- e->serial = 0;
- ptr = strchr(s, '.');
- if (ptr) {
- e->milli = strtoul(ptr+1, NULL, 10);
- *ptr = 0;
- if (errno)
- return -1;
- } else
- e->milli = 0;
- e->sec = strtoul(s, NULL, 10);
- if (errno)
- return -1;
- return 0;
-}
-
-static int inline events_are_equal(event *e1, event *e2)
-{
- if (!(e1->serial == e2->serial && e1->milli == e2->milli &&
- e1->sec == e2->sec))
- return 0;
- if (e1->node && e2->node) {
- if (strcmp(e1->node, e2->node))
- return 0;
- } else if (e1->node || e2->node)
- return 0;
- return 1;
-}
-
-/*
- * This function will look at the line and pick out pieces of it.
- */
-static int extract_timestamp(const char *b, event *e)
-{
- char *ptr, *tmp, *tnode, *ttype;
-
- e->node = NULL;
- if (*b == 'n')
- tmp = strndupa(b, 340);
- else
- tmp = strndupa(b, 80);
- ptr = audit_strsplit(tmp);
- if (ptr) {
- // Check to see if this is the node info
- if (*ptr == 'n') {
- tnode = ptr+5;
- ptr = audit_strsplit(NULL);
- } else
- tnode = NULL;
-
- // at this point we have type=
- ttype = ptr+5;
-
- // Now should be pointing to msg=
- ptr = audit_strsplit(NULL);
- if (ptr) {
- if (*(ptr+9) == '(')
- ptr+=9;
- else
- ptr = strchr(ptr, '(');
- if (ptr) {
- // now we should be pointed at the timestamp
- char *eptr;
- ptr++;
- eptr = strchr(ptr, ')');
- if (eptr)
- *eptr = 0;
- if (str2event(ptr, e)) {
- fprintf(stderr,
- "Error extracting time stamp (%s)\n",
- ptr);
- return 0;
- } else if ((start_time && e->sec < start_time)
- || (end_time && e->sec > end_time))
- return 0;
- else {
- if (tnode)
- e->node = strdup(tnode);
- e->type = audit_name_to_msg_type(ttype);
- }
- return 1;
- }
- // else we have a bad line
- }
- // else we have a bad line
- }
- // else we have a bad line
- return 0;
-}
-
-// This function will check events to see if they are complete
-// FIXME: Can we think of other ways to determine if the event is done?
-static void check_events(lol *lo, time_t sec)
-{
- int i;
-
- for(i=0;i<=lo->maxi; i++) {
- lolnode *cur = &lo->array[i];
- if (cur->status == L_BUILDING) {
- // If 2 seconds have elapsed, we are done
- if (cur->l->e.sec + 2 < sec) {
- cur->status = L_COMPLETE;
- ready++;
- } else if (cur->l->e.type < AUDIT_FIRST_EVENT ||
- cur->l->e.type >= AUDIT_FIRST_ANOM_MSG) {
- // If known to be 1 record event, we are done
- cur->status = L_COMPLETE;
- ready++;
- }
- }
- }
-}
-
-// This function adds a new record to an existing linked list
-// or creates a new one if its a new event
-int lol_add_record(lol *lo, char *buff)
-{
- int i;
- lnode n;
- event e;
- char *ptr;
- llist *l;
-
- // Short circuit if event is not of interest
- if (extract_timestamp(buff, &e) == 0)
- return 0;
-
- ptr = strrchr(buff, 0x0a);
- if (ptr) {
- *ptr = 0;
- n.mlen = ptr - buff;
- } else
- n.mlen = MAX_AUDIT_MESSAGE_LENGTH;
- n.message=strdup(buff);
- n.type = e.type;
-
- // Now see where this belongs
- for (i=0; i<=lo->maxi; i++) {
- if (lo->array[i].status == L_BUILDING) {
- l = lo->array[i].l;
- if (events_are_equal(&l->e, &e)) {
- free((char *)e.node);
- list_append(l, &n);
- return 1;
- }
- }
- }
- // Create new event and fill it in
- l = malloc(sizeof(llist));
- list_create(l);
- l->e.milli = e.milli;
- l->e.sec = e.sec;
- l->e.serial = e.serial;
- l->e.node = e.node;
- l->e.type = e.type;
- list_append(l, &n);
- lol_append(lo, l);
- check_events(lo, e.sec);
- return 1;
-}
-
-// This function will mark all events as "done"
-void terminate_all_events(lol *lo)
-{
- int i;
-
- for (i=0; i<=lo->maxi; i++) {
- lolnode *cur = &lo->array[i];
- if (cur->status == L_BUILDING) {
- cur->status = L_COMPLETE;
- ready++;
- }
- }
-//printf("maxi = %d\n",lo->maxi);
-}
-
-/* Search the list for any event that is ready to go. The caller
- * takes custody of the memory */
-llist* get_ready_event(lol *lo)
-{
- int i;
-
- if (ready == 0)
- return NULL;
-
- for (i=0; i<=lo->maxi; i++) {
- lolnode *cur = &lo->array[i];
- if (cur->status == L_COMPLETE) {
- cur->status = L_EMPTY;
- ready--;
- return cur->l;
- }
- }
-
- return NULL;
-}
-
diff --git a/framework/src/audit/src/ausearch-lol.h b/framework/src/audit/src/ausearch-lol.h
deleted file mode 100644
index 36b6bbca..00000000
--- a/framework/src/audit/src/ausearch-lol.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-* ausearch-lol.h - linked list of linked lists library header
-* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AUSEARCH_LOL_HEADER
-#define AUSEARCH_LOL_HEADER
-
-#include "config.h"
-#include "ausearch-llist.h"
-
-typedef enum { L_EMPTY, L_BUILDING, L_COMPLETE } lol_t;
-
-/* This is the node of the linked list. message & item are the only elements
- * at this time. Any data elements that are per item goes here. */
-typedef struct _lolnode{
- llist *l; // The linked list
- int status; // 0 = empty, 1 in use, 2 complete
-} lolnode;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- lolnode *array;
- int maxi; // Largest index used
- int limit; // Number of nodes in the array
-} lol;
-
-void lol_create(lol *lo);
-void lol_clear(lol *lo);
-int lol_add_record(lol *lo, char *buff);
-void terminate_all_events(lol *lo);
-llist* get_ready_event(lol *lo);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-lookup.c b/framework/src/audit/src/ausearch-lookup.c
deleted file mode 100644
index 10a219a5..00000000
--- a/framework/src/audit/src/ausearch-lookup.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
-* ausearch-lookup.c - Lookup values to something more readable
-* Copyright (c) 2005-06,2011-12,2015 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <linux/net.h>
-#include "ausearch-lookup.h"
-#include "ausearch-options.h"
-#include "ausearch-nvpair.h"
-
-/* This is the name/value pair used by search tables */
-struct nv_pair {
- int value;
- const char *name;
-};
-
-
-/* The machine based on elf type */
-static int machine = 0;
-static const char *Q = "?";
-static const char *results[3]= { "unset", "denied", "granted" };
-static const char *success[3]= { "unset", "no", "yes" };
-static const char *aulookup_socketcall(long sc);
-static const char *aulookup_ipccall(long ic);
-
-const char *aulookup_result(avc_t result)
-{
- return results[result];
-}
-
-const char *aulookup_success(int s)
-{
- switch (s)
- {
- default:
- return success[0];
- break;
- case S_FAILED:
- return success[1];
- break;
- case S_SUCCESS:
- return success[2];
- break;
- }
-}
-
-const char *aulookup_syscall(llist *l, char *buf, size_t size)
-{
- const char *sys;
-
- if (report_format <= RPT_DEFAULT) {
- snprintf(buf, size, "%d", l->s.syscall);
- return buf;
- }
- machine = audit_elf_to_machine(l->s.arch);
- if (machine < 0)
- return Q;
- sys = audit_syscall_to_name(l->s.syscall, machine);
- if (sys) {
- const char *func = NULL;
- if (strcmp(sys, "socketcall") == 0) {
- if (list_find_item(l, AUDIT_SYSCALL))
- func = aulookup_socketcall((long)l->cur->a0);
- } else if (strcmp(sys, "ipc") == 0) {
- if(list_find_item(l, AUDIT_SYSCALL))
- func = aulookup_ipccall((long)l->cur->a0);
- }
- if (func) {
- snprintf(buf, size, "%s(%s)", sys, func);
- return buf;
- }
- return sys;
- }
- snprintf(buf, size, "%d", l->s.syscall);
- return buf;
-}
-
-// See include/linux/net.h
-static struct nv_pair socktab[] = {
- {SYS_SOCKET, "socket"},
- {SYS_BIND, "bind"},
- {SYS_CONNECT, "connect"},
- {SYS_LISTEN, "listen"},
- {SYS_ACCEPT, "accept"},
- {SYS_GETSOCKNAME, "getsockname"},
- {SYS_GETPEERNAME, "getpeername"},
- {SYS_SOCKETPAIR, "socketpair"},
- {SYS_SEND, "send"},
- {SYS_RECV, "recv"},
- {SYS_SENDTO, "sendto"},
- {SYS_RECVFROM, "recvfrom"},
- {SYS_SHUTDOWN, "shutdown"},
- {SYS_SETSOCKOPT, "setsockopt"},
- {SYS_GETSOCKOPT, "getsockopt"},
- {SYS_SENDMSG, "sendmsg"},
- {SYS_RECVMSG, "recvmsg"},
- {SYS_ACCEPT4, "accept4"},
- {19, "recvmmsg"},
- {20, "sendmmsg"}
-};
-#define SOCK_NAMES (sizeof(socktab)/sizeof(socktab[0]))
-
-static const char *aulookup_socketcall(long sc)
-{
- int i;
-
- for (i = 0; i < SOCK_NAMES; i++)
- if (socktab[i].value == sc)
- return socktab[i].name;
-
- return NULL;
-}
-
-/* This is from asm/ipc.h. Copying it for now as some platforms
- * have broken headers. */
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/*
- * This table maps ipc calls to their text name
- */
-static struct nv_pair ipctab[] = {
- {SEMOP, "semop"},
- {SEMGET, "semget"},
- {SEMCTL, "semctl"},
- {SEMTIMEDOP, "semtimedop"},
- {MSGSND, "msgsnd"},
- {MSGRCV, "msgrcv"},
- {MSGGET, "msgget"},
- {MSGCTL, "msgctl"},
- {SHMAT, "shmat"},
- {SHMDT, "shmdt"},
- {SHMGET, "shmget"},
- {SHMCTL, "shmctl"}
-};
-#define IPC_NAMES (sizeof(ipctab)/sizeof(ipctab[0]))
-
-static const char *aulookup_ipccall(long ic)
-{
- int i;
-
- for (i = 0; i < IPC_NAMES; i++)
- if (ipctab[i].value == ic)
- return ipctab[i].name;
-
- return NULL;
-}
-
-static nvlist uid_nvl;
-static int uid_list_created=0;
-const char *aulookup_uid(uid_t uid, char *buf, size_t size)
-{
- char *name = NULL;
- int rc;
-
- if (report_format <= RPT_DEFAULT) {
- snprintf(buf, size, "%d", uid);
- return buf;
- }
- if (uid == -1) {
- snprintf(buf, size, "unset");
- return buf;
- }
-
- // Check the cache first
- if (uid_list_created == 0) {
- nvlist_create(&uid_nvl);
- nvlist_clear(&uid_nvl);
- uid_list_created = 1;
- }
- rc = nvlist_find_val(&uid_nvl, uid);
- if (rc) {
- name = uid_nvl.cur->name;
- } else {
- // Add it to cache
- struct passwd *pw;
- pw = getpwuid(uid);
- if (pw) {
- nvnode nv;
- nv.name = strdup(pw->pw_name);
- nv.val = uid;
- nvlist_append(&uid_nvl, &nv);
- name = uid_nvl.cur->name;
- }
- }
- if (name != NULL)
- snprintf(buf, size, "%s", name);
- else
- snprintf(buf, size, "unknown(%d)", uid);
- return buf;
-}
-
-void aulookup_destroy_uid_list(void)
-{
- if (uid_list_created == 0)
- return;
-
- nvlist_clear(&uid_nvl);
- uid_list_created = 0;
-}
-
-static nvlist gid_nvl;
-static int gid_list_created=0;
-const char *aulookup_gid(gid_t gid, char *buf, size_t size)
-{
- char *name = NULL;
- int rc;
-
- if (report_format <= RPT_DEFAULT) {
- snprintf(buf, size, "%d", gid);
- return buf;
- }
- if (gid == -1) {
- snprintf(buf, size, "unset");
- return buf;
- }
-
- // Check the cache first
- if (gid_list_created == 0) {
- nvlist_create(&gid_nvl);
- nvlist_clear(&gid_nvl);
- gid_list_created = 1;
- }
- rc = nvlist_find_val(&gid_nvl, gid);
- if (rc) {
- name = gid_nvl.cur->name;
- } else {
- // Add it to cache
- struct group *gr;
- gr = getgrgid(gid);
- if (gr) {
- nvnode nv;
- nv.name = strdup(gr->gr_name);
- nv.val = gid;
- nvlist_append(&gid_nvl, &nv);
- name = gid_nvl.cur->name;
- }
- }
- if (name != NULL)
- snprintf(buf, size, "%s", name);
- else
- snprintf(buf, size, "unknown(%d)", gid);
- return buf;
-}
-
-void aulookup_destroy_gid_list(void)
-{
- if (gid_list_created == 0)
- return;
-
- nvlist_clear(&gid_nvl);
- gid_list_created = 0;
-}
-
-int is_hex_string(const char *str)
-{
- int c=0;
- while (*str) {
- if (!isxdigit(*str))
- return 0;
- str++;
- c++;
- }
- return 1;
-}
-/*
- * This function will take a pointer to a 2 byte Ascii character buffer and
- * return the actual hex value.
- */
-static unsigned char x2c(unsigned char *buf)
-{
- static const char AsciiArray[17] = "0123456789ABCDEF";
- char *ptr;
- unsigned char total=0;
-
- ptr = strchr(AsciiArray, (char)toupper(buf[0]));
- if (ptr)
- total = (unsigned char)(((ptr-AsciiArray) & 0x0F)<<4);
- ptr = strchr(AsciiArray, (char)toupper(buf[1]));
- if (ptr)
- total += (unsigned char)((ptr-AsciiArray) & 0x0F);
-
- return total;
-}
-
-/* returns a freshly malloc'ed and converted buffer */
-char *unescape(const char *buf)
-{
- int len, i;
- char *str, *strptr;
- const char *ptr = buf;
-
- /* Find the end of the name */
- if (*ptr == '(') {
- ptr = strchr(ptr, ')');
- if (ptr == NULL)
- return NULL;
- else
- ptr++;
- } else {
- while (isxdigit(*ptr))
- ptr++;
- }
- str = strndup(buf, ptr - buf);
-
- if (*buf == '(')
- return str;
-
- /* We can get away with this since the buffer is 2 times
- * bigger than what we are putting there.
- */
- len = strlen(str);
- if (len < 2) {
- free(str);
- return NULL;
- }
- strptr = str;
- for (i=0; i<len; i+=2) {
- *strptr = x2c((unsigned char *)&str[i]);
- strptr++;
- }
- *strptr = 0;
- return str;
-}
-
-int need_sanitize(const unsigned char *s, unsigned int len)
-{
- unsigned int i = 0;
- while (i < len) {
- if (s[i] < 32)
- return 1;
- i++;
- }
- return 0;
-}
-
-void sanitize(const char *s, unsigned int len)
-{
- unsigned int i = 0;
- while (i < len) {
- if ((unsigned char)s[i] < 32) {
- putchar('\\');
- putchar('0' + ((s[i] & 0300) >> 6));
- putchar('0' + ((s[i] & 0070) >> 3));
- putchar('0' + (s[i] & 0007));
- } else
- putchar(s[i]);
- i++;
- }
-}
-
-void safe_print_string_n(const char *s, unsigned int len, int ret)
-{
- if (need_sanitize(s, len)) {
- sanitize(s, len);
- if (ret)
- putchar('\n');
- } else if (ret)
- puts(s);
- else
- printf("%s", s);
-}
-
-void safe_print_string(const char *s, int ret)
-{
- safe_print_string_n(s, strlen(s), ret);
-}
-
-/* Represent c as a character within a quoted string, and append it to buf. */
-static void tty_printable_char(unsigned char c)
-{
- if (c < 0x20 || c > 0x7E) {
- putchar('\\');
- putchar('0' + ((c >> 6) & 07));
- putchar('0' + ((c >> 3) & 07));
- putchar('0' + (c & 07));
- } else {
- if (c == '\\' || c == '"')
- putchar('\\');
- putchar(c);
- }
-}
-
-/* Search for a name of a sequence of TTY bytes.
- * If found, return the name and advance *INPUT.
- * Return NULL otherwise.
- */
-static const char *tty_find_named_key(unsigned char **input, size_t input_len)
-{
- /* NUL-terminated list of (sequence, NUL, name, NUL) entries.
- First match wins, even if a longer match were possible later */
- static const unsigned char named_keys[] =
-#define E(SEQ, NAME) SEQ "\0" NAME "\0"
-#include "auparse/tty_named_keys.h"
-#undef E
- "\0";
-
- unsigned char *src;
- const unsigned char *nk;
-
- src = *input;
- if (*src >= ' ' && (*src < 0x7F || *src >= 0xA0))
- return NULL; /* Fast path */
- nk = named_keys;
- do {
- const unsigned char *p;
- size_t nk_len;
-
- p = strchr((const char *)nk, '\0');
- nk_len = p - nk;
- if (nk_len <= input_len && memcmp(src, nk, nk_len) == 0) {
- *input += nk_len;
- return (const char *)(p + 1);
- }
- nk = strchr((const char *)p + 1, '\0') + 1;
- } while (*nk != '\0');
- return NULL;
-}
-
-void print_tty_data(const char *val)
-{
- int need_comma, in_printable = 0;
- unsigned char *data, *data_pos, *data_end;
-
- if (!is_hex_string(val)) {
- printf("%s", val);
- return;
- }
-
- if ((data = unescape((char *)val)) == NULL) {
- printf("conversion error(%s)", val);
- return;
- }
-
- data_end = data + strlen(val) / 2;
- data_pos = data;
- need_comma = 0;
- while (data_pos < data_end) {
- /* FIXME: Unicode */
- const char *desc;
-
- desc = tty_find_named_key(&data_pos, data_end - data_pos);
- if (desc != NULL) {
- if (in_printable != 0) {
- putchar('"');
- in_printable = 0;
- }
- if (need_comma != 0)
- putchar(',');
- printf("<%s>", desc);
- } else {
- if (in_printable == 0) {
- if (need_comma != 0)
- putchar(',');
- putchar('"');
- in_printable = 1;
- }
- tty_printable_char(*data_pos);
- data_pos++;
- }
- need_comma = 1;
- }
- if (in_printable != 0)
- putchar('"');
- free(data);
-}
-
diff --git a/framework/src/audit/src/ausearch-lookup.h b/framework/src/audit/src/ausearch-lookup.h
deleted file mode 100644
index ab12e176..00000000
--- a/framework/src/audit/src/ausearch-lookup.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-* ausearch-lookup.h - Header file for ausearch-lookup.c
-* Copyright (c) 2005-06,2014 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AULOOKUP_HEADER
-#define AULOOKUP_HEADER
-
-#include "config.h"
-#include <pwd.h>
-#include <grp.h>
-#include "libaudit.h"
-#include "ausearch-llist.h"
-
-
-const char *aulookup_result(avc_t result);
-const char *aulookup_success(int s);
-const char *aulookup_syscall(llist *l, char *buf, size_t size);
-const char *aulookup_uid(uid_t uid, char *buf, size_t size);
-void aulookup_destroy_uid_list(void);
-const char *aulookup_gid(gid_t gid, char *buf, size_t size);
-void aulookup_destroy_gid_list(void);
-char *unescape(const char *buf);
-int is_hex_string(const char *str);
-void print_tty_data(const char *val);
-int need_sanitize(const unsigned char *s, unsigned int len);
-void sanitize(const char *s, unsigned int len);
-void safe_print_string_n(const char *s, unsigned int len, int ret);
-void safe_print_string(const char *s, int ret);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-match.c b/framework/src/audit/src/ausearch-match.c
deleted file mode 100644
index 44c60887..00000000
--- a/framework/src/audit/src/ausearch-match.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-* ausearch-match.c - Extract interesting fields and check for match
-* Copyright (c) 2005-08, 2011 Red Hat Inc., Durham, North Carolina.
-* Copyright (c) 2011 IBM Corp.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-* Marcelo Henrique Cerri <mhcerri@br.ibm.com>
-*/
-
-#include "config.h"
-#include <string.h>
-#include "libaudit.h"
-#include "ausearch-options.h"
-#include "ausearch-parse.h"
-
-static int strmatch(const char *needle, const char *haystack);
-static int user_match(llist *l);
-static int group_match(llist *l);
-static int context_match(llist *l);
-
-/*
- * This function performs that matching of search params with the record.
- * It returns 1 on a match, and 0 if no match. The way that this function
- * works is that it will try to determine if there is not a match and exit
- * as soon as possible. We can do this since all command line params form
- * an 'and' statement. If anything does not match, no need to evaluate the
- * rest of the params.
- */
-#include <stdio.h>
-int match(llist *l)
-{
- // Are we within time range?
- if (start_time == 0 || l->e.sec >= start_time) {
- if (end_time == 0 || l->e.sec <= end_time) {
- if (event_id == -1 || event_id == l->e.serial) {
- // OK - do the heavier checking
- if (extract_search_items(l)) {
- return 0;
- }
-
- // perform additional tests for the field
- if (event_node_list) {
- const snode *sn;
- int found=0;
- slist *sptr = event_node_list;
-
- if (l->e.node == NULL)
- return 0;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- while (sn && !found) {
- if (sn->str && (!strcmp(sn->str, l->e.node)))
- found++;
- else
- sn=slist_next(sptr);
- }
- if (!found)
- return 0;
- }
- if (user_match(l) == 0)
- return 0;
- if (group_match(l) == 0)
- return 0;
- if ((event_ppid != -1) &&
- (event_ppid != l->s.ppid))
- return 0;
- if ((event_pid != -1) &&
- (event_pid != l->s.pid))
- return 0;
- if (event_machine != -1 &&
- (event_machine !=
- audit_elf_to_machine(l->s.arch)))
- return 0;
- if ((event_syscall != -1) &&
- (event_syscall != l->s.syscall))
- return 0;
- if ((event_session_id != -2) &&
- (event_session_id != l->s.session_id))
- return 0;
- if (event_exit_is_set) {
- if (l->s.exit_is_set == 0)
- return 0;
- if (event_exit != l->s.exit)
- return 0;
- }
-
- if ((event_success != S_UNSET) &&
- (event_success != l->s.success))
- return 0;
- // event_type requires looking at each item
- if (event_type != NULL) {
- int found = 0;
- const lnode *n;
-
- list_first(l);
- n = list_get_cur(l);
- do {
- int_node *in;
- ilist_first(event_type);
- in = ilist_get_cur(event_type);
- do {
- if (in->num == n->type){
- found = 1;
- break;
- }
- } while((in =
- ilist_next(event_type)));
- if (found)
- break;
- } while ((n = list_next(l)));
- if (!found)
- return 0;
- }
-
- // Done all the easy compares, now do the
- // string searches.
- if (event_filename) {
- int found = 0;
- if (l->s.filename == NULL && l->s.cwd == NULL)
- return 0;
- if (l->s.filename) {
- const snode *sn;
- slist *sptr = l->s.filename;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- do {
- if (sn->str == NULL)
- return 0;
- if (strmatch(
- event_filename,
- sn->str)) {
- found = 1;
- break;
- }
- } while ((sn=slist_next(sptr)));
-
- if (!found && l->s.cwd == NULL)
- return 0;
- }
- if (l->s.cwd && !found) {
- /* Check cwd, too */
- if (strmatch(event_filename,
- l->s.cwd) == 0)
- return 0;
- }
- }
- if (event_hostname) {
- if (l->s.hostname == NULL)
- return 0;
- if (strmatch(event_hostname,
- l->s.hostname) == 0)
- return 0;
- }
- if (event_terminal) {
- if (l->s.terminal == NULL)
- return 0;
- if (strmatch(event_terminal,
- l->s.terminal) == 0)
- return 0;
- }
- if (event_exe) {
- if (l->s.exe == NULL)
- return 0;
- if (strmatch(event_exe,
- l->s.exe) == 0)
- return 0;
- }
- if (event_comm) {
- if (l->s.comm == NULL)
- return 0;
- if (strmatch(event_comm,
- l->s.comm) == 0)
- return 0;
- }
- if (event_key) {
- if (l->s.key == NULL)
- return 0;
- else {
- int found = 0;
- const snode *sn;
- slist *sptr = l->s.key;
-
- slist_first(sptr);
- sn=slist_get_cur(sptr);
- do {
- if (sn->str == NULL)
- return 0;
- if (strmatch(
- event_key,
- sn->str)) {
- found = 1;
- break;
- }
- } while ((sn=slist_next(sptr)));
- if (!found)
- return 0;
- }
- }
- if (event_vmname) {
- if (l->s.vmname == NULL)
- return 0;
- if (strmatch(event_vmname,
- l->s.vmname) == 0)
- return 0;
- }
- if (event_uuid) {
- if (l->s.uuid == NULL)
- return 0;
- if (strmatch(event_uuid,
- l->s.uuid) == 0)
- return 0;
- }
- if (context_match(l) == 0)
- return 0;
- return 1;
- }
- }
- }
- return 0;
-}
-
-/*
- * This function compares strings. It returns a 0 if no match and a 1 if
- * there is a match
- */
-static int strmatch(const char *needle, const char *haystack)
-{
- if (event_exact_match) {
- if (strcmp(haystack, needle) != 0)
- return 0;
- } else {
- if (strstr(haystack, needle) == NULL)
- return 0;
- }
- return 1;
-}
-
-/*
- * This function compares user id's. It returns a 0 if no match and a 1 if
- * there is a match
- */
-static int user_match(llist *l)
-{
- if (event_ua) {
- // This will "or" the user tests
- if (event_uid == l->s.uid)
- return 1;
- if (event_euid == l->s.euid)
- return 1;
- if (event_loginuid == l->s.loginuid)
- return 1;
- return 0;
- } else {
- // This will "and" the user tests
- if ((event_uid != -1) && (event_uid != l->s.uid))
- return 0;
- if ((event_euid != -1) &&(event_euid != l->s.euid))
- return 0;
- if ((event_loginuid != -2) &&
- (event_loginuid != l->s.loginuid))
- return 0;
- }
- return 1;
-}
-
-/*
- * This function compares group id's. It returns a 0 if no match and a 1 if
- * there is a match
- */
-static int group_match(llist *l)
-{
- if (event_ga) {
- // This will "or" the group tests
- if (event_gid == l->s.gid)
- return 1;
- if (event_egid == l->s.egid)
- return 1;
- return 0;
- } else {
- // This will "and" the group tests
- if ((event_gid != -1) && (event_gid != l->s.gid))
- return 0;
- if ((event_egid != -1) &&(event_egid != l->s.egid))
- return 0;
- }
- return 1;
-}
-
-/*
- * This function compares contexts. It returns a 0 if no match and a 1 if
- * there is a match
- */
-static int context_match(llist *l)
-{
- if (event_se) { /* This does the "or" check if -se test */
- if (event_subject) {
- if (l->s.avc && alist_find_subj(l->s.avc)) {
- do {
- if (strmatch(event_subject,
- l->s.avc->cur->scontext))
- return 1;
- } while(alist_next_subj(l->s.avc));
- }
- }
- if (event_object) {
- if (l->s.avc) {
- alist_first(l->s.avc);
- if (alist_find_obj(l->s.avc)) {
- do {
- if (strmatch(event_object,
- l->s.avc->cur->tcontext))
- return 1;
- } while(alist_next_obj(l->s.avc));
- }
- }
- }
- return 0;
- } else {
- if (event_subject) {
- if (l->s.avc == NULL)
- return 0;
- if (alist_find_subj(l->s.avc)) {
- do {
- if (strmatch(event_subject,
- l->s.avc->cur->scontext))
- return 1;
- } while(alist_next_subj(l->s.avc));
- }
- return 0;
- }
- if (event_object) {
- if (l->s.avc == NULL)
- return 0;
- if (alist_find_obj(l->s.avc)) {
- do {
- if (strmatch(event_object,
- l->s.avc->cur->tcontext))
- return 1;
- } while(alist_next_obj(l->s.avc));
- }
- return 0;
- }
- }
- return 1;
-}
-
diff --git a/framework/src/audit/src/ausearch-nvpair.c b/framework/src/audit/src/ausearch-nvpair.c
deleted file mode 100644
index 3dfadb60..00000000
--- a/framework/src/audit/src/ausearch-nvpair.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-* ausearch-nvpair.c - Minimal linked list library for name-value pairs
-* Copyright (c) 2006-08 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <stdlib.h>
-#include "ausearch-nvpair.h"
-
-
-void nvlist_create(nvlist *l)
-{
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-nvnode *nvlist_next(nvlist *l)
-{
- if (l->cur == NULL)
- return NULL;
- l->cur = l->cur->next;
- return l->cur;
-}
-
-void nvlist_append(nvlist *l, nvnode *node)
-{
- nvnode* newnode = malloc(sizeof(nvnode));
-
- newnode->name = node->name;
- newnode->val = node->val;
- newnode->next = NULL;
-
- // if we are at top, fix this up
- if (l->head == NULL)
- l->head = newnode;
- else { // Add pointer to newnode and make sure we are at the end
- while (l->cur->next)
- l->cur = l->cur->next;
- l->cur->next = newnode;
- }
-
- // make newnode current
- l->cur = newnode;
- l->cnt++;
-}
-
-int nvlist_find_val(nvlist *l, long val)
-{
- register nvnode* window = l->head;
-
- while (window) {
- if (window->val == val) {
- l->cur = window;
- return 1;
- }
- else
- window = window->next;
- }
- return 0;
-}
-
-void nvlist_clear(nvlist* l)
-{
- nvnode* nextnode;
- register nvnode* current;
-
- current = l->head;
- while (current) {
- nextnode=current->next;
- free(current->name);
- free(current);
- current=nextnode;
- }
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
diff --git a/framework/src/audit/src/ausearch-nvpair.h b/framework/src/audit/src/ausearch-nvpair.h
deleted file mode 100644
index 9fb91ba9..00000000
--- a/framework/src/audit/src/ausearch-nvpair.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-* ausearch-nvpair.h - Header file for ausearch-nvpair.c
-* Copyright (c) 2006-08 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AUNVPAIR_HEADER
-#define AUNVPAIR_HEADER
-
-#include "config.h"
-#include <sys/types.h>
-
-/* This is the node of the linked list. message & item are the only elements
- * at this time. Any data elements that are per item goes here. */
-typedef struct _nvnode{
- char *name; // The name string
- long val; // The value field
- struct _nvnode* next; // Next nvpair node pointer
-} nvnode;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- nvnode *head; // List head
- nvnode *cur; // Pointer to current node
- unsigned int cnt; // How many items in this list
-} nvlist;
-
-void nvlist_create(nvlist *l);
-static inline void nvlist_first(nvlist *l) { l->cur = l->head; }
-nvnode *nvlist_next(nvlist *l);
-static inline nvnode *nvlist_get_cur(nvlist *l) { return l->cur; }
-void nvlist_append(nvlist *l, nvnode *node);
-void nvlist_clear(nvlist* l);
-
-/* Given a numeric index, find that record. */
-int nvlist_find_val(nvlist *l, long val);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-options.c b/framework/src/audit/src/ausearch-options.c
deleted file mode 100644
index 50469723..00000000
--- a/framework/src/audit/src/ausearch-options.c
+++ /dev/null
@@ -1,1175 +0,0 @@
-/* ausearch-options.c - parse commandline options and configure ausearch
- * Copyright 2005-08,2010-11,2014 Red Hat Inc., Durham, North Carolina.
- * Copyright (c) 2011 IBM Corp.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Debora Velarde <dvelarde@us.ibm.com>
- * Steve Grubb <sgrubb@redhat.com>
- * Marcelo Henrique Cerri <mhcerri@br.ibm.com>
- */
-
-#include "config.h"
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
-#include "ausearch-options.h"
-#include "ausearch-time.h"
-#include "ausearch-int.h"
-#include "libaudit.h"
-
-
-/* Global vars that will be accessed by the main program */
-char *user_file = NULL;
-int force_logs = 0;
-
-/* Global vars that will be accessed by the match model */
-unsigned int event_id = -1;
-gid_t event_gid = -1, event_egid = -1;
-ilist *event_type = NULL;
-pid_t event_pid = -1, event_ppid = -1;
-success_t event_success = S_UNSET;
-int event_exact_match = 0;
-uid_t event_uid = -1, event_euid = -1, event_loginuid = -2;
-int event_syscall = -1, event_machine = -1;
-int event_ua = 0, event_ga = 0, event_se = 0;
-int just_one = 0;
-uint32_t event_session_id = -2;
-long long event_exit = 0;
-int event_exit_is_set = 0;
-int line_buffered = 0;
-int event_debug = 0;
-int checkpt_timeonly = 0;
-const char *event_key = NULL;
-const char *event_filename = NULL;
-const char *event_exe = NULL;
-const char *event_comm = NULL;
-const char *event_hostname = NULL;
-const char *event_terminal = NULL;
-const char *event_subject = NULL;
-const char *event_object = NULL;
-const char *event_uuid = NULL;
-const char *event_vmname = NULL;
-const char *checkpt_filename = NULL; /* checkpoint filename if present */
-report_t report_format = RPT_DEFAULT;
-ilist *event_type;
-
-slist *event_node_list = NULL;
-
-struct nv_pair {
- int value;
- const char *name;
-};
-
-
-enum { S_EVENT, S_COMM, S_FILENAME, S_ALL_GID, S_EFF_GID, S_GID, S_HELP,
-S_HOSTNAME, S_INTERP, S_INFILE, S_MESSAGE_TYPE, S_PID, S_SYSCALL, S_OSUCCESS,
-S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, S_UID, S_LOGINID,
-S_VERSION, S_EXACT_MATCH, S_EXECUTABLE, S_CONTEXT, S_SUBJECT, S_OBJECT,
-S_PPID, S_KEY, S_RAW, S_NODE, S_IN_LOGS, S_JUST_ONE, S_SESSION, S_EXIT,
-S_LINEBUFFERED, S_UUID, S_VMNAME, S_DEBUG, S_CHECKPOINT, S_ARCH };
-
-static struct nv_pair optiontab[] = {
- { S_EVENT, "-a" },
- { S_ARCH, "--arch" },
- { S_EVENT, "--event" },
- { S_COMM, "-c" },
- { S_COMM, "--comm" },
- { S_CHECKPOINT, "--checkpoint" },
- { S_DEBUG, "--debug" },
- { S_EXIT, "-e" },
- { S_EXIT, "--exit" },
- { S_FILENAME, "-f" },
- { S_FILENAME, "--file" },
- { S_ALL_GID, "-ga" },
- { S_ALL_GID, "--gid-all" },
- { S_EFF_GID, "-ge" },
- { S_EFF_GID, "--gid-effective" },
- { S_GID, "-gi" },
- { S_GID, "--gid" },
- { S_HELP, "-h" },
- { S_HELP, "--help" },
- { S_HOSTNAME, "-hn" },
- { S_HOSTNAME, "--host" },
- { S_INTERP, "-i" },
- { S_INTERP, "--interpret" },
- { S_INFILE, "-if" },
- { S_INFILE, "--input" },
- { S_IN_LOGS, "--input-logs" },
- { S_JUST_ONE, "--just-one" },
- { S_KEY, "-k" },
- { S_KEY, "--key" },
- { S_LINEBUFFERED, "-l" },
- { S_LINEBUFFERED, "--line-buffered" },
- { S_MESSAGE_TYPE, "-m" },
- { S_MESSAGE_TYPE, "--message" },
- { S_NODE, "-n" },
- { S_NODE, "--node" },
- { S_OBJECT, "-o" },
- { S_OBJECT, "--object" },
- { S_PID, "-p" },
- { S_PID, "--pid" },
- { S_PPID, "-pp" },
- { S_PPID, "--ppid" },
- { S_RAW, "-r" },
- { S_RAW, "--raw" },
- { S_SYSCALL, "-sc" },
- { S_SYSCALL, "--syscall" },
- { S_CONTEXT, "-se" },
- { S_CONTEXT, "--context" },
- { S_SESSION, "--session" },
- { S_SUBJECT, "-su" },
- { S_SUBJECT, "--subject" },
- { S_OSUCCESS, "-sv" },
- { S_OSUCCESS, "--success" },
- { S_TIME_END, "-te"},
- { S_TIME_END, "--end"},
- { S_TIME_START, "-ts" },
- { S_TIME_START, "--start" },
- { S_TERMINAL, "-tm" },
- { S_TERMINAL, "--terminal" },
- { S_ALL_UID, "-ua" },
- { S_ALL_UID, "--uid-all" },
- { S_EFF_UID, "-ue" },
- { S_EFF_UID, "--uid-effective" },
- { S_UID, "-ui" },
- { S_UID, "--uid" },
- { S_UUID, "-uu" },
- { S_UUID, "--uuid" },
- { S_LOGINID, "-ul" },
- { S_LOGINID, "--loginuid" },
- { S_VERSION, "-v" },
- { S_VERSION, "--version" },
- { S_VMNAME, "-vm" },
- { S_VMNAME, "--vm-name" },
- { S_EXACT_MATCH, "-w" },
- { S_EXACT_MATCH, "--word" },
- { S_EXECUTABLE, "-x" },
- { S_EXECUTABLE, "--executable" }
-};
-#define OPTION_NAMES (sizeof(optiontab)/sizeof(optiontab[0]))
-
-
-static int audit_lookup_option(const char *name)
-{
- int i;
-
- for (i = 0; i < OPTION_NAMES; i++)
- if (!strcmp(optiontab[i].name, name))
- return optiontab[i].value;
- return -1;
-}
-
-static void usage(void)
-{
- printf("usage: ausearch [options]\n"
- "\t-a,--event <Audit event id>\tsearch based on audit event id\n"
- "\t--arch <CPU>\t\t\tsearch based on the CPU architecture\n"
- "\t-c,--comm <Comm name>\t\tsearch based on command line name\n"
- "\t--checkpoint <checkpoint file>\tsearch from last complete event\n"
- "\t--debug\t\t\tWrite malformed events that are skipped to stderr\n"
- "\t-e,--exit <Exit code or errno>\tsearch based on syscall exit code\n"
- "\t-f,--file <File name>\t\tsearch based on file name\n"
- "\t-ga,--gid-all <all Group id>\tsearch based on All group ids\n"
- "\t-ge,--gid-effective <effective Group id> search based on Effective\n\t\t\t\t\tgroup id\n"
- "\t-gi,--gid <Group Id>\t\tsearch based on group id\n"
- "\t-h,--help\t\t\thelp\n"
- "\t-hn,--host <Host Name>\t\tsearch based on remote host name\n"
- "\t-i,--interpret\t\t\tInterpret results to be human readable\n"
- "\t-if,--input <Input File name>\tuse this file instead of current logs\n"
- "\t--input-logs\t\t\tUse the logs even if stdin is a pipe\n"
- "\t--just-one\t\t\tEmit just one event\n"
- "\t-k,--key <key string>\t\tsearch based on key field\n"
- "\t-l, --line-buffered\t\tFlush output on every line\n"
- "\t-m,--message <Message type>\tsearch based on message type\n"
- "\t-n,--node <Node name>\t\tsearch based on machine's name\n"
- "\t-o,--object <SE Linux Object context> search based on context of object\n"
- "\t-p,--pid <Process id>\t\tsearch based on process id\n"
- "\t-pp,--ppid <Parent Process id>\tsearch based on parent process id\n"
- "\t-r,--raw\t\t\toutput is completely unformatted\n"
- "\t-sc,--syscall <SysCall name>\tsearch based on syscall name or number\n"
- "\t-se,--context <SE Linux context> search based on either subject or\n\t\t\t\t\t object\n"
- "\t--session <login session id>\tsearch based on login session id\n"
- "\t-su,--subject <SE Linux context> search based on context of the Subject\n"
- "\t-sv,--success <Success Value>\tsearch based on syscall or event\n\t\t\t\t\tsuccess value\n"
- "\t-te,--end [end date] [end time]\tending date & time for search\n"
- "\t-ts,--start [start date] [start time]\tstarting data & time for search\n"
- "\t-tm,--terminal <TerMinal>\tsearch based on terminal\n"
- "\t-ua,--uid-all <all User id>\tsearch based on All user id's\n"
- "\t-ue,--uid-effective <effective User id> search based on Effective\n\t\t\t\t\tuser id\n"
- "\t-ui,--uid <User Id>\t\tsearch based on user id\n"
- "\t-ul,--loginuid <login id>\tsearch based on the User's Login id\n"
- "\t-uu,--uuid <guest UUID>\t\tsearch for events related to the virtual\n"
- "\t\t\t\t\tmachine with the given UUID.\n"
- "\t-v,--version\t\t\tversion\n"
- "\t-vm,--vm-name <guest name>\tsearch for events related to the virtual\n"
- "\t\t\t\t\tmachine with the name.\n"
- "\t-w,--word\t\t\tstring matches are whole word\n"
- "\t-x,--executable <executable name> search based on executable name\n"
- );
-}
-
-static int convert_str_to_msg(const char *optarg)
-{
- int tmp, retval = 0;
-
- if (isdigit(optarg[0])) {
- errno = 0;
- tmp = strtoul(optarg, NULL, 10);
- if (errno) {
- fprintf(stderr,
- "Numeric message type conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- tmp = audit_name_to_msg_type(optarg);
- if (tmp < 0)
- retval = -1;
- }
- if (retval == 0) {
- if (event_type == NULL) {
- event_type = malloc(sizeof(ilist));
- if (event_type == NULL)
- return -1;
- ilist_create(event_type);
- }
- ilist_append(event_type, tmp, 1, 0);
- }
- return retval;
-}
-
-static int parse_msg(const char *optarg)
-{
- int retval = 0;
- char *saved;
-
- if (strchr(optarg, ',')) {
- char *ptr, *tmp = strdup(optarg);
- if (tmp == NULL)
- return -1;
- ptr = strtok_r(tmp, ",", &saved);
- while (ptr) {
- retval = convert_str_to_msg(ptr);
- if (retval != 0)
- break;
- ptr = strtok_r(NULL, ",", &saved);
- }
- free(tmp);
- return retval;
- }
-
- return convert_str_to_msg(optarg);
-}
-
-/*
- * This function examines the commandline parameters and sets various
- * search options. It returns a 0 on success and < 0 on failure
- */
-int check_params(int count, char *vars[])
-{
- int c = 1;
- int retval = 0;
- const char *optarg;
-
- if (count < 2) {
- usage();
- return -1;
- }
- while (c < count && retval == 0) {
- // Go ahead and point to the next argument
- if (c+1 < count) {
- if (vars[c+1][0] != '-')
- optarg = vars[c+1];
- else
- optarg = NULL;
- } else
- optarg = NULL;
-
- switch (audit_lookup_option(vars[c])) {
- case S_EVENT:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_id = strtoul(optarg, NULL, 10);
- if (errno) {
- fprintf(stderr,
- "Illegal value for audit event ID");
- retval = -1;
- }
- c++;
- } else {
- fprintf(stderr,
- "Audit event id must be a numeric value, was %s\n",
- optarg);
- retval = -1;
- }
- break;
- case S_COMM:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- } else {
- event_comm = strdup(optarg);
- if (event_comm == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_FILENAME:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_filename = strdup(optarg);
- if (event_filename == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_KEY:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_key = strdup(optarg);
- if (event_key == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_ALL_GID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_gid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric group ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- struct group *gr ;
-
- gr = getgrnam(optarg) ;
- if (gr == NULL) {
- fprintf(stderr,
- "Group ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_gid = gr->gr_gid;
- }
- event_egid = event_gid;
- event_ga = 1;
- c++;
- break;
- case S_EFF_GID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_egid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric group ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- struct group *gr ;
-
- gr = getgrnam(optarg) ;
- if (gr == NULL) {
- fprintf(stderr,
- "Effective group ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_egid = gr->gr_gid;
- }
- c++;
- break;
- case S_GID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_gid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric group ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- struct group *gr ;
-
- gr = getgrnam(optarg) ;
- if (gr == NULL) {
- fprintf(stderr,
- "Group ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_gid = gr->gr_gid;
- }
- c++;
- break;
- case S_HELP:
- usage();
- exit(0);
- break;
- case S_HOSTNAME:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_hostname = strdup(optarg);
- if (event_hostname == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_INTERP:
- if (report_format == RPT_DEFAULT)
- report_format = RPT_INTERP;
- else {
- fprintf(stderr,
- "Conflicting output format %s\n",
- vars[c]);
- retval = -1;
- }
- if (optarg) {
- fprintf(stderr,
- "Argument is NOT required for %s\n",
- vars[c]);
- retval = -1;
- }
- break;
- case S_INFILE:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- user_file = strdup(optarg);
- if (user_file == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_MESSAGE_TYPE:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- if (strcasecmp(optarg, "ALL") != 0) {
- retval = parse_msg(optarg);
- }
- c++;
- }
- if (retval < 0) {
- int i;
- fprintf(stderr,
- "Valid message types are: ALL ");
- for (i=AUDIT_USER;i<=AUDIT_LAST_VIRT_MSG;i++){
- const char *name;
- if (i == AUDIT_WATCH_INS) // Skip a few
- i = AUDIT_FIRST_USER_MSG;
- name = audit_msg_type_to_name(i);
- if (name)
- fprintf(stderr, "%s ", name);
- }
- fprintf(stderr, "\n");
- }
- break;
- case S_OBJECT:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- } else {
- event_object = strdup(optarg);
- if (event_object == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_PPID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_ppid = strtol(optarg,NULL,10);
- if (errno)
- retval = -1;
- c++;
- } else {
- fprintf(stderr,
- "Parent process id must be a numeric value, was %s\n",
- optarg);
- retval = -1;
- }
- break;
- case S_PID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_pid = strtol(optarg,NULL,10);
- if (errno)
- retval = -1;
- c++;
- } else {
- fprintf(stderr,
- "Process id must be a numeric value, was %s\n",
- optarg);
- retval = -1;
- }
- break;
- case S_RAW:
- if (report_format == RPT_DEFAULT)
- report_format = RPT_RAW;
- else {
- fprintf(stderr,
- "Conflicting output format --raw\n");
- retval = -1;
- }
- if (optarg) {
- fprintf(stderr,
- "Argument is NOT required for --raw\n");
- retval = -1;
- }
- break;
- case S_NODE:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- snode sn;
- c++;
-
- if (!event_node_list) {
- event_node_list = malloc(sizeof (slist));
- if (!event_node_list) {
- retval = -1;
- break;
- }
- slist_create(event_node_list);
- }
-
- sn.str = strdup(optarg);
- sn.key = NULL;
- sn.hits=0;
- slist_append(event_node_list, &sn);
- }
- break;
- case S_SYSCALL:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_syscall = (int)strtoul(optarg, NULL, 10);
- if (errno) {
- fprintf(stderr,
- "Syscall numeric conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- if (event_machine == -1) {
- int machine;
- machine = audit_detect_machine();
- if (machine < 0) {
- fprintf(stderr,
- "Error detecting machine type");
- retval = -1;
- break;
- }
- event_machine = machine;
- }
- event_syscall = audit_name_to_syscall(optarg,
- event_machine);
- if (event_syscall == -1) {
- fprintf(stderr,
- "Syscall %s not found\n",
- optarg);
- retval = -1;
- }
- }
- c++;
- break;
- case S_CONTEXT:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- } else {
- event_subject = strdup(optarg);
- if (event_subject == NULL)
- retval = -1;
- event_object = strdup(optarg);
- if (event_object == NULL)
- retval = -1;
- event_se = 1;
- c++;
- }
- break;
- case S_SUBJECT:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- } else {
- event_subject = strdup(optarg);
- if (event_subject == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_OSUCCESS:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if ( (strstr(optarg, "yes")!=NULL) ||
- (strstr(optarg, "no")!=NULL) ) {
- if (strcmp(optarg, "yes") == 0)
- event_success = S_SUCCESS;
- else
- event_success = S_FAILED;
- } else {
- fprintf(stderr,
- "Success must be 'yes' or 'no'.\n");
- retval = -1;
- }
- c++;
- break;
- case S_SESSION:
- if (!optarg) {
- if ((c+1 < count) && vars[c+1])
- optarg = vars[c+1];
- else {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- }
- {
- size_t len = strlen(optarg);
- if (isdigit(optarg[0])) {
- errno = 0;
- event_session_id = strtoul(optarg,NULL,10);
- if (errno)
- retval = -1;
- c++;
- } else if (len >= 2 && *(optarg)=='-' &&
- (isdigit(optarg[1]))) {
- errno = 0;
- event_session_id = strtoul(optarg, NULL, 0);
- if (errno) {
- retval = -1;
- fprintf(stderr, "Error converting %s\n",
- optarg);
- }
- c++;
- } else {
- fprintf(stderr,
- "Session id must be a numeric value, was %s\n",
- optarg);
- retval = -1;
- }
- }
- break;
- case S_EXIT:
- if (!optarg) {
- if ((c+1 < count) && vars[c+1])
- optarg = vars[c+1];
- else {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- }
- {
- size_t len = strlen(optarg);
- if (isdigit(optarg[0])) {
- errno = 0;
- event_exit = strtoll(optarg, NULL, 0);
- if (errno) {
- retval = -1;
- fprintf(stderr, "Error converting %s\n",
- optarg);
- }
- } else if (len >= 2 && *(optarg)=='-' &&
- (isdigit(optarg[1]))) {
- errno = 0;
- event_exit = strtoll(optarg, NULL, 0);
- if (errno) {
- retval = -1;
- fprintf(stderr, "Error converting %s\n",
- optarg);
- }
- } else {
- event_exit = audit_name_to_errno(optarg);
- if (event_exit == 0) {
- retval = -1;
- fprintf(stderr,
- "Unknown errno, was %s\n",
- optarg);
- }
- }
- c++;
- if (retval != -1)
- event_exit_is_set = 1;
- }
- break;
- case S_TIME_END:
- if (optarg) {
- if ( (c+2 < count) && vars[c+2] &&
- (vars[c+2][0] != '-') ) {
- /* Have both date and time - check order*/
- if (strchr(optarg, ':')) {
- if (ausearch_time_end(vars[c+2],
- optarg) != 0)
- retval = -1;
- } else {
- if (ausearch_time_end(optarg,
- vars[c+2]) != 0)
- retval = -1;
- }
- c++;
- } else {
- // Check against recognized words
- int t = lookup_time(optarg);
- if (t >= 0) {
- if (ausearch_time_end(optarg,
- NULL) != 0)
- retval = -1;
- } else if ( (strchr(optarg, ':')) == NULL) {
- /* Only have date */
- if (ausearch_time_end(optarg,
- NULL) != 0)
- retval = -1;
- } else {
- /* Only have time */
- if (ausearch_time_end(NULL,
- optarg) != 0)
- retval = -1;
- }
- }
- c++;
- break;
- }
- fprintf(stderr,
- "%s requires either date and/or time\n",
- vars[c]);
- retval = -1;
- break;
- case S_TIME_START:
- if (optarg) {
- if ( (c+2 < count) && vars[c+2] &&
- (vars[c+2][0] != '-') ) {
- /* Have both date and time - check order */
- if (strchr(optarg, ':')) {
- if (ausearch_time_start(
- vars[c+2], optarg) != 0)
- retval = -1;
- } else {
- if (ausearch_time_start(optarg,
- vars[c+2]) != 0)
- retval = -1;
- }
- c++;
- } else {
- // Check against recognized words
- int t = lookup_time(optarg);
- if (t >= 0) {
- if (ausearch_time_start(optarg,
- "00:00:00") != 0)
- retval = -1;
- } else if (strcmp(optarg,
- "checkpoint") == 0) {
- // Only use the timestamp from within
- // the checkpoint file
- checkpt_timeonly++;
- } else if (strchr(optarg, ':') == NULL){
- /* Only have date */
- if (ausearch_time_start(optarg,
- "00:00:00") != 0)
- retval = -1;
- } else {
- /* Only have time */
- if (ausearch_time_start(NULL,
- optarg) != 0)
- retval = -1;
- }
- }
- c++;
- break;
- }
- fprintf(stderr,
- "%s requires either date and/or time\n",
- vars[c]);
- retval = -1;
- break;
- case S_TERMINAL:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_terminal = strdup(optarg);
- if (event_terminal == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_UID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_uid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric user ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- struct passwd *pw;
-
- pw = getpwnam(optarg);
- if (pw == NULL) {
- fprintf(stderr,
- "Effective user ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_uid = pw->pw_uid;
- }
- c++;
- break;
- case S_EFF_UID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_euid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric user ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- struct passwd *pw ;
-
- pw = getpwnam(optarg) ;
- if (pw == NULL) {
- fprintf(stderr,
- "User ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_euid = pw->pw_uid;
- }
- c++;
- break;
- case S_ALL_UID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (isdigit(optarg[0])) {
- errno = 0;
- event_uid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric user ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else {
- struct passwd *pw ;
-
- pw = getpwnam(optarg) ;
- if (pw == NULL) {
- fprintf(stderr,
- "User ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_uid = pw->pw_uid;
- }
- event_ua = 1;
- event_euid = event_uid;
- event_loginuid = event_uid;
- c++;
- break;
- case S_LOGINID:
- if (!optarg) {
- if ((c+1 < count) && vars[c+1])
- optarg = vars[c+1];
- else {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- }
- {
- size_t len = strlen(optarg);
- if (isdigit(optarg[0])) {
- errno = 0;
- event_loginuid = strtoul(optarg,NULL,10);
- if (errno) {
- fprintf(stderr,
- "Numeric user ID conversion error (%s) for %s\n",
- strerror(errno), optarg);
- retval = -1;
- }
- } else if (len >= 2 && *(optarg)=='-' &&
- (isdigit(optarg[1]))) {
- errno = 0;
- event_loginuid = strtol(optarg, NULL, 0);
- if (errno) {
- retval = -1;
- fprintf(stderr, "Error converting %s\n",
- optarg);
- }
- } else {
- struct passwd *pw ;
-
- pw = getpwnam(optarg) ;
- if (pw == NULL) {
- fprintf(stderr,
- "Login user ID is non-numeric and unknown (%s)\n",
- optarg);
- retval = -1;
- break;
- }
- event_loginuid = pw->pw_uid;
- }
- }
- c++;
- break;
- case S_UUID:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_uuid = strdup(optarg);
- if (event_uuid == NULL) {
- retval = -1;
- }
- c++;
- }
- break;
- case S_VMNAME:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_vmname= strdup(optarg);
- if (event_vmname == NULL) {
- retval = -1;
- }
- c++;
- }
- break;
- case S_VERSION:
- printf("ausearch version %s\n", VERSION);
- exit(0);
- break;
- case S_EXACT_MATCH:
- event_exact_match=1;
- break;
- case S_IN_LOGS:
- force_logs = 1;
- break;
- case S_JUST_ONE:
- just_one = 1;
- break;
- case S_EXECUTABLE:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- event_exe = strdup(optarg);
- if (event_exe == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_LINEBUFFERED:
- line_buffered = 1;
- break;
- case S_DEBUG:
- event_debug = 1;
- break;
- case S_CHECKPOINT:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- } else {
- checkpt_filename = strdup(optarg);
- if (checkpt_filename == NULL)
- retval = -1;
- c++;
- }
- break;
- case S_ARCH:
- if (!optarg) {
- fprintf(stderr,
- "Argument is required for %s\n",
- vars[c]);
- retval = -1;
- break;
- }
- if (event_machine != -1) {
- if (event_syscall != -1)
- fprintf(stderr,
- "Arch needs to be defined before the syscall\n");
- else
- fprintf(stderr,
- "Arch is already defined\n");
- retval = -1;
- break;
- } else {
- int machine = audit_determine_machine(optarg);
- if (machine < 0) {
- fprintf(stderr, "Unknown arch %s\n",
- optarg);
- retval = -1;
- }
- event_machine = machine;
- }
- c++;
- break;
- default:
- fprintf(stderr, "%s is an unsupported option\n",
- vars[c]);
- retval = -1;
- break;
- }
- c++;
- }
-
- return retval;
-}
-
diff --git a/framework/src/audit/src/ausearch-options.h b/framework/src/audit/src/ausearch-options.h
deleted file mode 100644
index 1372762b..00000000
--- a/framework/src/audit/src/ausearch-options.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ausearch-options.h --
- * Copyright 2005,2008,2010 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- *
- */
-
-#ifndef AUSEARCH_OPTIONS_H
-#define AUSEARCH_OPTIONS_H
-
-#include <time.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include "ausearch-common.h"
-#include "ausearch-int.h"
-
-/* Global variables that describe what search is to be performed */
-extern const char *event_key;
-extern const char *event_subject;
-extern const char *event_object;
-extern int event_se;
-extern int just_one;
-extern int line_buffered;
-extern int event_debug;
-extern pid_t event_ppid;
-extern uint32_t event_session_id;
-extern ilist *event_type;
-
-/* Data type to govern output format */
-extern report_t report_format;
-
-/* Function to process commandline options */
-extern int check_params(int count, char *vars[]);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-parse.c b/framework/src/audit/src/ausearch-parse.c
deleted file mode 100644
index 1fb1c151..00000000
--- a/framework/src/audit/src/ausearch-parse.c
+++ /dev/null
@@ -1,2310 +0,0 @@
-/*
-* ausearch-parse.c - Extract interesting fields and check for match
-* Copyright (c) 2005-08,2011,2013-14 Red Hat Inc., Durham, North Carolina.
-* Copyright (c) 2011 IBM Corp.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-* Marcelo Henrique Cerri <mhcerri@br.ibm.com>
-*/
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netdb.h>
-#include <limits.h> /* PATH_MAX */
-#include <ctype.h>
-#include "libaudit.h"
-#include "ausearch-options.h"
-#include "ausearch-lookup.h"
-#include "ausearch-parse.h"
-
-#define NAME_OFFSET 36
-static const char key_sep[2] = { AUDIT_KEY_SEPARATOR, 0 };
-
-static int parse_syscall(lnode *n, search_items *s);
-static int parse_dir(const lnode *n, search_items *s);
-static int common_path_parser(search_items *s, char *path);
-static int avc_parse_path(const lnode *n, search_items *s);
-static int parse_path(const lnode *n, search_items *s);
-static int parse_user(const lnode *n, search_items *s);
-static int parse_obj(const lnode *n, search_items *s);
-static int parse_login(const lnode *n, search_items *s);
-static int parse_daemon1(const lnode *n, search_items *s);
-static int parse_daemon2(const lnode *n, search_items *s);
-static int parse_sockaddr(const lnode *n, search_items *s);
-static int parse_avc(const lnode *n, search_items *s);
-static int parse_integrity(const lnode *n, search_items *s);
-static int parse_kernel_anom(const lnode *n, search_items *s);
-static int parse_simple_message(const lnode *n, search_items *s);
-static int parse_tty(const lnode *n, search_items *s);
-static int parse_pkt(const lnode *n, search_items *s);
-
-
-static int audit_avc_init(search_items *s)
-{
- if (s->avc == NULL) {
- //create
- s->avc = malloc(sizeof(alist));
- if (s->avc == NULL)
- return -1;
- alist_create(s->avc);
- }
- return 0;
-}
-
-/*
- * This function will take the list and extract the searchable fields from it.
- * It returns 0 on success and 1 on failure.
- */
-int extract_search_items(llist *l)
-{
- int ret = 0;
- lnode *n;
- search_items *s = &l->s;
- list_first(l);
- n = list_get_cur(l);
- if (n) {
- do {
- switch (n->type) {
- case AUDIT_SYSCALL:
- ret = parse_syscall(n, s);
- break;
- case AUDIT_CWD:
- ret = parse_dir(n, s);
- break;
- case AUDIT_AVC_PATH:
- ret = avc_parse_path(n, s);
- break;
- case AUDIT_PATH:
- ret = parse_path(n, s);
- break;
- case AUDIT_USER:
- case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
- case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
- ret = parse_user(n, s);
- break;
- case AUDIT_SOCKADDR:
- ret = parse_sockaddr(n, s);
- break;
- case AUDIT_LOGIN:
- ret = parse_login(n, s);
- break;
- case AUDIT_IPC:
- case AUDIT_OBJ_PID:
- ret = parse_obj(n, s);
- break;
- case AUDIT_DAEMON_START:
- case AUDIT_DAEMON_END:
- case AUDIT_DAEMON_ABORT:
- case AUDIT_DAEMON_CONFIG:
- case AUDIT_DAEMON_ROTATE:
- case AUDIT_DAEMON_RESUME:
- ret = parse_daemon1(n, s);
- break;
- case AUDIT_DAEMON_ACCEPT:
- case AUDIT_DAEMON_CLOSE:
- ret = parse_daemon2(n, s);
- break;
- case AUDIT_CONFIG_CHANGE:
- ret = parse_simple_message(n, s);
- // We use AVC parser because it just looks for
- // the one field. We don't care about return
- // code since older events don't have path=
- avc_parse_path(n, s);
- break;
- case AUDIT_AVC:
- ret = parse_avc(n, s);
- break;
- case AUDIT_NETFILTER_PKT:
- ret = parse_pkt(n, s);
- break;
- case AUDIT_SECCOMP:
- case
- AUDIT_FIRST_KERN_ANOM_MSG...AUDIT_LAST_KERN_ANOM_MSG:
- ret = parse_kernel_anom(n, s);
- break;
- case AUDIT_MAC_POLICY_LOAD...AUDIT_MAC_UNLBL_STCDEL:
- ret = parse_simple_message(n, s);
- break;
- case AUDIT_INTEGRITY_DATA...AUDIT_INTEGRITY_RULE:
- ret = parse_integrity(n, s);
- break;
- case AUDIT_KERNEL:
- case AUDIT_SELINUX_ERR:
- case AUDIT_EXECVE:
- case AUDIT_IPC_SET_PERM:
- case AUDIT_MQ_OPEN:
- case AUDIT_MQ_SENDRECV:
- case AUDIT_MQ_NOTIFY:
- case AUDIT_MQ_GETSETATTR:
- case AUDIT_FD_PAIR:
- case AUDIT_BPRM_FCAPS:
- case AUDIT_CAPSET:
- case AUDIT_MMAP:
- case AUDIT_NETFILTER_CFG:
- // Nothing to parse
- break;
- case AUDIT_TTY:
- ret = parse_tty(n, s);
- break;
- default:
- if (event_debug)
- fprintf(stderr,
- "Unparsed type:%d\n - skipped",
- n->type);
- break;
- }
- if (event_debug && ret)
- fprintf(stderr,
- "Malformed event skipped, rc=%d. %s\n",
- ret, n->message);
- } while ((n=list_next(l)) && ret == 0);
- }
- return ret;
-}
-
-static int parse_syscall(lnode *n, search_items *s)
-{
- char *ptr, *str, *term;
- extern int event_machine;
-
- term = n->message;
- if (report_format > RPT_DEFAULT || event_machine != -1) {
- // get arch
- str = strstr(term, "arch=");
- if (str == NULL)
- return 1;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 2;
- *term = 0;
- errno = 0;
- s->arch = (int)strtoul(ptr, NULL, 16);
- if (errno)
- return 3;
- *term = ' ';
- }
- // get syscall
- str = strstr(term, "syscall=");
- if (str == NULL)
- return 4;
- ptr = str + 8;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 5;
- *term = 0;
- errno = 0;
- s->syscall = (int)strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- *term = ' ';
- // get success
- if (event_success != S_UNSET) {
- str = strstr(term, "success=");
- if (str) { // exit_group does not set success !?!
- ptr = str + 8;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 7;
- *term = 0;
- if (strcmp(ptr, "yes") == 0)
- s->success = S_SUCCESS;
- else
- s->success = S_FAILED;
- *term = ' ';
- }
- }
- // get exit
- if (event_exit_is_set) {
- str = strstr(term, "exit=");
- if (str == NULL)
- return 8;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 9;
- *term = 0;
- errno = 0;
- s->exit = strtoll(ptr, NULL, 0);
- if (errno)
- return 10;
- s->exit_is_set = 1;
- *term = ' ';
- }
- // get a0
- str = strstr(term, "a0=");
- if (str == NULL)
- return 11;
- ptr = str + 3;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 12;
- *term = 0;
- errno = 0;
- // 64 bit dump on 32 bit machine looks bad here - need long long
- n->a0 = strtoull(ptr, NULL, 16); // Hex
- if (errno)
- return 13;
- *term = ' ';
- // get a1
- str = strstr(term, "a1=");
- if (str == NULL)
- return 11;
- ptr = str + 3;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 12;
- *term = 0;
- errno = 0;
- // 64 bit dump on 32 bit machine looks bad here - need long long
- n->a1 = strtoull(ptr, NULL, 16); // Hex
- if (errno)
- return 13;
- *term = ' ';
- // ppid
- if (event_ppid != -1) {
- str = strstr(term, "ppid=");
- if (str != NULL) { // ppid is an optional field
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 14;
- *term = 0;
- errno = 0;
- s->ppid = strtoul(ptr, NULL, 10);
- if (errno)
- return 15;
- *term = ' ';
- }
- }
- // pid
- if (event_pid != -1) {
- str = strstr(term, " pid=");
- if (str == NULL)
- return 16;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 17;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 18;
- *term = ' ';
- }
- // optionally get loginuid
- if (event_loginuid != -2) {
- str = strstr(term, "auid=");
- if (str == NULL) {
- str = strstr(term, "loginuid=");
- if (str == NULL)
- return 19;
- ptr = str + 9;
- } else
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 20;
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 21;
- *term = ' ';
- }
- // optionally get uid
- if (event_uid != -1) {
- str = strstr(term, "uid=");
- if (str == NULL)
- return 22;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 23;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 24;
- *term = ' ';
- }
-
- // optionally get gid
- if (event_gid != -1) {
- str = strstr(term, "gid=");
- if (str == NULL)
- return 25;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 26;
- *term = 0;
- errno = 0;
- s->gid = strtoul(ptr, NULL, 10);
- if (errno)
- return 27;
- *term = ' ';
- }
-
- // euid
- if (event_euid != -1) {
- str = strstr(term, "euid=");
- if (str == NULL)
- return 28;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 29;
- *term = 0;
- errno = 0;
- s->euid = strtoul(ptr, NULL, 10);
- if (errno)
- return 30;
- *term = ' ';
- }
-
- // egid
- if (event_egid != -1) {
- str = strstr(term, "egid=");
- if (str == NULL)
- return 31;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 32;
- *term = 0;
- errno = 0;
- s->egid = strtoul(ptr, NULL, 10);
- if (errno)
- return 33;
- *term = ' ';
- }
-
- if (event_terminal) {
- // dont do this search unless needed
- str = strstr(term, "tty=");
- if (str) {
- str += 4;
- term = strchr(str, ' ');
- if (term == NULL)
- return 34;
- *term = 0;
- s->terminal = strdup(str);
- *term = ' ';
- }
- }
- // ses
- if (event_session_id != -2 ) {
- str = strstr(term, "ses=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 35;
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 36;
- *term = ' ';
- }
- }
- if (event_comm) {
- // dont do this search unless needed
- str = strstr(term, "comm=");
- if (str) {
- /* Make the syscall one override */
- if (s->comm)
- free(s->comm);
- str += 5;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 37;
- *term = 0;
- s->comm = strdup(str);
- *term = '"';
- } else
- s->comm = unescape(str);
- } else
- return 38;
- }
- if (event_exe) {
- // dont do this search unless needed
- str = strstr(n->message, "exe=");
- if (str) {
- str += 4;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 39;
- *term = 0;
- s->exe = strdup(str);
- *term = '"';
- } else
- s->exe = unescape(str);
- } else
- return 40;
- }
- if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str != NULL) {
- str += 5;
- term = strchr(str, ' ');
- if (term == NULL)
- return 41;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 42;
- }
- }
- if (event_key) {
- str = strstr(term, "key=");
- if (str) {
- if (!s->key) {
- //create
- s->key = malloc(sizeof(slist));
- if (s->key == NULL)
- return 43;
- slist_create(s->key);
- }
- str += 4;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 44;
- *term = 0;
- if (s->key) {
- // append
- snode sn;
- sn.str = strdup(str);
- sn.key = NULL;
- sn.hits = 1;
- slist_append(s->key, &sn);
- }
- *term = '"';
- } else {
- if (s->key) {
- char *saved;
- char *keyptr = unescape(str);
- char *kptr = strtok_r(keyptr,
- key_sep, &saved);
- while (kptr) {
- snode sn;
- // append
- sn.str = strdup(kptr);
- sn.key = NULL;
- sn.hits = 1;
- slist_append(s->key, &sn);
- kptr = strtok_r(NULL,
- key_sep, &saved);
- }
- free(keyptr);
-
- }
- }
- }
- }
- return 0;
-}
-
-static int parse_dir(const lnode *n, search_items *s)
-{
- char *str, *term;
-
- if (event_filename) {
- // dont do this search unless needed
- str = strstr(n->message+NAME_OFFSET, " cwd=");
- if (str) {
- str += 5;
- if (*str == '"') {
- /* string is normal */
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 1;
- *term = 0;
- if (!s->cwd)
- s->cwd = strdup(str);
- *term = '"';
- } else if (!s->cwd)
- s->cwd = unescape(str);
- }
- }
- return 0;
-}
-
-static int common_path_parser(search_items *s, char *path)
-{
- char *term;
-
- if (!s->filename) {
- //create
- s->filename = malloc(sizeof(slist));
- if (s->filename == NULL)
- return 1;
- slist_create(s->filename);
- }
- if (*path == '"') {
- /* string is normal */
- path++;
- term = strchr(path, '"');
- if (term == NULL)
- return 2;
- *term = 0;
- if (s->filename) {
- // append
- snode sn;
- sn.str = strdup(path);
- sn.key = NULL;
- sn.hits = 1;
- // Attempt to rebuild path if relative
- if ((sn.str[0] == '.') && ((sn.str[1] == '.') ||
- (sn.str[1] == '/')) && s->cwd) {
- char *tmp = malloc(PATH_MAX);
- if (tmp == NULL) {
- free(sn.str);
- return 3;
- }
- snprintf(tmp, PATH_MAX,
- "%s/%s", s->cwd, sn.str);
- free(sn.str);
- sn.str = tmp;
- }
- slist_append(s->filename, &sn);
- }
- *term = '"';
- } else {
- if (s->filename) {
- // append
- snode sn;
- sn.key = NULL;
- sn.hits = 1;
- if (strncmp(path, "(null)", 6) == 0) {
- sn.str = strdup("(null)");
- goto append;
- }
- if (!isxdigit(path[0]))
- return 4;
- if (path[0] == '0' && path[1] == '0')
- sn.str = unescape(&path[2]); // Abstract name
- else {
- term = strchr(path, ' ');
- if (term == NULL)
- return 5;
- *term = 0;
- sn.str = unescape(path);
- *term = ' ';
- }
- // Attempt to rebuild path if relative
- if ((sn.str[0] == '.') && ((sn.str[1] == '.') ||
- (sn.str[1] == '/')) && s->cwd) {
- char *tmp = malloc(PATH_MAX);
- if (tmp == NULL)
- return 6;
- snprintf(tmp, PATH_MAX, "%s/%s",
- s->cwd, sn.str);
- free(sn.str);
- sn.str = tmp;
- }
-append:
- slist_append(s->filename, &sn);
- }
- }
- return 0;
-}
-
-/* Older AVCs have path separate from the AVC record */
-static int avc_parse_path(const lnode *n, search_items *s)
-{
- char *str;
-
- if (event_filename) {
- // dont do this search unless needed
- str = strstr(n->message, " path=");
- if (str) {
- str += 6;
- return common_path_parser(s, str);
- }
- return 1;
- }
- return 0;
-}
-
-static int parse_path(const lnode *n, search_items *s)
-{
- // We add 32 to message because we do not nee to look at
- // anything before that. Its only time and type.
- char *str, *term = n->message+NAME_OFFSET;
-
- if (event_filename) {
- // dont do this search unless needed
- str = strstr(term, " name=");
- if (str) {
- int rc;
- str += 6;
- rc = common_path_parser(s, str);
- if (rc)
- return rc;
- }
- }
- if (event_object) {
- // tcontext
- str = strstr(term, "obj=");
- if (str != NULL) {
- str += 4;
- term = strchr(str, ' ');
- if (term)
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.tcontext = strdup(str);
- alist_append(s->avc, &an);
- if (term)
- *term = ' ';
- } else
- return 7;
- }
- }
- return 0;
-}
-
-static int parse_obj(const lnode *n, search_items *s)
-{
- char *str, *term;
-
- term = n->message;
- if (event_object) {
- // obj context
- str = strstr(term, "obj=");
- if (str != NULL) {
- str += 4;
- term = strchr(str, ' ');
- if (term)
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.tcontext = strdup(str);
- alist_append(s->avc, &an);
- if (term)
- *term = ' ';
- } else
- return 1;
- }
- }
- return 0;
-}
-
-static int parse_user(const lnode *n, search_items *s)
-{
- char *ptr, *str, *term, saved, *mptr;
-
- term = n->message;
-
- // get pid
- if (event_pid != -1) {
- str = strstr(term, "pid=");
- if (str == NULL)
- return 1;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 2;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 3;
- *term = ' ';
- }
- // optionally get uid
- if (event_uid != -1) {
- str = strstr(term, "uid=");
- if (str == NULL)
- return 4;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 5;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- *term = ' ';
- }
- // optionally get loginuid
- if (event_loginuid != -2) {
- *term = ' ';
- str = strstr(term, "auid=");
- if (str == NULL) { // Try the older one
- str = strstr(term, "loginuid=");
- if (str == NULL)
- return 7;
- ptr = str + 9;
- } else
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 8;
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 9;
- *term = ' ';
- }
- // ses
- if (event_session_id != -2 ) {
- str = strstr(term, "ses=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 10;
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 11;
- *term = ' ';
- }
- }
- if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str != NULL) {
- str += 5;
- term = strchr(str, ' ');
- if (term == NULL)
- return 12;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 13;
- }
- }
- // optionally get gid
- if (event_gid != -1) {
- if (n->type == AUDIT_ADD_GROUP || n->type == AUDIT_DEL_GROUP ||
- n->type == AUDIT_GRP_MGMT) {
- str = strstr(term, " id=");
- // Take second shot in the case of MGMT events
- if (str == NULL && n->type == AUDIT_GRP_MGMT)
- str = strstr(term, "gid=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 31;
- *term = 0;
- errno = 0;
- s->gid = strtoul(ptr, NULL, 10);
- if (errno)
- return 32;
- *term = ' ';
- }
- }
- }
- if (event_vmname) {
- str = strstr(term, "vm=");
- if (str) {
- str += 3;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 23;
- *term = 0;
- s->vmname = strdup(str);
- *term = '"';
- } else
- s->vmname = unescape(str);
- }
- }
- if (event_uuid) {
- str = strstr(term, "uuid=");
- if (str) {
- str += 5;
- term = str;
- while (*term != ' ' && *term != ':')
- term++;
- if (term == str)
- return 24;
- saved = *term;
- *term = 0;
- s->uuid = strdup(str);
- *term = saved;
- }
- }
- if (event_subject) {
- str = strstr(term, "vm-ctx=");
- if (str != NULL) {
- str += 7;
- term = strchr(str, ' ');
- if (term == NULL)
- return 27;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 28;
- }
- }
- if (event_object) {
- str = strstr(term, "img-ctx=");
- if (str != NULL) {
- str += 8;
- term = strchr(str, ' ');
- if (term == NULL)
- return 29;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.tcontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 30;
- }
- }
- // optionally get uid - some records the second uid is what we want.
- // USER_LOGIN for example.
- if (event_uid != -1) {
- str = strstr(term, "uid=");
- if (str) {
- if (*(str - 1) == 'a' || *(str - 1) == 's' ||
- *(str - 1) == 'u')
- goto skip;
- if (!(*(str - 1) == '\'' || *(str - 1) == ' '))
- return 25;
- ptr = str + 4;
- term = ptr;
- while (isdigit(*term))
- term++;
- if (term == ptr)
- return 14;
-
- saved = *term;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 15;
- *term = saved;
- }
- }
-skip:
- mptr = term + 1;
-
- if (event_comm) {
- // dont do this search unless needed
- str = strstr(mptr, "comm=");
- if (str) {
- str += 5;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 16;
- *term = 0;
- s->comm = strdup(str);
- *term = '"';
- } else
- s->comm = unescape(str);
- }
- }
-
- // Get acct for user/group add/del
- str = strstr(mptr, "acct=");
- if (str != NULL) {
- ptr = str + 5;
- term = ptr + 1;
- if (*ptr == '"') {
- while (*term != '"')
- term++;
- saved = *term;
- *term = 0;
- ptr++;
- s->acct = strdup(ptr);
- *term = saved;
- } else {
- /* Handle legacy accts */
- char *end = ptr;
- int legacy = 0;
-
- while (*end != ' ') {
- if (!isxdigit(*end))
- legacy = 1;
- end++;
- }
- term = end;
- if (!legacy)
- s->acct = unescape(ptr);
- else {
- saved = *term;
- *term = 0;
- s->acct = strdup(ptr);
- *term = saved;
- }
- }
- }
- mptr = term + 1;
-
- // get hostname
- if (event_hostname) {
- // dont do this search unless needed
- str = strstr(mptr, "hostname=");
- if (str) {
- str += 9;
- term = strchr(str, ',');
- if (term == NULL) {
- term = strchr(str, ' ');
- if (term == NULL)
- return 17;
- }
- saved = *term;
- *term = 0;
- s->hostname = strdup(str);
- *term = saved;
-
- // Lets see if there is something more
- // meaningful in addr
- if (strcmp(s->hostname, "?") == 0) {
- term++;
- str = strstr(term, "addr=");
- if (str) {
- str += 5;
- term = strchr(str, ',');
- if (term == NULL) {
- term = strchr(str, ' ');
- if (term == NULL)
- return 18;
- }
- saved = *term;
- *term = 0;
- free(s->hostname);
- s->hostname = strdup(str);
- *term = saved;
- }
- }
- }
- }
- if (event_filename) {
- // dont do this search unless needed
- str = strstr(mptr, "cwd=");
- if (str) {
- str += 4;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 20;
- *term = 0;
- s->cwd = strdup(str);
- *term = '"';
- } else {
- char *end = str;
- int legacy = 0;
-
- while (*end != ' ') {
- if (!isxdigit(*end)) {
- legacy = 1;
- }
- end++;
- }
- term = end;
- if (!legacy)
- s->cwd = unescape(str);
- else {
- saved = *term;
- *term = 0;
- s->cwd = strdup(str);
- *term = saved;
- }
- }
- }
- }
- if (event_terminal) {
- // dont do this search unless needed
- str = strstr(mptr, "terminal=");
- if (str) {
- str += 9;
- term = strchr(str, ' ');
- if (term == NULL) {
- term = strchr(str, ')');
- if (term == NULL)
- return 19;
- }
- *term = 0;
- s->terminal = strdup(str);
- *term = ' ';
- }
- }
- if (event_exe) {
- // dont do this search unless needed
- str = strstr(mptr, "exe=");
- if (str) {
- str += 4;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 26;
- *term = 0;
- s->exe = strdup(str);
- *term = '"';
- } else {
- char *end = str;
- int legacy = 0;
-
- while (*end != ' ') {
- if (!isxdigit(*end)) {
- legacy = 1;
- }
- end++;
- }
- term = end;
- if (!legacy)
- s->exe = unescape(str);
- else {
- saved = *term;
- *term = 0;
- s->exe = strdup(str);
- *term = saved;
- }
- }
- }
- }
-
- // get success
- if (event_success != S_UNSET) {
- str = strstr(mptr, "res=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, '\'');
- if (term == NULL)
- return 21;
- *term = 0;
- if (strncmp(ptr, "failed", 6) == 0)
- s->success = S_FAILED;
- else
- s->success = S_SUCCESS;
- *term = '\'';
- } else if ((str = strstr(mptr, "result="))) {
- ptr = str + 7;
- term = strchr(ptr, ')');
- if (term == NULL)
- return 22;
- *term = 0;
- if (strcasecmp(ptr, "success") == 0)
- s->success = S_SUCCESS;
- else
- s->success = S_FAILED;
- *term = ')';
- }
- }
- /* last return code used = 24 */
- return 0;
-}
-
-static int parse_login(const lnode *n, search_items *s)
-{
- char *ptr, *str, *term = n->message;
-
- // get pid
- if (event_pid != -1) {
- str = strstr(term, "pid=");
- if (str == NULL)
- return 1;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 2;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 3;
- *term = ' ';
- }
- // optionally get uid
- if (event_uid != -1) {
- str = strstr(term, "uid=");
- if (str == NULL)
- return 4;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 5;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- *term = ' ';
- }
- // optionally get subj
- if (event_subject) {
- str = strstr(term, "subj=");
- if (str) {
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 12;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 13;
- *term = ' ';
- }
- }
- // optionally get loginuid
- if (event_loginuid != -2) {
- str = strstr(term, "new auid=");
- if (str == NULL) {
- // 3.14 kernel changed it to the next line
- str = strstr(term, " auid=");
- if (str == NULL) {
- str = strstr(term, "new loginuid=");
- if (str == NULL)
- return 7;
- ptr = str + 13;
- } else
- ptr = str + 6;
- } else
- ptr = str + 9;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 8;
- if (term)
- *term = ' ';
- }
-
- // success
- if (event_success != S_UNSET) {
- if (term == NULL)
- term = n->message;
- str = strstr(term, "res=");
- if (str != NULL) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->success = strtoul(ptr, NULL, 10);
- if (errno)
- return 9;
- if (term)
- *term = ' ';
- } else // Assume older kernel where always successful
- s->success = S_SUCCESS;
- }
- // ses
- if (event_session_id != -2 ) {
- if (term == NULL)
- term = n->message;
- str = strstr(term, "new ses=");
- if (str == NULL) {
- // The 3.14 kernel changed it to the next line
- str = strstr(term, " ses=");
- if (str == NULL)
- return 14;
- ptr = str + 5;
- }
- else
- ptr = str + 8;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 11;
- if (term)
- *term = ' ';
- }
- return 0;
-}
-
-static int parse_daemon1(const lnode *n, search_items *s)
-{
- char *ptr, *str, *term, saved, *mptr;
-
- // Not all messages have a ')', use it if its there
- mptr = strchr(n->message, ')');
- if (mptr == NULL)
- mptr = n->message;
- term = mptr;
-
- // optionally get auid
- if (event_loginuid != -2 ) {
- str = strstr(mptr, "auid=");
- if (str == NULL)
- return 1;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 2;
- saved = *term;
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 3;
- *term = saved;
- }
-
- // pid
- if (event_pid != -1) {
- str = strstr(term, "pid=");
- if (str == NULL)
- return 4;
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 5;
- saved = *term;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- *term = saved;
- }
-
- if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str != NULL) {
- str += 5;
- term = strchr(str, ' ');
- if (term)
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- } else
- return 7;
- if (term)
- *term = ' ';
- }
- }
-
- // success
- if (event_success != S_UNSET) {
- str = strstr(mptr, "res=");
- if (str) {
- ptr = term = str + 4;
- while (isalpha(*term))
- term++;
- if (term == ptr)
- return 9;
- saved = *term;
- *term = 0;
- if (strncmp(ptr, "failed", 6) == 0)
- s->success = S_FAILED;
- else
- s->success = S_SUCCESS;
- *term = saved;
- }
- }
-
- return 0;
-}
-
-static int parse_daemon2(const lnode *n, search_items *s)
-{
- char *str, saved, *term = n->message;
-
- if (event_hostname) {
- str = strstr(term, "addr=");
- if (str) {
- str += 5;
- term = strchr(str, ':');
- if (term == NULL) {
- term = strchr(str, ' ');
- if (term == NULL)
- return 1;
- }
- saved = *term;
- *term = 0;
- free(s->hostname);
- s->hostname = strdup(str);
- *term = saved;
- }
- }
-
- if (event_success != S_UNSET) {
- char *str = strstr(term, "res=");
- if (str) {
- char *ptr, *term, saved;
-
- ptr = term = str + 4;
- while (isalpha(*term))
- term++;
- if (term == ptr)
- return 2;
- saved = *term;
- *term = 0;
- if (strncmp(ptr, "failed", 6) == 0)
- s->success = S_FAILED;
- else
- s->success = S_SUCCESS;
- *term = saved;
- }
- }
-
- return 0;
-}
-
-static int parse_sockaddr(const lnode *n, search_items *s)
-{
- char *str;
-
- if (event_hostname || event_filename) {
- str = strstr(n->message, "saddr=");
- if (str) {
- int len;
- struct sockaddr *saddr;
- char name[NI_MAXHOST];
-
- str += 6;
- len = strlen(str)/2;
- s->hostname = unescape(str);
- saddr = (struct sockaddr *)s->hostname;
- if (saddr->sa_family == AF_INET) {
- if (len < sizeof(struct sockaddr_in)) {
- fprintf(stderr,
- "sockaddr len too short\n");
- return 1;
- }
- len = sizeof(struct sockaddr_in);
- } else if (saddr->sa_family == AF_INET6) {
- if (len < sizeof(struct sockaddr_in6)) {
- fprintf(stderr,
- "sockaddr6 len too short\n");
- return 2;
- }
- len = sizeof(struct sockaddr_in6);
- } else if (saddr->sa_family == AF_UNIX) {
- struct sockaddr_un *un =
- (struct sockaddr_un *)saddr;
- if (un->sun_path[0])
- len = strlen(un->sun_path);
- else // abstract name
- len = strlen(&un->sun_path[1]);
- if (len == 0) {
- fprintf(stderr,
- "sun_path len too short\n");
- return 3;
- }
- if (event_filename) {
- if (!s->filename) {
- //create
- s->filename =
- malloc(sizeof(slist));
- if (s->filename == NULL)
- return 4;
- slist_create(s->filename);
- }
- if (s->filename) {
- // append
- snode sn;
- sn.str = strdup(un->sun_path);
- sn.key = NULL;
- sn.hits = 1;
- slist_append(s->filename, &sn);
- }
- free(s->hostname);
- s->hostname = NULL;
- return 0;
- } else { // No file name - no need for socket
- free(s->hostname);
- s->hostname = NULL;
- return 0;
- }
- } else {
- // addr family we don't care about
- free(s->hostname);
- s->hostname = NULL;
- return 0;
- }
- if (!event_hostname) {
- // we entered here for files - discard
- free(s->hostname);
- s->hostname = NULL;
- return 0;
- }
- if (getnameinfo(saddr, len, name, NI_MAXHOST,
- NULL, 0, NI_NUMERICHOST) ) {
- free(s->hostname);
- s->hostname = NULL;
- } else {
- free(s->hostname);
- s->hostname = strdup(name);
- }
- }
- }
- return 0;
-}
-
-static int parse_integrity(const lnode *n, search_items *s)
-{
- char *ptr, *str, *term;
-
- term = n->message;
- // get pid
- str = strstr(term, "pid=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 1;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 2;
- *term = ' ';
- }
-
- // optionally get uid
- if (event_uid != -1) {
- str = strstr(term, " uid=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 3;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 4;
- *term = ' ';
- }
- }
-
- // optionally get loginuid
- if (event_loginuid != -2) {
- str = strstr(n->message, "auid=");
- if (str) {
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 5;
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- *term = ' ';
- }
- }
-
- // ses
- if (event_session_id != -2 ) {
- str = strstr(term, "ses=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 10;
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 11;
- *term = ' ';
- }
- }
-
- if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str) {
- str += 5;
- term = strchr(str, ' ');
- if (term == NULL)
- return 12;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 13;
- }
- }
-
- if (event_comm) {
- str = strstr(term, "comm=");
- if (str) {
- str += 5;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 7;
- *term = 0;
- s->comm = strdup(str);
- *term = '"';
- } else
- s->comm = unescape(str);
- }
- }
-
- if (event_filename) {
- str = strstr(term, " name=");
- if (str) {
- str += 6;
- if (common_path_parser(s, str))
- return 8;
- }
- }
-
- // and results (usually last)
- if (event_success != S_UNSET) {
- str = strstr(term, "res=");
- if (str != NULL) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->success = strtoul(ptr, NULL, 10);
- if (errno)
- return 9;
- if (term)
- *term = ' ';
- }
- }
-
- return 0;
-}
-
-
-/* FIXME: If they are in permissive mode or hit an auditallow, there can
- * be more that 1 avc in the same syscall. For now, we pickup just the first.
- */
-static int parse_avc(const lnode *n, search_items *s)
-{
- char *str, *term;
- anode an;
- int rc=0;
-
- term = n->message;
- anode_init(&an);
-
- // get the avc message info.
- str = strstr(term, "avc: ");
- if (str) {
- str += 5;
- term = strchr(str, '{');
- if (term == NULL)
- return 1;
- if (event_success != S_UNSET) {
- *term = 0;
- // FIXME. Do not override syscall success if already
- // set. Syscall pass/fail is the authoritative value.
- if (strstr(str, "denied")) {
- s->success = S_FAILED;
- an.avc_result = AVC_DENIED;
- } else {
- s->success = S_SUCCESS;
- an.avc_result = AVC_GRANTED;
- }
- *term = '{';
- }
-
- // Now get permission
- str = term + 1;
- while (*str == ' ')
- str++;
- term = strchr(str, '}');
- if (term == NULL)
- return 2;
- while (*(term-1) == ' ')
- term--;
- *term = 0;
- an.avc_perm = strdup(str);
- *term = ' ';
- }
-
- // get pid
- if (event_pid != -1) {
- str = strstr(term, "pid=");
- if (str) {
- str = str + 4;
- term = strchr(str, ' ');
- if (term == NULL) {
- rc = 3;
- goto err;
- }
- *term = 0;
- errno = 0;
- s->pid = strtoul(str, NULL, 10);
- if (errno) {
- rc = 4;
- goto err;
- }
- *term = ' ';
- }
- }
-
- if (event_comm && s->comm == NULL) {
- // dont do this search unless needed
- str = strstr(term, "comm=");
- if (str == NULL) {
- rc = 5;
- goto err;
- }
- str += 5;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL) {
- rc = 6;
- goto err;
- }
- *term = 0;
- s->comm = strdup(str);
- *term = '"';
- } else {
- s->comm = unescape(str);
- term = str + 6;
- }
- }
- if (event_filename) {
- // do we have a path?
- str = strstr(term, " path=");
- if (str) {
- str += 6;
- rc = common_path_parser(s, str);
- if (rc)
- goto err;
- term += 7;
- } else {
- str = strstr(term, " name=");
- if (str) {
- str += 6;
- rc = common_path_parser(s, str);
- if (rc)
- goto err;
- term += 7;
- }
- }
- }
- if (event_subject) {
- // scontext
- str = strstr(term, "scontext=");
- if (str != NULL) {
- str += 9;
- term = strchr(str, ' ');
- if (term == NULL) {
- rc = 7;
- goto err;
- }
- *term = 0;
- an.scontext = strdup(str);
- *term = ' ';
- }
- }
-
- if (event_object) {
- // tcontext
- str = strstr(term, "tcontext=");
- if (str != NULL) {
- str += 9;
- term = strchr(str, ' ');
- if (term == NULL) {
- rc = 8;
- goto err;
- }
- *term = 0;
- an.tcontext = strdup(str);
- *term = ' ';
- }
- }
-
- // Now get the class...its at the end, so we do things different
- str = strstr(term, "tclass=");
- if (str == NULL) {
- rc = 9;
- goto err;
- }
- str += 7;
- term = strchr(str, ' ');
- if (term)
- *term = 0;
- an.avc_class = strdup(str);
- if (term)
- *term = ' ';
-
- if (audit_avc_init(s) == 0) {
- alist_append(s->avc, &an);
- } else {
- rc = 10;
- goto err;
- }
-
- return 0;
-err:
- anode_clear(&an);
- return rc;
-}
-
-static int parse_kernel_anom(const lnode *n, search_items *s)
-{
- char *str, *ptr, *term = n->message;
-
- // optionally get loginuid
- if (event_loginuid != -2) {
- str = strstr(term, "auid=");
- if (str == NULL)
- return 1;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 2;
- if (term)
- *term = ' ';
- else
- term = ptr;
- }
-
- // optionally get uid
- if (event_uid != -1) {
- str = strstr(term, "uid="); // if promiscuous, we start over
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 3;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 4;
- *term = ' ';
- }
- }
-
- // optionally get gid
- if (event_gid != -1) {
- str = strstr(term, "gid=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 5;
- *term = 0;
- errno = 0;
- s->gid = strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- *term = ' ';
- }
- }
-
- if (event_session_id != -2) {
- str = strstr(term, "ses=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 7;
- if (term)
- *term = ' ';
- else
- term = ptr;
- }
- }
-
- if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str) {
- str += 5;
- term = strchr(str, ' ');
- if (term == NULL)
- return 8;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 9;
- }
- }
-
- // get pid
- if (event_pid != -1) {
- str = strstr(term, "pid=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 10;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 11;
- *term = ' ';
- }
- }
-
- if (event_comm) {
- // dont do this search unless needed
- str = strstr(term, "comm=");
- if (str) {
- str += 5;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 12;
- *term = 0;
- s->comm = strdup(str);
- *term = '"';
- } else
- s->comm = unescape(str);
- }
- }
-
- if (n->type == AUDIT_SECCOMP) {
- if (event_exe) {
- // dont do this search unless needed
- str = strstr(n->message, "exe=");
- if (str) {
- str += 4;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 13;
- *term = 0;
- s->exe = strdup(str);
- *term = '"';
- } else
- s->exe = unescape(str);
- } else
- return 14;
- }
-
- // get arch
- str = strstr(term, "arch=");
- if (str == NULL)
- return 0; // A few kernel versions don't have it
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 15;
- *term = 0;
- errno = 0;
- s->arch = (int)strtoul(ptr, NULL, 16);
- if (errno)
- return 16;
- *term = ' ';
- // get syscall
- str = strstr(term, "syscall=");
- if (str == NULL)
- return 17;
- ptr = str + 8;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 18;
- *term = 0;
- errno = 0;
- s->syscall = (int)strtoul(ptr, NULL, 10);
- if (errno)
- return 19;
- *term = ' ';
- }
-
- return 0;
-}
-
-// This is for messages that only have the loginuid as the item
-// of interest.
-static int parse_simple_message(const lnode *n, search_items *s)
-{
- char *str, *ptr, *term = n->message;
-
- // optionally get loginuid - old kernels skip auid for CONFIG_CHANGE
- if (event_loginuid != -2) {
- str = strstr(term, "auid=");
- if (str == NULL && n->type != AUDIT_CONFIG_CHANGE)
- return 1;
- if (str) {
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 2;
- if (term)
- *term = ' ';
- else
- term = ptr;
- }
- }
-
- // ses
- if (event_session_id != -2 ) {
- str = strstr(term, "ses=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 3;
- if (term)
- *term = ' ';
- else
- term = ptr;
- }
- }
-
- // Now get subj label
- if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str != NULL) {
- str += 5;
- term = strchr(str, ' ');
- if (term)
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- if (term)
- *term = ' ';
- else // Set it back to something sane
- term = str;
- } else
- return 4;
- }
- }
-
- if (event_key) {
- str = strstr(term, "key=");
- if (str != NULL) {
- if (!s->key) {
- //create
- s->key = malloc(sizeof(slist));
- if (s->key == NULL)
- return 5;
- slist_create(s->key);
- }
- ptr = str + 4;
- if (*ptr == '"') {
- ptr++;
- term = strchr(ptr, '"');
- if (term != NULL) {
- *term = 0;
- if (s->key) {
- // append
- snode sn;
- sn.str = strdup(ptr);
- sn.key = NULL;
- sn.hits = 1;
- slist_append(s->key, &sn);
- }
- *term = '"';
- } else
- return 6;
- } else {
- if (s->key) {
- char *saved;
- char *keyptr = unescape(ptr);
- char *kptr = strtok_r(keyptr,
- key_sep, &saved);
- while (kptr) {
- snode sn;
- // append
- sn.str = strdup(kptr);
- sn.key = NULL;
- sn.hits = 1;
- slist_append(s->key, &sn);
- kptr = strtok_r(NULL,
- key_sep, &saved);
- }
- free(keyptr);
- }
- }
- }
- }
-
- // defaulting this to 1 for these messages. The kernel generally
- // does not log the res since it can be nothing but success.
- // But it can still be overriden below if res= is found in the event
- if (n->type == AUDIT_CONFIG_CHANGE)
- s->success = S_SUCCESS;
-
- // and results (usually last)
- if (event_success != S_UNSET) {
- str = strstr(term, "res=");
- if (str != NULL) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->success = strtoul(ptr, NULL, 10);
- if (errno)
- return 7;
- if (term)
- *term = ' ';
- }
- }
-
- return 0;
-}
-
-static int parse_tty(const lnode *n, search_items *s)
-{
- char *str, *ptr, *term=n->message;
-
- // get pid
- if (event_pid != -1) {
- str = strstr(n->message, "pid=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 1;
- *term = 0;
- errno = 0;
- s->pid = strtoul(ptr, NULL, 10);
- if (errno)
- return 2;
- *term = ' ';
- }
- }
-
- // optionally get uid
- if (event_uid != -1) {
- str = strstr(term, " uid="); // if promiscuous, we start over
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 3;
- *term = 0;
- errno = 0;
- s->uid = strtoul(ptr, NULL, 10);
- if (errno)
- return 4;
- *term = ' ';
- }
- }
-
- // optionally get loginuid
- if (event_loginuid != -2) {
- str = strstr(term, "auid=");
- if (str == NULL)
- return 5;
- ptr = str + 5;
- term = strchr(ptr, ' ');
- if (term)
- *term = 0;
- errno = 0;
- s->loginuid = strtoul(ptr, NULL, 10);
- if (errno)
- return 6;
- if (term)
- *term = ' ';
- else
- term = ptr;
- }
-
- // ses
- if (event_session_id != -2 ) {
- str = strstr(term, "ses=");
- if (str) {
- ptr = str + 4;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 7;
- *term = 0;
- errno = 0;
- s->session_id = strtoul(ptr, NULL, 10);
- if (errno)
- return 8;
- *term = ' ';
- }
- }
-
-/* if (event_subject) {
- // scontext
- str = strstr(term, "subj=");
- if (str) {
- str += 5;
- term = strchr(str, ' ');
- if (term == NULL)
- return 9;
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.scontext = strdup(str);
- alist_append(s->avc, &an);
- *term = ' ';
- } else
- return 10;
- }
- } */
-
- if (event_comm) {
- // dont do this search unless needed
- str = strstr(term, "comm=");
- if (str) {
- str += 5;
- if (*str == '"') {
- str++;
- term = strchr(str, '"');
- if (term == NULL)
- return 11;
- *term = 0;
- s->comm = strdup(str);
- *term = '"';
- } else
- s->comm = unescape(str);
- }
- }
-
- return 0;
-}
-
-static int parse_pkt(const lnode *n, search_items *s)
-{
- char *str, *ptr, *term=n->message;
-
- // get hostname
- if (event_hostname) {
- str = strstr(n->message, "saddr=");
- if (str) {
- ptr = str + 6;
- term = strchr(ptr, ' ');
- if (term == NULL)
- return 1;
- *term = 0;
- s->hostname = strdup(ptr);
- *term = ' ';
- }
- }
-
- // obj context
- if (event_object) {
- str = strstr(term, "obj=");
- if (str != NULL) {
- str += 4;
- term = strchr(str, ' ');
- if (term)
- *term = 0;
- if (audit_avc_init(s) == 0) {
- anode an;
-
- anode_init(&an);
- an.tcontext = strdup(str);
- alist_append(s->avc, &an);
- if (term)
- *term = ' ';
- } else
- return 2;
- }
- }
-
- return 0;
-}
-
diff --git a/framework/src/audit/src/ausearch-parse.h b/framework/src/audit/src/ausearch-parse.h
deleted file mode 100644
index 36557105..00000000
--- a/framework/src/audit/src/ausearch-parse.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-* ausearch-parse.h - Header file for ausearch-llist.c
-* Copyright (c) 2005 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AUPARSE_HEADER
-#define AUPARSE_HEADER
-
-#include "config.h"
-#include "ausearch-llist.h"
-
-int extract_search_items(llist *l);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-report.c b/framework/src/audit/src/ausearch-report.c
deleted file mode 100644
index a4f1e15d..00000000
--- a/framework/src/audit/src/ausearch-report.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
-* ausearch-report.c - Format and output events
-* Copyright (c) 2005-09,2011-13 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "config.h"
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include "libaudit.h"
-#include "ausearch-options.h"
-#include "ausearch-parse.h"
-#include "ausearch-lookup.h"
-#include "auparse-idata.h"
-#include "auparse-defs.h"
-
-/* Local functions */
-static void output_raw(llist *l);
-static void output_default(llist *l);
-static void output_interpreted(llist *l);
-static void output_interpreted_node(const lnode *n, const event *e);
-static void interpret(char *name, char *val, int comma, int rtype);
-
-/* The machine based on elf type */
-static unsigned long machine = -1;
-static int cur_syscall = -1;
-
-/* The first syscall argument */
-static unsigned long long a0, a1;
-
-/* This function branches to the correct output format */
-void output_record(llist *l)
-{
- switch (report_format) {
- case RPT_RAW:
- output_raw(l);
- break;
- case RPT_DEFAULT:
- output_default(l);
- break;
- case RPT_INTERP:
- output_interpreted(l);
- break;
- case RPT_PRETTY:
- break;
- default:
- fprintf(stderr, "Report format error");
- exit(1);
- }
-}
-
-/* This function will output the record as is */
-static void output_raw(llist *l)
-{
- const lnode *n;
-
- list_first(l);
- n = list_get_cur(l);
- if (!n) {
- fprintf(stderr, "Error - no elements in record.");
- return;
- }
- do {
- puts(n->message);
- } while ((n=list_next(l)));
-}
-
-/*
- * This function will take the linked list and format it for output. No
- * interpretation is performed. The output order is lifo for everything.
- */
-static void output_default(llist *l)
-{
- const lnode *n;
-
- list_last(l);
- n = list_get_cur(l);
- printf("----\ntime->%s", ctime(&l->e.sec));
- if (!n) {
- fprintf(stderr, "Error - no elements in record.");
- return;
- }
- if (n->type >= AUDIT_DAEMON_START && n->type < AUDIT_SYSCALL)
- puts(n->message); // No injection possible
- else {
- do {
- safe_print_string_n(n->message, n->mlen, 1);
- } while ((n=list_prev(l)));
- }
-}
-
-/*
- * This function will take the linked list and format it for output.
- * Interpretation is performed to aid understanding of records. The output
- * order is lifo for everything.
- */
-static void output_interpreted(llist *l)
-{
- const lnode *n;
-
- list_last(l);
- n = list_get_cur(l);
- printf("----\n");
- if (!n) {
- fprintf(stderr, "Error - no elements in record.");
- return;
- }
- if (n->type >= AUDIT_DAEMON_START && n->type < AUDIT_SYSCALL)
- output_interpreted_node(n, &(l->e));
- else {
- do {
- output_interpreted_node(n, &(l->e));
- } while ((n=list_prev(l)));
- }
-}
-
-/*
- * This function will cycle through a single record and lookup each field's
- * value that it finds.
- */
-static void output_interpreted_node(const lnode *n, const event *e)
-{
- char *ptr, *str = n->message;
- int found, comma = 0;
- int num = n->type;
- struct tm *btm;
- char tmp[32];
-
- // Reset these because each record could be different
- machine = -1;
- cur_syscall = -1;
-
- /* Check and see if we start with a node
- * If we do, and there is a space in the line
- * move the pointer to the first character past
- * the space
- */
- if (e->node) {
- if ((ptr=strchr(str, ' ')) != NULL) {
- str = ptr+1;
- }
- }
-
- // First locate time stamp.
- ptr = strchr(str, '(');
- if (ptr == NULL) {
- fprintf(stderr, "can't find time stamp\n");
- return;
- }
-
- *ptr++ = 0; /* move to the start of the timestamp */
-
- // print everything up to it.
- if (num >= 0) {
- const char * bptr;
- bptr = audit_msg_type_to_name(num);
- if (bptr) {
- if (e->node)
- printf("node=%s ", e->node);
- printf("type=%s msg=audit(", bptr);
- goto no_print;
- }
- }
- if (e->node)
- printf("node=%s ", e->node);
- printf("%s(", str);
-no_print:
-
- str = strchr(ptr, ')');
- if(str == NULL)
- return;
- *str++ = 0;
- btm = localtime(&e->sec);
- strftime(tmp, sizeof(tmp), "%x %T", btm);
- printf("%s", tmp);
- printf(".%03d:%lu) ", e->milli, e->serial);
-
- if (n->type == AUDIT_SYSCALL) {
- a0 = n->a0;
- a1 = n->a1;
- }
-
- // for each item.
- found = 0;
- while (str && *str && (ptr = strchr(str, '='))) {
- char *name, *val;
- comma = 0;
- found = 1;
-
- // look back to last space - this is name
- name = ptr;
- while (*name != ' ' && name > str)
- --name;
- *ptr++ = 0;
-
- // print everything up to the '='
- printf("%s=", str);
-
- // Some user messages have msg='uid=500 in this case
- // skip the msg= piece since the real stuff is the uid=
- if (strcmp(name, "msg") == 0) {
- str = ptr;
- continue;
- }
-
- // In the above case, after msg= we need to trim the ' from uid
- if (*name == '\'')
- name++;
-
- // get string after = to the next space or end - this is value
- if (*ptr == '\'' || *ptr == '"') {
- str = strchr(ptr+1, *ptr);
- if (str) {
- str++;
- if (*str)
- *str++ = 0;
- }
- } else {
- str = strchr(ptr, ',');
- val = strchr(ptr, ' ');
- if (str && val && (str < val)) {
- // Value side has commas and another field exists
- // Known: LABEL_LEVEL_CHANGE banners=none,none
- // Known: ROLL_ASSIGN new-role=r,r
- // Known: any MAC LABEL can potentially have commas
- int ftype = auparse_interp_adjust_type(n->type,
- name, val);
- if (ftype == AUPARSE_TYPE_MAC_LABEL) {
- str = val;
- *str++ = 0;
- } else {
- *str++ = 0;
- comma = 1;
- }
- } else if (str && (val == NULL)) {
- // Goes all the way to the end. Done parsing
- // Known: MCS context in PATH rec obj=u:r:t:s0:c2,c7
- int ftype = auparse_interp_adjust_type(n->type,
- name, ptr);
- if (ftype == AUPARSE_TYPE_MAC_LABEL)
- str = NULL;
- else {
- *str++ = 0;
- comma = 1;
- }
- } else if (val) {
- // There is another field, point to next (normal path)
- str = val;
- *str++ = 0;
- }
- }
- // val points to begin & str 1 past end
- val = ptr;
-
- // print interpreted string
- interpret(name, val, comma, n->type);
- }
- // If nothing found, just print out as is
- if (!found && ptr == NULL && str)
- safe_print_string(str, 1);
-
- // If last field had comma, output the rest
- else if (comma)
- safe_print_string(str, 1);
- printf("\n");
-}
-
-static void interpret(char *name, char *val, int comma, int rtype)
-{
- int type;
- idata id;
-
- while (*name == ' '||*name == '(')
- name++;
-
- if (*name == 'a' && strcmp(name, "acct") == 0) {
- // Remove trailing punctuation
- int len = strlen(val);
- if (val[len-1] == ':')
- val[len-1] = 0;
- }
- type = auparse_interp_adjust_type(rtype, name, val);
-
- if (rtype == AUDIT_SYSCALL || rtype == AUDIT_SECCOMP) {
- if (machine == (unsigned long)-1)
- machine = audit_detect_machine();
- if (*name == 'a' && strcmp(name, "arch") == 0) {
- unsigned long ival;
- errno = 0;
- ival = strtoul(val, NULL, 16);
- if (errno) {
- printf("arch conversion error(%s) ", val);
- return;
- }
- machine = audit_elf_to_machine(ival);
- }
- if (cur_syscall < 0 && *name == 's' &&
- strcmp(name, "syscall") == 0) {
- unsigned long ival;
- errno = 0;
- ival = strtoul(val, NULL, 10);
- if (errno) {
- printf("syscall conversion error(%s) ", val);
- return;
- }
- cur_syscall = ival;
- }
- id.syscall = cur_syscall;
- } else
- id.syscall = 0;
- id.machine = machine;
- id.a0 = a0;
- id.a1 = a1;
- id.name = name;
- id.val = val;
-
- char *out = auparse_do_interpretation(type, &id);
- if (type == AUPARSE_TYPE_UNCLASSIFIED)
- printf("%s%c", val, comma ? ',' : ' ');
- else if (name[0] == 'k' && strcmp(name, "key") == 0) {
- char *str, *ptr = out;
- int count = 0;
- while ((str = strchr(ptr, AUDIT_KEY_SEPARATOR))) {
- *str = 0;
- if (count == 0) {
- printf("%s", ptr);
- count++;
- } else
- printf(" key=%s", ptr);
- ptr = str+1;
- }
- if (count == 0)
- printf("%s ", out);
- else
- printf(" key=%s ", ptr);
- } else if (type == AUPARSE_TYPE_TTY_DATA)
- printf("%s", out);
- else
- printf("%s ", out);
-
- free(out);
-}
-
diff --git a/framework/src/audit/src/ausearch-string.c b/framework/src/audit/src/ausearch-string.c
deleted file mode 100644
index 3c5c55e3..00000000
--- a/framework/src/audit/src/ausearch-string.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-* ausearch-string.c - Minimal linked list library for strings
-* Copyright (c) 2005,2008,2014 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#include "ausearch-string.h"
-#include <stdlib.h>
-#include <string.h>
-
-
-void slist_create(slist *l)
-{
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-void slist_last(slist *l)
-{
- register snode* cur;
-
- if (l->head == NULL)
- return;
-
- // Try using cur so that we don't have to start at beginnning
- if (l->cur)
- cur = l->cur;
- else
- cur = l->head;
-
- // Loop until no next value
- while (cur->next)
- cur = cur->next;
- l->cur = cur;
-}
-
-snode *slist_next(slist *l)
-{
- if (l->cur == NULL)
- return NULL;
- l->cur = l->cur->next;
- return l->cur;
-}
-
-void slist_append(slist *l, snode *node)
-{
- snode* newnode;
-
- newnode = malloc(sizeof(snode));
-
- if (node->str)
- newnode->str = node->str;
- else
- newnode->str = NULL;
-
- if (node->key)
- newnode->key = node->key;
- else
- newnode->key = NULL;
-
- newnode->hits = node->hits;
- newnode->next = NULL;
-
- // Make sure cursor is at the end
- slist_last(l);
-
- // if we are at top, fix this up
- if (l->head == NULL)
- l->head = newnode;
- else // Otherwise add pointer to newnode
- l->cur->next = newnode;
-
- // make newnode current
- l->cur = newnode;
- l->cnt++;
-}
-
-void slist_clear(slist* l)
-{
- snode* nextnode;
- register snode* current;
-
- current = l->head;
- while (current) {
- nextnode=current->next;
- free(current->str);
- free(current->key);
- free(current);
- current=nextnode;
- }
- l->head = NULL;
- l->cur = NULL;
- l->cnt = 0;
-}
-
-/* This function dominates the timing of aureport. Needs to be more efficient */
-int slist_add_if_uniq(slist *l, const char *str)
-{
- snode sn;
- register snode *cur;
-
- cur = l->head;
- while (cur) {
- if (strcmp(str, cur->str) == 0) {
- cur->hits++;
- l->cur = cur;
- return 0;
- } else
- cur = cur->next;
- }
-
- /* No matches, append to the end */
- sn.str = strdup(str);
- sn.key = NULL;
- sn.hits = 1;
- slist_append(l, &sn);
- return 1;
-}
-
-// If lprev would be NULL, use l->head
-static void swap_nodes(snode *lprev, snode *left, snode *right)
-{
- snode *t = right->next;
- if (lprev)
- lprev->next = right;
- right->next = left;
- left->next = t;
-}
-
-// This will sort the list from most hits to least
-void slist_sort_by_hits(slist *l)
-{
- register snode* cur, *prev;
-
- if (l->cnt <= 1)
- return;
-
- prev = cur = l->head;
-
- while (cur && cur->next) {
- /* If the next node is bigger */
- if (cur->hits < cur->next->hits) {
- if (cur == l->head) {
- // Update the actual list head
- l->head = cur->next;
- prev = NULL;
- }
- swap_nodes(prev, cur, cur->next);
-
- // start over
- prev = cur = l->head;
- continue;
- }
- prev = cur;
- cur = cur->next;
- }
- // End with cur pointing at first record
- l->cur = l->head;
-}
-
diff --git a/framework/src/audit/src/ausearch-string.h b/framework/src/audit/src/ausearch-string.h
deleted file mode 100644
index 08cf2ffc..00000000
--- a/framework/src/audit/src/ausearch-string.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-* ausearch-string.h - Header file for ausearch-string.c
-* Copyright (c) 2005,2008 Red Hat Inc., Durham, North Carolina.
-* All Rights Reserved.
-*
-* This software may be freely redistributed and/or modified under the
-* terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2, or (at your option) any
-* later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; see the file COPYING. If not, write to the
-* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Authors:
-* Steve Grubb <sgrubb@redhat.com>
-*/
-
-#ifndef AUSTRING_HEADER
-#define AUSTRING_HEADER
-
-#include "config.h"
-
-/* This is the node of the linked list. message & item are the only elements
- * at this time. Any data elements that are per item goes here. */
-typedef struct _snode{
- char *str; // The string
- char *key; // The key string
- unsigned int hits; // Number of times this string was attempted to be added
- struct _snode* next; // Next string node pointer
-} snode;
-
-/* This is the linked list head. Only data elements that are 1 per
- * event goes here. */
-typedef struct {
- snode *head; // List head
- snode *cur; // Pointer to current node
- unsigned int cnt; // How many items in this list
-} slist;
-
-void slist_create(slist *l);
-static inline void slist_first(slist *l) { l->cur = l->head; }
-void slist_last(slist *l);
-snode *slist_next(slist *l);
-static inline snode *slist_get_cur(slist *l) { return l->cur; }
-void slist_append(slist *l, snode *node);
-void slist_clear(slist* l);
-
-/* append a string if its not already on the list */
-int slist_add_if_uniq(slist *l, const char *str);
-void slist_sort_by_hits(slist *l);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch-time.c b/framework/src/audit/src/ausearch-time.c
deleted file mode 100644
index 3cd33c87..00000000
--- a/framework/src/audit/src/ausearch-time.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/* ausearch-time.c - time handling utility functions
- * Copyright 2006-08,2011 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include "ausearch-time.h"
-
-
-#define SECONDS_IN_DAY 24*60*60
-static void clear_tm(struct tm *t);
-static void replace_time(struct tm *t1, struct tm *t2);
-static void replace_date(struct tm *t1, struct tm *t2);
-
-
-time_t start_time = 0, end_time = 0;
-
-struct nv_pair {
- int value;
- const char *name;
-};
-
-static struct nv_pair timetab[] = {
- { T_NOW, "now" },
- { T_RECENT, "recent" },
- { T_TODAY, "today" },
- { T_YESTERDAY, "yesterday" },
- { T_THIS_WEEK, "this-week" },
- { T_WEEK_AGO, "week-ago" },
- { T_THIS_MONTH, "this-month" },
- { T_THIS_YEAR, "this-year" },
-};
-#define TIME_NAMES (sizeof(timetab)/sizeof(timetab[0]))
-
-int lookup_time(const char *name)
-{
- int i;
-
- for (i = 0; i < TIME_NAMES; i++) {
- if (strcmp(timetab[i].name, name) == 0) {
- return timetab[i].value;
- }
- }
- return -1;
-
-}
-
-static void clear_tm(struct tm *t)
-{
- t->tm_sec = 0; /* seconds */
- t->tm_min = 0; /* minutes */
- t->tm_hour = 0; /* hours */
- t->tm_mday = 0; /* day of the month */
- t->tm_mon = 0; /* month */
- t->tm_year = 0; /* year */
- t->tm_isdst = 0; /* DST flag */
-}
-
-static void set_tm_now(struct tm *d)
-{
- time_t t = time(NULL);
- struct tm *tv = localtime(&t);
- replace_time(d, tv);
- replace_date(d, tv);
-}
-
-static void set_tm_today(struct tm *d)
-{
- time_t t = time(NULL);
- struct tm *tv = localtime(&t);
- d->tm_sec = 0; /* seconds */
- d->tm_min = 0; /* minutes */
- d->tm_hour = 0; /* hours */
- replace_date(d, tv);
-}
-
-static void set_tm_yesterday(struct tm *d)
-{
- time_t t = time(NULL) - (time_t)(SECONDS_IN_DAY);
- struct tm *tv = localtime(&t);
- d->tm_sec = 0; /* seconds */
- d->tm_min = 0; /* minutes */
- d->tm_hour = 0; /* hours */
- replace_date(d, tv);
-}
-
-static void set_tm_recent(struct tm *d)
-{
- time_t t = time(NULL) - (time_t)(10*60); /* 10 minutes ago */
- struct tm *tv = localtime(&t);
- replace_time(d, tv);
- replace_date(d, tv);
-}
-
-static void set_tm_this_week(struct tm *d)
-{
- time_t t = time(NULL);
- struct tm *tv = localtime(&t);
- d->tm_sec = 0; /* seconds */
- d->tm_min = 0; /* minutes */
- d->tm_hour = 0; /* hours */
- t -= (time_t)(tv->tm_wday*SECONDS_IN_DAY);
- tv = localtime(&t);
- replace_date(d, tv);
-}
-
-static void set_tm_week_ago(struct tm *d)
-{
- time_t t = time(NULL);
- struct tm *tv;
- d->tm_sec = 0; /* seconds */
- d->tm_min = 0; /* minutes */
- d->tm_hour = 0; /* hours */
- t -= (time_t)(7*SECONDS_IN_DAY);
- tv = localtime(&t);
- replace_date(d, tv);
-}
-
-static void set_tm_this_month(struct tm *d)
-{
- time_t t = time(NULL);
- struct tm *tv = localtime(&t);
- d->tm_sec = 0; /* seconds */
- d->tm_min = 0; /* minutes */
- d->tm_hour = 0; /* hours */
- replace_date(d, tv);
- d->tm_mday = 1; /* override day of month */
-}
-
-static void set_tm_this_year(struct tm *d)
-{
- time_t t = time(NULL);
- struct tm *tv = localtime(&t);
- d->tm_sec = 0; /* seconds */
- d->tm_min = 0; /* minutes */
- d->tm_hour = 0; /* hours */
- replace_date(d, tv);
- d->tm_mday = 1; /* override day of month */
- d->tm_mon = 0; /* override month */
-}
-
-/* Combine date & time into 1 struct. Results in date. */
-static void add_tm(struct tm *d, struct tm *t)
-{
- time_t dst;
- struct tm *lt;
-
- replace_time(d, t);
-
- /* Now we need to figure out if DST is in effect */
- dst = time(NULL);
- lt = localtime(&dst);
- d->tm_isdst = lt->tm_isdst;
-}
-
-/* The time in t1 is replaced by t2 */
-static void replace_time(struct tm *t1, struct tm *t2)
-{
- t1->tm_sec = t2->tm_sec; /* seconds */
- t1->tm_min = t2->tm_min; /* minutes */
- t1->tm_hour = t2->tm_hour; /* hours */
-}
-
-/* The date in t1 is replaced by t2 */
-static void replace_date(struct tm *t1, struct tm *t2)
-{
- t1->tm_mday = t2->tm_mday; /* day */
- t1->tm_mon = t2->tm_mon; /* month */
- t1->tm_year = t2->tm_year; /* year */
- t1->tm_isdst = t2->tm_isdst; /* daylight savings time */
-}
-
-/* Given 2 char strings, create a time struct *
-void set_time(struct tm *t, int num, const char *t1, const char *t2)
-{
- switch (num)
- {
- case 1:
- // if keyword, init time
- // elif time use today and replace time
- // elif date, set to 00:00:01 and replace date
- // else error
- break;
- case 2:
- // if keyword
- // init time with it
- // get other time str and replace
- // otherwise, figure out which is time
- // and set time adding them
- break;
- default:
- break;
- }
-} */
-
-static int lookup_and_set_time(const char *da, struct tm *d)
-{
- int retval = lookup_time(da);
- if (retval >= 0) {
- switch (retval)
- {
- case T_NOW:
- set_tm_now(d);
- break;
- case T_RECENT:
- set_tm_recent(d);
- break;
- case T_TODAY:
- set_tm_today(d);
- break;
- case T_YESTERDAY:
- set_tm_yesterday(d);
- break;
- case T_THIS_WEEK:
- set_tm_this_week(d);
- break;
- case T_WEEK_AGO:
- set_tm_week_ago(d);
- break;
- case T_THIS_MONTH:
- set_tm_this_month(d);
- break;
- case T_THIS_YEAR:
- set_tm_this_year(d);
- break;
- }
- return 0;
- } else
- return -1;
-}
-
-/* static void print_time(struct tm *d)
-{
- char outstr[200];
- strftime(outstr, sizeof(outstr), "%c", d);
- printf("%s\n", outstr);
-} */
-
-int ausearch_time_start(const char *da, const char *ti)
-{
-/* If da == NULL, use current date */
-/* If ti == NULL, then use midnight 00:00:00 */
- int rc = 0;
- struct tm d, t;
- char *ret;
-
- if (da == NULL)
- set_tm_now(&d);
- else {
- if (lookup_and_set_time(da, &d) < 0) {
- ret = strptime(da, "%x", &d);
- if (ret == NULL) {
- fprintf(stderr,
- "Invalid start date (%s). Month, Day, and Year are required.\n",
- da);
- return 1;
- }
- if (*ret != 0) {
- fprintf(stderr,
- "Error parsing start date (%s)\n", da);
- return 1;
- }
- } else {
- int keyword=lookup_time(da);
- if (keyword == T_RECENT || keyword == T_NOW) {
- if (ti == NULL || strcmp(ti, "00:00:00") == 0)
- goto set_it;
- }
- }
- }
-
- if (ti != NULL) {
- char tmp_t[36];
-
- if (strlen(ti) <= 5) {
- snprintf(tmp_t, sizeof(tmp_t), "%s:00", ti);
- } else {
- tmp_t[0]=0;
- strncat(tmp_t, ti, sizeof(tmp_t)-1);
- }
- ret = strptime(tmp_t, "%X", &t);
- if (ret == NULL) {
- fprintf(stderr,
- "Invalid start time (%s). Hour, Minute, and Second are required.\n",
- ti);
- return 1;
- }
- if (*ret != 0) {
- fprintf(stderr, "Error parsing start time (%s)\n", ti);
- return 1;
- }
- } else
- clear_tm(&t);
-
- add_tm(&d, &t);
- if (d.tm_year < 104) {
- fprintf(stderr, "Error - year is %d\n", d.tm_year+1900);
- return -1;
- }
-set_it:
- // printf("start is: %s\n", ctime(&start_time));
- start_time = mktime(&d);
- if (start_time == -1) {
- fprintf(stderr, "Error converting start time\n");
- rc = -1;
- }
- return rc;
-}
-
-int ausearch_time_end(const char *da, const char *ti)
-{
-/* If date == NULL, use current date */
-/* If ti == NULL, use current time */
- int rc = 0;
- struct tm d, t;
- char *ret;
-
- if (da == NULL)
- set_tm_now(&d);
- else {
- if (lookup_and_set_time(da, &d) < 0) {
- ret = strptime(da, "%x", &d);
- if (ret == NULL) {
- fprintf(stderr,
- "Invalid end date (%s). Month, Day, and Year are required.\n",
- da);
- return 1;
- }
- if (*ret != 0) {
- fprintf(stderr,
- "Error parsing end date (%s)\n", da);
- return 1;
- }
- } else {
- int keyword=lookup_time(da);
- if (keyword == T_RECENT || keyword == T_NOW) {
- if (ti == NULL || strcmp(ti, "00:00:00") == 0)
- goto set_it;
- }
- // Special case today
- if (keyword == T_TODAY) {
- set_tm_now(&d);
- if (ti == NULL || strcmp(ti, "00:00:00") == 0)
- goto set_it;
- }
- }
- }
-
- if (ti != NULL) {
- char tmp_t[36];
-
- if (strlen(ti) <= 5) {
- snprintf(tmp_t, sizeof(tmp_t), "%s:00", ti);
- } else {
- tmp_t[0]=0;
- strncat(tmp_t, ti, sizeof(tmp_t)-1);
- }
- ret = strptime(tmp_t, "%X", &t);
- if (ret == NULL) {
- fprintf(stderr,
- "Invalid end time (%s). Hour, Minute, and Second are required.\n",
- ti);
- return 1;
- }
- if (*ret != 0) {
- fprintf(stderr, "Error parsing end time (%s)\n", ti);
- return 1;
- }
- } else {
- time_t tt = time(NULL);
- struct tm *tv = localtime(&tt);
- clear_tm(&t);
- t.tm_hour = tv->tm_hour;
- t.tm_min = tv->tm_min;
- t.tm_sec = tv->tm_sec;
- t.tm_isdst = tv->tm_isdst;
-
- }
- add_tm(&d, &t);
- if (d.tm_year < 104) {
- fprintf(stderr, "Error - year is %d\n", d.tm_year+1900);
- return -1;
- }
-set_it:
- // printf("end is: %s\n", ctime(&end_time));
- end_time = mktime(&d);
- if (end_time == -1) {
- fprintf(stderr, "Error converting end time\n");
- rc = -1;
- }
- return rc;
-}
-
diff --git a/framework/src/audit/src/ausearch-time.h b/framework/src/audit/src/ausearch-time.h
deleted file mode 100644
index 15051a5a..00000000
--- a/framework/src/audit/src/ausearch-time.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* ausearch-time.h - header file for ausearch-time.c
- * Copyright 2006-07 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#ifndef AUSEARCH_TIME_HEADERS
-#define AUSEARCH_TIME_HEADERS
-
-#include <time.h>
-
-enum { T_NOW, T_RECENT, T_TODAY, T_YESTERDAY, T_THIS_WEEK, T_WEEK_AGO,
- T_THIS_MONTH, T_THIS_YEAR };
-
-extern time_t start_time, end_time;
-
-int lookup_time(const char *name);
-int ausearch_time_start(const char *da, const char *ti);
-int ausearch_time_end(const char *da, const char *ti);
-
-#endif
-
diff --git a/framework/src/audit/src/ausearch.c b/framework/src/audit/src/ausearch.c
deleted file mode 100644
index 06213f8b..00000000
--- a/framework/src/audit/src/ausearch.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * ausearch.c - main file for ausearch utility
- * Copyright 2005-08,2010,2013,2014 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <locale.h>
-#include <signal.h>
-#include "libaudit.h"
-#include "auditd-config.h"
-#include "ausearch-options.h"
-#include "ausearch-lol.h"
-#include "ausearch-lookup.h"
-#include "auparse.h"
-#include "ausearch-checkpt.h"
-
-
-static FILE *log_fd = NULL;
-static lol lo;
-static int found = 0;
-static int input_is_pipe = 0;
-static int timeout_interval = 3; /* timeout in seconds */
-static int files_to_process = 0; /* number of log files yet to process when reading multiple */
-static int process_logs(void);
-static int process_log_fd(void);
-static int process_stdin(void);
-static int process_file(char *filename);
-static int get_record(llist **);
-
-extern const char *checkpt_filename; /* checkpoint file name */
-extern int checkpt_timeonly; /* use timestamp from within checkpoint file */
-static int have_chkpt_data = 0; /* have checkpt need to compare wit */
-extern char *user_file;
-extern int force_logs;
-extern int match(llist *l);
-extern void output_record(llist *l);
-
-static int userfile_is_dir = 0;
-
-static int is_pipe(int fd)
-{
- struct stat st;
- int pipe_mode=0;
-
- if (fstat(fd, &st) == 0) {
- if (S_ISFIFO(st.st_mode))
- pipe_mode = 1;
- }
- return pipe_mode;
-}
-
-int main(int argc, char *argv[])
-{
- struct rlimit limit;
- int rc;
- struct stat sb;
-
- /* Check params and build regexpr */
- setlocale (LC_ALL, "");
- if (check_params(argc, argv))
- return 1;
-
- /* Raise the rlimits in case we're being started from a shell
- * with restrictions. Not a fatal error. */
- limit.rlim_cur = RLIM_INFINITY;
- limit.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_FSIZE, &limit);
- setrlimit(RLIMIT_CPU, &limit);
- set_aumessage_mode(MSG_STDERR, DBG_NO);
- (void) umask( umask( 077 ) | 027 );
-
- /* Load the checkpoint file if requested */
- if (checkpt_filename) {
- rc = load_ChkPt(checkpt_filename);
- /*
- * If < -1, then some load/parse error
- * If == -1 then no file present (OK)
- * If == 0, then checkpoint has data
- */
- if (rc < -1) {
- (void)free((void *)checkpt_filename);
- free_ChkPtMemory();
- return 10; /* bad checkpoint status file */
- } else if (rc == -1) {
- /*
- * No file, so no checking required. This just means
- * we have never checkpointed before and this is the
- * first time.
- */
- have_chkpt_data = 0;
- } else {
- /* We will need to check */
- have_chkpt_data++;
- }
- }
-
- lol_create(&lo);
- if (user_file) {
- if (stat(user_file, &sb) == -1) {
- perror("stat");
- return 1;
- }
- switch (sb.st_mode & S_IFMT) {
- case S_IFDIR:
- userfile_is_dir = 1;
- rc = process_logs();
- break;
- case S_IFREG:
- default:
- rc = process_file(user_file);
- break;
- }
- } else if (force_logs)
- rc = process_logs();
- else if (is_pipe(0))
- rc = process_stdin();
- else
- rc = process_logs();
-
- /* Generate a checkpoint if required */
- if (checkpt_filename) {
- /* Providing we found something and haven't failed */
- if (!checkpt_failure && found)
- save_ChkPt(checkpt_filename);
- free_ChkPtMemory();
- free((void *)checkpt_filename);
- /*
- * A checkpoint failure at this point means either
- * - we failed in attempting to create the checkpouint file
- * and so we will return 11
- * - we had a corrupted checkpoint file and so we will return 12
- */
- if (checkpt_failure) {
- rc = ((checkpt_failure & CP_CORRUPTED) ==
- CP_CORRUPTED) ? 12 : 11;
- }
- }
-
- lol_clear(&lo);
- ilist_clear(event_type);
- free(event_type);
- free(user_file);
- free((char *)event_key);
- auparse_destroy(NULL);
- if (rc)
- return rc;
- if (!found) {
- if (report_format != RPT_RAW)
- fprintf(stderr, "<no matches>\n");
- return 1;
- }
- return 0;
-}
-
-static int process_logs(void)
-{
- struct daemon_conf config;
- char *filename;
- int len, num = 0;
- int found_chkpt_file = -1;
- int ret;
-
- if (user_file && userfile_is_dir) {
- char dirname[MAXPATHLEN];
- clear_config (&config);
-
- strcpy(dirname, user_file);
- if (dirname[strlen(dirname)-1] != '/')
- strcat(dirname, "/");
- strcat (dirname, "audit.log");
- free((void *)config.log_file);
- config.log_file=strdup(dirname);
- fprintf(stderr, "NOTE - using logs in %s\n", config.log_file);
- }
- else {
- /* Load config so we know where logs are */
- if (load_config(&config, TEST_SEARCH)) {
- fprintf(stderr,
- "NOTE - using built-in logs: %s\n",
- config.log_file);
- }
- }
-
- /* for each file */
- len = strlen(config.log_file) + 16;
- filename = malloc(len);
- if (!filename) {
- fprintf(stderr, "No memory\n");
- free_config(&config);
- return 1;
- }
- /* Find oldest log file */
- snprintf(filename, len, "%s", config.log_file);
- do {
- if (access(filename, R_OK) != 0)
- break;
-
- /*
- * If we have prior checkpoint data, we ignore files till we
- * find the file we last checkpointed from
- */
- if (checkpt_filename && have_chkpt_data) {
- struct stat sbuf;
-
- if (stat(filename, &sbuf)) {
- fprintf(stderr, "Error stat'ing %s (%s)\n",
- filename, strerror(errno));
- free(filename);
- free_config(&config);
- return 1;
- }
- /*
- * Have we accessed the checkpointed file?
- * If so, stop checking further files.
- */
- if ( (sbuf.st_dev == chkpt_input_dev) &&
- (sbuf.st_ino == chkpt_input_ino) ) {
- /*
- * If we are ignoing all but time, then we
- * don't stop checking more files and just
- * let this loop go to completion and hence
- * we will find the 'oldest' file.
- */
- if (!checkpt_timeonly) {
- found_chkpt_file = num++;
- break;
- }
- }
- }
-
- num++;
- snprintf(filename, len, "%s.%d", config.log_file, num);
- } while (1);
-
- /* If a checkpoint is loaded but can't find it's file, and we
- * are not only just checking the timestamp from the checkpoint file,
- * we need to error */
- if (checkpt_filename && have_chkpt_data && found_chkpt_file == -1
- && !checkpt_timeonly) {
- free(filename);
- free_config(&config);
- return 10;
- }
-
- num--;
-
- /* We note how many files we need to process */
- files_to_process = num;
-
- /* Got it, now process logs from last to first */
- if (num > 0)
- snprintf(filename, len, "%s.%d", config.log_file, num);
- else
- snprintf(filename, len, "%s", config.log_file);
- do {
- if ((ret = process_file(filename))) {
- free(filename);
- free_config(&config);
- return ret;
- }
- if (just_one && found)
- break;
- files_to_process--; /* one less file to process */
-
- /* Get next log file */
- num--;
- if (num > 0)
- snprintf(filename, len, "%s.%d", config.log_file, num);
- else if (num == 0)
- snprintf(filename, len, "%s", config.log_file);
- else
- break;
- } while (1);
- /*
- * If performing a checkpoint, set the checkpointed
- * file details - ie remember the last file processed
- */
- ret = 0;
- if (checkpt_filename)
- ret = set_ChkPtFileDetails(filename);
-
- free(filename);
- free_config(&config);
- return ret;
-}
-
-/*
- * Decide if we should start outputing events given we loaded a checkpoint.
- *
- * The previous checkpoint will have recorded the last event outputted,
- * if there was one. If nothing is to be output, either the audit.log file
- * is empty, all the events in it were incomplete, or ???
- *
- * We can return
- * 0 no output
- * 1 can output
- * 2 can output but not this event
- * 3 we have found an event whose time is > MAX_EVENT_DELTA_SECS secs
- * past our checkpoint time, which means this particulare event is
- * complete. This should not happen, for we should have found our
- * checkpoint event before ANY other completed event.
- *
- */
-static int chkpt_output_decision(event * e)
-{
- static int can_output = 0;
-
- /* Short cut. Once we made the decision, it's made for good */
- if (can_output)
- return 1;
-
- /* If there was no checkpoint file, we turn on output */
- if (have_chkpt_data == 0) {
- can_output = 1;
- return 1; /* can output on this event */
- }
-
- /*
- * If the previous checkpoint had no recorded output, then
- * we assume everything was partial so we turn on output
- */
- if (chkpt_input_levent.sec == 0) {
- can_output = 1;
- return 1; /* can output on this event */
- }
-
- /*
- * If we are ignoring all but event time from within the checkpoint
- * file, then we output if the current event's time is greater than
- * or equal to the checkpoint time.
- */
- if (checkpt_timeonly) {
- if ( (chkpt_input_levent.sec < e->sec) ||
- ( (chkpt_input_levent.sec == e->sec) &&
- (chkpt_input_levent.milli <= e->milli) ) ) {
- can_output = 1;
- return 1; /* can output on this event */
- }
- }
-
- if (chkpt_input_levent.sec == e->sec &&
- chkpt_input_levent.milli == e->milli &&
- chkpt_input_levent.serial == e->serial &&
- chkpt_input_levent.type == e->type ) {
-
- /* So far a match, so now check the nodes */
- if (chkpt_input_levent.node == NULL && e->node == NULL) {
- can_output = 1;
- return 2; /* output after this event */
- }
- if (chkpt_input_levent.node && e->node &&
- (strcmp(chkpt_input_levent.node, e->node) == 0) ) {
- can_output = 1;
- return 2; /* output after this event */
- }
- /*
- * The nodes are different. Drop through to further checks.
- */
- }
- /*
- * If the event we are looking at is more than MAX_EVENT_DELTA_SECS
- * seconds past our checkpoint event, then by definition we should
- * have had a complete event (ie a complete event is one where at
- * least MAX_EVENT_DELTA_SECS seconds have passed since it's last
- * output record).
- * This means there is a problem, for the recorded checkpoint event was
- * the last complete event in the file when we last processed it.
- * Normally we see this if the checkpoint is very old and the system
- * has used the same inode again in an audit log file.
- */
- if ( (chkpt_input_levent.sec < e->sec) &&
- ((e->sec - chkpt_input_levent.sec) > MAX_EVENT_DELTA_SECS) ) {
-/* fprintf(stderr, "%s %lu.%03u:%lu vs %s %lu.%03u:%lu\n",
- chkpt_input_levent.host ? chkpt_input_levent.host : "-",
- chkpt_input_levent.sec, chkpt_input_levent.milli,
- chkpt_input_levent.serial,
- e->host, e->sec, e->milli, e->serial); */
- return 3;
- }
-
- return 0;
-}
-
-static int process_log_fd(void)
-{
- llist *entries; // entries in a record
- int ret;
- int do_output = 1;
-
- /* For each record in file */
- do {
- ret = get_record(&entries);
- if ((ret != 0)||(entries->cnt == 0)) {
- break;
- }
- /*
- * We flush all events on the last log file being processed.
- * Thus incomplete events are 'carried forward' to be
- * completed from the rest of it's records we expect to find
- * in the next file we are about to process.
- */
- if (match(entries)) {
- /*
- * If we are checkpointing, decide if we output
- * this event
- */
- if (checkpt_filename)
- do_output = chkpt_output_decision(&entries->e);
-
- if (do_output == 1) {
- found = 1;
- output_record(entries);
-
- /* Remember this event if checkpointing */
- if (checkpt_filename) {
- if (set_ChkPtLastEvent(&entries->e)) {
- list_clear(entries);
- free(entries);
- fclose(log_fd);
- return 4; /* no memory */
- }
- }
- } else if (do_output == 3) {
- fprintf(stderr,
- "Corrupted checkpoint file. Inode match, but newer complete event (%lu.%03u:%lu) found before loaded checkpoint %lu.%03u:%lu\n",
- entries->e.sec, entries->e.milli,
- entries->e.serial,
- chkpt_input_levent.sec,
- chkpt_input_levent.milli,
- chkpt_input_levent.serial);
- checkpt_failure |= CP_CORRUPTED;
- list_clear(entries);
- free(entries);
- fclose(log_fd);
- return 10;
- }
- if (just_one) {
- list_clear(entries);
- free(entries);
- break;
- }
- if (line_buffered)
- fflush(stdout);
- }
- list_clear(entries);
- free(entries);
- } while (ret == 0);
- fclose(log_fd);
-
- return 0;
-}
-
-static void alarm_handler(int signal)
-{
- /* will interrupt current syscall */
-}
-
-static int process_stdin(void)
-{
- log_fd = stdin;
- input_is_pipe=1;
-
- if (signal(SIGALRM, alarm_handler) == SIG_ERR ||
- siginterrupt(SIGALRM, 1) == -1)
- return -1;
-
- return process_log_fd();
-}
-
-static int process_file(char *filename)
-{
- log_fd = fopen(filename, "rm");
- if (log_fd == NULL) {
- fprintf(stderr, "Error opening %s (%s)\n", filename,
- strerror(errno));
- return 1;
- }
-
- __fsetlocking(log_fd, FSETLOCKING_BYCALLER);
- return process_log_fd();
-}
-
-/*
- * This function returns a malloc'd buffer of the next record in the audit
- * logs. It returns 0 on success, 1 on eof, -1 on error.
- */
-static int get_record(llist **l)
-{
- char *rc;
- char *buff = NULL;
- int rcount = 0, timer_running = 0;
-
- /*
- * If we have any events ready to print ie have all records that
- * make up the event, we just return. If not, we read more lines
- * from the files until we get a complete event or finish reading
- * input
- */
- *l = get_ready_event(&lo);
- if (*l)
- return 0;
-
- while (1) {
- rcount++;
-
- if (!buff) {
- buff = malloc(MAX_AUDIT_MESSAGE_LENGTH);
- if (!buff)
- return -1;
- }
-
- if (input_is_pipe && rcount > 1) {
- timer_running = 1;
- alarm(timeout_interval);
- }
-
- rc = fgets_unlocked(buff, MAX_AUDIT_MESSAGE_LENGTH,
- log_fd);
-
- if (timer_running) {
- /* timer may have fired but thats ok */
- timer_running = 0;
- alarm(0);
- }
-
- if (rc) {
- if (lol_add_record(&lo, buff)) {
- *l = get_ready_event(&lo);
- if (*l)
- break;
- }
- } else {
- free(buff);
- /*
- * If we get an EINTR error or we are at EOF, we check
- * to see if we have any events to print and return
- * appropriately. If we are the last file being
- * processed, we mark all incomplete events as
- * complete so they will be printed.
- */
- if ((ferror_unlocked(log_fd) &&
- errno == EINTR) || feof_unlocked(log_fd)) {
- /*
- * Only mark all events as L_COMPLETE if we are
- * the last file being processed.
- * We DO NOT do this if we are checkpointing.
- */
- if (files_to_process == 0) {
- if (!checkpt_filename)
- terminate_all_events(&lo);
- }
- *l = get_ready_event(&lo);
- if (*l)
- return 0;
- else
- return 1;
- } else
- return -1; /* all other errors are terminal */
- }
- }
- free(buff);
- return 0;
-}
-
diff --git a/framework/src/audit/src/autrace.c b/framework/src/audit/src/autrace.c
deleted file mode 100644
index 03c0b556..00000000
--- a/framework/src/audit/src/autrace.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* autrace.c --
- * Copyright 2005-09,2011,2015 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <linux/net.h>
-#include "libaudit.h"
-#include "private.h"
-
-/*
- * This program will add the audit rules to trace a process similar
- * to strace. It will then execute the process.
- */
-static int threat = 0;
-static int count_rules(void);
-static int count_em(int fd);
-extern int delete_all_rules(int fd);
-
-static void usage(void)
-{
- fprintf(stderr, "usage: autrace [-r] program\n");
-}
-
-static int insert_rule(int audit_fd, const char *field)
-{
- int rc;
- int flags = AUDIT_FILTER_EXIT;
- int action = AUDIT_ALWAYS;
- struct audit_rule_data *rule = malloc(sizeof(struct audit_rule_data));
- int machine = audit_detect_machine();
- char *t_field = NULL;
-
- if (rule == NULL)
- goto err;
- memset(rule, 0, sizeof(struct audit_rule_data));
- if (threat) {
- rc = 0;
- if (machine != MACH_AARCH64) {
- rc |= audit_rule_syscallbyname_data(rule, "open");
- rc |= audit_rule_syscallbyname_data(rule, "creat");
- rc |= audit_rule_syscallbyname_data(rule, "rename");
- rc |= audit_rule_syscallbyname_data(rule, "unlink");
- rc |= audit_rule_syscallbyname_data(rule, "mknod");
- rc |= audit_rule_syscallbyname_data(rule, "mkdir");
- rc |= audit_rule_syscallbyname_data(rule, "rmdir");
- rc |= audit_rule_syscallbyname_data(rule, "chown");
- rc |= audit_rule_syscallbyname_data(rule, "lchown");
- rc |= audit_rule_syscallbyname_data(rule, "chmod");
- rc |= audit_rule_syscallbyname_data(rule, "link");
- rc |= audit_rule_syscallbyname_data(rule, "symlink");
- rc |= audit_rule_syscallbyname_data(rule, "readlink");
- }
- rc |= audit_rule_syscallbyname_data(rule, "openat");
- rc |= audit_rule_syscallbyname_data(rule, "truncate");
- rc |= audit_rule_syscallbyname_data(rule, "renameat");
- rc |= audit_rule_syscallbyname_data(rule, "unlinkat");
- rc |= audit_rule_syscallbyname_data(rule, "mknodat");
- rc |= audit_rule_syscallbyname_data(rule, "mkdirat");
- rc |= audit_rule_syscallbyname_data(rule, "chdir");
- rc |= audit_rule_syscallbyname_data(rule, "fchownat");
- rc |= audit_rule_syscallbyname_data(rule, "fchmodat");
- rc |= audit_rule_syscallbyname_data(rule, "linkat");
- rc |= audit_rule_syscallbyname_data(rule, "symlinkat");
- rc |= audit_rule_syscallbyname_data(rule, "readlinkat");
- rc |= audit_rule_syscallbyname_data(rule, "execve");
- rc |= audit_rule_syscallbyname_data(rule, "name_to_handle_at");
-
- if (machine != MACH_X86 && machine != MACH_S390X &&
- machine != MACH_S390) {
- rc |= audit_rule_syscallbyname_data(rule, "connect");
- rc |= audit_rule_syscallbyname_data(rule, "bind");
- rc |= audit_rule_syscallbyname_data(rule, "accept");
- rc |= audit_rule_syscallbyname_data(rule, "sendto");
- rc |= audit_rule_syscallbyname_data(rule, "recvfrom");
- rc |= audit_rule_syscallbyname_data(rule, "accept4");
- }
-
- rc |= audit_rule_syscallbyname_data(rule, "sendfile");
- } else
- rc = audit_rule_syscallbyname_data(rule, "all");
- if (rc < 0)
- goto err;
- t_field = strdup(field);
- rc = audit_rule_fieldpair_data(&rule, t_field, flags);
- free(t_field);
- if (rc < 0)
- goto err;
- rc = audit_add_rule_data(audit_fd, rule, flags, action);
- if (rc < 0)
- goto err;
-
- // Now if i386, lets add its network rules
- if (machine == MACH_X86 || machine == MACH_S390X ||
- machine == MACH_S390) {
- int i, a0[6] = { SYS_CONNECT, SYS_BIND, SYS_ACCEPT, SYS_SENDTO,
- SYS_RECVFROM, SYS_ACCEPT4 };
- for (i=0; i<6; i++) {
- char pair[32];
-
- memset(rule, 0, sizeof(struct audit_rule_data));
- rc |= audit_rule_syscallbyname_data(rule, "socketcall");
- snprintf(pair, sizeof(pair), "a0=%d", a0[i]);
- rc |= audit_rule_fieldpair_data(&rule, pair, flags);
- t_field = strdup(field);
- rc |= audit_rule_fieldpair_data(&rule, t_field, flags);
- free(t_field);
- rc |= audit_add_rule_data(audit_fd, rule, flags, action);
- }
- }
- free(rule);
- return 0;
-err:
- fprintf(stderr, "Error inserting audit rule for %s\n", field);
- free(rule);
- return 1;
-}
-
-int key_match(struct audit_reply *rep)
-{
- return 1;
-}
-
-/*
- * Algorithm:
- * check that user is root
- * check to see if program exists
- * if so fork, child waits for parent
- * parent clears audit rules, loads audit all syscalls with child's pid
- * parent tells child to go & waits for sigchld
- * child exec's program
- * parent deletes rules after getting sigchld
- */
-int main(int argc, char *argv[])
-{
- int fd[2];
- int pid,cmd=1;
- char buf[2];
-
- if (argc < 2) {
- usage();
- return 1;
- }
- if (strcmp(argv[cmd], "-h") == 0) {
- usage();
- return 1;
- }
- if (strcmp(argv[cmd], "-r") == 0) {
- threat = 1;
- cmd++;
- }
- if (getuid() != 0) {
- fprintf(stderr, "You must be root to run this program.\n");
- return 1;
- }
- if (access(argv[cmd], X_OK)) {
- if (errno == ENOENT)
- fprintf(stderr, "Error - can't find: %s\n", argv[cmd]);
- else
- fprintf(stderr, "Error checking %s (%s)\n",
- argv[cmd], strerror(errno));
- return 1;
- }
- set_aumessage_mode(MSG_STDERR, DBG_NO);
- switch (count_rules())
- {
- case -1:
- if (errno == ECONNREFUSED)
- fprintf(stderr,
- "The audit system is disabled\n");
- else
- fprintf(stderr,
- "Error - can't get rule count.\n");
- return 1;
- case 0:
- break;
- default:
- fprintf(stderr,
- "autrace cannot be run with rules loaded.\n"
- "Please delete all rules using 'auditctl -D' if you "
- "really wanted to\nrun this command.\n");
- return 1;
- }
- if (pipe(fd) != 0) {
- fprintf(stderr, "Error creating pipe.\n");
- return 1;
- }
-
- switch ((pid=fork()))
- {
- case -1:
- fprintf(stderr, "Error forking.\n");
- return 1;
- case 0: /* Child */
- close(fd[1]);
- printf("Waiting to execute: %s\n", argv[cmd]);
- while (read(fd[0], buf, 1) == -1 && errno == EINTR)
- /* blank */ ;
- close(fd[0]);
- execvp(argv[cmd], &argv[cmd]);
- fprintf(stderr, "Failed to exec %s\n", argv[cmd]);
- return 1;
- default: /* Parent */
- close(fd[0]);
- fcntl(fd[1], F_SETFD, FD_CLOEXEC);
- {
- char field[16];
- int audit_fd;
- audit_fd = audit_open();
- if (audit_fd < 0)
- exit(1);
- snprintf(field, sizeof(field), "pid=%d", pid);
- if (insert_rule(audit_fd, field)) {
- kill(pid,SIGTERM);
- (void)delete_all_rules(audit_fd);
- exit(1);
- }
- snprintf(field, sizeof(field), "ppid=%d", pid);
- if (insert_rule(audit_fd, field)) {
- kill(pid,SIGTERM);
- (void)delete_all_rules(audit_fd);
- exit(1);
- }
- sleep(1);
- if (write(fd[1],"1", 1) != 1) {
- kill(pid,SIGTERM);
- (void)delete_all_rules(audit_fd);
- exit(1);
- }
- waitpid(pid, NULL, 0);
- close(fd[1]);
- puts("Cleaning up...");
- (void)delete_all_rules(audit_fd);
- close(audit_fd);
- }
- printf("Trace complete. "
- "You can locate the records with "
- "\'ausearch -i -p %d\'\n",
- pid);
- break;
- }
-
- return 0;
-}
-
-static int count_rules(void)
-{
- int fd, total, rc;
-
- fd = audit_open();
- if (fd < 0)
- return -1;
-
- rc = audit_request_rules_list_data(fd);
- if (rc > 0)
- total = count_em(fd);
- else
- total = -1;
-
- close(fd);
- return total;
-}
-
-static int count_em(int fd)
-{
- int i, retval, count = 0;
- int timeout = 40; /* loop has delay of .1 - this is 4 seconds */
- struct audit_reply rep;
- fd_set read_mask;
-
- FD_ZERO(&read_mask);
- FD_SET(fd, &read_mask);
-
- for (i = 0; i < timeout; i++) {
- retval = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
- if (retval > 0) {
- struct timeval t;
-
- if (rep.type == NLMSG_ERROR &&
- rep.error->error == 0)
- continue;
- t.tv_sec = 0;
- t.tv_usec = 100000; /* .1 second */
- do {
- retval=select(fd+1, &read_mask, NULL, NULL, &t);
- } while (retval < 0 && errno == EINTR);
- switch (rep.type)
- {
- case NLMSG_DONE:
- return count;
- case AUDIT_LIST_RULES:
- i = 0;
- count++;
- break;
- case NLMSG_ERROR:
- return -1;
- default:
- break;
- }
- }
- }
- return count;
-}
-
diff --git a/framework/src/audit/src/delete_all.c b/framework/src/audit/src/delete_all.c
deleted file mode 100644
index 4e0feed1..00000000
--- a/framework/src/audit/src/delete_all.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* delete_all.c --
- * Copyright 2005-06, 2008-09,2014 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "libaudit.h"
-#include "private.h"
-
-#include "auditctl-llist.h"
-
-extern int key_match(const struct audit_rule_data *r);
-
-/* Returns 0 for success and -1 for failure */
-int delete_all_rules(int fd)
-{
- int seq, i, rc;
- int timeout = 40; /* tenths of seconds */
- struct audit_reply rep;
- fd_set read_mask;
- llist l;
- lnode *n;
-
- /* list the rules */
- seq = audit_request_rules_list_data(fd);
- if (seq <= 0)
- return -1;
-
- FD_ZERO(&read_mask);
- FD_SET(fd, &read_mask);
- list_create(&l);
-
- for (i = 0; i < timeout; i++) {
- struct timeval t;
-
- t.tv_sec = 0;
- t.tv_usec = 100000; /* .1 second */
- do {
- rc = select(fd+1, &read_mask, NULL, NULL, &t);
- } while (rc < 0 && errno == EINTR);
- // We'll try to read just in case
- rc = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
- if (rc > 0) {
- /* Reset timeout */
- i = 0;
-
- /* Don't make decisions based on wrong packet */
- if (rep.nlh->nlmsg_seq != seq)
- continue;
-
- /* If we get done or error, break out */
- if (rep.type == NLMSG_DONE)
- break;
-
- if (rep.type == NLMSG_ERROR && rep.error->error) {
- audit_msg(LOG_ERR,
- "Error receiving rules list (%s)",
- strerror(-rep.error->error));
- return -1;
- }
-
- /* If its not what we are expecting, keep looping */
- if (rep.type != AUDIT_LIST_RULES)
- continue;
-
- if (key_match(rep.ruledata))
- list_append(&l, rep.ruledata,
- sizeof(struct audit_rule_data) +
- rep.ruledata->buflen);
-
- }
- }
- list_first(&l);
- n = l.cur;
- while (n) {
- /* Bounce it right back with delete */
- rc = audit_send(fd, AUDIT_DEL_RULE, n->r, n->size);
- if (rc < 0) {
- audit_msg(LOG_ERR, "Error deleting rule (%s)",
- strerror(-rc));
- return -1;
- }
- n = list_next(&l);
- }
- list_clear(&l);
-
- return 0;
-}
-
diff --git a/framework/src/audit/src/libev/Makefile.am b/framework/src/audit/src/libev/Makefile.am
deleted file mode 100644
index a35e7b0d..00000000
--- a/framework/src/audit/src/libev/Makefile.am
+++ /dev/null
@@ -1,29 +0,0 @@
-# Makefile.am--
-# Copyright 2008,2011-12 Red Hat Inc., Durham, North Carolina.
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Authors:
-# Steve Grubb <sgrubb@redhat.com>
-#
-VERSION_INFO = 4:0:0
-EXTRA_DIST = README ev_epoll.c ev_poll.c ev_select.c libev.m4
-AM_CFLAGS = -fPIC -DPIC -g -fno-strict-aliasing ${DEBUG}
-
-noinst_HEADERS = ev.h ev_vars.h ev_wrap.h event.h
-noinst_LIBRARIES = libev.a
-
-libev_a_SOURCES = ev.c event.c
diff --git a/framework/src/audit/src/libev/README b/framework/src/audit/src/libev/README
deleted file mode 100644
index 31f61938..00000000
--- a/framework/src/audit/src/libev/README
+++ /dev/null
@@ -1,58 +0,0 @@
-libev is a high-performance event loop/event model with lots of features.
-(see benchmark at http://libev.schmorp.de/bench.html)
-
-
-ABOUT
-
- Homepage: http://software.schmorp.de/pkg/libev
- Mailinglist: libev@lists.schmorp.de
- http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
- Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
-
- Libev is modelled (very losely) after libevent and the Event perl
- module, but is faster, scales better and is more correct, and also more
- featureful. And also smaller. Yay.
-
- Some of the specialties of libev not commonly found elsewhere are:
-
- - extensive and detailed, readable documentation (not doxygen garbage).
- - fully supports fork, can detect fork in various ways and automatically
- re-arms kernel mechanisms that do not support fork.
- - highly optimised select, poll, epoll, kqueue and event ports backends.
- - filesystem object (path) watching (with optional linux inotify support).
- - wallclock-based times (using absolute time, cron-like).
- - relative timers/timeouts (handle time jumps).
- - fast intra-thread communication between multiple
- event loops (with optional fast linux eventfd backend).
- - extremely easy to embed (fully documented, no dependencies,
- autoconf supported but optional).
- - very small codebase, no bloated library, simple code.
- - fully extensible by being able to plug into the event loop,
- integrate other event loops, integrate other event loop users.
- - very little memory use (small watchers, small event loop data).
- - optional C++ interface allowing method and function callbacks
- at no extra memory or runtime overhead.
- - optional Perl interface with similar characteristics (capable
- of running Glib/Gtk2 on libev).
- - support for other languages (multiple C++ interfaces, D, Ruby,
- Python) available from third-parties.
-
- Examples of programs that embed libev: the EV perl module, node.js,
- auditd, rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the
- Deliantra MMORPG server (http://www.deliantra.net/), Rubinius (a
- next-generation Ruby VM), the Ebb web server, the Rev event toolkit.
-
-
-CONTRIBUTORS
-
- libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
-
- The following people sent in patches or made other noteworthy
- contributions to the design (for minor patches, see the Changes
- file. If I forgot to include you, please shout at me, it was an
- accident):
-
- W.C.A. Wijngaards
- Christopher Layne
- Chris Brody
-
diff --git a/framework/src/audit/src/libev/ev.c b/framework/src/audit/src/libev/ev.c
deleted file mode 100644
index 3e7013f9..00000000
--- a/framework/src/audit/src/libev/ev.c
+++ /dev/null
@@ -1,4971 +0,0 @@
-/*
- * libev event processing core, watcher management
- *
- * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-/* this big block deduces configuration from config.h */
-#ifndef EV_STANDALONE
-# ifdef EV_CONFIG_H
-# include EV_CONFIG_H
-# else
-# include "config.h"
-# endif
-
-# if HAVE_FLOOR
-# ifndef EV_USE_FLOOR
-# define EV_USE_FLOOR 1
-# endif
-# endif
-
-# if HAVE_CLOCK_SYSCALL
-# ifndef EV_USE_CLOCK_SYSCALL
-# define EV_USE_CLOCK_SYSCALL 1
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 1
-# endif
-# endif
-# elif !defined EV_USE_CLOCK_SYSCALL
-# define EV_USE_CLOCK_SYSCALL 0
-# endif
-
-# if HAVE_CLOCK_GETTIME
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 1
-# endif
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-# else
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 0
-# endif
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-# endif
-
-# if HAVE_NANOSLEEP
-# ifndef EV_USE_NANOSLEEP
-# define EV_USE_NANOSLEEP EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_NANOSLEEP
-# define EV_USE_NANOSLEEP 0
-# endif
-
-# if HAVE_SELECT && HAVE_SYS_SELECT_H
-# ifndef EV_USE_SELECT
-# define EV_USE_SELECT EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_SELECT
-# define EV_USE_SELECT 0
-# endif
-
-# if HAVE_POLL && HAVE_POLL_H
-# ifndef EV_USE_POLL
-# define EV_USE_POLL EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_POLL
-# define EV_USE_POLL 0
-# endif
-
-# if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
-# ifndef EV_USE_EPOLL
-# define EV_USE_EPOLL EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_EPOLL
-# define EV_USE_EPOLL 0
-# endif
-
-# if HAVE_KQUEUE && HAVE_SYS_EVENT_H
-# ifndef EV_USE_KQUEUE
-# define EV_USE_KQUEUE EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_KQUEUE
-# define EV_USE_KQUEUE 0
-# endif
-
-# if HAVE_PORT_H && HAVE_PORT_CREATE
-# ifndef EV_USE_PORT
-# define EV_USE_PORT EV_FEATURE_BACKENDS
-# endif
-# else
-# undef EV_USE_PORT
-# define EV_USE_PORT 0
-# endif
-
-# if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H
-# ifndef EV_USE_INOTIFY
-# define EV_USE_INOTIFY EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_INOTIFY
-# define EV_USE_INOTIFY 0
-# endif
-
-# if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H
-# ifndef EV_USE_SIGNALFD
-# define EV_USE_SIGNALFD EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_SIGNALFD
-# define EV_USE_SIGNALFD 0
-# endif
-
-# if HAVE_EVENTFD
-# ifndef EV_USE_EVENTFD
-# define EV_USE_EVENTFD EV_FEATURE_OS
-# endif
-# else
-# undef EV_USE_EVENTFD
-# define EV_USE_EVENTFD 0
-# endif
-
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stddef.h>
-
-#include <stdio.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <time.h>
-#include <limits.h>
-
-#include <signal.h>
-
-#ifdef EV_H
-# include EV_H
-#else
-# include "ev.h"
-#endif
-
-#if EV_NO_THREADS
-# undef EV_NO_SMP
-# define EV_NO_SMP 1
-# undef ECB_NO_THREADS
-# define ECB_NO_THREADS 1
-#endif
-#if EV_NO_SMP
-# undef EV_NO_SMP
-# define ECB_NO_SMP 1
-#endif
-
-#ifndef _WIN32
-# include <sys/time.h>
-# include <sys/wait.h>
-# include <unistd.h>
-#else
-# include <io.h>
-# define WIN32_LEAN_AND_MEAN
-# include <winsock2.h>
-# include <windows.h>
-# ifndef EV_SELECT_IS_WINSOCKET
-# define EV_SELECT_IS_WINSOCKET 1
-# endif
-# undef EV_AVOID_STDIO
-#endif
-
-/* OS X, in its infinite idiocy, actually HARDCODES
- * a limit of 1024 into their select. Where people have brains,
- * OS X engineers apparently have a vacuum. Or maybe they were
- * ordered to have a vacuum, or they do anything for money.
- * This might help. Or not.
- */
-#define _DARWIN_UNLIMITED_SELECT 1
-
-/* this block tries to deduce configuration from header-defined symbols and defaults */
-
-/* try to deduce the maximum number of signals on this platform */
-#if defined EV_NSIG
-/* use what's provided */
-#elif defined NSIG
-# define EV_NSIG (NSIG)
-#elif defined _NSIG
-# define EV_NSIG (_NSIG)
-#elif defined SIGMAX
-# define EV_NSIG (SIGMAX+1)
-#elif defined SIG_MAX
-# define EV_NSIG (SIG_MAX+1)
-#elif defined _SIG_MAX
-# define EV_NSIG (_SIG_MAX+1)
-#elif defined MAXSIG
-# define EV_NSIG (MAXSIG+1)
-#elif defined MAX_SIG
-# define EV_NSIG (MAX_SIG+1)
-#elif defined SIGARRAYSIZE
-# define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */
-#elif defined _sys_nsig
-# define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
-#else
-# define EV_NSIG (8 * sizeof (sigset_t) + 1)
-#endif
-
-#ifndef EV_USE_FLOOR
-# define EV_USE_FLOOR 0
-#endif
-
-#ifndef EV_USE_CLOCK_SYSCALL
-# if __linux && __GLIBC__ == 2 && __GLIBC_MINOR__ < 17
-# define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS
-# else
-# define EV_USE_CLOCK_SYSCALL 0
-# endif
-#endif
-
-#if !(_POSIX_TIMERS > 0)
-# ifndef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 0
-# endif
-# ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-# endif
-#endif
-
-#ifndef EV_USE_MONOTONIC
-# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
-# define EV_USE_MONOTONIC EV_FEATURE_OS
-# else
-# define EV_USE_MONOTONIC 0
-# endif
-#endif
-
-#ifndef EV_USE_REALTIME
-# define EV_USE_REALTIME !EV_USE_CLOCK_SYSCALL
-#endif
-
-#ifndef EV_USE_NANOSLEEP
-# if _POSIX_C_SOURCE >= 199309L
-# define EV_USE_NANOSLEEP EV_FEATURE_OS
-# else
-# define EV_USE_NANOSLEEP 0
-# endif
-#endif
-
-#ifndef EV_USE_SELECT
-# define EV_USE_SELECT EV_FEATURE_BACKENDS
-#endif
-
-#ifndef EV_USE_POLL
-# ifdef _WIN32
-# define EV_USE_POLL 0
-# else
-# define EV_USE_POLL EV_FEATURE_BACKENDS
-# endif
-#endif
-
-#ifndef EV_USE_EPOLL
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
-# define EV_USE_EPOLL EV_FEATURE_BACKENDS
-# else
-# define EV_USE_EPOLL 0
-# endif
-#endif
-
-#ifndef EV_USE_KQUEUE
-# define EV_USE_KQUEUE 0
-#endif
-
-#ifndef EV_USE_PORT
-# define EV_USE_PORT 0
-#endif
-
-#ifndef EV_USE_INOTIFY
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
-# define EV_USE_INOTIFY EV_FEATURE_OS
-# else
-# define EV_USE_INOTIFY 0
-# endif
-#endif
-
-#ifndef EV_PID_HASHSIZE
-# define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1
-#endif
-
-#ifndef EV_INOTIFY_HASHSIZE
-# define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1
-#endif
-
-#ifndef EV_USE_EVENTFD
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
-# define EV_USE_EVENTFD EV_FEATURE_OS
-# else
-# define EV_USE_EVENTFD 0
-# endif
-#endif
-
-#ifndef EV_USE_SIGNALFD
-# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
-# define EV_USE_SIGNALFD EV_FEATURE_OS
-# else
-# define EV_USE_SIGNALFD 0
-# endif
-#endif
-
-#if 0 /* debugging */
-# define EV_VERIFY 3
-# define EV_USE_4HEAP 1
-# define EV_HEAP_CACHE_AT 1
-#endif
-
-#ifndef EV_VERIFY
-# define EV_VERIFY (EV_FEATURE_API ? 1 : 0)
-#endif
-
-#ifndef EV_USE_4HEAP
-# define EV_USE_4HEAP EV_FEATURE_DATA
-#endif
-
-#ifndef EV_HEAP_CACHE_AT
-# define EV_HEAP_CACHE_AT EV_FEATURE_DATA
-#endif
-
-#ifdef ANDROID
-/* supposedly, android doesn't typedef fd_mask */
-# undef EV_USE_SELECT
-# define EV_USE_SELECT 0
-/* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */
-# undef EV_USE_CLOCK_SYSCALL
-# define EV_USE_CLOCK_SYSCALL 0
-#endif
-
-/* aix's poll.h seems to cause lots of trouble */
-#ifdef _AIX
-/* AIX has a completely broken poll.h header */
-# undef EV_USE_POLL
-# define EV_USE_POLL 0
-#endif
-
-/* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
-/* which makes programs even slower. might work on other unices, too. */
-#if EV_USE_CLOCK_SYSCALL
-# include <sys/syscall.h>
-# ifdef SYS_clock_gettime
-# define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
-# undef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 1
-# else
-# undef EV_USE_CLOCK_SYSCALL
-# define EV_USE_CLOCK_SYSCALL 0
-# endif
-#endif
-
-/* this block fixes any misconfiguration where we know we run into trouble otherwise */
-
-#ifndef CLOCK_MONOTONIC
-# undef EV_USE_MONOTONIC
-# define EV_USE_MONOTONIC 0
-#endif
-
-#ifndef CLOCK_REALTIME
-# undef EV_USE_REALTIME
-# define EV_USE_REALTIME 0
-#endif
-
-#if !EV_STAT_ENABLE
-# undef EV_USE_INOTIFY
-# define EV_USE_INOTIFY 0
-#endif
-
-#if !EV_USE_NANOSLEEP
-/* hp-ux has it in sys/time.h, which we unconditionally include above */
-# if !defined _WIN32 && !defined __hpux
-# include <sys/select.h>
-# endif
-#endif
-
-#if EV_USE_INOTIFY
-# include <sys/statfs.h>
-# include <sys/inotify.h>
-/* some very old inotify.h headers don't have IN_DONT_FOLLOW */
-# ifndef IN_DONT_FOLLOW
-# undef EV_USE_INOTIFY
-# define EV_USE_INOTIFY 0
-# endif
-#endif
-
-#if EV_USE_EVENTFD
-/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
-# include <stdint.h>
-# ifndef EFD_NONBLOCK
-# define EFD_NONBLOCK O_NONBLOCK
-# endif
-# ifndef EFD_CLOEXEC
-# ifdef O_CLOEXEC
-# define EFD_CLOEXEC O_CLOEXEC
-# else
-# define EFD_CLOEXEC 02000000
-# endif
-# endif
-EV_CPP(extern "C") int (eventfd) (unsigned int initval, int flags);
-#endif
-
-#if EV_USE_SIGNALFD
-/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
-# include <stdint.h>
-# ifndef SFD_NONBLOCK
-# define SFD_NONBLOCK O_NONBLOCK
-# endif
-# ifndef SFD_CLOEXEC
-# ifdef O_CLOEXEC
-# define SFD_CLOEXEC O_CLOEXEC
-# else
-# define SFD_CLOEXEC 02000000
-# endif
-# endif
-EV_CPP (extern "C") int signalfd (int fd, const sigset_t *mask, int flags);
-
-struct signalfd_siginfo
-{
- uint32_t ssi_signo;
- char pad[128 - sizeof (uint32_t)];
-};
-#endif
-
-/**/
-
-#if EV_VERIFY >= 3
-# define EV_FREQUENT_CHECK ev_verify (EV_A)
-#else
-# define EV_FREQUENT_CHECK do { } while (0)
-#endif
-
-/*
- * This is used to work around floating point rounding problems.
- * This value is good at least till the year 4000.
- */
-#define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */
-/*#define MIN_INTERVAL 0.00000095367431640625 * 1/2**20, good till 2200 */
-
-#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
-#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
-
-#define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0)
-#define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0)
-
-/* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */
-/* ECB.H BEGIN */
-/*
- * libecb - http://software.schmorp.de/pkg/libecb
- *
- * Copyright (©) 2009-2015 Marc Alexander Lehmann <libecb@schmorp.de>
- * Copyright (©) 2011 Emanuele Giaquinta
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef ECB_H
-#define ECB_H
-
-/* 16 bits major, 16 bits minor */
-#define ECB_VERSION 0x00010004
-
-#ifdef _WIN32
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- typedef signed short int16_t;
- typedef unsigned short uint16_t;
- typedef signed int int32_t;
- typedef unsigned int uint32_t;
- #if __GNUC__
- typedef signed long long int64_t;
- typedef unsigned long long uint64_t;
- #else /* _MSC_VER || __BORLANDC__ */
- typedef signed __int64 int64_t;
- typedef unsigned __int64 uint64_t;
- #endif
- #ifdef _WIN64
- #define ECB_PTRSIZE 8
- typedef uint64_t uintptr_t;
- typedef int64_t intptr_t;
- #else
- #define ECB_PTRSIZE 4
- typedef uint32_t uintptr_t;
- typedef int32_t intptr_t;
- #endif
-#else
- #include <inttypes.h>
- #if UINTMAX_MAX > 0xffffffffU
- #define ECB_PTRSIZE 8
- #else
- #define ECB_PTRSIZE 4
- #endif
-#endif
-
-#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__)
-#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64)
-
-/* work around x32 idiocy by defining proper macros */
-#if ECB_GCC_AMD64 || ECB_MSVC_AMD64
- #if _ILP32
- #define ECB_AMD64_X32 1
- #else
- #define ECB_AMD64 1
- #endif
-#endif
-
-/* many compilers define _GNUC_ to some versions but then only implement
- * what their idiot authors think are the "more important" extensions,
- * causing enormous grief in return for some better fake benchmark numbers.
- * or so.
- * we try to detect these and simply assume they are not gcc - if they have
- * an issue with that they should have done it right in the first place.
- */
-#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
- #define ECB_GCC_VERSION(major,minor) 0
-#else
- #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
-#endif
-
-#define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor)))
-
-#if __clang__ && defined __has_builtin
- #define ECB_CLANG_BUILTIN(x) __has_builtin (x)
-#else
- #define ECB_CLANG_BUILTIN(x) 0
-#endif
-
-#if __clang__ && defined __has_extension
- #define ECB_CLANG_EXTENSION(x) __has_extension (x)
-#else
- #define ECB_CLANG_EXTENSION(x) 0
-#endif
-
-#define ECB_CPP (__cplusplus+0)
-#define ECB_CPP11 (__cplusplus >= 201103L)
-
-#if ECB_CPP
- #define ECB_C 0
- #define ECB_STDC_VERSION 0
-#else
- #define ECB_C 1
- #define ECB_STDC_VERSION __STDC_VERSION__
-#endif
-
-#define ECB_C99 (ECB_STDC_VERSION >= 199901L)
-#define ECB_C11 (ECB_STDC_VERSION >= 201112L)
-
-#if ECB_CPP
- #define ECB_EXTERN_C extern "C"
- #define ECB_EXTERN_C_BEG ECB_EXTERN_C {
- #define ECB_EXTERN_C_END }
-#else
- #define ECB_EXTERN_C extern
- #define ECB_EXTERN_C_BEG
- #define ECB_EXTERN_C_END
-#endif
-
-/*****************************************************************************/
-
-/* ECB_NO_THREADS - ecb is not used by multiple threads, ever */
-/* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */
-
-#if ECB_NO_THREADS
- #define ECB_NO_SMP 1
-#endif
-
-#if ECB_NO_SMP
- #define ECB_MEMORY_FENCE do { } while (0)
-#endif
-
-/* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/compiler_ref/compiler_builtins.html */
-#if __xlC__ && ECB_CPP
- #include <builtins.h>
-#endif
-
-#ifndef ECB_MEMORY_FENCE
- #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
- #if __i386 || __i386__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
- #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
- #elif ECB_GCC_AMD64
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
- #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
- #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
- #elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \
- || defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
- #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
- || defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
- #elif __aarch64__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory")
- #elif (__sparc || __sparc__) && !__sparcv8
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
- #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
- #elif defined __s390__ || defined __s390x__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
- #elif defined __mips__
- /* GNU/Linux emulates sync on mips1 architectures, so we force its use */
- /* anybody else who still uses mips1 is supposed to send in their version, with detection code. */
- #define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory")
- #elif defined __alpha__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory")
- #elif defined __hppa__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
- #elif defined __ia64__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory")
- #elif defined __m68k__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
- #elif defined __m88k__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory")
- #elif defined __sh__
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
- #endif
- #endif
-#endif
-
-#ifndef ECB_MEMORY_FENCE
- #if ECB_GCC_VERSION(4,7)
- /* see comment below (stdatomic.h) about the C11 memory model. */
- #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
- #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
- #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
-
- #elif ECB_CLANG_EXTENSION(c_atomic)
- /* see comment below (stdatomic.h) about the C11 memory model. */
- #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
- #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
- #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
-
- #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
- #define ECB_MEMORY_FENCE __sync_synchronize ()
- #elif _MSC_VER >= 1500 /* VC++ 2008 */
- /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */
- #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
- #define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier()
- #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */
- #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier()
- #elif _MSC_VER >= 1400 /* VC++ 2005 */
- #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
- #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
- #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
- #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
- #elif defined _WIN32
- #include <WinNT.h>
- #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
- #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
- #include <mbarrier.h>
- #define ECB_MEMORY_FENCE __machine_rw_barrier ()
- #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
- #define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier ()
- #elif __xlC__
- #define ECB_MEMORY_FENCE __sync ()
- #endif
-#endif
-
-#ifndef ECB_MEMORY_FENCE
- #if ECB_C11 && !defined __STDC_NO_ATOMICS__
- /* we assume that these memory fences work on all variables/all memory accesses, */
- /* not just C11 atomics and atomic accesses */
- #include <stdatomic.h>
- /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
- /* any fence other than seq_cst, which isn't very efficient for us. */
- /* Why that is, we don't know - either the C11 memory model is quite useless */
- /* for most usages, or gcc and clang have a bug */
- /* I *currently* lean towards the latter, and inefficiently implement */
- /* all three of ecb's fences as a seq_cst fence */
- /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
- /* for all __atomic_thread_fence's except seq_cst */
- #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
- #endif
-#endif
-
-#ifndef ECB_MEMORY_FENCE
- #if !ECB_AVOID_PTHREADS
- /*
- * if you get undefined symbol references to pthread_mutex_lock,
- * or failure to find pthread.h, then you should implement
- * the ECB_MEMORY_FENCE operations for your cpu/compiler
- * OR provide pthread.h and link against the posix thread library
- * of your system.
- */
- #include <pthread.h>
- #define ECB_NEEDS_PTHREADS 1
- #define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1
-
- static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
- #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
- #endif
-#endif
-
-#if !defined ECB_MEMORY_FENCE_ACQUIRE && defined ECB_MEMORY_FENCE
- #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
-#endif
-
-#if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE
- #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
-#endif
-
-/*****************************************************************************/
-
-#if ECB_CPP
- #define ecb_inline static inline
-#elif ECB_GCC_VERSION(2,5)
- #define ecb_inline static __inline__
-#elif ECB_C99
- #define ecb_inline static inline
-#else
- #define ecb_inline static
-#endif
-
-#if ECB_GCC_VERSION(3,3)
- #define ecb_restrict __restrict__
-#elif ECB_C99
- #define ecb_restrict restrict
-#else
- #define ecb_restrict
-#endif
-
-typedef int ecb_bool;
-
-#define ECB_CONCAT_(a, b) a ## b
-#define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
-#define ECB_STRINGIFY_(a) # a
-#define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
-#define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr))
-
-#define ecb_function_ ecb_inline
-
-#if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8)
- #define ecb_attribute(attrlist) __attribute__ (attrlist)
-#else
- #define ecb_attribute(attrlist)
-#endif
-
-#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p)
- #define ecb_is_constant(expr) __builtin_constant_p (expr)
-#else
- /* possible C11 impl for integral types
- typedef struct ecb_is_constant_struct ecb_is_constant_struct;
- #define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */
-
- #define ecb_is_constant(expr) 0
-#endif
-
-#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect)
- #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
-#else
- #define ecb_expect(expr,value) (expr)
-#endif
-
-#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch)
- #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
-#else
- #define ecb_prefetch(addr,rw,locality)
-#endif
-
-/* no emulation for ecb_decltype */
-#if ECB_CPP11
- // older implementations might have problems with decltype(x)::type, work around it
- template<class T> struct ecb_decltype_t { typedef T type; };
- #define ecb_decltype(x) ecb_decltype_t<decltype (x)>::type
-#elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8)
- #define ecb_decltype(x) __typeof__ (x)
-#endif
-
-#if _MSC_VER >= 1300
- #define ecb_deprecated __declspec (deprecated)
-#else
- #define ecb_deprecated ecb_attribute ((__deprecated__))
-#endif
-
-#if _MSC_VER >= 1500
- #define ecb_deprecated_message(msg) __declspec (deprecated (msg))
-#elif ECB_GCC_VERSION(4,5)
- #define ecb_deprecated_message(msg) ecb_attribute ((__deprecated__ (msg))
-#else
- #define ecb_deprecated_message(msg) ecb_deprecated
-#endif
-
-#if _MSC_VER >= 1400
- #define ecb_noinline __declspec (noinline)
-#else
- #define ecb_noinline ecb_attribute ((__noinline__))
-#endif
-
-#define ecb_unused ecb_attribute ((__unused__))
-#define ecb_const ecb_attribute ((__const__))
-#define ecb_pure ecb_attribute ((__pure__))
-
-#if ECB_C11 || __IBMC_NORETURN
- /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/noreturn.html */
- #define ecb_noreturn _Noreturn
-#elif ECB_CPP11
- #define ecb_noreturn [[noreturn]]
-#elif _MSC_VER >= 1200
- /* http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx */
- #define ecb_noreturn __declspec (noreturn)
-#else
- #define ecb_noreturn ecb_attribute ((__noreturn__))
-#endif
-
-#if ECB_GCC_VERSION(4,3)
- #define ecb_artificial ecb_attribute ((__artificial__))
- #define ecb_hot ecb_attribute ((__hot__))
- #define ecb_cold ecb_attribute ((__cold__))
-#else
- #define ecb_artificial
- #define ecb_hot
- #define ecb_cold
-#endif
-
-/* put around conditional expressions if you are very sure that the */
-/* expression is mostly true or mostly false. note that these return */
-/* booleans, not the expression. */
-#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
-#define ecb_expect_true(expr) ecb_expect (!!(expr), 1)
-/* for compatibility to the rest of the world */
-#define ecb_likely(expr) ecb_expect_true (expr)
-#define ecb_unlikely(expr) ecb_expect_false (expr)
-
-/* count trailing zero bits and count # of one bits */
-#if ECB_GCC_VERSION(3,4) \
- || (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \
- && ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \
- && ECB_CLANG_BUILTIN(__builtin_popcount))
- /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
- #define ecb_ld32(x) (__builtin_clz (x) ^ 31)
- #define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
- #define ecb_ctz32(x) __builtin_ctz (x)
- #define ecb_ctz64(x) __builtin_ctzll (x)
- #define ecb_popcount32(x) __builtin_popcount (x)
- /* no popcountll */
-#else
- ecb_function_ ecb_const int ecb_ctz32 (uint32_t x);
- ecb_function_ ecb_const int
- ecb_ctz32 (uint32_t x)
- {
- int r = 0;
-
- x &= ~x + 1; /* this isolates the lowest bit */
-
-#if ECB_branchless_on_i386
- r += !!(x & 0xaaaaaaaa) << 0;
- r += !!(x & 0xcccccccc) << 1;
- r += !!(x & 0xf0f0f0f0) << 2;
- r += !!(x & 0xff00ff00) << 3;
- r += !!(x & 0xffff0000) << 4;
-#else
- if (x & 0xaaaaaaaa) r += 1;
- if (x & 0xcccccccc) r += 2;
- if (x & 0xf0f0f0f0) r += 4;
- if (x & 0xff00ff00) r += 8;
- if (x & 0xffff0000) r += 16;
-#endif
-
- return r;
- }
-
- ecb_function_ ecb_const int ecb_ctz64 (uint64_t x);
- ecb_function_ ecb_const int
- ecb_ctz64 (uint64_t x)
- {
- int shift = x & 0xffffffffU ? 0 : 32;
- return ecb_ctz32 (x >> shift) + shift;
- }
-
- ecb_function_ ecb_const int ecb_popcount32 (uint32_t x);
- ecb_function_ ecb_const int
- ecb_popcount32 (uint32_t x)
- {
- x -= (x >> 1) & 0x55555555;
- x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
- x = ((x >> 4) + x) & 0x0f0f0f0f;
- x *= 0x01010101;
-
- return x >> 24;
- }
-
- ecb_function_ ecb_const int ecb_ld32 (uint32_t x);
- ecb_function_ ecb_const int ecb_ld32 (uint32_t x)
- {
- int r = 0;
-
- if (x >> 16) { x >>= 16; r += 16; }
- if (x >> 8) { x >>= 8; r += 8; }
- if (x >> 4) { x >>= 4; r += 4; }
- if (x >> 2) { x >>= 2; r += 2; }
- if (x >> 1) { r += 1; }
-
- return r;
- }
-
- ecb_function_ ecb_const int ecb_ld64 (uint64_t x);
- ecb_function_ ecb_const int ecb_ld64 (uint64_t x)
- {
- int r = 0;
-
- if (x >> 32) { x >>= 32; r += 32; }
-
- return r + ecb_ld32 (x);
- }
-#endif
-
-ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x);
-ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
-ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x);
-ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
-
-ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x);
-ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x)
-{
- return ( (x * 0x0802U & 0x22110U)
- | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
-}
-
-ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x);
-ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x)
-{
- x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
- x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
- x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4);
- x = ( x >> 8 ) | ( x << 8);
-
- return x;
-}
-
-ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x);
-ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x)
-{
- x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
- x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
- x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
- x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
- x = ( x >> 16 ) | ( x << 16);
-
- return x;
-}
-
-/* popcount64 is only available on 64 bit cpus as gcc builtin */
-/* so for this version we are lazy */
-ecb_function_ ecb_const int ecb_popcount64 (uint64_t x);
-ecb_function_ ecb_const int
-ecb_popcount64 (uint64_t x)
-{
- return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
-}
-
-ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count);
-ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count);
-ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count);
-ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count);
-ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count);
-ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count);
-ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count);
-ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count);
-
-ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
-ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
-ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
-ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
-ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
-ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
-ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
-ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
-
-#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64))
- #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16)
- #define ecb_bswap16(x) __builtin_bswap16 (x)
- #else
- #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
- #endif
- #define ecb_bswap32(x) __builtin_bswap32 (x)
- #define ecb_bswap64(x) __builtin_bswap64 (x)
-#elif _MSC_VER
- #include <stdlib.h>
- #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x)))
- #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x)))
- #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x)))
-#else
- ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x);
- ecb_function_ ecb_const uint16_t
- ecb_bswap16 (uint16_t x)
- {
- return ecb_rotl16 (x, 8);
- }
-
- ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x);
- ecb_function_ ecb_const uint32_t
- ecb_bswap32 (uint32_t x)
- {
- return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
- }
-
- ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x);
- ecb_function_ ecb_const uint64_t
- ecb_bswap64 (uint64_t x)
- {
- return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
- }
-#endif
-
-#if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable)
- #define ecb_unreachable() __builtin_unreachable ()
-#else
- /* this seems to work fine, but gcc always emits a warning for it :/ */
- ecb_inline ecb_noreturn void ecb_unreachable (void);
- ecb_inline ecb_noreturn void ecb_unreachable (void) { }
-#endif
-
-/* try to tell the compiler that some condition is definitely true */
-#define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
-
-ecb_inline ecb_const unsigned char ecb_byteorder_helper (void);
-ecb_inline ecb_const unsigned char
-ecb_byteorder_helper (void)
-{
- /* the union code still generates code under pressure in gcc, */
- /* but less than using pointers, and always seems to */
- /* successfully return a constant. */
- /* the reason why we have this horrible preprocessor mess */
- /* is to avoid it in all cases, at least on common architectures */
- /* or when using a recent enough gcc version (>= 4.6) */
-#if ((__i386 || __i386__) && !__VOS__) || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64
- return 0x44;
-#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- return 0x44;
-#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
- return 0x11;
-#else
- union
- {
- uint32_t i;
- uint8_t c;
- } u = { 0x11223344 };
- return u.c;
-#endif
-}
-
-ecb_inline ecb_const ecb_bool ecb_big_endian (void);
-ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
-ecb_inline ecb_const ecb_bool ecb_little_endian (void);
-ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
-
-#if ECB_GCC_VERSION(3,0) || ECB_C99
- #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
-#else
- #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
-#endif
-
-#if ECB_CPP
- template<typename T>
- static inline T ecb_div_rd (T val, T div)
- {
- return val < 0 ? - ((-val + div - 1) / div) : (val ) / div;
- }
- template<typename T>
- static inline T ecb_div_ru (T val, T div)
- {
- return val < 0 ? - ((-val ) / div) : (val + div - 1) / div;
- }
-#else
- #define ecb_div_rd(val,div) ((val) < 0 ? - ((-(val) + (div) - 1) / (div)) : ((val) ) / (div))
- #define ecb_div_ru(val,div) ((val) < 0 ? - ((-(val) ) / (div)) : ((val) + (div) - 1) / (div))
-#endif
-
-#if ecb_cplusplus_does_not_suck
- /* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */
- template<typename T, int N>
- static inline int ecb_array_length (const T (&arr)[N])
- {
- return N;
- }
-#else
- #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
-#endif
-
-/*******************************************************************************/
-/* floating point stuff, can be disabled by defining ECB_NO_LIBM */
-
-/* basically, everything uses "ieee pure-endian" floating point numbers */
-/* the only noteworthy exception is ancient armle, which uses order 43218765 */
-#if 0 \
- || __i386 || __i386__ \
- || ECB_GCC_AMD64 \
- || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
- || defined __s390__ || defined __s390x__ \
- || defined __mips__ \
- || defined __alpha__ \
- || defined __hppa__ \
- || defined __ia64__ \
- || defined __m68k__ \
- || defined __m88k__ \
- || defined __sh__ \
- || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \
- || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \
- || defined __aarch64__
- #define ECB_STDFP 1
- #include <string.h> /* for memcpy */
-#else
- #define ECB_STDFP 0
-#endif
-
-#ifndef ECB_NO_LIBM
-
- #include <math.h> /* for frexp*, ldexp*, INFINITY, NAN */
-
- /* only the oldest of old doesn't have this one. solaris. */
- #ifdef INFINITY
- #define ECB_INFINITY INFINITY
- #else
- #define ECB_INFINITY HUGE_VAL
- #endif
-
- #ifdef NAN
- #define ECB_NAN NAN
- #else
- #define ECB_NAN ECB_INFINITY
- #endif
-
- #if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L
- #define ecb_ldexpf(x,e) ldexpf ((x), (e))
- #define ecb_frexpf(x,e) frexpf ((x), (e))
- #else
- #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e))
- #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e))
- #endif
-
- /* converts an ieee half/binary16 to a float */
- ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x);
- ecb_function_ ecb_const float
- ecb_binary16_to_float (uint16_t x)
- {
- int e = (x >> 10) & 0x1f;
- int m = x & 0x3ff;
- float r;
-
- if (!e ) r = ecb_ldexpf (m , -24);
- else if (e != 31) r = ecb_ldexpf (m + 0x400, e - 25);
- else if (m ) r = ECB_NAN;
- else r = ECB_INFINITY;
-
- return x & 0x8000 ? -r : r;
- }
-
- /* convert a float to ieee single/binary32 */
- ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x);
- ecb_function_ ecb_const uint32_t
- ecb_float_to_binary32 (float x)
- {
- uint32_t r;
-
- #if ECB_STDFP
- memcpy (&r, &x, 4);
- #else
- /* slow emulation, works for anything but -0 */
- uint32_t m;
- int e;
-
- if (x == 0e0f ) return 0x00000000U;
- if (x > +3.40282346638528860e+38f) return 0x7f800000U;
- if (x < -3.40282346638528860e+38f) return 0xff800000U;
- if (x != x ) return 0x7fbfffffU;
-
- m = ecb_frexpf (x, &e) * 0x1000000U;
-
- r = m & 0x80000000U;
-
- if (r)
- m = -m;
-
- if (e <= -126)
- {
- m &= 0xffffffU;
- m >>= (-125 - e);
- e = -126;
- }
-
- r |= (e + 126) << 23;
- r |= m & 0x7fffffU;
- #endif
-
- return r;
- }
-
- /* converts an ieee single/binary32 to a float */
- ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x);
- ecb_function_ ecb_const float
- ecb_binary32_to_float (uint32_t x)
- {
- float r;
-
- #if ECB_STDFP
- memcpy (&r, &x, 4);
- #else
- /* emulation, only works for normals and subnormals and +0 */
- int neg = x >> 31;
- int e = (x >> 23) & 0xffU;
-
- x &= 0x7fffffU;
-
- if (e)
- x |= 0x800000U;
- else
- e = 1;
-
- /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
- r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126);
-
- r = neg ? -r : r;
- #endif
-
- return r;
- }
-
- /* convert a double to ieee double/binary64 */
- ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x);
- ecb_function_ ecb_const uint64_t
- ecb_double_to_binary64 (double x)
- {
- uint64_t r;
-
- #if ECB_STDFP
- memcpy (&r, &x, 8);
- #else
- /* slow emulation, works for anything but -0 */
- uint64_t m;
- int e;
-
- if (x == 0e0 ) return 0x0000000000000000U;
- if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U;
- if (x < -1.79769313486231470e+308) return 0xfff0000000000000U;
- if (x != x ) return 0X7ff7ffffffffffffU;
-
- m = frexp (x, &e) * 0x20000000000000U;
-
- r = m & 0x8000000000000000;;
-
- if (r)
- m = -m;
-
- if (e <= -1022)
- {
- m &= 0x1fffffffffffffU;
- m >>= (-1021 - e);
- e = -1022;
- }
-
- r |= ((uint64_t)(e + 1022)) << 52;
- r |= m & 0xfffffffffffffU;
- #endif
-
- return r;
- }
-
- /* converts an ieee double/binary64 to a double */
- ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x);
- ecb_function_ ecb_const double
- ecb_binary64_to_double (uint64_t x)
- {
- double r;
-
- #if ECB_STDFP
- memcpy (&r, &x, 8);
- #else
- /* emulation, only works for normals and subnormals and +0 */
- int neg = x >> 63;
- int e = (x >> 52) & 0x7ffU;
-
- x &= 0xfffffffffffffU;
-
- if (e)
- x |= 0x10000000000000U;
- else
- e = 1;
-
- /* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */
- r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022);
-
- r = neg ? -r : r;
- #endif
-
- return r;
- }
-
-#endif
-
-#endif
-
-/* ECB.H END */
-
-#if ECB_MEMORY_FENCE_NEEDS_PTHREADS
-/* if your architecture doesn't need memory fences, e.g. because it is
- * single-cpu/core, or if you use libev in a project that doesn't use libev
- * from multiple threads, then you can define ECB_AVOID_PTHREADS when compiling
- * libev, in which cases the memory fences become nops.
- * alternatively, you can remove this #error and link against libpthread,
- * which will then provide the memory fences.
- */
-# error "memory fences not defined for your architecture, please report"
-#endif
-
-#ifndef ECB_MEMORY_FENCE
-# define ECB_MEMORY_FENCE do { } while (0)
-# define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
-# define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
-#endif
-
-#define expect_false(cond) ecb_expect_false (cond)
-#define expect_true(cond) ecb_expect_true (cond)
-#define noinline ecb_noinline
-
-#define inline_size ecb_inline
-
-#if EV_FEATURE_CODE
-# define inline_speed ecb_inline
-#else
-# define inline_speed static noinline
-#endif
-
-#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
-
-#if EV_MINPRI == EV_MAXPRI
-# define ABSPRI(w) (((W)w), 0)
-#else
-# define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
-#endif
-
-#define EMPTY /* required for microsofts broken pseudo-c compiler */
-#define EMPTY2(a,b) /* used to suppress some warnings */
-
-typedef ev_watcher *W;
-typedef ev_watcher_list *WL;
-typedef ev_watcher_time *WT;
-
-#define ev_active(w) ((W)(w))->active
-#define ev_at(w) ((WT)(w))->at
-
-#if EV_USE_REALTIME
-/* sig_atomic_t is used to avoid per-thread variables or locking but still */
-/* giving it a reasonably high chance of working on typical architectures */
-static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */
-#endif
-
-#if EV_USE_MONOTONIC
-static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
-#endif
-
-#ifndef EV_FD_TO_WIN32_HANDLE
-# define EV_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
-#endif
-#ifndef EV_WIN32_HANDLE_TO_FD
-# define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
-#endif
-#ifndef EV_WIN32_CLOSE_FD
-# define EV_WIN32_CLOSE_FD(fd) close (fd)
-#endif
-
-#ifdef _WIN32
-# include "ev_win32.c"
-#endif
-
-/*****************************************************************************/
-
-/* define a suitable floor function (only used by periodics atm) */
-
-#if EV_USE_FLOOR
-# include <math.h>
-# define ev_floor(v) floor (v)
-#else
-
-#include <float.h>
-
-/* a floor() replacement function, should be independent of ev_tstamp type */
-static ev_tstamp noinline
-ev_floor (ev_tstamp v)
-{
- /* the choice of shift factor is not terribly important */
-#if FLT_RADIX != 2 /* assume FLT_RADIX == 10 */
- const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.;
-#else
- const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.;
-#endif
-
- /* argument too large for an unsigned long? */
- if (expect_false (v >= shift))
- {
- ev_tstamp f;
-
- if (v == v - 1.)
- return v; /* very large number */
-
- f = shift * ev_floor (v * (1. / shift));
- return f + ev_floor (v - f);
- }
-
- /* special treatment for negative args? */
- if (expect_false (v < 0.))
- {
- ev_tstamp f = -ev_floor (-v);
-
- return f - (f == v ? 0 : 1);
- }
-
- /* fits into an unsigned long */
- return (unsigned long)v;
-}
-
-#endif
-
-/*****************************************************************************/
-
-#ifdef __linux
-# include <sys/utsname.h>
-#endif
-
-static unsigned int noinline ecb_cold
-ev_linux_version (void)
-{
-#ifdef __linux
- unsigned int v = 0;
- struct utsname buf;
- int i;
- char *p = buf.release;
-
- if (uname (&buf))
- return 0;
-
- for (i = 3+1; --i; )
- {
- unsigned int c = 0;
-
- for (;;)
- {
- if (*p >= '0' && *p <= '9')
- c = c * 10 + *p++ - '0';
- else
- {
- p += *p == '.';
- break;
- }
- }
-
- v = (v << 8) | c;
- }
-
- return v;
-#else
- return 0;
-#endif
-}
-
-/*****************************************************************************/
-
-#if EV_AVOID_STDIO
-static void noinline ecb_cold
-ev_printerr (const char *msg)
-{
- int rc;
- do {
- rc = write (STDERR_FILENO, msg, strlen (msg));
- } while (errno == EINTR && rc < 0);
-}
-#endif
-
-static void (*syserr_cb)(const char *msg) EV_THROW;
-
-void ecb_cold
-ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW
-{
- syserr_cb = cb;
-}
-
-static void noinline ecb_cold
-ev_syserr (const char *msg)
-{
- if (!msg)
- msg = "(libev) system error";
-
- if (syserr_cb)
- syserr_cb (msg);
- else
- {
-#if EV_AVOID_STDIO
- ev_printerr (msg);
- ev_printerr (": ");
- ev_printerr (strerror (errno));
- ev_printerr ("\n");
-#else
- perror (msg);
-#endif
- abort ();
- }
-}
-
-static void *
-ev_realloc_emul (void *ptr, long size) EV_THROW
-{
- /* some systems, notably openbsd and darwin, fail to properly
- * implement realloc (x, 0) (as required by both ansi c-89 and
- * the single unix specification, so work around them here.
- * recently, also (at least) fedora and debian started breaking it,
- * despite documenting it otherwise.
- */
-
- if (size)
- return realloc (ptr, size);
-
- free (ptr);
- return 0;
-}
-
-static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
-
-void ecb_cold
-ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW
-{
- alloc = cb;
-}
-
-inline_speed void *
-ev_realloc (void *ptr, long size)
-{
- ptr = alloc (ptr, size);
-
- if (!ptr && size)
- {
-#if EV_AVOID_STDIO
- ev_printerr ("(libev) memory allocation failed, aborting.\n");
-#else
- fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size);
-#endif
- abort ();
- }
-
- return ptr;
-}
-
-#define ev_malloc(size) ev_realloc (0, (size))
-#define ev_free(ptr) free (ptr)
-
-/*****************************************************************************/
-
-/* set in reify when reification needed */
-#define EV_ANFD_REIFY 1
-
-/* file descriptor info structure */
-typedef struct
-{
- WL head;
- unsigned char events; /* the events watched for */
- unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */
- unsigned char emask; /* the epoll backend stores the actual kernel mask in here */
- unsigned char unused;
-#if EV_USE_EPOLL
- unsigned int egen; /* generation counter to counter epoll bugs */
-#endif
-#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
- SOCKET handle;
-#endif
-#if EV_USE_IOCP
- OVERLAPPED or, ow;
-#endif
-} ANFD;
-
-/* stores the pending event set for a given watcher */
-typedef struct
-{
- W w;
- int events; /* the pending event set for the given watcher */
-} ANPENDING;
-
-#if EV_USE_INOTIFY
-/* hash table entry per inotify-id */
-typedef struct
-{
- WL head;
-} ANFS;
-#endif
-
-/* Heap Entry */
-#if EV_HEAP_CACHE_AT
- /* a heap element */
- typedef struct {
- ev_tstamp at;
- WT w;
- } ANHE;
-
- #define ANHE_w(he) (he).w /* access watcher, read-write */
- #define ANHE_at(he) (he).at /* access cached at, read-only */
- #define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */
-#else
- /* a heap element */
- typedef WT ANHE;
-
- #define ANHE_w(he) (he)
- #define ANHE_at(he) (he)->at
- #define ANHE_at_cache(he)
-#endif
-
-#if EV_MULTIPLICITY
-
- struct ev_loop
- {
- ev_tstamp ev_rt_now;
- #define ev_rt_now ((loop)->ev_rt_now)
- #define VAR(name,decl) decl;
- #include "ev_vars.h"
- #undef VAR
- };
- #include "ev_wrap.h"
-
- static struct ev_loop default_loop_struct;
- EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
-
-#else
-
- EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a definition despite extern */
- #define VAR(name,decl) static decl;
- #include "ev_vars.h"
- #undef VAR
-
- static int ev_default_loop_ptr;
-
-#endif
-
-#if EV_FEATURE_API
-# define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A)
-# define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A)
-# define EV_INVOKE_PENDING invoke_cb (EV_A)
-#else
-# define EV_RELEASE_CB (void)0
-# define EV_ACQUIRE_CB (void)0
-# define EV_INVOKE_PENDING ev_invoke_pending (EV_A)
-#endif
-
-#define EVBREAK_RECURSE 0x80
-
-/*****************************************************************************/
-
-#ifndef EV_HAVE_EV_TIME
-ev_tstamp
-ev_time (void) EV_THROW
-{
-#if EV_USE_REALTIME
- if (expect_true (have_realtime))
- {
- struct timespec ts;
- clock_gettime (CLOCK_REALTIME, &ts);
- return ts.tv_sec + ts.tv_nsec * 1e-9;
- }
-#endif
-
- struct timeval tv;
- gettimeofday (&tv, 0);
- return tv.tv_sec + tv.tv_usec * 1e-6;
-}
-#endif
-
-inline_size ev_tstamp
-get_clock (void)
-{
-#if EV_USE_MONOTONIC
- if (expect_true (have_monotonic))
- {
- struct timespec ts;
- clock_gettime (CLOCK_MONOTONIC, &ts);
- return ts.tv_sec + ts.tv_nsec * 1e-9;
- }
-#endif
-
- return ev_time ();
-}
-
-#if EV_MULTIPLICITY
-ev_tstamp
-ev_now (EV_P) EV_THROW
-{
- return ev_rt_now;
-}
-#endif
-
-void
-ev_sleep (ev_tstamp delay) EV_THROW
-{
- if (delay > 0.)
- {
-#if EV_USE_NANOSLEEP
- struct timespec ts;
-
- EV_TS_SET (ts, delay);
- nanosleep (&ts, 0);
-#elif defined _WIN32
- Sleep ((unsigned long)(delay * 1e3));
-#else
- struct timeval tv;
-
- /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */
- /* something not guaranteed by newer posix versions, but guaranteed */
- /* by older ones */
- EV_TV_SET (tv, delay);
- select (0, 0, 0, 0, &tv);
-#endif
- }
-}
-
-/*****************************************************************************/
-
-#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
-
-/* find a suitable new size for the given array, */
-/* hopefully by rounding to a nice-to-malloc size */
-inline_size int
-array_nextsize (int elem, int cur, int cnt)
-{
- int ncur = cur + 1;
-
- do
- ncur <<= 1;
- while (cnt > ncur);
-
- /* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */
- if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
- {
- ncur *= elem;
- ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1);
- ncur = ncur - sizeof (void *) * 4;
- ncur /= elem;
- }
-
- return ncur;
-}
-
-static void * noinline ecb_cold
-array_realloc (int elem, void *base, int *cur, int cnt)
-{
- *cur = array_nextsize (elem, *cur, cnt);
- return ev_realloc (base, elem * *cur);
-}
-
-#define array_init_zero(base,count) \
- memset ((void *)(base), 0, sizeof (*(base)) * (count))
-
-#define array_needsize(type,base,cur,cnt,init) \
- if (expect_false ((cnt) > (cur))) \
- { \
- int ecb_unused ocur_ = (cur); \
- (base) = (type *)array_realloc \
- (sizeof (type), (base), &(cur), (cnt)); \
- init ((base) + (ocur_), (cur) - ocur_); \
- }
-
-#if 0
-#define array_slim(type,stem) \
- if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
- { \
- stem ## max = array_roundsize (stem ## cnt >> 1); \
- base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\
- fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
- }
-#endif
-
-#define array_free(stem, idx) \
- ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; stem ## s idx = 0
-
-/*****************************************************************************/
-
-/* dummy callback for pending events */
-static void noinline
-pendingcb (EV_P_ ev_prepare *w, int revents)
-{
-}
-
-void noinline
-ev_feed_event (EV_P_ void *w, int revents) EV_THROW
-{
- W w_ = (W)w;
- int pri = ABSPRI (w_);
-
- if (expect_false (w_->pending))
- pendings [pri][w_->pending - 1].events |= revents;
- else
- {
- w_->pending = ++pendingcnt [pri];
- array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2);
- pendings [pri][w_->pending - 1].w = w_;
- pendings [pri][w_->pending - 1].events = revents;
- }
-
- pendingpri = NUMPRI - 1;
-}
-
-inline_speed void
-feed_reverse (EV_P_ W w)
-{
- array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, EMPTY2);
- rfeeds [rfeedcnt++] = w;
-}
-
-inline_size void
-feed_reverse_done (EV_P_ int revents)
-{
- do
- ev_feed_event (EV_A_ rfeeds [--rfeedcnt], revents);
- while (rfeedcnt);
-}
-
-inline_speed void
-queue_events (EV_P_ W *events, int eventcnt, int type)
-{
- int i;
-
- for (i = 0; i < eventcnt; ++i)
- ev_feed_event (EV_A_ events [i], type);
-}
-
-/*****************************************************************************/
-
-inline_speed void
-fd_event_nocheck (EV_P_ int fd, int revents)
-{
- ANFD *anfd = anfds + fd;
- ev_io *w;
-
- for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
- {
- int ev = w->events & revents;
-
- if (ev)
- ev_feed_event (EV_A_ (W)w, ev);
- }
-}
-
-/* do not submit kernel events for fds that have reify set */
-/* because that means they changed while we were polling for new events */
-inline_speed void
-fd_event (EV_P_ int fd, int revents)
-{
- ANFD *anfd = anfds + fd;
-
- if (expect_true (!anfd->reify))
- fd_event_nocheck (EV_A_ fd, revents);
-}
-
-void
-ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW
-{
- if (fd >= 0 && fd < anfdmax)
- fd_event_nocheck (EV_A_ fd, revents);
-}
-
-/* make sure the external fd watch events are in-sync */
-/* with the kernel/libev internal state */
-inline_size void
-fd_reify (EV_P)
-{
- int i;
-
-#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
- for (i = 0; i < fdchangecnt; ++i)
- {
- int fd = fdchanges [i];
- ANFD *anfd = anfds + fd;
-
- if (anfd->reify & EV__IOFDSET && anfd->head)
- {
- SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd);
-
- if (handle != anfd->handle)
- {
- unsigned long arg;
-
- assert (("libev: only socket fds supported in this configuration", ioctlsocket (handle, FIONREAD, &arg) == 0));
-
- /* handle changed, but fd didn't - we need to do it in two steps */
- backend_modify (EV_A_ fd, anfd->events, 0);
- anfd->events = 0;
- anfd->handle = handle;
- }
- }
- }
-#endif
-
- for (i = 0; i < fdchangecnt; ++i)
- {
- int fd = fdchanges [i];
- ANFD *anfd = anfds + fd;
- ev_io *w;
-
- unsigned char o_events = anfd->events;
- unsigned char o_reify = anfd->reify;
-
- anfd->reify = 0;
-
- /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
- {
- anfd->events = 0;
-
- for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
- anfd->events |= (unsigned char)w->events;
-
- if (o_events != anfd->events)
- o_reify = EV__IOFDSET; /* actually |= */
- }
-
- if (o_reify & EV__IOFDSET)
- backend_modify (EV_A_ fd, o_events, anfd->events);
- }
-
- fdchangecnt = 0;
-}
-
-/* something about the given fd changed */
-inline_size void
-fd_change (EV_P_ int fd, int flags)
-{
- unsigned char reify = anfds [fd].reify;
- anfds [fd].reify |= flags;
-
- if (expect_true (!reify))
- {
- ++fdchangecnt;
- array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
- fdchanges [fdchangecnt - 1] = fd;
- }
-}
-
-/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
-inline_speed void ecb_cold
-fd_kill (EV_P_ int fd)
-{
- ev_io *w;
-
- while ((w = (ev_io *)anfds [fd].head))
- {
- ev_io_stop (EV_A_ w);
- ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE);
- }
-}
-
-/* check whether the given fd is actually valid, for error recovery */
-inline_size int ecb_cold
-fd_valid (int fd)
-{
-#ifdef _WIN32
- return EV_FD_TO_WIN32_HANDLE (fd) != -1;
-#else
- return fcntl (fd, F_GETFD) != -1;
-#endif
-}
-
-/* called on EBADF to verify fds */
-static void noinline ecb_cold
-fd_ebadf (EV_P)
-{
- int fd;
-
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)
- if (!fd_valid (fd) && errno == EBADF)
- fd_kill (EV_A_ fd);
-}
-
-/* called on ENOMEM in select/poll to kill some fds and retry */
-static void noinline ecb_cold
-fd_enomem (EV_P)
-{
- int fd;
-
- for (fd = anfdmax; fd--; )
- if (anfds [fd].events)
- {
- fd_kill (EV_A_ fd);
- break;
- }
-}
-
-/* usually called after fork if backend needs to re-arm all fds from scratch */
-static void noinline
-fd_rearm_all (EV_P)
-{
- int fd;
-
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)
- {
- anfds [fd].events = 0;
- anfds [fd].emask = 0;
- fd_change (EV_A_ fd, EV__IOFDSET | EV_ANFD_REIFY);
- }
-}
-
-/* used to prepare libev internal fd's */
-/* this is not fork-safe */
-inline_speed void
-fd_intern (int fd)
-{
-#ifdef _WIN32
- unsigned long arg = 1;
- ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg);
-#else
- fcntl (fd, F_SETFD, FD_CLOEXEC);
- fcntl (fd, F_SETFL, O_NONBLOCK);
-#endif
-}
-
-/*****************************************************************************/
-
-/*
- * the heap functions want a real array index. array index 0 is guaranteed to not
- * be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives
- * the branching factor of the d-tree.
- */
-
-/*
- * at the moment we allow libev the luxury of two heaps,
- * a small-code-size 2-heap one and a ~1.5kb larger 4-heap
- * which is more cache-efficient.
- * the difference is about 5% with 50000+ watchers.
- */
-#if EV_USE_4HEAP
-
-#define DHEAP 4
-#define HEAP0 (DHEAP - 1) /* index of first element in heap */
-#define HPARENT(k) ((((k) - HEAP0 - 1) / DHEAP) + HEAP0)
-#define UPHEAP_DONE(p,k) ((p) == (k))
-
-/* away from the root */
-inline_speed void
-downheap (ANHE *heap, int N, int k)
-{
- ANHE he = heap [k];
- ANHE *E = heap + N + HEAP0;
-
- for (;;)
- {
- ev_tstamp minat;
- ANHE *minpos;
- ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1;
-
- /* find minimum child */
- if (expect_true (pos + DHEAP - 1 < E))
- {
- /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
- if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
- if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
- if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
- }
- else if (pos < E)
- {
- /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
- if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
- if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
- if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
- }
- else
- break;
-
- if (ANHE_at (he) <= minat)
- break;
-
- heap [k] = *minpos;
- ev_active (ANHE_w (*minpos)) = k;
-
- k = minpos - heap;
- }
-
- heap [k] = he;
- ev_active (ANHE_w (he)) = k;
-}
-
-#else /* 4HEAP */
-
-#define HEAP0 1
-#define HPARENT(k) ((k) >> 1)
-#define UPHEAP_DONE(p,k) (!(p))
-
-/* away from the root */
-inline_speed void
-downheap (ANHE *heap, int N, int k)
-{
- ANHE he = heap [k];
-
- for (;;)
- {
- int c = k << 1;
-
- if (c >= N + HEAP0)
- break;
-
- c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
- ? 1 : 0;
-
- if (ANHE_at (he) <= ANHE_at (heap [c]))
- break;
-
- heap [k] = heap [c];
- ev_active (ANHE_w (heap [k])) = k;
-
- k = c;
- }
-
- heap [k] = he;
- ev_active (ANHE_w (he)) = k;
-}
-#endif
-
-/* towards the root */
-inline_speed void
-upheap (ANHE *heap, int k)
-{
- ANHE he = heap [k];
-
- for (;;)
- {
- int p = HPARENT (k);
-
- if (UPHEAP_DONE (p, k) || ANHE_at (heap [p]) <= ANHE_at (he))
- break;
-
- heap [k] = heap [p];
- ev_active (ANHE_w (heap [k])) = k;
- k = p;
- }
-
- heap [k] = he;
- ev_active (ANHE_w (he)) = k;
-}
-
-/* move an element suitably so it is in a correct place */
-inline_size void
-adjustheap (ANHE *heap, int N, int k)
-{
- if (k > HEAP0 && ANHE_at (heap [k]) <= ANHE_at (heap [HPARENT (k)]))
- upheap (heap, k);
- else
- downheap (heap, N, k);
-}
-
-/* rebuild the heap: this function is used only once and executed rarely */
-inline_size void
-reheap (ANHE *heap, int N)
-{
- int i;
-
- /* we don't use floyds algorithm, upheap is simpler and is more cache-efficient */
- /* also, this is easy to implement and correct for both 2-heaps and 4-heaps */
- for (i = 0; i < N; ++i)
- upheap (heap, i + HEAP0);
-}
-
-/*****************************************************************************/
-
-/* associate signal watchers to a signal signal */
-typedef struct
-{
- EV_ATOMIC_T pending;
-#if EV_MULTIPLICITY
- EV_P;
-#endif
- WL head;
-} ANSIG;
-
-static ANSIG signals [EV_NSIG];
-
-/*****************************************************************************/
-
-#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
-
-static void noinline ecb_cold
-evpipe_init (EV_P)
-{
- if (!ev_is_active (&pipe_w))
- {
- int fds [2];
-
-# if EV_USE_EVENTFD
- fds [0] = -1;
- fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
- if (fds [1] < 0 && errno == EINVAL)
- fds [1] = eventfd (0, 0);
-
- if (fds [1] < 0)
-# endif
- {
- while (pipe (fds))
- ev_syserr ("(libev) error creating signal/async pipe");
-
- fd_intern (fds [0]);
- }
-
- evpipe [0] = fds [0];
-
- if (evpipe [1] < 0)
- evpipe [1] = fds [1]; /* first call, set write fd */
- else
- {
- /* on subsequent calls, do not change evpipe [1] */
- /* so that evpipe_write can always rely on its value. */
- /* this branch does not do anything sensible on windows, */
- /* so must not be executed on windows */
-
- dup2 (fds [1], evpipe [1]);
- close (fds [1]);
- }
-
- fd_intern (evpipe [1]);
-
- ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ);
- ev_io_start (EV_A_ &pipe_w);
- ev_unref (EV_A); /* watcher should not keep loop alive */
- }
-}
-
-inline_speed void
-evpipe_write (EV_P_ EV_ATOMIC_T *flag)
-{
- ECB_MEMORY_FENCE; /* push out the write before this function was called, acquire flag */
-
- if (expect_true (*flag))
- return;
-
- *flag = 1;
- ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */
-
- pipe_write_skipped = 1;
-
- ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */
-
- if (pipe_write_wanted)
- {
- int old_errno, rc;
-
- pipe_write_skipped = 0;
- ECB_MEMORY_FENCE_RELEASE;
-
- old_errno = errno; /* save errno because write will clobber it */
-
-#if EV_USE_EVENTFD
- if (evpipe [0] < 0)
- {
- uint64_t counter = 1;
- do {
- rc = write (evpipe [1], &counter, sizeof (uint64_t));
- } while (errno == EINTR && rc < 0);
- }
- else
-#endif
- {
-#ifdef _WIN32
- WSABUF buf;
- DWORD sent;
- buf.buf = &buf;
- buf.len = 1;
- WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0);
-#else
- do {
- rc = write (evpipe [1], &(evpipe [1]), 1);
- } while (errno == EINTR && rc < 0);
-#endif
- }
-
- errno = old_errno;
- }
-}
-
-/* called whenever the libev signal pipe */
-/* got some events (signal, async) */
-static void
-pipecb (EV_P_ ev_io *iow, int revents)
-{
- int i;
-
- if (revents & EV_READ)
- {
-#if EV_USE_EVENTFD
- if (evpipe [0] < 0)
- {
- uint64_t counter;
- read (evpipe [1], &counter, sizeof (uint64_t));
- }
- else
-#endif
- {
- char dummy[4];
-#ifdef _WIN32
- WSABUF buf;
- DWORD recvd;
- DWORD flags = 0;
- buf.buf = dummy;
- buf.len = sizeof (dummy);
- WSARecv (EV_FD_TO_WIN32_HANDLE (evpipe [0]), &buf, 1, &recvd, &flags, 0, 0);
-#else
- read (evpipe [0], &dummy, sizeof (dummy));
-#endif
- }
- }
-
- pipe_write_skipped = 0;
-
- ECB_MEMORY_FENCE; /* push out skipped, acquire flags */
-
-#if EV_SIGNAL_ENABLE
- if (sig_pending)
- {
- sig_pending = 0;
-
- ECB_MEMORY_FENCE;
-
- for (i = EV_NSIG - 1; i--; )
- if (expect_false (signals [i].pending))
- ev_feed_signal_event (EV_A_ i + 1);
- }
-#endif
-
-#if EV_ASYNC_ENABLE
- if (async_pending)
- {
- async_pending = 0;
-
- ECB_MEMORY_FENCE;
-
- for (i = asynccnt; i--; )
- if (asyncs [i]->sent)
- {
- asyncs [i]->sent = 0;
- ECB_MEMORY_FENCE_RELEASE;
- ev_feed_event (EV_A_ asyncs [i], EV_ASYNC);
- }
- }
-#endif
-}
-
-/*****************************************************************************/
-
-void
-ev_feed_signal (int signum) EV_THROW
-{
-#if EV_MULTIPLICITY
- EV_P;
- ECB_MEMORY_FENCE_ACQUIRE;
- EV_A = signals [signum - 1].loop;
-
- if (!EV_A)
- return;
-#endif
-
- signals [signum - 1].pending = 1;
- evpipe_write (EV_A_ &sig_pending);
-}
-
-static void
-ev_sighandler (int signum)
-{
-#ifdef _WIN32
- signal (signum, ev_sighandler);
-#endif
-
- ev_feed_signal (signum);
-}
-
-void noinline
-ev_feed_signal_event (EV_P_ int signum) EV_THROW
-{
- WL w;
-
- if (expect_false (signum <= 0 || signum >= EV_NSIG))
- return;
-
- --signum;
-
-#if EV_MULTIPLICITY
- /* it is permissible to try to feed a signal to the wrong loop */
- /* or, likely more useful, feeding a signal nobody is waiting for */
-
- if (expect_false (signals [signum].loop != EV_A))
- return;
-#endif
-
- signals [signum].pending = 0;
- ECB_MEMORY_FENCE_RELEASE;
-
- for (w = signals [signum].head; w; w = w->next)
- ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
-}
-
-#if EV_USE_SIGNALFD
-static void
-sigfdcb (EV_P_ ev_io *iow, int revents)
-{
- struct signalfd_siginfo si[2], *sip; /* these structs are big */
-
- for (;;)
- {
- ssize_t res = read (sigfd, si, sizeof (si));
-
- /* not ISO-C, as res might be -1, but works with SuS */
- for (sip = si; (char *)sip < (char *)si + res; ++sip)
- ev_feed_signal_event (EV_A_ sip->ssi_signo);
-
- if (res < (ssize_t)sizeof (si))
- break;
- }
-}
-#endif
-
-#endif
-
-/*****************************************************************************/
-
-#if EV_CHILD_ENABLE
-static WL childs [EV_PID_HASHSIZE];
-
-static ev_signal childev;
-
-#ifndef WIFCONTINUED
-# define WIFCONTINUED(status) 0
-#endif
-
-/* handle a single child status event */
-inline_speed void
-child_reap (EV_P_ int chain, int pid, int status)
-{
- ev_child *w;
- int traced = WIFSTOPPED (status) || WIFCONTINUED (status);
-
- for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
- {
- if ((w->pid == pid || !w->pid)
- && (!traced || (w->flags & 1)))
- {
- ev_set_priority (w, EV_MAXPRI); /* need to do it *now*, this *must* be the same prio as the signal watcher itself */
- w->rpid = pid;
- w->rstatus = status;
- ev_feed_event (EV_A_ (W)w, EV_CHILD);
- }
- }
-}
-
-#ifndef WCONTINUED
-# define WCONTINUED 0
-#endif
-
-/* called on sigchld etc., calls waitpid */
-static void
-childcb (EV_P_ ev_signal *sw, int revents)
-{
- int pid, status;
-
- /* some systems define WCONTINUED but then fail to support it (linux 2.4) */
- if (0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)))
- if (!WCONTINUED
- || errno != EINVAL
- || 0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED)))
- return;
-
- /* make sure we are called again until all children have been reaped */
- /* we need to do it this way so that the callback gets called before we continue */
- ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
-
- child_reap (EV_A_ pid, pid, status);
- if ((EV_PID_HASHSIZE) > 1)
- child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
-}
-
-#endif
-
-/*****************************************************************************/
-
-#if EV_USE_IOCP
-# include "ev_iocp.c"
-#endif
-#if EV_USE_PORT
-# include "ev_port.c"
-#endif
-#if EV_USE_KQUEUE
-# include "ev_kqueue.c"
-#endif
-#if EV_USE_EPOLL
-# include "ev_epoll.c"
-#endif
-#if EV_USE_POLL
-# include "ev_poll.c"
-#endif
-#if EV_USE_SELECT
-# include "ev_select.c"
-#endif
-
-int ecb_cold
-ev_version_major (void) EV_THROW
-{
- return EV_VERSION_MAJOR;
-}
-
-int ecb_cold
-ev_version_minor (void) EV_THROW
-{
- return EV_VERSION_MINOR;
-}
-
-/* return true if we are running with elevated privileges and should ignore env variables */
-int inline_size ecb_cold
-enable_secure (void)
-{
-#ifdef _WIN32
- return 0;
-#else
- return getuid () != geteuid ()
- || getgid () != getegid ();
-#endif
-}
-
-unsigned int ecb_cold
-ev_supported_backends (void) EV_THROW
-{
- unsigned int flags = 0;
-
- if (EV_USE_PORT ) flags |= EVBACKEND_PORT;
- if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE;
- if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL;
- if (EV_USE_POLL ) flags |= EVBACKEND_POLL;
- if (EV_USE_SELECT) flags |= EVBACKEND_SELECT;
-
- return flags;
-}
-
-unsigned int ecb_cold
-ev_recommended_backends (void) EV_THROW
-{
- unsigned int flags = ev_supported_backends ();
-
-#ifndef __NetBSD__
- /* kqueue is borked on everything but netbsd apparently */
- /* it usually doesn't work correctly on anything but sockets and pipes */
- flags &= ~EVBACKEND_KQUEUE;
-#endif
-#ifdef __APPLE__
- /* only select works correctly on that "unix-certified" platform */
- flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
- flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
-#endif
-#ifdef __FreeBSD__
- flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
-#endif
-
- return flags;
-}
-
-unsigned int ecb_cold
-ev_embeddable_backends (void) EV_THROW
-{
- int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
-
- /* epoll embeddability broken on all linux versions up to at least 2.6.23 */
- if (ev_linux_version () < 0x020620) /* disable it on linux < 2.6.32 */
- flags &= ~EVBACKEND_EPOLL;
-
- return flags;
-}
-
-unsigned int
-ev_backend (EV_P) EV_THROW
-{
- return backend;
-}
-
-#if EV_FEATURE_API
-unsigned int
-ev_iteration (EV_P) EV_THROW
-{
- return loop_count;
-}
-
-unsigned int
-ev_depth (EV_P) EV_THROW
-{
- return loop_depth;
-}
-
-void
-ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
-{
- io_blocktime = interval;
-}
-
-void
-ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
-{
- timeout_blocktime = interval;
-}
-
-void
-ev_set_userdata (EV_P_ void *data) EV_THROW
-{
- userdata = data;
-}
-
-void *
-ev_userdata (EV_P) EV_THROW
-{
- return userdata;
-}
-
-void
-ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW
-{
- invoke_cb = invoke_pending_cb;
-}
-
-void
-ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW
-{
- release_cb = release;
- acquire_cb = acquire;
-}
-#endif
-
-/* initialise a loop structure, must be zero-initialised */
-static void noinline ecb_cold
-loop_init (EV_P_ unsigned int flags) EV_THROW
-{
- if (!backend)
- {
- origflags = flags;
-
-#if EV_USE_REALTIME
- if (!have_realtime)
- {
- struct timespec ts;
-
- if (!clock_gettime (CLOCK_REALTIME, &ts))
- have_realtime = 1;
- }
-#endif
-
-#if EV_USE_MONOTONIC
- if (!have_monotonic)
- {
- struct timespec ts;
-
- if (!clock_gettime (CLOCK_MONOTONIC, &ts))
- have_monotonic = 1;
- }
-#endif
-
- /* pid check not overridable via env */
-#ifndef _WIN32
- if (flags & EVFLAG_FORKCHECK)
- curpid = getpid ();
-#endif
-
- if (!(flags & EVFLAG_NOENV)
- && !enable_secure ()
- && getenv ("LIBEV_FLAGS"))
- flags = atoi (getenv ("LIBEV_FLAGS"));
-
- ev_rt_now = ev_time ();
- mn_now = get_clock ();
- now_floor = mn_now;
- rtmn_diff = ev_rt_now - mn_now;
-#if EV_FEATURE_API
- invoke_cb = ev_invoke_pending;
-#endif
-
- io_blocktime = 0.;
- timeout_blocktime = 0.;
- backend = 0;
- backend_fd = -1;
- sig_pending = 0;
-#if EV_ASYNC_ENABLE
- async_pending = 0;
-#endif
- pipe_write_skipped = 0;
- pipe_write_wanted = 0;
- evpipe [0] = -1;
- evpipe [1] = -1;
-#if EV_USE_INOTIFY
- fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
-#endif
-#if EV_USE_SIGNALFD
- sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
-#endif
-
- if (!(flags & EVBACKEND_MASK))
- flags |= ev_recommended_backends ();
-
-#if EV_USE_IOCP
- if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
-#endif
-#if EV_USE_PORT
- if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
-#endif
-#if EV_USE_KQUEUE
- if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
-#endif
-#if EV_USE_EPOLL
- if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
-#endif
-#if EV_USE_POLL
- if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
-#endif
-#if EV_USE_SELECT
- if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
-#endif
-
- ev_prepare_init (&pending_w, pendingcb);
-
-#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
- ev_init (&pipe_w, pipecb);
- ev_set_priority (&pipe_w, EV_MAXPRI);
-#endif
- }
-}
-
-/* free up a loop structure */
-void ecb_cold
-ev_loop_destroy (EV_P)
-{
- int i;
-
-#if EV_MULTIPLICITY
- /* mimic free (0) */
- if (!EV_A)
- return;
-#endif
-
-#if EV_CLEANUP_ENABLE
- /* queue cleanup watchers (and execute them) */
- if (expect_false (cleanupcnt))
- {
- queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP);
- EV_INVOKE_PENDING;
- }
-#endif
-
-#if EV_CHILD_ENABLE
- if (ev_is_default_loop (EV_A) && ev_is_active (&childev))
- {
- ev_ref (EV_A); /* child watcher */
- ev_signal_stop (EV_A_ &childev);
- }
-#endif
-
- if (ev_is_active (&pipe_w))
- {
- /*ev_ref (EV_A);*/
- /*ev_io_stop (EV_A_ &pipe_w);*/
-
- if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]);
- if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]);
- }
-
-#if EV_USE_SIGNALFD
- if (ev_is_active (&sigfd_w))
- close (sigfd);
-#endif
-
-#if EV_USE_INOTIFY
- if (fs_fd >= 0)
- close (fs_fd);
-#endif
-
- if (backend_fd >= 0)
- close (backend_fd);
-
-#if EV_USE_IOCP
- if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
-#endif
-#if EV_USE_PORT
- if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
-#endif
-#if EV_USE_KQUEUE
- if (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
-#endif
-#if EV_USE_EPOLL
- if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
-#endif
-#if EV_USE_POLL
- if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
-#endif
-#if EV_USE_SELECT
- if (backend == EVBACKEND_SELECT) select_destroy (EV_A);
-#endif
-
- for (i = NUMPRI; i--; )
- {
- array_free (pending, [i]);
-#if EV_IDLE_ENABLE
- array_free (idle, [i]);
-#endif
- }
-
- ev_free (anfds); anfds = 0; anfdmax = 0;
-
- /* have to use the microsoft-never-gets-it-right macro */
- array_free (rfeed, EMPTY);
- array_free (fdchange, EMPTY);
- array_free (timer, EMPTY);
-#if EV_PERIODIC_ENABLE
- array_free (periodic, EMPTY);
-#endif
-#if EV_FORK_ENABLE
- array_free (fork, EMPTY);
-#endif
-#if EV_CLEANUP_ENABLE
- array_free (cleanup, EMPTY);
-#endif
- array_free (prepare, EMPTY);
- array_free (check, EMPTY);
-#if EV_ASYNC_ENABLE
- array_free (async, EMPTY);
-#endif
-
- backend = 0;
-
-#if EV_MULTIPLICITY
- if (ev_is_default_loop (EV_A))
-#endif
- ev_default_loop_ptr = 0;
-#if EV_MULTIPLICITY
- else
- ev_free (EV_A);
-#endif
-}
-
-#if EV_USE_INOTIFY
-inline_size void infy_fork (EV_P);
-#endif
-
-inline_size void
-loop_fork (EV_P)
-{
-#if EV_USE_PORT
- if (backend == EVBACKEND_PORT ) port_fork (EV_A);
-#endif
-#if EV_USE_KQUEUE
- if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A);
-#endif
-#if EV_USE_EPOLL
- if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
-#endif
-#if EV_USE_INOTIFY
- infy_fork (EV_A);
-#endif
-
-#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
- if (ev_is_active (&pipe_w))
- {
- /* pipe_write_wanted must be false now, so modifying fd vars should be safe */
-
- ev_ref (EV_A);
- ev_io_stop (EV_A_ &pipe_w);
-
- if (evpipe [0] >= 0)
- EV_WIN32_CLOSE_FD (evpipe [0]);
-
- evpipe_init (EV_A);
- /* iterate over everything, in case we missed something before */
- ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
- }
-#endif
-
- postfork = 0;
-}
-
-#if EV_MULTIPLICITY
-
-struct ev_loop * ecb_cold
-ev_loop_new (unsigned int flags) EV_THROW
-{
- EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
-
- memset (EV_A, 0, sizeof (struct ev_loop));
- loop_init (EV_A_ flags);
-
- if (ev_backend (EV_A))
- return EV_A;
-
- ev_free (EV_A);
- return 0;
-}
-
-#endif /* multiplicity */
-
-#if EV_VERIFY
-static void noinline ecb_cold
-verify_watcher (EV_P_ W w)
-{
- assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
-
- if (w->pending)
- assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
-}
-
-static void noinline ecb_cold
-verify_heap (EV_P_ ANHE *heap, int N)
-{
- int i;
-
- for (i = HEAP0; i < N + HEAP0; ++i)
- {
- assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i));
- assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i])));
- assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i]))));
-
- verify_watcher (EV_A_ (W)ANHE_w (heap [i]));
- }
-}
-
-static void noinline ecb_cold
-array_verify (EV_P_ W *ws, int cnt)
-{
- while (cnt--)
- {
- assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1));
- verify_watcher (EV_A_ ws [cnt]);
- }
-}
-#endif
-
-#if EV_FEATURE_API
-void ecb_cold
-ev_verify (EV_P) EV_THROW
-{
-#if EV_VERIFY
- int i;
- WL w, w2;
-
- assert (activecnt >= -1);
-
- assert (fdchangemax >= fdchangecnt);
- for (i = 0; i < fdchangecnt; ++i)
- assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0));
-
- assert (anfdmax >= 0);
- for (i = 0; i < anfdmax; ++i)
- {
- int j = 0;
-
- for (w = w2 = anfds [i].head; w; w = w->next)
- {
- verify_watcher (EV_A_ (W)w);
-
- if (j++ & 1)
- {
- assert (("libev: io watcher list contains a loop", w != w2));
- w2 = w2->next;
- }
-
- assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
- assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
- }
- }
-
- assert (timermax >= timercnt);
- verify_heap (EV_A_ timers, timercnt);
-
-#if EV_PERIODIC_ENABLE
- assert (periodicmax >= periodiccnt);
- verify_heap (EV_A_ periodics, periodiccnt);
-#endif
-
- for (i = NUMPRI; i--; )
- {
- assert (pendingmax [i] >= pendingcnt [i]);
-#if EV_IDLE_ENABLE
- assert (idleall >= 0);
- assert (idlemax [i] >= idlecnt [i]);
- array_verify (EV_A_ (W *)idles [i], idlecnt [i]);
-#endif
- }
-
-#if EV_FORK_ENABLE
- assert (forkmax >= forkcnt);
- array_verify (EV_A_ (W *)forks, forkcnt);
-#endif
-
-#if EV_CLEANUP_ENABLE
- assert (cleanupmax >= cleanupcnt);
- array_verify (EV_A_ (W *)cleanups, cleanupcnt);
-#endif
-
-#if EV_ASYNC_ENABLE
- assert (asyncmax >= asynccnt);
- array_verify (EV_A_ (W *)asyncs, asynccnt);
-#endif
-
-#if EV_PREPARE_ENABLE
- assert (preparemax >= preparecnt);
- array_verify (EV_A_ (W *)prepares, preparecnt);
-#endif
-
-#if EV_CHECK_ENABLE
- assert (checkmax >= checkcnt);
- array_verify (EV_A_ (W *)checks, checkcnt);
-#endif
-
-# if 0
-#if EV_CHILD_ENABLE
- for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
- for (signum = EV_NSIG - 1; signum--; ) if (signals [signum].pending)
-#endif
-# endif
-#endif
-}
-#endif
-
-#if EV_MULTIPLICITY
-struct ev_loop * ecb_cold
-#else
-int
-#endif
-ev_default_loop (unsigned int flags) EV_THROW
-{
- if (!ev_default_loop_ptr)
- {
-#if EV_MULTIPLICITY
- EV_P = ev_default_loop_ptr = &default_loop_struct;
-#else
- ev_default_loop_ptr = 1;
-#endif
-
- loop_init (EV_A_ flags);
-
- if (ev_backend (EV_A))
- {
-#if EV_CHILD_ENABLE
- ev_signal_init (&childev, childcb, SIGCHLD);
- ev_set_priority (&childev, EV_MAXPRI);
- ev_signal_start (EV_A_ &childev);
- ev_unref (EV_A); /* child watcher should not keep loop alive */
-#endif
- }
- else
- ev_default_loop_ptr = 0;
- }
-
- return ev_default_loop_ptr;
-}
-
-void
-ev_loop_fork (EV_P) EV_THROW
-{
- postfork = 1;
-}
-
-/*****************************************************************************/
-
-void
-ev_invoke (EV_P_ void *w, int revents)
-{
- EV_CB_INVOKE ((W)w, revents);
-}
-
-unsigned int
-ev_pending_count (EV_P) EV_THROW
-{
- int pri;
- unsigned int count = 0;
-
- for (pri = NUMPRI; pri--; )
- count += pendingcnt [pri];
-
- return count;
-}
-
-void noinline
-ev_invoke_pending (EV_P)
-{
- pendingpri = NUMPRI;
-
- while (pendingpri) /* pendingpri possibly gets modified in the inner loop */
- {
- --pendingpri;
-
- while (pendingcnt [pendingpri])
- {
- ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri];
-
- p->w->pending = 0;
- EV_CB_INVOKE (p->w, p->events);
- EV_FREQUENT_CHECK;
- }
- }
-}
-
-#if EV_IDLE_ENABLE
-/* make idle watchers pending. this handles the "call-idle */
-/* only when higher priorities are idle" logic */
-inline_size void
-idle_reify (EV_P)
-{
- if (expect_false (idleall))
- {
- int pri;
-
- for (pri = NUMPRI; pri--; )
- {
- if (pendingcnt [pri])
- break;
-
- if (idlecnt [pri])
- {
- queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
- break;
- }
- }
- }
-}
-#endif
-
-/* make timers pending */
-inline_size void
-timers_reify (EV_P)
-{
- EV_FREQUENT_CHECK;
-
- if (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
- {
- do
- {
- ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
-
- /*assert (("libev: inactive timer on timer heap detected", ev_is_active (w)));*/
-
- /* first reschedule or stop timer */
- if (w->repeat)
- {
- ev_at (w) += w->repeat;
- if (ev_at (w) < mn_now)
- ev_at (w) = mn_now;
-
- assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.));
-
- ANHE_at_cache (timers [HEAP0]);
- downheap (timers, timercnt, HEAP0);
- }
- else
- ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
-
- EV_FREQUENT_CHECK;
- feed_reverse (EV_A_ (W)w);
- }
- while (timercnt && ANHE_at (timers [HEAP0]) < mn_now);
-
- feed_reverse_done (EV_A_ EV_TIMER);
- }
-}
-
-#if EV_PERIODIC_ENABLE
-
-static void noinline
-periodic_recalc (EV_P_ ev_periodic *w)
-{
- ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL;
- ev_tstamp at = w->offset + interval * ev_floor ((ev_rt_now - w->offset) / interval);
-
- /* the above almost always errs on the low side */
- while (at <= ev_rt_now)
- {
- ev_tstamp nat = at + w->interval;
-
- /* when resolution fails us, we use ev_rt_now */
- if (expect_false (nat == at))
- {
- at = ev_rt_now;
- break;
- }
-
- at = nat;
- }
-
- ev_at (w) = at;
-}
-
-/* make periodics pending */
-inline_size void
-periodics_reify (EV_P)
-{
- EV_FREQUENT_CHECK;
-
- while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
- {
- do
- {
- ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
-
- /*assert (("libev: inactive timer on periodic heap detected", ev_is_active (w)));*/
-
- /* first reschedule or stop timer */
- if (w->reschedule_cb)
- {
- ev_at (w) = w->reschedule_cb (w, ev_rt_now);
-
- assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
-
- ANHE_at_cache (periodics [HEAP0]);
- downheap (periodics, periodiccnt, HEAP0);
- }
- else if (w->interval)
- {
- periodic_recalc (EV_A_ w);
- ANHE_at_cache (periodics [HEAP0]);
- downheap (periodics, periodiccnt, HEAP0);
- }
- else
- ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
-
- EV_FREQUENT_CHECK;
- feed_reverse (EV_A_ (W)w);
- }
- while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now);
-
- feed_reverse_done (EV_A_ EV_PERIODIC);
- }
-}
-
-/* simply recalculate all periodics */
-/* TODO: maybe ensure that at least one event happens when jumping forward? */
-static void noinline ecb_cold
-periodics_reschedule (EV_P)
-{
- int i;
-
- /* adjust periodics after time jump */
- for (i = HEAP0; i < periodiccnt + HEAP0; ++i)
- {
- ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]);
-
- if (w->reschedule_cb)
- ev_at (w) = w->reschedule_cb (w, ev_rt_now);
- else if (w->interval)
- periodic_recalc (EV_A_ w);
-
- ANHE_at_cache (periodics [i]);
- }
-
- reheap (periodics, periodiccnt);
-}
-#endif
-
-/* adjust all timers by a given offset */
-static void noinline ecb_cold
-timers_reschedule (EV_P_ ev_tstamp adjust)
-{
- int i;
-
- for (i = 0; i < timercnt; ++i)
- {
- ANHE *he = timers + i + HEAP0;
- ANHE_w (*he)->at += adjust;
- ANHE_at_cache (*he);
- }
-}
-
-/* fetch new monotonic and realtime times from the kernel */
-/* also detect if there was a timejump, and act accordingly */
-inline_speed void
-time_update (EV_P_ ev_tstamp max_block)
-{
-#if EV_USE_MONOTONIC
- if (expect_true (have_monotonic))
- {
- int i;
- ev_tstamp odiff = rtmn_diff;
-
- mn_now = get_clock ();
-
- /* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */
- /* interpolate in the meantime */
- if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))
- {
- ev_rt_now = rtmn_diff + mn_now;
- return;
- }
-
- now_floor = mn_now;
- ev_rt_now = ev_time ();
-
- /* loop a few times, before making important decisions.
- * on the choice of "4": one iteration isn't enough,
- * in case we get preempted during the calls to
- * ev_time and get_clock. a second call is almost guaranteed
- * to succeed in that case, though. and looping a few more times
- * doesn't hurt either as we only do this on time-jumps or
- * in the unlikely event of having been preempted here.
- */
- for (i = 4; --i; )
- {
- ev_tstamp diff;
- rtmn_diff = ev_rt_now - mn_now;
-
- diff = odiff - rtmn_diff;
-
- if (expect_true ((diff < 0. ? -diff : diff) < MIN_TIMEJUMP))
- return; /* all is well */
-
- ev_rt_now = ev_time ();
- mn_now = get_clock ();
- now_floor = mn_now;
- }
-
- /* no timer adjustment, as the monotonic clock doesn't jump */
- /* timers_reschedule (EV_A_ rtmn_diff - odiff) */
-# if EV_PERIODIC_ENABLE
- periodics_reschedule (EV_A);
-# endif
- }
- else
-#endif
- {
- ev_rt_now = ev_time ();
-
- if (expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + MIN_TIMEJUMP))
- {
- /* adjust timers. this is easy, as the offset is the same for all of them */
- timers_reschedule (EV_A_ ev_rt_now - mn_now);
-#if EV_PERIODIC_ENABLE
- periodics_reschedule (EV_A);
-#endif
- }
-
- mn_now = ev_rt_now;
- }
-}
-
-int
-ev_run (EV_P_ int flags)
-{
-#if EV_FEATURE_API
- ++loop_depth;
-#endif
-
- assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));
-
- loop_done = EVBREAK_CANCEL;
-
- EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */
-
- do
- {
-#if EV_VERIFY >= 2
- ev_verify (EV_A);
-#endif
-
-#ifndef _WIN32
- if (expect_false (curpid)) /* penalise the forking check even more */
- if (expect_false (getpid () != curpid))
- {
- curpid = getpid ();
- postfork = 1;
- }
-#endif
-
-#if EV_FORK_ENABLE
- /* we might have forked, so queue fork handlers */
- if (expect_false (postfork))
- if (forkcnt)
- {
- queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK);
- EV_INVOKE_PENDING;
- }
-#endif
-
-#if EV_PREPARE_ENABLE
- /* queue prepare watchers (and execute them) */
- if (expect_false (preparecnt))
- {
- queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE);
- EV_INVOKE_PENDING;
- }
-#endif
-
- if (expect_false (loop_done))
- break;
-
- /* we might have forked, so reify kernel state if necessary */
- if (expect_false (postfork))
- loop_fork (EV_A);
-
- /* update fd-related kernel structures */
- fd_reify (EV_A);
-
- /* calculate blocking time */
- {
- ev_tstamp waittime = 0.;
- ev_tstamp sleeptime = 0.;
-
- /* remember old timestamp for io_blocktime calculation */
- ev_tstamp prev_mn_now = mn_now;
-
- /* update time to cancel out callback processing overhead */
- time_update (EV_A_ 1e100);
-
- /* from now on, we want a pipe-wake-up */
- pipe_write_wanted = 1;
-
- ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */
-
- if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
- {
- waittime = MAX_BLOCKTIME;
-
- if (timercnt)
- {
- ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now;
- if (waittime > to) waittime = to;
- }
-
-#if EV_PERIODIC_ENABLE
- if (periodiccnt)
- {
- ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now;
- if (waittime > to) waittime = to;
- }
-#endif
-
- /* don't let timeouts decrease the waittime below timeout_blocktime */
- if (expect_false (waittime < timeout_blocktime))
- waittime = timeout_blocktime;
-
- /* at this point, we NEED to wait, so we have to ensure */
- /* to pass a minimum nonzero value to the backend */
- if (expect_false (waittime < backend_mintime))
- waittime = backend_mintime;
-
- /* extra check because io_blocktime is commonly 0 */
- if (expect_false (io_blocktime))
- {
- sleeptime = io_blocktime - (mn_now - prev_mn_now);
-
- if (sleeptime > waittime - backend_mintime)
- sleeptime = waittime - backend_mintime;
-
- if (expect_true (sleeptime > 0.))
- {
- ev_sleep (sleeptime);
- waittime -= sleeptime;
- }
- }
- }
-
-#if EV_FEATURE_API
- ++loop_count;
-#endif
- assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
- backend_poll (EV_A_ waittime);
- assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
-
- pipe_write_wanted = 0; /* just an optimisation, no fence needed */
-
- ECB_MEMORY_FENCE_ACQUIRE;
- if (pipe_write_skipped)
- {
- assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
- ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
- }
-
-
- /* update ev_rt_now, do magic */
- time_update (EV_A_ waittime + sleeptime);
- }
-
- /* queue pending timers and reschedule them */
- timers_reify (EV_A); /* relative timers called last */
-#if EV_PERIODIC_ENABLE
- periodics_reify (EV_A); /* absolute timers called first */
-#endif
-
-#if EV_IDLE_ENABLE
- /* queue idle watchers unless other events are pending */
- idle_reify (EV_A);
-#endif
-
-#if EV_CHECK_ENABLE
- /* queue check watchers, to be executed first */
- if (expect_false (checkcnt))
- queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
-#endif
-
- EV_INVOKE_PENDING;
- }
- while (expect_true (
- activecnt
- && !loop_done
- && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))
- ));
-
- if (loop_done == EVBREAK_ONE)
- loop_done = EVBREAK_CANCEL;
-
-#if EV_FEATURE_API
- --loop_depth;
-#endif
-
- return activecnt;
-}
-
-void
-ev_break (EV_P_ int how) EV_THROW
-{
- loop_done = how;
-}
-
-void
-ev_ref (EV_P) EV_THROW
-{
- ++activecnt;
-}
-
-void
-ev_unref (EV_P) EV_THROW
-{
- --activecnt;
-}
-
-void
-ev_now_update (EV_P) EV_THROW
-{
- time_update (EV_A_ 1e100);
-}
-
-void
-ev_suspend (EV_P) EV_THROW
-{
- ev_now_update (EV_A);
-}
-
-void
-ev_resume (EV_P) EV_THROW
-{
- ev_tstamp mn_prev = mn_now;
-
- ev_now_update (EV_A);
- timers_reschedule (EV_A_ mn_now - mn_prev);
-#if EV_PERIODIC_ENABLE
- /* TODO: really do this? */
- periodics_reschedule (EV_A);
-#endif
-}
-
-/*****************************************************************************/
-/* singly-linked list management, used when the expected list length is short */
-
-inline_size void
-wlist_add (WL *head, WL elem)
-{
- elem->next = *head;
- *head = elem;
-}
-
-inline_size void
-wlist_del (WL *head, WL elem)
-{
- while (*head)
- {
- if (expect_true (*head == elem))
- {
- *head = elem->next;
- break;
- }
-
- head = &(*head)->next;
- }
-}
-
-/* internal, faster, version of ev_clear_pending */
-inline_speed void
-clear_pending (EV_P_ W w)
-{
- if (w->pending)
- {
- pendings [ABSPRI (w)][w->pending - 1].w = (W)&pending_w;
- w->pending = 0;
- }
-}
-
-int
-ev_clear_pending (EV_P_ void *w) EV_THROW
-{
- W w_ = (W)w;
- int pending = w_->pending;
-
- if (expect_true (pending))
- {
- ANPENDING *p = pendings [ABSPRI (w_)] + pending - 1;
- p->w = (W)&pending_w;
- w_->pending = 0;
- return p->events;
- }
- else
- return 0;
-}
-
-inline_size void
-pri_adjust (EV_P_ W w)
-{
- int pri = ev_priority (w);
- pri = pri < EV_MINPRI ? EV_MINPRI : pri;
- pri = pri > EV_MAXPRI ? EV_MAXPRI : pri;
- ev_set_priority (w, pri);
-}
-
-inline_speed void
-ev_start (EV_P_ W w, int active)
-{
- pri_adjust (EV_A_ w);
- w->active = active;
- ev_ref (EV_A);
-}
-
-inline_size void
-ev_stop (EV_P_ W w)
-{
- ev_unref (EV_A);
- w->active = 0;
-}
-
-/*****************************************************************************/
-
-void noinline
-ev_io_start (EV_P_ ev_io *w) EV_THROW
-{
- int fd = w->fd;
-
- if (expect_false (ev_is_active (w)))
- return;
-
- assert (("libev: ev_io_start called with negative fd", fd >= 0));
- assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, 1);
- array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
- wlist_add (&anfds[fd].head, (WL)w);
-
- /* common bug, apparently */
- assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w));
-
- fd_change (EV_A_ fd, (w->events & EV__IOFDSET) | EV_ANFD_REIFY);
- w->events &= ~EV__IOFDSET;
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_io_stop (EV_P_ ev_io *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
-
- EV_FREQUENT_CHECK;
-
- wlist_del (&anfds[w->fd].head, (WL)w);
- ev_stop (EV_A_ (W)w);
-
- fd_change (EV_A_ w->fd, EV_ANFD_REIFY);
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_timer_start (EV_P_ ev_timer *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- ev_at (w) += mn_now;
-
- assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
-
- EV_FREQUENT_CHECK;
-
- ++timercnt;
- ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
- array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
- ANHE_w (timers [ev_active (w)]) = (WT)w;
- ANHE_at_cache (timers [ev_active (w)]);
- upheap (timers, ev_active (w));
-
- EV_FREQUENT_CHECK;
-
- /*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
-}
-
-void noinline
-ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
-
- --timercnt;
-
- if (expect_true (active < timercnt + HEAP0))
- {
- timers [active] = timers [timercnt + HEAP0];
- adjustheap (timers, timercnt, active);
- }
- }
-
- ev_at (w) -= mn_now;
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_timer_again (EV_P_ ev_timer *w) EV_THROW
-{
- EV_FREQUENT_CHECK;
-
- clear_pending (EV_A_ (W)w);
-
- if (ev_is_active (w))
- {
- if (w->repeat)
- {
- ev_at (w) = mn_now + w->repeat;
- ANHE_at_cache (timers [ev_active (w)]);
- adjustheap (timers, timercnt, ev_active (w));
- }
- else
- ev_timer_stop (EV_A_ w);
- }
- else if (w->repeat)
- {
- ev_at (w) = w->repeat;
- ev_timer_start (EV_A_ w);
- }
-
- EV_FREQUENT_CHECK;
-}
-
-ev_tstamp
-ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
-{
- return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
-}
-
-#if EV_PERIODIC_ENABLE
-void noinline
-ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- if (w->reschedule_cb)
- ev_at (w) = w->reschedule_cb (w, ev_rt_now);
- else if (w->interval)
- {
- assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
- periodic_recalc (EV_A_ w);
- }
- else
- ev_at (w) = w->offset;
-
- EV_FREQUENT_CHECK;
-
- ++periodiccnt;
- ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
- array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
- ANHE_w (periodics [ev_active (w)]) = (WT)w;
- ANHE_at_cache (periodics [ev_active (w)]);
- upheap (periodics, ev_active (w));
-
- EV_FREQUENT_CHECK;
-
- /*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
-}
-
-void noinline
-ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
-
- --periodiccnt;
-
- if (expect_true (active < periodiccnt + HEAP0))
- {
- periodics [active] = periodics [periodiccnt + HEAP0];
- adjustheap (periodics, periodiccnt, active);
- }
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
-{
- /* TODO: use adjustheap and recalculation */
- ev_periodic_stop (EV_A_ w);
- ev_periodic_start (EV_A_ w);
-}
-#endif
-
-#ifndef SA_RESTART
-# define SA_RESTART 0
-#endif
-
-#if EV_SIGNAL_ENABLE
-
-void noinline
-ev_signal_start (EV_P_ ev_signal *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG));
-
-#if EV_MULTIPLICITY
- assert (("libev: a signal must not be attached to two different loops",
- !signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop));
-
- signals [w->signum - 1].loop = EV_A;
- ECB_MEMORY_FENCE_RELEASE;
-#endif
-
- EV_FREQUENT_CHECK;
-
-#if EV_USE_SIGNALFD
- if (sigfd == -2)
- {
- sigfd = signalfd (-1, &sigfd_set, SFD_NONBLOCK | SFD_CLOEXEC);
- if (sigfd < 0 && errno == EINVAL)
- sigfd = signalfd (-1, &sigfd_set, 0); /* retry without flags */
-
- if (sigfd >= 0)
- {
- fd_intern (sigfd); /* doing it twice will not hurt */
-
- sigemptyset (&sigfd_set);
-
- ev_io_init (&sigfd_w, sigfdcb, sigfd, EV_READ);
- ev_set_priority (&sigfd_w, EV_MAXPRI);
- ev_io_start (EV_A_ &sigfd_w);
- ev_unref (EV_A); /* signalfd watcher should not keep loop alive */
- }
- }
-
- if (sigfd >= 0)
- {
- /* TODO: check .head */
- sigaddset (&sigfd_set, w->signum);
- sigprocmask (SIG_BLOCK, &sigfd_set, 0);
-
- signalfd (sigfd, &sigfd_set, 0);
- }
-#endif
-
- ev_start (EV_A_ (W)w, 1);
- wlist_add (&signals [w->signum - 1].head, (WL)w);
-
- if (!((WL)w)->next)
-# if EV_USE_SIGNALFD
- if (sigfd < 0) /*TODO*/
-# endif
- {
-# ifdef _WIN32
- evpipe_init (EV_A);
-
- signal (w->signum, ev_sighandler);
-# else
- struct sigaction sa;
-
- evpipe_init (EV_A);
-
- sa.sa_handler = ev_sighandler;
- sigfillset (&sa.sa_mask);
- sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
- sigaction (w->signum, &sa, 0);
-
- if (origflags & EVFLAG_NOSIGMASK)
- {
- sigemptyset (&sa.sa_mask);
- sigaddset (&sa.sa_mask, w->signum);
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
- }
-#endif
- }
-
- EV_FREQUENT_CHECK;
-}
-
-void noinline
-ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- wlist_del (&signals [w->signum - 1].head, (WL)w);
- ev_stop (EV_A_ (W)w);
-
- if (!signals [w->signum - 1].head)
- {
-#if EV_MULTIPLICITY
- signals [w->signum - 1].loop = 0; /* unattach from signal */
-#endif
-#if EV_USE_SIGNALFD
- if (sigfd >= 0)
- {
- sigset_t ss;
-
- sigemptyset (&ss);
- sigaddset (&ss, w->signum);
- sigdelset (&sigfd_set, w->signum);
-
- signalfd (sigfd, &sigfd_set, 0);
- sigprocmask (SIG_UNBLOCK, &ss, 0);
- }
- else
-#endif
- signal (w->signum, SIG_DFL);
- }
-
- EV_FREQUENT_CHECK;
-}
-
-#endif
-
-#if EV_CHILD_ENABLE
-
-void
-ev_child_start (EV_P_ ev_child *w) EV_THROW
-{
-#if EV_MULTIPLICITY
- assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
-#endif
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, 1);
- wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_child_stop (EV_P_ ev_child *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-#endif
-
-#if EV_STAT_ENABLE
-
-# ifdef _WIN32
-# undef lstat
-# define lstat(a,b) _stati64 (a,b)
-# endif
-
-#define DEF_STAT_INTERVAL 5.0074891
-#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */
-#define MIN_STAT_INTERVAL 0.1074891
-
-static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
-
-#if EV_USE_INOTIFY
-
-/* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
-# define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX)
-
-static void noinline
-infy_add (EV_P_ ev_stat *w)
-{
- w->wd = inotify_add_watch (fs_fd, w->path,
- IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY
- | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
- | IN_DONT_FOLLOW | IN_MASK_ADD);
-
- if (w->wd >= 0)
- {
- struct statfs sfs;
-
- /* now local changes will be tracked by inotify, but remote changes won't */
- /* unless the filesystem is known to be local, we therefore still poll */
- /* also do poll on <2.6.25, but with normal frequency */
-
- if (!fs_2625)
- w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
- else if (!statfs (w->path, &sfs)
- && (sfs.f_type == 0x1373 /* devfs */
- || sfs.f_type == 0x4006 /* fat */
- || sfs.f_type == 0x4d44 /* msdos */
- || sfs.f_type == 0xEF53 /* ext2/3 */
- || sfs.f_type == 0x72b6 /* jffs2 */
- || sfs.f_type == 0x858458f6 /* ramfs */
- || sfs.f_type == 0x5346544e /* ntfs */
- || sfs.f_type == 0x3153464a /* jfs */
- || sfs.f_type == 0x9123683e /* btrfs */
- || sfs.f_type == 0x52654973 /* reiser3 */
- || sfs.f_type == 0x01021994 /* tmpfs */
- || sfs.f_type == 0x58465342 /* xfs */))
- w->timer.repeat = 0.; /* filesystem is local, kernel new enough */
- else
- w->timer.repeat = w->interval ? w->interval : NFS_STAT_INTERVAL; /* remote, use reduced frequency */
- }
- else
- {
- /* can't use inotify, continue to stat */
- w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
-
- /* if path is not there, monitor some parent directory for speedup hints */
- /* note that exceeding the hardcoded path limit is not a correctness issue, */
- /* but an efficiency issue only */
- if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096)
- {
- char path [4096];
- strcpy (path, w->path);
-
- do
- {
- int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF
- | (errno == EACCES ? IN_ATTRIB : IN_CREATE | IN_MOVED_TO);
-
- char *pend = strrchr (path, '/');
-
- if (!pend || pend == path)
- break;
-
- *pend = 0;
- w->wd = inotify_add_watch (fs_fd, path, mask);
- }
- while (w->wd < 0 && (errno == ENOENT || errno == EACCES));
- }
- }
-
- if (w->wd >= 0)
- wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
-
- /* now re-arm timer, if required */
- if (ev_is_active (&w->timer)) ev_ref (EV_A);
- ev_timer_again (EV_A_ &w->timer);
- if (ev_is_active (&w->timer)) ev_unref (EV_A);
-}
-
-static void noinline
-infy_del (EV_P_ ev_stat *w)
-{
- int slot;
- int wd = w->wd;
-
- if (wd < 0)
- return;
-
- w->wd = -2;
- slot = wd & ((EV_INOTIFY_HASHSIZE) - 1);
- wlist_del (&fs_hash [slot].head, (WL)w);
-
- /* remove this watcher, if others are watching it, they will rearm */
- inotify_rm_watch (fs_fd, wd);
-}
-
-static void noinline
-infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
-{
- if (slot < 0)
- /* overflow, need to check for all hash slots */
- for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
- infy_wd (EV_A_ slot, wd, ev);
- else
- {
- WL w_;
-
- for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; )
- {
- ev_stat *w = (ev_stat *)w_;
- w_ = w_->next; /* lets us remove this watcher and all before it */
-
- if (w->wd == wd || wd == -1)
- {
- if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF))
- {
- wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
- w->wd = -1;
- infy_add (EV_A_ w); /* re-add, no matter what */
- }
-
- stat_timer_cb (EV_A_ &w->timer, 0);
- }
- }
- }
-}
-
-static void
-infy_cb (EV_P_ ev_io *w, int revents)
-{
- char buf [EV_INOTIFY_BUFSIZE];
- int ofs;
- int len = read (fs_fd, buf, sizeof (buf));
-
- for (ofs = 0; ofs < len; )
- {
- struct inotify_event *ev = (struct inotify_event *)(buf + ofs);
- infy_wd (EV_A_ ev->wd, ev->wd, ev);
- ofs += sizeof (struct inotify_event) + ev->len;
- }
-}
-
-inline_size void ecb_cold
-ev_check_2625 (EV_P)
-{
- /* kernels < 2.6.25 are borked
- * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html
- */
- if (ev_linux_version () < 0x020619)
- return;
-
- fs_2625 = 1;
-}
-
-inline_size int
-infy_newfd (void)
-{
-#if defined IN_CLOEXEC && defined IN_NONBLOCK
- int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK);
- if (fd >= 0)
- return fd;
-#endif
- return inotify_init ();
-}
-
-inline_size void
-infy_init (EV_P)
-{
- if (fs_fd != -2)
- return;
-
- fs_fd = -1;
-
- ev_check_2625 (EV_A);
-
- fs_fd = infy_newfd ();
-
- if (fs_fd >= 0)
- {
- fd_intern (fs_fd);
- ev_io_init (&fs_w, infy_cb, fs_fd, EV_READ);
- ev_set_priority (&fs_w, EV_MAXPRI);
- ev_io_start (EV_A_ &fs_w);
- ev_unref (EV_A);
- }
-}
-
-inline_size void
-infy_fork (EV_P)
-{
- int slot;
-
- if (fs_fd < 0)
- return;
-
- ev_ref (EV_A);
- ev_io_stop (EV_A_ &fs_w);
- close (fs_fd);
- fs_fd = infy_newfd ();
-
- if (fs_fd >= 0)
- {
- fd_intern (fs_fd);
- ev_io_set (&fs_w, fs_fd, EV_READ);
- ev_io_start (EV_A_ &fs_w);
- ev_unref (EV_A);
- }
-
- for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
- {
- WL w_ = fs_hash [slot].head;
- fs_hash [slot].head = 0;
-
- while (w_)
- {
- ev_stat *w = (ev_stat *)w_;
- w_ = w_->next; /* lets us add this watcher */
-
- w->wd = -1;
-
- if (fs_fd >= 0)
- infy_add (EV_A_ w); /* re-add, no matter what */
- else
- {
- w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
- if (ev_is_active (&w->timer)) ev_ref (EV_A);
- ev_timer_again (EV_A_ &w->timer);
- if (ev_is_active (&w->timer)) ev_unref (EV_A);
- }
- }
- }
-}
-
-#endif
-
-#ifdef _WIN32
-# define EV_LSTAT(p,b) _stati64 (p, b)
-#else
-# define EV_LSTAT(p,b) lstat (p, b)
-#endif
-
-void
-ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
-{
- if (lstat (w->path, &w->attr) < 0)
- w->attr.st_nlink = 0;
- else if (!w->attr.st_nlink)
- w->attr.st_nlink = 1;
-}
-
-static void noinline
-stat_timer_cb (EV_P_ ev_timer *w_, int revents)
-{
- ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));
-
- ev_statdata prev = w->attr;
- ev_stat_stat (EV_A_ w);
-
- /* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */
- if (
- prev.st_dev != w->attr.st_dev
- || prev.st_ino != w->attr.st_ino
- || prev.st_mode != w->attr.st_mode
- || prev.st_nlink != w->attr.st_nlink
- || prev.st_uid != w->attr.st_uid
- || prev.st_gid != w->attr.st_gid
- || prev.st_rdev != w->attr.st_rdev
- || prev.st_size != w->attr.st_size
- || prev.st_atime != w->attr.st_atime
- || prev.st_mtime != w->attr.st_mtime
- || prev.st_ctime != w->attr.st_ctime
- ) {
- /* we only update w->prev on actual differences */
- /* in case we test more often than invoke the callback, */
- /* to ensure that prev is always different to attr */
- w->prev = prev;
-
- #if EV_USE_INOTIFY
- if (fs_fd >= 0)
- {
- infy_del (EV_A_ w);
- infy_add (EV_A_ w);
- ev_stat_stat (EV_A_ w); /* avoid race... */
- }
- #endif
-
- ev_feed_event (EV_A_ w, EV_STAT);
- }
-}
-
-void
-ev_stat_start (EV_P_ ev_stat *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- ev_stat_stat (EV_A_ w);
-
- if (w->interval < MIN_STAT_INTERVAL && w->interval)
- w->interval = MIN_STAT_INTERVAL;
-
- ev_timer_init (&w->timer, stat_timer_cb, 0., w->interval ? w->interval : DEF_STAT_INTERVAL);
- ev_set_priority (&w->timer, ev_priority (w));
-
-#if EV_USE_INOTIFY
- infy_init (EV_A);
-
- if (fs_fd >= 0)
- infy_add (EV_A_ w);
- else
-#endif
- {
- ev_timer_again (EV_A_ &w->timer);
- ev_unref (EV_A);
- }
-
- ev_start (EV_A_ (W)w, 1);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
-#if EV_USE_INOTIFY
- infy_del (EV_A_ w);
-#endif
-
- if (ev_is_active (&w->timer))
- {
- ev_ref (EV_A);
- ev_timer_stop (EV_A_ &w->timer);
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_IDLE_ENABLE
-void
-ev_idle_start (EV_P_ ev_idle *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- pri_adjust (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ++idlecnt [ABSPRI (w)];
-
- ++idleall;
- ev_start (EV_A_ (W)w, active);
-
- array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
- idles [ABSPRI (w)][active - 1] = w;
- }
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]];
- ev_active (idles [ABSPRI (w)][active - 1]) = active;
-
- ev_stop (EV_A_ (W)w);
- --idleall;
- }
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_PREPARE_ENABLE
-void
-ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++preparecnt);
- array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
- prepares [preparecnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- prepares [active - 1] = prepares [--preparecnt];
- ev_active (prepares [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_CHECK_ENABLE
-void
-ev_check_start (EV_P_ ev_check *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++checkcnt);
- array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
- checks [checkcnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_check_stop (EV_P_ ev_check *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- checks [active - 1] = checks [--checkcnt];
- ev_active (checks [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_EMBED_ENABLE
-void noinline
-ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW
-{
- ev_run (w->other, EVRUN_NOWAIT);
-}
-
-static void
-embed_io_cb (EV_P_ ev_io *io, int revents)
-{
- ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io));
-
- if (ev_cb (w))
- ev_feed_event (EV_A_ (W)w, EV_EMBED);
- else
- ev_run (w->other, EVRUN_NOWAIT);
-}
-
-static void
-embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
-{
- ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare));
-
- {
- EV_P = w->other;
-
- while (fdchangecnt)
- {
- fd_reify (EV_A);
- ev_run (EV_A_ EVRUN_NOWAIT);
- }
- }
-}
-
-static void
-embed_fork_cb (EV_P_ ev_fork *fork_w, int revents)
-{
- ev_embed *w = (ev_embed *)(((char *)fork_w) - offsetof (ev_embed, fork));
-
- ev_embed_stop (EV_A_ w);
-
- {
- EV_P = w->other;
-
- ev_loop_fork (EV_A);
- ev_run (EV_A_ EVRUN_NOWAIT);
- }
-
- ev_embed_start (EV_A_ w);
-}
-
-#if 0
-static void
-embed_idle_cb (EV_P_ ev_idle *idle, int revents)
-{
- ev_idle_stop (EV_A_ idle);
-}
-#endif
-
-void
-ev_embed_start (EV_P_ ev_embed *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- {
- EV_P = w->other;
- assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
- ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
- }
-
- EV_FREQUENT_CHECK;
-
- ev_set_priority (&w->io, ev_priority (w));
- ev_io_start (EV_A_ &w->io);
-
- ev_prepare_init (&w->prepare, embed_prepare_cb);
- ev_set_priority (&w->prepare, EV_MINPRI);
- ev_prepare_start (EV_A_ &w->prepare);
-
- ev_fork_init (&w->fork, embed_fork_cb);
- ev_fork_start (EV_A_ &w->fork);
-
- /*ev_idle_init (&w->idle, e,bed_idle_cb);*/
-
- ev_start (EV_A_ (W)w, 1);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_io_stop (EV_A_ &w->io);
- ev_prepare_stop (EV_A_ &w->prepare);
- ev_fork_stop (EV_A_ &w->fork);
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_FORK_ENABLE
-void
-ev_fork_start (EV_P_ ev_fork *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++forkcnt);
- array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
- forks [forkcnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- forks [active - 1] = forks [--forkcnt];
- ev_active (forks [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_CLEANUP_ENABLE
-void
-ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++cleanupcnt);
- array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2);
- cleanups [cleanupcnt - 1] = w;
-
- /* cleanup watchers should never keep a refcount on the loop */
- ev_unref (EV_A);
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
- ev_ref (EV_A);
-
- {
- int active = ev_active (w);
-
- cleanups [active - 1] = cleanups [--cleanupcnt];
- ev_active (cleanups [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-#endif
-
-#if EV_ASYNC_ENABLE
-void
-ev_async_start (EV_P_ ev_async *w) EV_THROW
-{
- if (expect_false (ev_is_active (w)))
- return;
-
- w->sent = 0;
-
- evpipe_init (EV_A);
-
- EV_FREQUENT_CHECK;
-
- ev_start (EV_A_ (W)w, ++asynccnt);
- array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
- asyncs [asynccnt - 1] = w;
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_async_stop (EV_P_ ev_async *w) EV_THROW
-{
- clear_pending (EV_A_ (W)w);
- if (expect_false (!ev_is_active (w)))
- return;
-
- EV_FREQUENT_CHECK;
-
- {
- int active = ev_active (w);
-
- asyncs [active - 1] = asyncs [--asynccnt];
- ev_active (asyncs [active - 1]) = active;
- }
-
- ev_stop (EV_A_ (W)w);
-
- EV_FREQUENT_CHECK;
-}
-
-void
-ev_async_send (EV_P_ ev_async *w) EV_THROW
-{
- w->sent = 1;
- evpipe_write (EV_A_ &async_pending);
-}
-#endif
-
-/*****************************************************************************/
-
-struct ev_once
-{
- ev_io io;
- ev_timer to;
- void (*cb)(int revents, void *arg);
- void *arg;
-};
-
-static void
-once_cb (EV_P_ struct ev_once *once, int revents)
-{
- void (*cb)(int revents, void *arg) = once->cb;
- void *arg = once->arg;
-
- ev_io_stop (EV_A_ &once->io);
- ev_timer_stop (EV_A_ &once->to);
- ev_free (once);
-
- cb (revents, arg);
-}
-
-static void
-once_cb_io (EV_P_ ev_io *w, int revents)
-{
- struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, io));
-
- once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->to));
-}
-
-static void
-once_cb_to (EV_P_ ev_timer *w, int revents)
-{
- struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, to));
-
- once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->io));
-}
-
-void
-ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW
-{
- struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
-
- if (expect_false (!once))
- {
- cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
- return;
- }
-
- once->cb = cb;
- once->arg = arg;
-
- ev_init (&once->io, once_cb_io);
- if (fd >= 0)
- {
- ev_io_set (&once->io, fd, events);
- ev_io_start (EV_A_ &once->io);
- }
-
- ev_init (&once->to, once_cb_to);
- if (timeout >= 0.)
- {
- ev_timer_set (&once->to, timeout, 0.);
- ev_timer_start (EV_A_ &once->to);
- }
-}
-
-/*****************************************************************************/
-
-#if EV_WALK_ENABLE
-void ecb_cold
-ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW
-{
- int i, j;
- ev_watcher_list *wl, *wn;
-
- if (types & (EV_IO | EV_EMBED))
- for (i = 0; i < anfdmax; ++i)
- for (wl = anfds [i].head; wl; )
- {
- wn = wl->next;
-
-#if EV_EMBED_ENABLE
- if (ev_cb ((ev_io *)wl) == embed_io_cb)
- {
- if (types & EV_EMBED)
- cb (EV_A_ EV_EMBED, ((char *)wl) - offsetof (struct ev_embed, io));
- }
- else
-#endif
-#if EV_USE_INOTIFY
- if (ev_cb ((ev_io *)wl) == infy_cb)
- ;
- else
-#endif
- if ((ev_io *)wl != &pipe_w)
- if (types & EV_IO)
- cb (EV_A_ EV_IO, wl);
-
- wl = wn;
- }
-
- if (types & (EV_TIMER | EV_STAT))
- for (i = timercnt + HEAP0; i-- > HEAP0; )
-#if EV_STAT_ENABLE
- /*TODO: timer is not always active*/
- if (ev_cb ((ev_timer *)ANHE_w (timers [i])) == stat_timer_cb)
- {
- if (types & EV_STAT)
- cb (EV_A_ EV_STAT, ((char *)ANHE_w (timers [i])) - offsetof (struct ev_stat, timer));
- }
- else
-#endif
- if (types & EV_TIMER)
- cb (EV_A_ EV_TIMER, ANHE_w (timers [i]));
-
-#if EV_PERIODIC_ENABLE
- if (types & EV_PERIODIC)
- for (i = periodiccnt + HEAP0; i-- > HEAP0; )
- cb (EV_A_ EV_PERIODIC, ANHE_w (periodics [i]));
-#endif
-
-#if EV_IDLE_ENABLE
- if (types & EV_IDLE)
- for (j = NUMPRI; j--; )
- for (i = idlecnt [j]; i--; )
- cb (EV_A_ EV_IDLE, idles [j][i]);
-#endif
-
-#if EV_FORK_ENABLE
- if (types & EV_FORK)
- for (i = forkcnt; i--; )
- if (ev_cb (forks [i]) != embed_fork_cb)
- cb (EV_A_ EV_FORK, forks [i]);
-#endif
-
-#if EV_ASYNC_ENABLE
- if (types & EV_ASYNC)
- for (i = asynccnt; i--; )
- cb (EV_A_ EV_ASYNC, asyncs [i]);
-#endif
-
-#if EV_PREPARE_ENABLE
- if (types & EV_PREPARE)
- for (i = preparecnt; i--; )
-# if EV_EMBED_ENABLE
- if (ev_cb (prepares [i]) != embed_prepare_cb)
-# endif
- cb (EV_A_ EV_PREPARE, prepares [i]);
-#endif
-
-#if EV_CHECK_ENABLE
- if (types & EV_CHECK)
- for (i = checkcnt; i--; )
- cb (EV_A_ EV_CHECK, checks [i]);
-#endif
-
-#if EV_SIGNAL_ENABLE
- if (types & EV_SIGNAL)
- for (i = 0; i < EV_NSIG - 1; ++i)
- for (wl = signals [i].head; wl; )
- {
- wn = wl->next;
- cb (EV_A_ EV_SIGNAL, wl);
- wl = wn;
- }
-#endif
-
-#if EV_CHILD_ENABLE
- if (types & EV_CHILD)
- for (i = (EV_PID_HASHSIZE); i--; )
- for (wl = childs [i]; wl; )
- {
- wn = wl->next;
- cb (EV_A_ EV_CHILD, wl);
- wl = wn;
- }
-#endif
-/* EV_STAT 0x00001000 * stat data changed */
-/* EV_EMBED 0x00010000 * embedded event loop needs sweep */
-}
-#endif
-
-#if EV_MULTIPLICITY
- #include "ev_wrap.h"
-#endif
-
diff --git a/framework/src/audit/src/libev/ev.h b/framework/src/audit/src/libev/ev.h
deleted file mode 100644
index 7c6e7eb8..00000000
--- a/framework/src/audit/src/libev/ev.h
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * libev native API header
- *
- * Copyright (c) 2007,2008,2009,2010,2011,2012,2015 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef EV_H_
-#define EV_H_
-
-#ifdef __cplusplus
-# define EV_CPP(x) x
-# if __cplusplus >= 201103L
-# define EV_THROW noexcept
-# else
-# define EV_THROW throw ()
-# endif
-#else
-# define EV_CPP(x)
-# define EV_THROW
-#endif
-
-EV_CPP(extern "C" {)
-
-/*****************************************************************************/
-
-/* pre-4.0 compatibility */
-#ifndef EV_COMPAT3
-# define EV_COMPAT3 1
-#endif
-
-#ifndef EV_FEATURES
-# if defined __OPTIMIZE_SIZE__
-# define EV_FEATURES 0x7c
-# else
-# define EV_FEATURES 0x7f
-# endif
-#endif
-
-#define EV_FEATURE_CODE ((EV_FEATURES) & 1)
-#define EV_FEATURE_DATA ((EV_FEATURES) & 2)
-#define EV_FEATURE_CONFIG ((EV_FEATURES) & 4)
-#define EV_FEATURE_API ((EV_FEATURES) & 8)
-#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
-#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
-#define EV_FEATURE_OS ((EV_FEATURES) & 64)
-
-/* these priorities are inclusive, higher priorities will be invoked earlier */
-#ifndef EV_MINPRI
-# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
-#endif
-#ifndef EV_MAXPRI
-# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
-#endif
-
-#ifndef EV_MULTIPLICITY
-# define EV_MULTIPLICITY EV_FEATURE_CONFIG
-#endif
-
-#ifndef EV_PERIODIC_ENABLE
-# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_STAT_ENABLE
-# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_PREPARE_ENABLE
-# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_CHECK_ENABLE
-# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_IDLE_ENABLE
-# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_FORK_ENABLE
-# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_CLEANUP_ENABLE
-# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_SIGNAL_ENABLE
-# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_CHILD_ENABLE
-# ifdef _WIN32
-# define EV_CHILD_ENABLE 0
-# else
-# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
-#endif
-#endif
-
-#ifndef EV_ASYNC_ENABLE
-# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_EMBED_ENABLE
-# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
-#endif
-
-#ifndef EV_WALK_ENABLE
-# define EV_WALK_ENABLE 0 /* not yet */
-#endif
-
-/*****************************************************************************/
-
-#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
-# undef EV_SIGNAL_ENABLE
-# define EV_SIGNAL_ENABLE 1
-#endif
-
-/*****************************************************************************/
-
-typedef double ev_tstamp;
-
-#include <string.h> /* for memmove */
-
-#ifndef EV_ATOMIC_T
-# include <signal.h>
-# define EV_ATOMIC_T sig_atomic_t volatile
-#endif
-
-#if EV_STAT_ENABLE
-# ifdef _WIN32
-# include <time.h>
-# include <sys/types.h>
-# endif
-# include <sys/stat.h>
-#endif
-
-/* support multiple event loops? */
-#if EV_MULTIPLICITY
-struct ev_loop;
-# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
-# define EV_P_ EV_P, /* a loop as first of multiple parameters */
-# define EV_A loop /* a loop as sole argument to a function call */
-# define EV_A_ EV_A, /* a loop as first of multiple arguments */
-# define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */
-# define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */
-# define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */
-# define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */
-#else
-# define EV_P void
-# define EV_P_
-# define EV_A
-# define EV_A_
-# define EV_DEFAULT
-# define EV_DEFAULT_
-# define EV_DEFAULT_UC
-# define EV_DEFAULT_UC_
-# undef EV_EMBED_ENABLE
-#endif
-
-/* EV_INLINE is used for functions in header files */
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
-# define EV_INLINE static inline
-#else
-# define EV_INLINE static
-#endif
-
-#ifdef EV_API_STATIC
-# define EV_API_DECL static
-#else
-# define EV_API_DECL extern
-#endif
-
-/* EV_PROTOTYPES can be used to switch of prototype declarations */
-#ifndef EV_PROTOTYPES
-# define EV_PROTOTYPES 1
-#endif
-
-/*****************************************************************************/
-
-#define EV_VERSION_MAJOR 4
-#define EV_VERSION_MINOR 20
-
-/* eventmask, revents, events... */
-enum {
- EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */
- EV_NONE = 0x00, /* no events */
- EV_READ = 0x01, /* ev_io detected read will not block */
- EV_WRITE = 0x02, /* ev_io detected write will not block */
- EV__IOFDSET = 0x80, /* internal use only */
- EV_IO = EV_READ, /* alias for type-detection */
- EV_TIMER = 0x00000100, /* timer timed out */
-#if EV_COMPAT3
- EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
-#endif
- EV_PERIODIC = 0x00000200, /* periodic timer timed out */
- EV_SIGNAL = 0x00000400, /* signal was received */
- EV_CHILD = 0x00000800, /* child/pid had status change */
- EV_STAT = 0x00001000, /* stat data changed */
- EV_IDLE = 0x00002000, /* event loop is idling */
- EV_PREPARE = 0x00004000, /* event loop about to poll */
- EV_CHECK = 0x00008000, /* event loop finished poll */
- EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
- EV_FORK = 0x00020000, /* event loop resumed in child */
- EV_CLEANUP = 0x00040000, /* event loop resumed in child */
- EV_ASYNC = 0x00080000, /* async intra-loop signal */
- EV_CUSTOM = 0x01000000, /* for use by user code */
- EV_ERROR = (int)0x80000000 /* sent when an error occurs */
-};
-
-/* can be used to add custom fields to all watchers, while losing binary compatibility */
-#ifndef EV_COMMON
-# define EV_COMMON void *data;
-#endif
-
-#ifndef EV_CB_DECLARE
-# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
-#endif
-#ifndef EV_CB_INVOKE
-# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
-#endif
-
-/* not official, do not use */
-#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
-
-/*
- * struct member types:
- * private: you may look at them, but not change them,
- * and they might not mean anything to you.
- * ro: can be read anytime, but only changed when the watcher isn't active.
- * rw: can be read and modified anytime, even when the watcher is active.
- *
- * some internal details that might be helpful for debugging:
- *
- * active is either 0, which means the watcher is not active,
- * or the array index of the watcher (periodics, timers)
- * or the array index + 1 (most other watchers)
- * or simply 1 for watchers that aren't in some array.
- * pending is either 0, in which case the watcher isn't,
- * or the array index + 1 in the pendings array.
- */
-
-#if EV_MINPRI == EV_MAXPRI
-# define EV_DECL_PRIORITY
-#elif !defined (EV_DECL_PRIORITY)
-# define EV_DECL_PRIORITY int priority;
-#endif
-
-/* shared by all watchers */
-#define EV_WATCHER(type) \
- int active; /* private */ \
- int pending; /* private */ \
- EV_DECL_PRIORITY /* private */ \
- EV_COMMON /* rw */ \
- EV_CB_DECLARE (type) /* private */
-
-#define EV_WATCHER_LIST(type) \
- EV_WATCHER (type) \
- struct ev_watcher_list *next; /* private */
-
-#define EV_WATCHER_TIME(type) \
- EV_WATCHER (type) \
- ev_tstamp at; /* private */
-
-/* base class, nothing to see here unless you subclass */
-typedef struct ev_watcher
-{
- EV_WATCHER (ev_watcher)
-} ev_watcher;
-
-/* base class, nothing to see here unless you subclass */
-typedef struct ev_watcher_list
-{
- EV_WATCHER_LIST (ev_watcher_list)
-} ev_watcher_list;
-
-/* base class, nothing to see here unless you subclass */
-typedef struct ev_watcher_time
-{
- EV_WATCHER_TIME (ev_watcher_time)
-} ev_watcher_time;
-
-/* invoked when fd is either EV_READable or EV_WRITEable */
-/* revent EV_READ, EV_WRITE */
-typedef struct ev_io
-{
- EV_WATCHER_LIST (ev_io)
-
- int fd; /* ro */
- int events; /* ro */
-} ev_io;
-
-/* invoked after a specific time, repeatable (based on monotonic clock) */
-/* revent EV_TIMEOUT */
-typedef struct ev_timer
-{
- EV_WATCHER_TIME (ev_timer)
-
- ev_tstamp repeat; /* rw */
-} ev_timer;
-
-/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
-/* revent EV_PERIODIC */
-typedef struct ev_periodic
-{
- EV_WATCHER_TIME (ev_periodic)
-
- ev_tstamp offset; /* rw */
- ev_tstamp interval; /* rw */
- ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
-} ev_periodic;
-
-/* invoked when the given signal has been received */
-/* revent EV_SIGNAL */
-typedef struct ev_signal
-{
- EV_WATCHER_LIST (ev_signal)
-
- int signum; /* ro */
-} ev_signal;
-
-/* invoked when sigchld is received and waitpid indicates the given pid */
-/* revent EV_CHILD */
-/* does not support priorities */
-typedef struct ev_child
-{
- EV_WATCHER_LIST (ev_child)
-
- int flags; /* private */
- int pid; /* ro */
- int rpid; /* rw, holds the received pid */
- int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
-} ev_child;
-
-#if EV_STAT_ENABLE
-/* st_nlink = 0 means missing file or other error */
-# ifdef _WIN32
-typedef struct _stati64 ev_statdata;
-# else
-typedef struct stat ev_statdata;
-# endif
-
-/* invoked each time the stat data changes for a given path */
-/* revent EV_STAT */
-typedef struct ev_stat
-{
- EV_WATCHER_LIST (ev_stat)
-
- ev_timer timer; /* private */
- ev_tstamp interval; /* ro */
- const char *path; /* ro */
- ev_statdata prev; /* ro */
- ev_statdata attr; /* ro */
-
- int wd; /* wd for inotify, fd for kqueue */
-} ev_stat;
-#endif
-
-#if EV_IDLE_ENABLE
-/* invoked when the nothing else needs to be done, keeps the process from blocking */
-/* revent EV_IDLE */
-typedef struct ev_idle
-{
- EV_WATCHER (ev_idle)
-} ev_idle;
-#endif
-
-/* invoked for each run of the mainloop, just before the blocking call */
-/* you can still change events in any way you like */
-/* revent EV_PREPARE */
-typedef struct ev_prepare
-{
- EV_WATCHER (ev_prepare)
-} ev_prepare;
-
-/* invoked for each run of the mainloop, just after the blocking call */
-/* revent EV_CHECK */
-typedef struct ev_check
-{
- EV_WATCHER (ev_check)
-} ev_check;
-
-#if EV_FORK_ENABLE
-/* the callback gets invoked before check in the child process when a fork was detected */
-/* revent EV_FORK */
-typedef struct ev_fork
-{
- EV_WATCHER (ev_fork)
-} ev_fork;
-#endif
-
-#if EV_CLEANUP_ENABLE
-/* is invoked just before the loop gets destroyed */
-/* revent EV_CLEANUP */
-typedef struct ev_cleanup
-{
- EV_WATCHER (ev_cleanup)
-} ev_cleanup;
-#endif
-
-#if EV_EMBED_ENABLE
-/* used to embed an event loop inside another */
-/* the callback gets invoked when the event loop has handled events, and can be 0 */
-typedef struct ev_embed
-{
- EV_WATCHER (ev_embed)
-
- struct ev_loop *other; /* ro */
- ev_io io; /* private */
- ev_prepare prepare; /* private */
- ev_check check; /* unused */
- ev_timer timer; /* unused */
- ev_periodic periodic; /* unused */
- ev_idle idle; /* unused */
- ev_fork fork; /* private */
-#if EV_CLEANUP_ENABLE
- ev_cleanup cleanup; /* unused */
-#endif
-} ev_embed;
-#endif
-
-#if EV_ASYNC_ENABLE
-/* invoked when somebody calls ev_async_send on the watcher */
-/* revent EV_ASYNC */
-typedef struct ev_async
-{
- EV_WATCHER (ev_async)
-
- EV_ATOMIC_T sent; /* private */
-} ev_async;
-
-# define ev_async_pending(w) (+(w)->sent)
-#endif
-
-/* the presence of this union forces similar struct layout */
-union ev_any_watcher
-{
- struct ev_watcher w;
- struct ev_watcher_list wl;
-
- struct ev_io io;
- struct ev_timer timer;
- struct ev_periodic periodic;
- struct ev_signal signal;
- struct ev_child child;
-#if EV_STAT_ENABLE
- struct ev_stat stat;
-#endif
-#if EV_IDLE_ENABLE
- struct ev_idle idle;
-#endif
- struct ev_prepare prepare;
- struct ev_check check;
-#if EV_FORK_ENABLE
- struct ev_fork fork;
-#endif
-#if EV_CLEANUP_ENABLE
- struct ev_cleanup cleanup;
-#endif
-#if EV_EMBED_ENABLE
- struct ev_embed embed;
-#endif
-#if EV_ASYNC_ENABLE
- struct ev_async async;
-#endif
-};
-
-/* flag bits for ev_default_loop and ev_loop_new */
-enum {
- /* the default */
- EVFLAG_AUTO = 0x00000000U, /* not quite a mask */
- /* flag bits */
- EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */
- EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
- /* debugging/feature disable */
- EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
-#if EV_COMPAT3
- EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */
-#endif
- EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */
- EVFLAG_NOSIGMASK = 0x00400000U /* avoid modifying the signal mask */
-};
-
-/* method bits to be ored together */
-enum {
- EVBACKEND_SELECT = 0x00000001U, /* about anywhere */
- EVBACKEND_POLL = 0x00000002U, /* !win */
- EVBACKEND_EPOLL = 0x00000004U, /* linux */
- EVBACKEND_KQUEUE = 0x00000008U, /* bsd */
- EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
- EVBACKEND_PORT = 0x00000020U, /* solaris 10 */
- EVBACKEND_ALL = 0x0000003FU, /* all known backends */
- EVBACKEND_MASK = 0x0000FFFFU /* all future backends */
-};
-
-#if EV_PROTOTYPES
-EV_API_DECL int ev_version_major (void) EV_THROW;
-EV_API_DECL int ev_version_minor (void) EV_THROW;
-
-EV_API_DECL unsigned int ev_supported_backends (void) EV_THROW;
-EV_API_DECL unsigned int ev_recommended_backends (void) EV_THROW;
-EV_API_DECL unsigned int ev_embeddable_backends (void) EV_THROW;
-
-EV_API_DECL ev_tstamp ev_time (void) EV_THROW;
-EV_API_DECL void ev_sleep (ev_tstamp delay) EV_THROW; /* sleep for a while */
-
-/* Sets the allocation function to use, works like realloc.
- * It is used to allocate and free memory.
- * If it returns zero when memory needs to be allocated, the library might abort
- * or take some potentially destructive action.
- * The default is your system realloc function.
- */
-EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW;
-
-/* set the callback function to call on a
- * retryable syscall error
- * (such as failed select, poll, epoll_wait)
- */
-EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW;
-
-#if EV_MULTIPLICITY
-
-/* the default loop is the only one that handles signals and child watchers */
-/* you can call this as often as you like */
-EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW;
-
-#ifdef EV_API_STATIC
-EV_API_DECL struct ev_loop *ev_default_loop_ptr;
-#endif
-
-EV_INLINE struct ev_loop *
-ev_default_loop_uc_ (void) EV_THROW
-{
- extern struct ev_loop *ev_default_loop_ptr;
-
- return ev_default_loop_ptr;
-}
-
-EV_INLINE int
-ev_is_default_loop (EV_P) EV_THROW
-{
- return EV_A == EV_DEFAULT_UC;
-}
-
-/* create and destroy alternative loops that don't handle signals */
-EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_THROW;
-
-EV_API_DECL ev_tstamp ev_now (EV_P) EV_THROW; /* time w.r.t. timers and the eventloop, updated after each poll */
-
-#else
-
-EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW; /* returns true when successful */
-
-EV_API_DECL ev_tstamp ev_rt_now;
-
-EV_INLINE ev_tstamp
-ev_now (void) EV_THROW
-{
- return ev_rt_now;
-}
-
-/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
-EV_INLINE int
-ev_is_default_loop (void) EV_THROW
-{
- return 1;
-}
-
-#endif /* multiplicity */
-
-/* destroy event loops, also works for the default loop */
-EV_API_DECL void ev_loop_destroy (EV_P);
-
-/* this needs to be called after fork, to duplicate the loop */
-/* when you want to re-use it in the child */
-/* you can call it in either the parent or the child */
-/* you can actually call it at any time, anywhere :) */
-EV_API_DECL void ev_loop_fork (EV_P) EV_THROW;
-
-EV_API_DECL unsigned int ev_backend (EV_P) EV_THROW; /* backend in use by loop */
-
-EV_API_DECL void ev_now_update (EV_P) EV_THROW; /* update event loop time */
-
-#if EV_WALK_ENABLE
-/* walk (almost) all watchers in the loop of a given type, invoking the */
-/* callback on every such watcher. The callback might stop the watcher, */
-/* but do nothing else with the loop */
-EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW;
-#endif
-
-#endif /* prototypes */
-
-/* ev_run flags values */
-enum {
- EVRUN_NOWAIT = 1, /* do not block/wait */
- EVRUN_ONCE = 2 /* block *once* only */
-};
-
-/* ev_break how values */
-enum {
- EVBREAK_CANCEL = 0, /* undo unloop */
- EVBREAK_ONE = 1, /* unloop once */
- EVBREAK_ALL = 2 /* unloop all loops */
-};
-
-#if EV_PROTOTYPES
-EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0));
-EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_THROW; /* break out of the loop */
-
-/*
- * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
- * keeps one reference. if you have a long-running watcher you never unregister that
- * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
- */
-EV_API_DECL void ev_ref (EV_P) EV_THROW;
-EV_API_DECL void ev_unref (EV_P) EV_THROW;
-
-/*
- * convenience function, wait for a single event, without registering an event watcher
- * if timeout is < 0, do wait indefinitely
- */
-EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW;
-
-# if EV_FEATURE_API
-EV_API_DECL unsigned int ev_iteration (EV_P) EV_THROW; /* number of loop iterations */
-EV_API_DECL unsigned int ev_depth (EV_P) EV_THROW; /* #ev_loop enters - #ev_loop leaves */
-EV_API_DECL void ev_verify (EV_P) EV_THROW; /* abort if loop data corrupted */
-
-EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
-EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
-
-/* advanced stuff for threading etc. support, see docs */
-EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW;
-EV_API_DECL void *ev_userdata (EV_P) EV_THROW;
-typedef void (*ev_loop_callback)(EV_P);
-EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW;
-/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */
-EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW;
-
-EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */
-EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
-
-/*
- * stop/start the timer handling.
- */
-EV_API_DECL void ev_suspend (EV_P) EV_THROW;
-EV_API_DECL void ev_resume (EV_P) EV_THROW;
-#endif
-
-#endif
-
-/* these may evaluate ev multiple times, and the other arguments at most once */
-/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
-#define ev_init(ev,cb_) do { \
- ((ev_watcher *)(void *)(ev))->active = \
- ((ev_watcher *)(void *)(ev))->pending = 0; \
- ev_set_priority ((ev), 0); \
- ev_set_cb ((ev), cb_); \
-} while (0)
-
-#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
-#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
-#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
-#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
-#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
-#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
-#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
-#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */
-#define ev_async_set(ev) /* nop, yes, this is a serious in-joke */
-
-#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
-#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
-#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
-#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
-#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
-#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
-#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
-#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
-#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
-#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
-#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
-#define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
-#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
-
-#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
-#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
-
-#define ev_cb_(ev) (ev)->cb /* rw */
-#define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb)
-
-#if EV_MINPRI == EV_MAXPRI
-# define ev_priority(ev) ((ev), EV_MINPRI)
-# define ev_set_priority(ev,pri) ((ev), (pri))
-#else
-# define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority))
-# define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri)
-#endif
-
-#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
-
-#ifndef ev_set_cb
-# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
-#endif
-
-/* stopping (enabling, adding) a watcher does nothing if it is already running */
-/* stopping (disabling, deleting) a watcher does nothing unless it's already running */
-#if EV_PROTOTYPES
-
-/* feeds an event into a watcher as if the event actually occurred */
-/* accepts any ev_watcher type */
-EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_THROW;
-EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW;
-#if EV_SIGNAL_ENABLE
-EV_API_DECL void ev_feed_signal (int signum) EV_THROW;
-EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_THROW;
-#endif
-EV_API_DECL void ev_invoke (EV_P_ void *w, int revents);
-EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_THROW;
-
-EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_THROW;
-EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_THROW;
-
-EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_THROW;
-EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_THROW;
-/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
-EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_THROW;
-/* return remaining time */
-EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW;
-
-#if EV_PERIODIC_ENABLE
-EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW;
-EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW;
-EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW;
-#endif
-
-/* only supported in the default loop */
-#if EV_SIGNAL_ENABLE
-EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_THROW;
-EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_THROW;
-#endif
-
-/* only supported in the default loop */
-# if EV_CHILD_ENABLE
-EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_THROW;
-EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_THROW;
-# endif
-
-# if EV_STAT_ENABLE
-EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_THROW;
-EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_THROW;
-EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_THROW;
-# endif
-
-# if EV_IDLE_ENABLE
-EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_THROW;
-EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_THROW;
-# endif
-
-#if EV_PREPARE_ENABLE
-EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW;
-EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW;
-#endif
-
-#if EV_CHECK_ENABLE
-EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_THROW;
-EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_THROW;
-#endif
-
-# if EV_FORK_ENABLE
-EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_THROW;
-EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_THROW;
-# endif
-
-# if EV_CLEANUP_ENABLE
-EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW;
-EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW;
-# endif
-
-# if EV_EMBED_ENABLE
-/* only supported when loop to be embedded is in fact embeddable */
-EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_THROW;
-EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_THROW;
-EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW;
-# endif
-
-# if EV_ASYNC_ENABLE
-EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_THROW;
-EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_THROW;
-EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_THROW;
-# endif
-
-#if EV_COMPAT3
- #define EVLOOP_NONBLOCK EVRUN_NOWAIT
- #define EVLOOP_ONESHOT EVRUN_ONCE
- #define EVUNLOOP_CANCEL EVBREAK_CANCEL
- #define EVUNLOOP_ONE EVBREAK_ONE
- #define EVUNLOOP_ALL EVBREAK_ALL
- #if EV_PROTOTYPES
- EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
- EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
- EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
- EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); }
- #if EV_FEATURE_API
- EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); }
- EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); }
- EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); }
- #endif
- #endif
-#else
- typedef struct ev_loop ev_loop;
-#endif
-
-#endif
-
-EV_CPP(})
-
-#endif
-
diff --git a/framework/src/audit/src/libev/ev_epoll.c b/framework/src/audit/src/libev/ev_epoll.c
deleted file mode 100644
index 8a9b20f6..00000000
--- a/framework/src/audit/src/libev/ev_epoll.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * libev epoll fd activity backend
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-/*
- * general notes about epoll:
- *
- * a) epoll silently removes fds from the fd set. as nothing tells us
- * that an fd has been removed otherwise, we have to continually
- * "rearm" fds that we suspect *might* have changed (same
- * problem with kqueue, but much less costly there).
- * b) the fact that ADD != MOD creates a lot of extra syscalls due to a)
- * and seems not to have any advantage.
- * c) the inability to handle fork or file descriptors (think dup)
- * limits the applicability over poll, so this is not a generic
- * poll replacement.
- * d) epoll doesn't work the same as select with many file descriptors
- * (such as files). while not critical, no other advanced interface
- * seems to share this (rather non-unixy) limitation.
- * e) epoll claims to be embeddable, but in practise you never get
- * a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
- * f) epoll_ctl returning EPERM means the fd is always ready.
- *
- * lots of "weird code" and complication handling in this file is due
- * to these design problems with epoll, as we try very hard to avoid
- * epoll_ctl syscalls for common usage patterns and handle the breakage
- * ensuing from receiving events for closed and otherwise long gone
- * file descriptors.
- */
-
-#include <sys/epoll.h>
-
-#define EV_EMASK_EPERM 0x80
-
-static void
-epoll_modify (EV_P_ int fd, int oev, int nev)
-{
- struct epoll_event ev;
- unsigned char oldmask;
-
- /*
- * we handle EPOLL_CTL_DEL by ignoring it here
- * on the assumption that the fd is gone anyways
- * if that is wrong, we have to handle the spurious
- * event in epoll_poll.
- * if the fd is added again, we try to ADD it, and, if that
- * fails, we assume it still has the same eventmask.
- */
- if (!nev)
- return;
-
- oldmask = anfds [fd].emask;
- anfds [fd].emask = nev;
-
- /* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */
- ev.data.u64 = (uint64_t)(uint32_t)fd
- | ((uint64_t)(uint32_t)++anfds [fd].egen << 32);
- ev.events = (nev & EV_READ ? EPOLLIN : 0)
- | (nev & EV_WRITE ? EPOLLOUT : 0);
-
- if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev)))
- return;
-
- if (expect_true (errno == ENOENT))
- {
- /* if ENOENT then the fd went away, so try to do the right thing */
- if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev))
- return;
- }
- else if (expect_true (errno == EEXIST))
- {
- /* EEXIST means we ignored a previous DEL, but the fd is still active */
- /* if the kernel mask is the same as the new mask, we assume it hasn't changed */
- if (oldmask == nev)
- goto dec_egen;
-
- if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
- return;
- }
- else if (expect_true (errno == EPERM))
- {
- /* EPERM means the fd is always ready, but epoll is too snobbish */
- /* to handle it, unlike select or poll. */
- anfds [fd].emask = EV_EMASK_EPERM;
-
- /* add fd to epoll_eperms, if not already inside */
- if (!(oldmask & EV_EMASK_EPERM))
- {
- array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2);
- epoll_eperms [epoll_epermcnt++] = fd;
- }
-
- return;
- }
-
- fd_kill (EV_A_ fd);
-
-dec_egen:
- /* we didn't successfully call epoll_ctl, so decrement the generation counter again */
- --anfds [fd].egen;
-}
-
-static void
-epoll_poll (EV_P_ ev_tstamp timeout)
-{
- int i;
- int eventcnt;
-
- if (expect_false (epoll_epermcnt))
- timeout = 0.;
-
- /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
- /* the default libev max wait time, however. */
- EV_RELEASE_CB;
- eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, timeout * 1e3);
- EV_ACQUIRE_CB;
-
- if (expect_false (eventcnt < 0))
- {
- if (errno != EINTR)
- ev_syserr ("(libev) epoll_wait");
-
- return;
- }
-
- for (i = 0; i < eventcnt; ++i)
- {
- struct epoll_event *ev = epoll_events + i;
-
- int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */
- int want = anfds [fd].events;
- int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
- | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
-
- /*
- * check for spurious notification.
- * this only finds spurious notifications on egen updates
- * other spurious notifications will be found by epoll_ctl, below
- * we assume that fd is always in range, as we never shrink the anfds array
- */
- if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
- {
- /* recreate kernel state */
- postfork = 1;
- continue;
- }
-
- if (expect_false (got & ~want))
- {
- anfds [fd].emask = want;
-
- /*
- * we received an event but are not interested in it, try mod or del
- * this often happens because we optimistically do not unregister fds
- * when we are no longer interested in them, but also when we get spurious
- * notifications for fds from another process. this is partially handled
- * above with the gencounter check (== our fd is not the event fd), and
- * partially here, when epoll_ctl returns an error (== a child has the fd
- * but we closed it).
- */
- ev->events = (want & EV_READ ? EPOLLIN : 0)
- | (want & EV_WRITE ? EPOLLOUT : 0);
-
- /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */
- /* which is fortunately easy to do for us. */
- if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
- {
- postfork = 1; /* an error occurred, recreate kernel state */
- continue;
- }
- }
-
- fd_event (EV_A_ fd, got);
- }
-
- /* if the receive array was full, increase its size */
- if (expect_false (eventcnt == epoll_eventmax))
- {
- ev_free (epoll_events);
- epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
- epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
- }
-
- /* now synthesize events for all fds where epoll fails, while select works... */
- for (i = epoll_epermcnt; i--; )
- {
- int fd = epoll_eperms [i];
- unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE);
-
- if (anfds [fd].emask & EV_EMASK_EPERM && events)
- fd_event (EV_A_ fd, events);
- else
- {
- epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
- anfds [fd].emask = 0;
- }
- }
-}
-
-int inline_size
-epoll_init (EV_P_ int flags)
-{
-#ifdef EPOLL_CLOEXEC
- backend_fd = epoll_create1 (EPOLL_CLOEXEC);
-
- if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS))
-#endif
- backend_fd = epoll_create (256);
-
- if (backend_fd < 0)
- return 0;
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
-
- backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */
- backend_modify = epoll_modify;
- backend_poll = epoll_poll;
-
- epoll_eventmax = 64; /* initial number of events receivable per poll */
- epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
-
- return EVBACKEND_EPOLL;
-}
-
-void inline_size
-epoll_destroy (EV_P)
-{
- ev_free (epoll_events);
- array_free (epoll_eperm, EMPTY);
-}
-
-void inline_size
-epoll_fork (EV_P)
-{
- close (backend_fd);
-
- while ((backend_fd = epoll_create (256)) < 0)
- ev_syserr ("(libev) epoll_create");
-
- fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
-
- fd_rearm_all (EV_A);
-}
-
diff --git a/framework/src/audit/src/libev/ev_poll.c b/framework/src/audit/src/libev/ev_poll.c
deleted file mode 100644
index 48323516..00000000
--- a/framework/src/audit/src/libev/ev_poll.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * libev poll fd activity backend
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#include <poll.h>
-
-void inline_size
-pollidx_init (int *base, int count)
-{
- /* consider using memset (.., -1, ...), which is practically guaranteed
- * to work on all systems implementing poll */
- while (count--)
- *base++ = -1;
-}
-
-static void
-poll_modify (EV_P_ int fd, int oev, int nev)
-{
- int idx;
-
- if (oev == nev)
- return;
-
- array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
-
- idx = pollidxs [fd];
-
- if (idx < 0) /* need to allocate a new pollfd */
- {
- pollidxs [fd] = idx = pollcnt++;
- array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
- polls [idx].fd = fd;
- }
-
- assert (polls [idx].fd == fd);
-
- if (nev)
- polls [idx].events =
- (nev & EV_READ ? POLLIN : 0)
- | (nev & EV_WRITE ? POLLOUT : 0);
- else /* remove pollfd */
- {
- pollidxs [fd] = -1;
-
- if (expect_true (idx < --pollcnt))
- {
- polls [idx] = polls [pollcnt];
- pollidxs [polls [idx].fd] = idx;
- }
- }
-}
-
-static void
-poll_poll (EV_P_ ev_tstamp timeout)
-{
- struct pollfd *p;
- int res;
-
- EV_RELEASE_CB;
- res = poll (polls, pollcnt, timeout * 1e3);
- EV_ACQUIRE_CB;
-
- if (expect_false (res < 0))
- {
- if (errno == EBADF)
- fd_ebadf (EV_A);
- else if (errno == ENOMEM && !syserr_cb)
- fd_enomem (EV_A);
- else if (errno != EINTR)
- ev_syserr ("(libev) poll");
- }
- else
- for (p = polls; res; ++p)
- {
- assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
-
- if (expect_false (p->revents)) /* this expect is debatable */
- {
- --res;
-
- if (expect_false (p->revents & POLLNVAL))
- fd_kill (EV_A_ p->fd);
- else
- fd_event (
- EV_A_
- p->fd,
- (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
- | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
- );
- }
- }
-}
-
-int inline_size
-poll_init (EV_P_ int flags)
-{
- backend_mintime = 1e-3;
- backend_modify = poll_modify;
- backend_poll = poll_poll;
-
- pollidxs = 0; pollidxmax = 0;
- polls = 0; pollmax = 0; pollcnt = 0;
-
- return EVBACKEND_POLL;
-}
-
-void inline_size
-poll_destroy (EV_P)
-{
- ev_free (pollidxs);
- ev_free (polls);
-}
-
diff --git a/framework/src/audit/src/libev/ev_select.c b/framework/src/audit/src/libev/ev_select.c
deleted file mode 100644
index f38d6ca3..00000000
--- a/framework/src/audit/src/libev/ev_select.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * libev select fd activity backend
- *
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef _WIN32
-/* for unix systems */
-# include <inttypes.h>
-# ifndef __hpux
-/* for REAL unix systems */
-# include <sys/select.h>
-# endif
-#endif
-
-#ifndef EV_SELECT_USE_FD_SET
-# ifdef NFDBITS
-# define EV_SELECT_USE_FD_SET 0
-# else
-# define EV_SELECT_USE_FD_SET 1
-# endif
-#endif
-
-#if EV_SELECT_IS_WINSOCKET
-# undef EV_SELECT_USE_FD_SET
-# define EV_SELECT_USE_FD_SET 1
-# undef NFDBITS
-# define NFDBITS 0
-#endif
-
-#if !EV_SELECT_USE_FD_SET
-# define NFDBYTES (NFDBITS / 8)
-#endif
-
-#include <string.h>
-
-static void
-select_modify (EV_P_ int fd, int oev, int nev)
-{
- if (oev == nev)
- return;
-
- {
-#if EV_SELECT_USE_FD_SET
-
- #if EV_SELECT_IS_WINSOCKET
- SOCKET handle = anfds [fd].handle;
- #else
- int handle = fd;
- #endif
-
- assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));
-
- /* FD_SET is broken on windows (it adds the fd to a set twice or more,
- * which eventually leads to overflows). Need to call it only on changes.
- */
- #if EV_SELECT_IS_WINSOCKET
- if ((oev ^ nev) & EV_READ)
- #endif
- if (nev & EV_READ)
- FD_SET (handle, (fd_set *)vec_ri);
- else
- FD_CLR (handle, (fd_set *)vec_ri);
-
- #if EV_SELECT_IS_WINSOCKET
- if ((oev ^ nev) & EV_WRITE)
- #endif
- if (nev & EV_WRITE)
- FD_SET (handle, (fd_set *)vec_wi);
- else
- FD_CLR (handle, (fd_set *)vec_wi);
-
-#else
-
- int word = fd / NFDBITS;
- fd_mask mask = 1UL << (fd % NFDBITS);
-
- if (expect_false (vec_max <= word))
- {
- int new_max = word + 1;
-
- vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
- vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
- vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
- vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
- #ifdef _WIN32
- vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
- #endif
-
- for (; vec_max < new_max; ++vec_max)
- ((fd_mask *)vec_ri) [vec_max] =
- ((fd_mask *)vec_wi) [vec_max] = 0;
- }
-
- ((fd_mask *)vec_ri) [word] |= mask;
- if (!(nev & EV_READ))
- ((fd_mask *)vec_ri) [word] &= ~mask;
-
- ((fd_mask *)vec_wi) [word] |= mask;
- if (!(nev & EV_WRITE))
- ((fd_mask *)vec_wi) [word] &= ~mask;
-#endif
- }
-}
-
-static void
-select_poll (EV_P_ ev_tstamp timeout)
-{
- struct timeval tv;
- int res;
- int fd_setsize;
-
- EV_RELEASE_CB;
- EV_TV_SET (tv, timeout);
-
-#if EV_SELECT_USE_FD_SET
- fd_setsize = sizeof (fd_set);
-#else
- fd_setsize = vec_max * NFDBYTES;
-#endif
-
- memcpy (vec_ro, vec_ri, fd_setsize);
- memcpy (vec_wo, vec_wi, fd_setsize);
-
-#ifdef _WIN32
- /* pass in the write set as except set.
- * the idea behind this is to work around a windows bug that causes
- * errors to be reported as an exception and not by setting
- * the writable bit. this is so uncontrollably lame.
- */
- memcpy (vec_eo, vec_wi, fd_setsize);
- res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
-#elif EV_SELECT_USE_FD_SET
- fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
- res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
-#else
- res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
-#endif
- EV_ACQUIRE_CB;
-
- if (expect_false (res < 0))
- {
- #if EV_SELECT_IS_WINSOCKET
- errno = WSAGetLastError ();
- #endif
- #ifdef WSABASEERR
- /* on windows, select returns incompatible error codes, fix this */
- if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
- if (errno == WSAENOTSOCK)
- errno = EBADF;
- else
- errno -= WSABASEERR;
- #endif
-
- #ifdef _WIN32
- /* select on windows erroneously returns EINVAL when no fd sets have been
- * provided (this is documented). what microsoft doesn't tell you that this bug
- * exists even when the fd sets _are_ provided, so we have to check for this bug
- * here and emulate by sleeping manually.
- * we also get EINVAL when the timeout is invalid, but we ignore this case here
- * and assume that EINVAL always means: you have to wait manually.
- */
- if (errno == EINVAL)
- {
- if (timeout)
- {
- unsigned long ms = timeout * 1e3;
- Sleep (ms ? ms : 1);
- }
-
- return;
- }
- #endif
-
- if (errno == EBADF)
- fd_ebadf (EV_A);
- else if (errno == ENOMEM && !syserr_cb)
- fd_enomem (EV_A);
- else if (errno != EINTR)
- ev_syserr ("(libev) select");
-
- return;
- }
-
-#if EV_SELECT_USE_FD_SET
-
- {
- int fd;
-
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)
- {
- int events = 0;
- #if EV_SELECT_IS_WINSOCKET
- SOCKET handle = anfds [fd].handle;
- #else
- int handle = fd;
- #endif
-
- if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
- if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
- #ifdef _WIN32
- if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
- #endif
-
- if (expect_true (events))
- fd_event (EV_A_ fd, events);
- }
- }
-
-#else
-
- {
- int word, bit;
- for (word = vec_max; word--; )
- {
- fd_mask word_r = ((fd_mask *)vec_ro) [word];
- fd_mask word_w = ((fd_mask *)vec_wo) [word];
- #ifdef _WIN32
- word_w |= ((fd_mask *)vec_eo) [word];
- #endif
-
- if (word_r || word_w)
- for (bit = NFDBITS; bit--; )
- {
- fd_mask mask = 1UL << bit;
- int events = 0;
-
- events |= word_r & mask ? EV_READ : 0;
- events |= word_w & mask ? EV_WRITE : 0;
-
- if (expect_true (events))
- fd_event (EV_A_ word * NFDBITS + bit, events);
- }
- }
- }
-
-#endif
-}
-
-int inline_size
-select_init (EV_P_ int flags)
-{
- backend_mintime = 1e-6;
- backend_modify = select_modify;
- backend_poll = select_poll;
-
-#if EV_SELECT_USE_FD_SET
- vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
- vec_ro = ev_malloc (sizeof (fd_set));
- vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
- vec_wo = ev_malloc (sizeof (fd_set));
- #ifdef _WIN32
- vec_eo = ev_malloc (sizeof (fd_set));
- #endif
-#else
- vec_max = 0;
- vec_ri = 0;
- vec_ro = 0;
- vec_wi = 0;
- vec_wo = 0;
- #ifdef _WIN32
- vec_eo = 0;
- #endif
-#endif
-
- return EVBACKEND_SELECT;
-}
-
-void inline_size
-select_destroy (EV_P)
-{
- ev_free (vec_ri);
- ev_free (vec_ro);
- ev_free (vec_wi);
- ev_free (vec_wo);
- #ifdef _WIN32
- ev_free (vec_eo);
- #endif
-}
-
diff --git a/framework/src/audit/src/libev/ev_vars.h b/framework/src/audit/src/libev/ev_vars.h
deleted file mode 100644
index 04d4db16..00000000
--- a/framework/src/audit/src/libev/ev_vars.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * loop member variable declarations
- *
- * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#define VARx(type,name) VAR(name, type name)
-
-VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
-VARx(ev_tstamp, mn_now) /* monotonic clock "now" */
-VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */
-
-/* for reverse feeding of events */
-VARx(W *, rfeeds)
-VARx(int, rfeedmax)
-VARx(int, rfeedcnt)
-
-VAR (pendings, ANPENDING *pendings [NUMPRI])
-VAR (pendingmax, int pendingmax [NUMPRI])
-VAR (pendingcnt, int pendingcnt [NUMPRI])
-VARx(int, pendingpri) /* highest priority currently pending */
-VARx(ev_prepare, pending_w) /* dummy pending watcher */
-
-VARx(ev_tstamp, io_blocktime)
-VARx(ev_tstamp, timeout_blocktime)
-
-VARx(int, backend)
-VARx(int, activecnt) /* total number of active events ("refcount") */
-VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */
-
-VARx(int, backend_fd)
-VARx(ev_tstamp, backend_mintime) /* assumed typical timer resolution */
-VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
-VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
-
-VARx(ANFD *, anfds)
-VARx(int, anfdmax)
-
-VAR (evpipe, int evpipe [2])
-VARx(ev_io, pipe_w)
-VARx(EV_ATOMIC_T, pipe_write_wanted)
-VARx(EV_ATOMIC_T, pipe_write_skipped)
-
-#if !defined(_WIN32) || EV_GENWRAP
-VARx(pid_t, curpid)
-#endif
-
-VARx(char, postfork) /* true if we need to recreate kernel state after fork */
-
-#if EV_USE_SELECT || EV_GENWRAP
-VARx(void *, vec_ri)
-VARx(void *, vec_ro)
-VARx(void *, vec_wi)
-VARx(void *, vec_wo)
-#if defined(_WIN32) || EV_GENWRAP
-VARx(void *, vec_eo)
-#endif
-VARx(int, vec_max)
-#endif
-
-#if EV_USE_POLL || EV_GENWRAP
-VARx(struct pollfd *, polls)
-VARx(int, pollmax)
-VARx(int, pollcnt)
-VARx(int *, pollidxs) /* maps fds into structure indices */
-VARx(int, pollidxmax)
-#endif
-
-#if EV_USE_EPOLL || EV_GENWRAP
-VARx(struct epoll_event *, epoll_events)
-VARx(int, epoll_eventmax)
-VARx(int *, epoll_eperms)
-VARx(int, epoll_epermcnt)
-VARx(int, epoll_epermmax)
-#endif
-
-#if EV_USE_KQUEUE || EV_GENWRAP
-VARx(pid_t, kqueue_fd_pid)
-VARx(struct kevent *, kqueue_changes)
-VARx(int, kqueue_changemax)
-VARx(int, kqueue_changecnt)
-VARx(struct kevent *, kqueue_events)
-VARx(int, kqueue_eventmax)
-#endif
-
-#if EV_USE_PORT || EV_GENWRAP
-VARx(struct port_event *, port_events)
-VARx(int, port_eventmax)
-#endif
-
-#if EV_USE_IOCP || EV_GENWRAP
-VARx(HANDLE, iocp)
-#endif
-
-VARx(int *, fdchanges)
-VARx(int, fdchangemax)
-VARx(int, fdchangecnt)
-
-VARx(ANHE *, timers)
-VARx(int, timermax)
-VARx(int, timercnt)
-
-#if EV_PERIODIC_ENABLE || EV_GENWRAP
-VARx(ANHE *, periodics)
-VARx(int, periodicmax)
-VARx(int, periodiccnt)
-#endif
-
-#if EV_IDLE_ENABLE || EV_GENWRAP
-VAR (idles, ev_idle **idles [NUMPRI])
-VAR (idlemax, int idlemax [NUMPRI])
-VAR (idlecnt, int idlecnt [NUMPRI])
-#endif
-VARx(int, idleall) /* total number */
-
-VARx(struct ev_prepare **, prepares)
-VARx(int, preparemax)
-VARx(int, preparecnt)
-
-VARx(struct ev_check **, checks)
-VARx(int, checkmax)
-VARx(int, checkcnt)
-
-#if EV_FORK_ENABLE || EV_GENWRAP
-VARx(struct ev_fork **, forks)
-VARx(int, forkmax)
-VARx(int, forkcnt)
-#endif
-
-#if EV_CLEANUP_ENABLE || EV_GENWRAP
-VARx(struct ev_cleanup **, cleanups)
-VARx(int, cleanupmax)
-VARx(int, cleanupcnt)
-#endif
-
-#if EV_ASYNC_ENABLE || EV_GENWRAP
-VARx(EV_ATOMIC_T, async_pending)
-VARx(struct ev_async **, asyncs)
-VARx(int, asyncmax)
-VARx(int, asynccnt)
-#endif
-
-#if EV_USE_INOTIFY || EV_GENWRAP
-VARx(int, fs_fd)
-VARx(ev_io, fs_w)
-VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */
-VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
-#endif
-
-VARx(EV_ATOMIC_T, sig_pending)
-#if EV_USE_SIGNALFD || EV_GENWRAP
-VARx(int, sigfd)
-VARx(ev_io, sigfd_w)
-VARx(sigset_t, sigfd_set)
-#endif
-
-VARx(unsigned int, origflags) /* original loop flags */
-
-#if EV_FEATURE_API || EV_GENWRAP
-VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
-VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */
-
-VARx(void *, userdata)
-/* C++ doesn't support the ev_loop_callback typedef here. stinks. */
-VAR (release_cb, void (*release_cb)(EV_P) EV_THROW)
-VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_THROW)
-VAR (invoke_cb , ev_loop_callback invoke_cb)
-#endif
-
-#undef VARx
-
diff --git a/framework/src/audit/src/libev/ev_wrap.h b/framework/src/audit/src/libev/ev_wrap.h
deleted file mode 100644
index ad989ea7..00000000
--- a/framework/src/audit/src/libev/ev_wrap.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* DO NOT EDIT, automatically generated by update_ev_wrap */
-#ifndef EV_WRAP_H
-#define EV_WRAP_H
-#define acquire_cb ((loop)->acquire_cb)
-#define activecnt ((loop)->activecnt)
-#define anfdmax ((loop)->anfdmax)
-#define anfds ((loop)->anfds)
-#define async_pending ((loop)->async_pending)
-#define asynccnt ((loop)->asynccnt)
-#define asyncmax ((loop)->asyncmax)
-#define asyncs ((loop)->asyncs)
-#define backend ((loop)->backend)
-#define backend_fd ((loop)->backend_fd)
-#define backend_mintime ((loop)->backend_mintime)
-#define backend_modify ((loop)->backend_modify)
-#define backend_poll ((loop)->backend_poll)
-#define checkcnt ((loop)->checkcnt)
-#define checkmax ((loop)->checkmax)
-#define checks ((loop)->checks)
-#define cleanupcnt ((loop)->cleanupcnt)
-#define cleanupmax ((loop)->cleanupmax)
-#define cleanups ((loop)->cleanups)
-#define curpid ((loop)->curpid)
-#define epoll_epermcnt ((loop)->epoll_epermcnt)
-#define epoll_epermmax ((loop)->epoll_epermmax)
-#define epoll_eperms ((loop)->epoll_eperms)
-#define epoll_eventmax ((loop)->epoll_eventmax)
-#define epoll_events ((loop)->epoll_events)
-#define evpipe ((loop)->evpipe)
-#define fdchangecnt ((loop)->fdchangecnt)
-#define fdchangemax ((loop)->fdchangemax)
-#define fdchanges ((loop)->fdchanges)
-#define forkcnt ((loop)->forkcnt)
-#define forkmax ((loop)->forkmax)
-#define forks ((loop)->forks)
-#define fs_2625 ((loop)->fs_2625)
-#define fs_fd ((loop)->fs_fd)
-#define fs_hash ((loop)->fs_hash)
-#define fs_w ((loop)->fs_w)
-#define idleall ((loop)->idleall)
-#define idlecnt ((loop)->idlecnt)
-#define idlemax ((loop)->idlemax)
-#define idles ((loop)->idles)
-#define invoke_cb ((loop)->invoke_cb)
-#define io_blocktime ((loop)->io_blocktime)
-#define iocp ((loop)->iocp)
-#define kqueue_changecnt ((loop)->kqueue_changecnt)
-#define kqueue_changemax ((loop)->kqueue_changemax)
-#define kqueue_changes ((loop)->kqueue_changes)
-#define kqueue_eventmax ((loop)->kqueue_eventmax)
-#define kqueue_events ((loop)->kqueue_events)
-#define kqueue_fd_pid ((loop)->kqueue_fd_pid)
-#define loop_count ((loop)->loop_count)
-#define loop_depth ((loop)->loop_depth)
-#define loop_done ((loop)->loop_done)
-#define mn_now ((loop)->mn_now)
-#define now_floor ((loop)->now_floor)
-#define origflags ((loop)->origflags)
-#define pending_w ((loop)->pending_w)
-#define pendingcnt ((loop)->pendingcnt)
-#define pendingmax ((loop)->pendingmax)
-#define pendingpri ((loop)->pendingpri)
-#define pendings ((loop)->pendings)
-#define periodiccnt ((loop)->periodiccnt)
-#define periodicmax ((loop)->periodicmax)
-#define periodics ((loop)->periodics)
-#define pipe_w ((loop)->pipe_w)
-#define pipe_write_skipped ((loop)->pipe_write_skipped)
-#define pipe_write_wanted ((loop)->pipe_write_wanted)
-#define pollcnt ((loop)->pollcnt)
-#define pollidxmax ((loop)->pollidxmax)
-#define pollidxs ((loop)->pollidxs)
-#define pollmax ((loop)->pollmax)
-#define polls ((loop)->polls)
-#define port_eventmax ((loop)->port_eventmax)
-#define port_events ((loop)->port_events)
-#define postfork ((loop)->postfork)
-#define preparecnt ((loop)->preparecnt)
-#define preparemax ((loop)->preparemax)
-#define prepares ((loop)->prepares)
-#define release_cb ((loop)->release_cb)
-#define rfeedcnt ((loop)->rfeedcnt)
-#define rfeedmax ((loop)->rfeedmax)
-#define rfeeds ((loop)->rfeeds)
-#define rtmn_diff ((loop)->rtmn_diff)
-#define sig_pending ((loop)->sig_pending)
-#define sigfd ((loop)->sigfd)
-#define sigfd_set ((loop)->sigfd_set)
-#define sigfd_w ((loop)->sigfd_w)
-#define timeout_blocktime ((loop)->timeout_blocktime)
-#define timercnt ((loop)->timercnt)
-#define timermax ((loop)->timermax)
-#define timers ((loop)->timers)
-#define userdata ((loop)->userdata)
-#define vec_eo ((loop)->vec_eo)
-#define vec_max ((loop)->vec_max)
-#define vec_ri ((loop)->vec_ri)
-#define vec_ro ((loop)->vec_ro)
-#define vec_wi ((loop)->vec_wi)
-#define vec_wo ((loop)->vec_wo)
-#else
-#undef EV_WRAP_H
-#undef acquire_cb
-#undef activecnt
-#undef anfdmax
-#undef anfds
-#undef async_pending
-#undef asynccnt
-#undef asyncmax
-#undef asyncs
-#undef backend
-#undef backend_fd
-#undef backend_mintime
-#undef backend_modify
-#undef backend_poll
-#undef checkcnt
-#undef checkmax
-#undef checks
-#undef cleanupcnt
-#undef cleanupmax
-#undef cleanups
-#undef curpid
-#undef epoll_epermcnt
-#undef epoll_epermmax
-#undef epoll_eperms
-#undef epoll_eventmax
-#undef epoll_events
-#undef evpipe
-#undef fdchangecnt
-#undef fdchangemax
-#undef fdchanges
-#undef forkcnt
-#undef forkmax
-#undef forks
-#undef fs_2625
-#undef fs_fd
-#undef fs_hash
-#undef fs_w
-#undef idleall
-#undef idlecnt
-#undef idlemax
-#undef idles
-#undef invoke_cb
-#undef io_blocktime
-#undef iocp
-#undef kqueue_changecnt
-#undef kqueue_changemax
-#undef kqueue_changes
-#undef kqueue_eventmax
-#undef kqueue_events
-#undef kqueue_fd_pid
-#undef loop_count
-#undef loop_depth
-#undef loop_done
-#undef mn_now
-#undef now_floor
-#undef origflags
-#undef pending_w
-#undef pendingcnt
-#undef pendingmax
-#undef pendingpri
-#undef pendings
-#undef periodiccnt
-#undef periodicmax
-#undef periodics
-#undef pipe_w
-#undef pipe_write_skipped
-#undef pipe_write_wanted
-#undef pollcnt
-#undef pollidxmax
-#undef pollidxs
-#undef pollmax
-#undef polls
-#undef port_eventmax
-#undef port_events
-#undef postfork
-#undef preparecnt
-#undef preparemax
-#undef prepares
-#undef release_cb
-#undef rfeedcnt
-#undef rfeedmax
-#undef rfeeds
-#undef rtmn_diff
-#undef sig_pending
-#undef sigfd
-#undef sigfd_set
-#undef sigfd_w
-#undef timeout_blocktime
-#undef timercnt
-#undef timermax
-#undef timers
-#undef userdata
-#undef vec_eo
-#undef vec_max
-#undef vec_ri
-#undef vec_ro
-#undef vec_wi
-#undef vec_wo
-#endif
diff --git a/framework/src/audit/src/libev/event.c b/framework/src/audit/src/libev/event.c
deleted file mode 100644
index 5586cd35..00000000
--- a/framework/src/audit/src/libev/event.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * libevent compatibility layer
- *
- * Copyright (c) 2007,2008,2009,2010,2012 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#ifdef EV_EVENT_H
-# include EV_EVENT_H
-#else
-# include "event.h"
-#endif
-
-#if EV_MULTIPLICITY
-# define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base
-# define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base
-#else
-# define dLOOPev
-# define dLOOPbase
-#endif
-
-/* never accessed, will always be cast from/to ev_loop */
-struct event_base
-{
- int dummy;
-};
-
-static struct event_base *ev_x_cur;
-
-static ev_tstamp
-ev_tv_get (struct timeval *tv)
-{
- if (tv)
- {
- ev_tstamp after = tv->tv_sec + tv->tv_usec * 1e-6;
- return after ? after : 1e-6;
- }
- else
- return -1.;
-}
-
-#define EVENT_STRINGIFY(s) # s
-#define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b)
-
-const char *
-event_get_version (void)
-{
- /* returns ABI, not API or library, version */
- return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
-}
-
-const char *
-event_get_method (void)
-{
- return "libev";
-}
-
-void *event_init (void)
-{
-#if EV_MULTIPLICITY
- if (ev_x_cur)
- ev_x_cur = (struct event_base *)ev_loop_new (EVFLAG_AUTO);
- else
- ev_x_cur = (struct event_base *)ev_default_loop (EVFLAG_AUTO);
-#else
- assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY", !ev_x_cur));
-
- ev_x_cur = (struct event_base *)(long)ev_default_loop (EVFLAG_AUTO);
-#endif
-
- return ev_x_cur;
-}
-
-const char *
-event_base_get_method (const struct event_base *base)
-{
- return "libev";
-}
-
-struct event_base *
-event_base_new (void)
-{
-#if EV_MULTIPLICITY
- return (struct event_base *)ev_loop_new (EVFLAG_AUTO);
-#else
- assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY"));
- return NULL;
-#endif
-}
-
-void event_base_free (struct event_base *base)
-{
- dLOOPbase;
-
-#if EV_MULTIPLICITY
- if (!ev_is_default_loop (loop))
- ev_loop_destroy (loop);
-#endif
-}
-
-int event_dispatch (void)
-{
- return event_base_dispatch (ev_x_cur);
-}
-
-#ifdef EV_STANDALONE
-void event_set_log_callback (event_log_cb cb)
-{
- /* nop */
-}
-#endif
-
-int event_loop (int flags)
-{
- return event_base_loop (ev_x_cur, flags);
-}
-
-int event_loopexit (struct timeval *tv)
-{
- return event_base_loopexit (ev_x_cur, tv);
-}
-
-event_callback_fn event_get_callback
-(const struct event *ev)
-{
- return ev->ev_callback;
-}
-
-static void
-ev_x_cb (struct event *ev, int revents)
-{
- revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL;
-
- ev->ev_res = revents;
- ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
-}
-
-static void
-ev_x_cb_sig (EV_P_ struct ev_signal *w, int revents)
-{
- struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.sig));
-
- if (revents & EV_ERROR)
- event_del (ev);
-
- ev_x_cb (ev, revents);
-}
-
-static void
-ev_x_cb_io (EV_P_ struct ev_io *w, int revents)
-{
- struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io));
-
- if ((revents & EV_ERROR) || !(ev->ev_events & EV_PERSIST))
- event_del (ev);
-
- ev_x_cb (ev, revents);
-}
-
-static void
-ev_x_cb_to (EV_P_ struct ev_timer *w, int revents)
-{
- struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, to));
-
- event_del (ev);
-
- ev_x_cb (ev, revents);
-}
-
-void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)
-{
- if (events & EV_SIGNAL)
- ev_init (&ev->iosig.sig, ev_x_cb_sig);
- else
- ev_init (&ev->iosig.io, ev_x_cb_io);
-
- ev_init (&ev->to, ev_x_cb_to);
-
- ev->ev_base = ev_x_cur; /* not threadsafe, but it's how libevent works */
- ev->ev_fd = fd;
- ev->ev_events = events;
- ev->ev_pri = 0;
- ev->ev_callback = cb;
- ev->ev_arg = arg;
- ev->ev_res = 0;
- ev->ev_flags = EVLIST_INIT;
-}
-
-int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
-{
- return event_base_once (ev_x_cur, fd, events, cb, arg, tv);
-}
-
-int event_add (struct event *ev, struct timeval *tv)
-{
- dLOOPev;
-
- if (ev->ev_events & EV_SIGNAL)
- {
- if (!ev_is_active (&ev->iosig.sig))
- {
- ev_signal_set (&ev->iosig.sig, ev->ev_fd);
- ev_signal_start (EV_A_ &ev->iosig.sig);
-
- ev->ev_flags |= EVLIST_SIGNAL;
- }
- }
- else if (ev->ev_events & (EV_READ | EV_WRITE))
- {
- if (!ev_is_active (&ev->iosig.io))
- {
- ev_io_set (&ev->iosig.io, ev->ev_fd, ev->ev_events & (EV_READ | EV_WRITE));
- ev_io_start (EV_A_ &ev->iosig.io);
-
- ev->ev_flags |= EVLIST_INSERTED;
- }
- }
-
- if (tv)
- {
- ev->to.repeat = ev_tv_get (tv);
- ev_timer_again (EV_A_ &ev->to);
- ev->ev_flags |= EVLIST_TIMEOUT;
- }
- else
- {
- ev_timer_stop (EV_A_ &ev->to);
- ev->ev_flags &= ~EVLIST_TIMEOUT;
- }
-
- ev->ev_flags |= EVLIST_ACTIVE;
-
- return 0;
-}
-
-int event_del (struct event *ev)
-{
- dLOOPev;
-
- if (ev->ev_events & EV_SIGNAL)
- ev_signal_stop (EV_A_ &ev->iosig.sig);
- else if (ev->ev_events & (EV_READ | EV_WRITE))
- ev_io_stop (EV_A_ &ev->iosig.io);
-
- if (ev_is_active (&ev->to))
- ev_timer_stop (EV_A_ &ev->to);
-
- ev->ev_flags = EVLIST_INIT;
-
- return 0;
-}
-
-void event_active (struct event *ev, int res, short ncalls)
-{
- dLOOPev;
-
- if (res & EV_TIMEOUT)
- ev_feed_event (EV_A_ &ev->to, res & EV_TIMEOUT);
-
- if (res & EV_SIGNAL)
- ev_feed_event (EV_A_ &ev->iosig.sig, res & EV_SIGNAL);
-
- if (res & (EV_READ | EV_WRITE))
- ev_feed_event (EV_A_ &ev->iosig.io, res & (EV_READ | EV_WRITE));
-}
-
-int event_pending (struct event *ev, short events, struct timeval *tv)
-{
- short revents = 0;
- dLOOPev;
-
- if (ev->ev_events & EV_SIGNAL)
- {
- /* sig */
- if (ev_is_active (&ev->iosig.sig) || ev_is_pending (&ev->iosig.sig))
- revents |= EV_SIGNAL;
- }
- else if (ev->ev_events & (EV_READ | EV_WRITE))
- {
- /* io */
- if (ev_is_active (&ev->iosig.io) || ev_is_pending (&ev->iosig.io))
- revents |= ev->ev_events & (EV_READ | EV_WRITE);
- }
-
- if (ev->ev_events & EV_TIMEOUT || ev_is_active (&ev->to) || ev_is_pending (&ev->to))
- {
- revents |= EV_TIMEOUT;
-
- if (tv)
- {
- ev_tstamp at = ev_now (EV_A);
-
- tv->tv_sec = (long)at;
- tv->tv_usec = (long)((at - (ev_tstamp)tv->tv_sec) * 1e6);
- }
- }
-
- return events & revents;
-}
-
-int event_priority_init (int npri)
-{
- return event_base_priority_init (ev_x_cur, npri);
-}
-
-int event_priority_set (struct event *ev, int pri)
-{
- ev->ev_pri = pri;
-
- return 0;
-}
-
-int event_base_set (struct event_base *base, struct event *ev)
-{
- ev->ev_base = base;
-
- return 0;
-}
-
-int event_base_loop (struct event_base *base, int flags)
-{
- dLOOPbase;
-
- return !ev_run (EV_A_ flags);
-}
-
-int event_base_dispatch (struct event_base *base)
-{
- return event_base_loop (base, 0);
-}
-
-static void
-ev_x_loopexit_cb (int revents, void *base)
-{
- dLOOPbase;
-
- ev_break (EV_A_ EVBREAK_ONE);
-}
-
-int event_base_loopexit (struct event_base *base, struct timeval *tv)
-{
- ev_tstamp after = ev_tv_get (tv);
- dLOOPbase;
-
- ev_once (EV_A_ -1, 0, after >= 0. ? after : 0., ev_x_loopexit_cb, (void *)base);
-
- return 0;
-}
-
-struct ev_x_once
-{
- int fd;
- void (*cb)(int, short, void *);
- void *arg;
-};
-
-static void
-ev_x_once_cb (int revents, void *arg)
-{
- struct ev_x_once *once = (struct ev_x_once *)arg;
-
- once->cb (once->fd, (short)revents, once->arg);
- free (once);
-}
-
-int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
-{
- struct ev_x_once *once = (struct ev_x_once *)malloc (sizeof (struct ev_x_once));
- dLOOPbase;
-
- if (!once)
- return -1;
-
- once->fd = fd;
- once->cb = cb;
- once->arg = arg;
-
- ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), ev_tv_get (tv), ev_x_once_cb, (void *)once);
-
- return 0;
-}
-
-int event_base_priority_init (struct event_base *base, int npri)
-{
- /*dLOOPbase;*/
-
- return 0;
-}
-
diff --git a/framework/src/audit/src/libev/event.h b/framework/src/audit/src/libev/event.h
deleted file mode 100644
index aa81928f..00000000
--- a/framework/src/audit/src/libev/event.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * libevent compatibility header, only core events supported
- *
- * Copyright (c) 2007,2008,2010,2012 Marc Alexander Lehmann <libev@schmorp.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License ("GPL") version 2 or any later version,
- * in which case the provisions of the GPL are applicable instead of
- * the above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the BSD license, indicate your decision
- * by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file under
- * either the BSD or the GPL.
- */
-
-#ifndef EVENT_H_
-#define EVENT_H_
-
-#ifdef EV_H
-# include EV_H
-#else
-# include "ev.h"
-#endif
-
-#ifndef EVLOOP_NONBLOCK
-# define EVLOOP_NONBLOCK EVRUN_NOWAIT
-#endif
-#ifndef EVLOOP_ONESHOT
-# define EVLOOP_ONESHOT EVRUN_ONCE
-#endif
-#ifndef EV_TIMEOUT
-# define EV_TIMEOUT EV_TIMER
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* we need sys/time.h for struct timeval only */
-#if !defined (WIN32) || defined (__MINGW32__)
-# include <time.h> /* mingw seems to need this, for whatever reason */
-# include <sys/time.h>
-#endif
-
-struct event_base;
-
-#define EVLIST_TIMEOUT 0x01
-#define EVLIST_INSERTED 0x02
-#define EVLIST_SIGNAL 0x04
-#define EVLIST_ACTIVE 0x08
-#define EVLIST_INTERNAL 0x10
-#define EVLIST_INIT 0x80
-
-typedef void (*event_callback_fn)(int, short, void *);
-
-struct event
-{
- /* libev watchers we map onto */
- union {
- struct ev_io io;
- struct ev_signal sig;
- } iosig;
- struct ev_timer to;
-
- /* compatibility slots */
- struct event_base *ev_base;
- event_callback_fn ev_callback;
- void *ev_arg;
- int ev_fd;
- int ev_pri;
- int ev_res;
- int ev_flags;
- short ev_events;
-};
-
-event_callback_fn event_get_callback (const struct event *ev);
-
-#define EV_READ EV_READ
-#define EV_WRITE EV_WRITE
-#define EV_PERSIST 0x10
-#define EV_ET 0x20 /* nop */
-
-#define EVENT_SIGNAL(ev) ((int) (ev)->ev_fd)
-#define EVENT_FD(ev) ((int) (ev)->ev_fd)
-
-#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
-
-#define evtimer_add(ev,tv) event_add (ev, tv)
-#define evtimer_set(ev,cb,data) event_set (ev, -1, 0, cb, data)
-#define evtimer_del(ev) event_del (ev)
-#define evtimer_pending(ev,tv) event_pending (ev, EV_TIMEOUT, tv)
-#define evtimer_initialized(ev) event_initialized (ev)
-
-#define timeout_add(ev,tv) evtimer_add (ev, tv)
-#define timeout_set(ev,cb,data) evtimer_set (ev, cb, data)
-#define timeout_del(ev) evtimer_del (ev)
-#define timeout_pending(ev,tv) evtimer_pending (ev, tv)
-#define timeout_initialized(ev) evtimer_initialized (ev)
-
-#define signal_add(ev,tv) event_add (ev, tv)
-#define signal_set(ev,sig,cb,data) event_set (ev, sig, EV_SIGNAL | EV_PERSIST, cb, data)
-#define signal_del(ev) event_del (ev)
-#define signal_pending(ev,tv) event_pending (ev, EV_SIGNAL, tv)
-#define signal_initialized(ev) event_initialized (ev)
-
-const char *event_get_version (void);
-const char *event_get_method (void);
-
-void *event_init (void);
-void event_base_free (struct event_base *base);
-
-#define EVLOOP_ONCE EVLOOP_ONESHOT
-int event_loop (int);
-int event_loopexit (struct timeval *tv);
-int event_dispatch (void);
-
-#define _EVENT_LOG_DEBUG 0
-#define _EVENT_LOG_MSG 1
-#define _EVENT_LOG_WARN 2
-#define _EVENT_LOG_ERR 3
-typedef void (*event_log_cb)(int severity, const char *msg);
-void event_set_log_callback(event_log_cb cb);
-
-void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg);
-int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
-
-int event_add (struct event *ev, struct timeval *tv);
-int event_del (struct event *ev);
-void event_active (struct event *ev, int res, short ncalls); /* ncalls is being ignored */
-
-int event_pending (struct event *ev, short, struct timeval *tv);
-
-int event_priority_init (int npri);
-int event_priority_set (struct event *ev, int pri);
-
-struct event_base *event_base_new (void);
-const char *event_base_get_method (const struct event_base *);
-int event_base_set (struct event_base *base, struct event *ev);
-int event_base_loop (struct event_base *base, int);
-int event_base_loopexit (struct event_base *base, struct timeval *tv);
-int event_base_dispatch (struct event_base *base);
-int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
-int event_base_priority_init (struct event_base *base, int fd);
-
-/* next line is different in the libevent+libev version */
-/*libevent-include*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/framework/src/audit/src/libev/libev.m4 b/framework/src/audit/src/libev/libev.m4
deleted file mode 100644
index 439fbde2..00000000
--- a/framework/src/audit/src/libev/libev.m4
+++ /dev/null
@@ -1,42 +0,0 @@
-dnl this file is part of libev, do not make local modifications
-dnl http://software.schmorp.de/pkg/libev
-
-dnl libev support
-AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h)
-
-AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd)
-
-AC_CHECK_FUNCS(clock_gettime, [], [
- dnl on linux, try syscall wrapper first
- if test $(uname) = Linux; then
- AC_MSG_CHECKING(for clock_gettime syscall)
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
- [#include <unistd.h>
- #include <sys/syscall.h>
- #include <time.h>],
- [struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)])],
- [ac_have_clock_syscall=1
- AC_DEFINE(HAVE_CLOCK_SYSCALL, 1, Define to 1 to use the syscall interface for clock_gettime)
- AC_MSG_RESULT(yes)],
- [AC_MSG_RESULT(no)])
- fi
- if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then
- AC_CHECK_LIB(rt, clock_gettime)
- unset ac_cv_func_clock_gettime
- AC_CHECK_FUNCS(clock_gettime)
- fi
-])
-
-AC_CHECK_FUNCS(nanosleep, [], [
- if test -z "$LIBEV_M4_AVOID_LIBRT"; then
- AC_CHECK_LIB(rt, nanosleep)
- unset ac_cv_func_nanosleep
- AC_CHECK_FUNCS(nanosleep)
- fi
-])
-
-if test -z "$LIBEV_M4_AVOID_LIBM"; then
- LIBM=m
-fi
-AC_SEARCH_LIBS(floor, $LIBM, [AC_DEFINE(HAVE_FLOOR, 1, Define to 1 if the floor function is available)])
-
diff --git a/framework/src/audit/src/mt/Makefile.am b/framework/src/audit/src/mt/Makefile.am
deleted file mode 100644
index 1d613d79..00000000
--- a/framework/src/audit/src/mt/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
-# Makefile.am --
-# Copyright 2005-06,2008,2012,2014-15 Red Hat Inc., Durham, North Carolina.
-# All Rights Reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Authors:
-# Steve Grubb <sgrubb@redhat.com>
-#
-# This make file builds a static multi-threaded libary for the audit
-# daemon's own use.
-
-AUTOMAKE_OPTIONS = no-dependencies
-AM_CPPFLAGS = -I${top_srcdir}/lib -I${top_builddir}/lib
-CONFIG_CLEAN_FILES = *.rej *.orig
-AM_CFLAGS = -fPIC -DPIC -D_REENTRANT -D_GNU_SOURCE -DNO_TABLES
-
-noinst_LIBRARIES = libauditmt.a
-
-libauditmt_a_SOURCES = ${top_srcdir}/lib/libaudit.c \
- ${top_srcdir}/lib/message.c ${top_srcdir}/lib/netlink.c \
- ${top_srcdir}/lib/lookup_table.c ${top_srcdir}/lib/audit_logging.c \
- ${top_srcdir}/lib/deprecated.c ${top_srcdir}/lib/strsplit.c
-libauditmt_a_HEADERS: ${top_builddir}/config.h ${top_srcdir}/lib/libaudit.h \
- ${top_srcdir}/lib/private.h
-libauditmt_a_DEPENDENCIES = $(libaudit_a_SOURCES) ${top_builddir}/config.h \
- ${top_srcdir}/lib/gen_tables.h ${top_builddir}/lib/i386_tables.h \
- ${top_builddir}/lib/ia64_tables.h ${top_builddir}/lib/ppc_tables.h \
- ${top_builddir}/lib/s390_tables.h ${top_builddir}/lib/s390x_tables.h \
- ${top_builddir}/lib/x86_64_tables.h ${top_srcdir}/lib/private.h \
- ${top_builddir}/lib/actiontabs.h ${top_builddir}/lib/fieldtabs.h \
- ${top_builddir}/lib/flagtabs.h ${top_builddir}/lib/ftypetabs.h \
- ${top_builddir}/lib/machinetabs.h ${top_builddir}/lib/msg_typetabs.h \
- ${top_builddir}/lib/optabs.h
-AM_LDFLAGS = -Wl,-z,relro
-
-lib_OBJECTS = $(libauditmt_a_OBJECTS)
diff --git a/framework/src/audit/src/test/Makefile.am b/framework/src/audit/src/test/Makefile.am
deleted file mode 100644
index b6f44edb..00000000
--- a/framework/src/audit/src/test/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2008,2014,2015 Red Hat Inc., Durham, North Carolina.
-# All Rights Reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Authors:
-# Steve Grubb <sgrubb@redhat.com>
-#
-
-AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/src
-check_PROGRAMS = ilist_test slist_test
-TESTS = $(check_PROGRAMS)
-ilist_test_LDADD = ${top_builddir}/src/ausearch-int.o
-slist_test_LDADD = ${top_builddir}/src/ausearch-string.o
diff --git a/framework/src/audit/src/test/ilist_test.c b/framework/src/audit/src/test/ilist_test.c
deleted file mode 100644
index 85787126..00000000
--- a/framework/src/audit/src/test/ilist_test.c
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <stdio.h>
-#include "ausearch-int.h"
-
-int main(void)
-{
- int i = 0;
- ilist e;
- int_node *node;
-
- ilist_create(&e);
-
- // This first test checks to see if list is
- // created in a numeric order
- ilist_add_if_uniq(&e, 6, 0);
- ilist_add_if_uniq(&e, 5, 0);
- ilist_add_if_uniq(&e, 7, 0);
- ilist_add_if_uniq(&e, 1, 0);
- ilist_add_if_uniq(&e, 8, 0);
- ilist_add_if_uniq(&e, 2, 0);
- ilist_add_if_uniq(&e, 9, 0);
- ilist_add_if_uniq(&e, 0, 0);
- ilist_add_if_uniq(&e, 4, 0);
- ilist_add_if_uniq(&e, 3, 0);
-
- ilist_first(&e);
- do {
- node = ilist_get_cur(&e);
- if (i != node->num) {
- printf("Test failed - i:%d != num:%d\n", i, node->num);
- return 1;
- }
- i++;
- } while ((node = ilist_next(&e)));
-
- ilist_clear(&e);
- puts("starting sort test");
-
- // Now test to see if the sort function works
- // Fill the list exactly backwards
- ilist_add_if_uniq(&e, 3, 0);
- ilist_add_if_uniq(&e, 3, 0);
- ilist_add_if_uniq(&e, 4, 0);
- ilist_add_if_uniq(&e, 3, 0);
- ilist_add_if_uniq(&e, 4, 0);
- ilist_add_if_uniq(&e, 2, 0);
- ilist_add_if_uniq(&e, 4, 0);
- ilist_add_if_uniq(&e, 2, 0);
- ilist_add_if_uniq(&e, 4, 0);
- ilist_add_if_uniq(&e, 1, 0);
-
- ilist_sort_by_hits(&e);
-
- i = 0;
- ilist_first(&e);
- do {
- node = ilist_get_cur(&e);
- if (node->hits != (4-i)) {
- printf("Sort test failed - i:%d != ihits:%d\n", i, node->hits);
- return 1;
- }
- i++;
- } while ((node = ilist_next(&e)));
-
- ilist_clear(&e);
-
- printf("ilist tests passed\n");
- return 0;
-}
-
diff --git a/framework/src/audit/src/test/slist_test.c b/framework/src/audit/src/test/slist_test.c
deleted file mode 100644
index e0336149..00000000
--- a/framework/src/audit/src/test/slist_test.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "ausearch-string.h"
-
-slist s;
-
-int print_list(void)
-{
- int cnt = 0;
- slist_first(&s);
- do {
- snode *cur = slist_get_cur(&s);
- if (cur) {
- cnt++;
- printf("%s\n", cur->str);
- }
- } while (slist_next(&s));
- return cnt;
-}
-
-int main(void)
-{
- snode n, *node;
- int rc, i = 0;
-
- slist_create(&s);
-
- // This first test checks to see if list is
- // created in a numeric order
- slist_add_if_uniq(&s, "test1");
- slist_add_if_uniq(&s, "test2");
- slist_first(&s);
- slist_add_if_uniq(&s, "test3");
- puts("should be 3");
- rc = print_list();
- if (s.cnt != 3 || rc !=3) {
- puts("test count is wrong");
- return 1;
- }
-
- n.str = strdup("test4");
- n.key = NULL;
- n.hits = 1;
- slist_append(&s, &n);
- puts("should add a #4");
- rc = print_list();
- if (s.cnt != 4 || rc != 4) {
- puts("test count is wrong");
- return 1;
- }
-
- slist_add_if_uniq(&s, "test2");
- puts("should be same");
- rc = print_list();
- if (s.cnt != 4 || rc != 4) {
- puts("test count is wrong");
- return 1;
- }
-
- slist_clear(&s);
- puts("should be empty");
- rc = print_list();
- if (s.cnt != 0 || rc != 0) {
- puts("test count is wrong");
- return 1;
- }
- puts("starting sort test");
-
- // Now test to see if the sort function works
- // Fill the list exactly backwards
- slist_add_if_uniq(&s, "test3");
- slist_add_if_uniq(&s, "test3");
- slist_add_if_uniq(&s, "test4");
- slist_add_if_uniq(&s, "test3");
- slist_add_if_uniq(&s, "test4");
- slist_add_if_uniq(&s, "test2");
- slist_add_if_uniq(&s, "test4");
- slist_add_if_uniq(&s, "test2");
- slist_add_if_uniq(&s, "test4");
- slist_add_if_uniq(&s, "test1");
-
- slist_sort_by_hits(&s);
- slist_first(&s);
- do {
- node = slist_get_cur(&s);
- if (node->hits != (4-i)) {
- printf("Sort test failed - i:%d != hits:%d\n", i, node->hits);
- return 1;
- }
- i++;
- } while ((node = slist_next(&s)));
- puts("sort test passes");
-
- slist_clear(&s);
-
- return 0;
-}
-