diff options
Diffstat (limited to 'framework/src/audit/src/auditctl-listing.c')
-rw-r--r-- | framework/src/audit/src/auditctl-listing.c | 577 |
1 files changed, 0 insertions, 577 deletions
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; -} - |