aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/audit/src/auditctl-listing.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/audit/src/auditctl-listing.c')
-rw-r--r--framework/src/audit/src/auditctl-listing.c577
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;
-}
-