From 47be9ff57e72906660bb62a515222f482131e1fb Mon Sep 17 00:00:00 2001 From: Miroslav Grepl Date: Fri, 11 Apr 2014 09:37:53 +0200 Subject: Create setools-3.3.7 git repo --- libseaudit/src/sort.c | 744 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 744 insertions(+) create mode 100644 libseaudit/src/sort.c (limited to 'libseaudit/src/sort.c') diff --git a/libseaudit/src/sort.c b/libseaudit/src/sort.c new file mode 100644 index 0000000..2d119b9 --- /dev/null +++ b/libseaudit/src/sort.c @@ -0,0 +1,744 @@ +/** + * @file + * Implementation of seaudit sort routines. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * @author Jeremy Solt jsolt@tresys.com + * + * Copyright (C) 2003-2007 Tresys Technology, LLC + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "seaudit_internal.h" + +#include + +#include +#include + +/** + * Callback that compares two messages. + */ +typedef int (sort_comp_func) (const seaudit_sort_t * sort, const seaudit_message_t * a, const seaudit_message_t * b); + +/** + * Callback that returns non-zero if the sort routine can handle the + * given message, 0 if not supported. + */ +typedef int (sort_supported_func) (const seaudit_sort_t * sort, const seaudit_message_t * m); + +struct seaudit_sort +{ + const char *name; + sort_comp_func *comp; + sort_supported_func *support; + int direction; +}; + +seaudit_sort_t *seaudit_sort_create_from_sort(const seaudit_sort_t * sort) +{ + seaudit_sort_t *s; + if (sort == NULL) { + errno = EINVAL; + return NULL; + } + if ((s = calloc(1, sizeof(*s))) == NULL) { + return NULL; + } + s->name = sort->name; + s->comp = sort->comp; + s->support = sort->support; + s->direction = sort->direction; + return s; +} + +void seaudit_sort_destroy(seaudit_sort_t ** sort) +{ + if (sort != NULL && *sort != NULL) { + free(*sort); + *sort = NULL; + } +} + +static seaudit_sort_t *sort_create(const char *name, sort_comp_func * comp, sort_supported_func support, const int direction) +{ + seaudit_sort_t *s = calloc(1, sizeof(*s)); + if (s == NULL) { + return NULL; + } + s->name = name; + s->comp = comp; + s->support = support; + s->direction = direction; + return s; +} + +seaudit_sort_t *sort_create_from_sort(const seaudit_sort_t * sort) +{ + if (sort == NULL) { + errno = EINVAL; + return NULL; + } + return sort_create(sort->name, sort->comp, sort->support, sort->direction); +} + +static int sort_message_type_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + if (a->type != b->type) { + return a->type - b->type; + } + if (a->type == SEAUDIT_MESSAGE_TYPE_AVC) { + return a->data.avc->msg - b->data.avc->msg; + } + return 0; +} + +static int sort_message_type_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type != SEAUDIT_MESSAGE_TYPE_INVALID; +} + +seaudit_sort_t *seaudit_sort_by_message_type(const int direction) +{ + return sort_create("message_type", sort_message_type_comp, sort_message_type_support, direction); +} + +/** + * Given two dates compare them, checking to see if the dates passed + * in have valid years and correcting if not before comparing. + */ +static int sort_date_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + /* tm has year, month, day, hour, min, sec */ + /* if we should compare the years */ + struct tm *t1 = a->date_stamp; + struct tm *t2 = b->date_stamp; + int retval; + if (t1->tm_year != 0 && t2->tm_year != 0 && (retval = t1->tm_year - t2->tm_year) != 0) { + return retval; + } + if ((retval = t1->tm_mon - t2->tm_mon) != 0) { + return retval; + } + if ((retval = t1->tm_mday - t2->tm_mday) != 0) { + return retval; + } + if ((retval = t1->tm_hour - t2->tm_hour) != 0) { + return retval; + } + if ((retval = t1->tm_min - t2->tm_min) != 0) { + return retval; + } + if ((retval = t1->tm_sec - t2->tm_sec) != 0) { + return retval; + } + return 0; +} + +static int sort_date_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->date_stamp != NULL; +} + +seaudit_sort_t *seaudit_sort_by_date(const int direction) +{ + return sort_create("date", sort_date_comp, sort_date_support, direction); +} + +static int sort_host_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->host, b->host); +} + +static int sort_host_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->host != NULL; +} + +seaudit_sort_t *seaudit_sort_by_host(const int direction) +{ + return sort_create("host", sort_host_comp, sort_host_support, direction); +} + +static int sort_perm_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + size_t i; + return apol_vector_compare(a->data.avc->perms, b->data.avc->perms, apol_str_strcmp, NULL, &i); +} + +static int sort_perm_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && + msg->data.avc->perms != NULL && apol_vector_get_size(msg->data.avc->perms) >= 1; +} + +seaudit_sort_t *seaudit_sort_by_permission(const int direction) +{ + return sort_create("permission", sort_perm_comp, sort_perm_support, direction); +} + +static int sort_source_user_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->suser, b->data.avc->suser); +} + +static int sort_source_user_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->suser != NULL; +} + +seaudit_sort_t *seaudit_sort_by_source_user(const int direction) +{ + return sort_create("source_user", sort_source_user_comp, sort_source_user_support, direction); +} + +static int sort_source_role_comp(const seaudit_sort_t * sort __attribute((unused)), const seaudit_message_t * a, + const seaudit_message_t * b) +{ + return strcmp(a->data.avc->srole, b->data.avc->srole); +} + +static int sort_source_role_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->srole != NULL; +} + +seaudit_sort_t *seaudit_sort_by_source_role(const int direction) +{ + return sort_create("source_role", sort_source_role_comp, sort_source_role_support, direction); +} + +static int sort_source_type_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->stype, b->data.avc->stype); +} + +static int sort_source_type_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->stype != NULL; +} + +seaudit_sort_t *seaudit_sort_by_source_type(const int direction) +{ + return sort_create("source_type", sort_source_type_comp, sort_source_type_support, direction); +} + +static int sort_source_mls_lvl_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->smls_lvl, b->data.avc->smls_lvl); +} + +static int sort_source_mls_lvl_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->smls_lvl != NULL; +} + +seaudit_sort_t *seaudit_sort_by_source_mls_lvl(const int direction) +{ + return sort_create("source_mls_lvl", sort_source_mls_lvl_comp, sort_source_mls_lvl_support, direction); +} + +static int sort_source_mls_clr_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->smls_clr, b->data.avc->smls_clr); +} + +static int sort_source_mls_clr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->smls_clr != NULL; +} + +seaudit_sort_t *seaudit_sort_by_source_mls_clr(const int direction) +{ + return sort_create("source_mls_clr", sort_source_mls_clr_comp, sort_source_mls_clr_support, direction); +} + +static int sort_target_user_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->tuser, b->data.avc->tuser); +} + +static int sort_target_user_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tuser != NULL; +} + +seaudit_sort_t *seaudit_sort_by_target_user(const int direction) +{ + return sort_create("target_user", sort_target_user_comp, sort_target_user_support, direction); +} + +static int sort_target_role_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->trole, b->data.avc->trole); +} + +static int sort_target_role_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->trole != NULL; +} + +seaudit_sort_t *seaudit_sort_by_target_role(const int direction) +{ + return sort_create("target_role", sort_target_role_comp, sort_target_role_support, direction); +} + +static int sort_target_type_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->ttype, b->data.avc->ttype); +} + +static int sort_target_type_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->ttype != NULL; +} + +seaudit_sort_t *seaudit_sort_by_target_type(const int direction) +{ + return sort_create("target_type", sort_target_type_comp, sort_target_type_support, direction); +} + +static int sort_target_mls_lvl_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->tmls_lvl, b->data.avc->tmls_lvl); +} + +static int sort_target_mls_lvl_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tmls_lvl != NULL; +} + +seaudit_sort_t *seaudit_sort_by_target_mls_lvl(const int direction) +{ + return sort_create("target_mls_lvl", sort_target_mls_lvl_comp, sort_target_mls_lvl_support, direction); +} + +static int sort_target_mls_clr_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->tmls_clr, b->data.avc->tmls_clr); +} + +static int sort_target_mls_clr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tmls_clr != NULL; +} + +seaudit_sort_t *seaudit_sort_by_target_mls_clr(const int direction) +{ + return sort_create("target_mls_clr", sort_target_mls_clr_comp, sort_target_mls_clr_support, direction); +} + +static int sort_object_class_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->tclass, b->data.avc->tclass); +} + +static int sort_object_class_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tclass != NULL; +} + +seaudit_sort_t *seaudit_sort_by_object_class(const int direction) +{ + return sort_create("object_class", sort_object_class_comp, sort_object_class_support, direction); +} + +static int sort_executable_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->exe, b->data.avc->exe); +} + +static int sort_executable_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->exe != NULL; +} + +seaudit_sort_t *seaudit_sort_by_executable(const int direction) +{ + return sort_create("executable", sort_executable_comp, sort_executable_support, direction); +} + +static int sort_command_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->comm, b->data.avc->comm); +} + +static int sort_command_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->comm != NULL; +} + +seaudit_sort_t *seaudit_sort_by_command(const int direction) +{ + return sort_create("command", sort_command_comp, sort_command_support, direction); +} + +static int sort_name_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->name, b->data.avc->name); +} + +static int sort_name_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->name != NULL; +} + +seaudit_sort_t *seaudit_sort_by_name(const int direction) +{ + return sort_create("name", sort_name_comp, sort_name_support, direction); +} + +static int sort_path_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->path, b->data.avc->path); +} + +static int sort_path_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->path != NULL; +} + +seaudit_sort_t *seaudit_sort_by_path(const int direction) +{ + return sort_create("path", sort_path_comp, sort_path_support, direction); +} + +static int sort_device_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->dev, b->data.avc->dev); +} + +static int sort_device_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->dev != NULL; +} + +seaudit_sort_t *seaudit_sort_by_device(const int direction) +{ + return sort_create("device", sort_device_comp, sort_device_support, direction); +} + +static int sort_inode_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + /* need this logic because inodes are unsigned, so subtraction + * could overflow */ + if (a->data.avc->inode < b->data.avc->inode) { + return -1; + } + return a->data.avc->inode - b->data.avc->inode; +} + +static int sort_inode_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->inode > 0; +} + +seaudit_sort_t *seaudit_sort_by_inode(const int direction) +{ + return sort_create("inode", sort_inode_comp, sort_inode_support, direction); +} + +static int sort_pid_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + /* need this logic because pids are unsigned, so subtraction + * could overflow */ + if (a->data.avc->pid < b->data.avc->pid) { + return -1; + } + return a->data.avc->pid - b->data.avc->pid; +} + +static int sort_pid_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->pid > 0; +} + +seaudit_sort_t *seaudit_sort_by_pid(const int direction) +{ + return sort_create("pid", sort_pid_comp, sort_pid_support, direction); +} + +static int sort_port_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->port - b->data.avc->port; +} + +static int sort_port_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->port > 0; +} + +seaudit_sort_t *seaudit_sort_by_port(const int direction) +{ + return sort_create("port", sort_port_comp, sort_port_support, direction); +} + +static int sort_laddr_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->laddr, b->data.avc->laddr); +} + +static int sort_laddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->laddr != NULL; +} + +seaudit_sort_t *seaudit_sort_by_laddr(const int direction) +{ + return sort_create("laddr", sort_laddr_comp, sort_laddr_support, direction); +} + +static int sort_lport_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->lport - b->data.avc->lport; +} + +static int sort_lport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->lport > 0; +} + +seaudit_sort_t *seaudit_sort_by_lport(const int direction) +{ + return sort_create("lport", sort_lport_comp, sort_lport_support, direction); +} + +static int sort_faddr_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->faddr, b->data.avc->faddr); +} + +static int sort_faddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->faddr != NULL; +} + +seaudit_sort_t *seaudit_sort_by_faddr(const int direction) +{ + return sort_create("faddr", sort_faddr_comp, sort_faddr_support, direction); +} + +static int sort_fport_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->fport - b->data.avc->fport; +} + +static int sort_fport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->fport > 0; +} + +seaudit_sort_t *seaudit_sort_by_fport(const int direction) +{ + return sort_create("fport", sort_fport_comp, sort_fport_support, direction); +} + +static int sort_saddr_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->saddr, b->data.avc->saddr); +} + +static int sort_saddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->saddr != NULL; +} + +seaudit_sort_t *seaudit_sort_by_saddr(const int direction) +{ + return sort_create("saddr", sort_saddr_comp, sort_saddr_support, direction); +} + +static int sort_sport_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->source - b->data.avc->source; +} + +static int sort_sport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->source > 0; +} + +seaudit_sort_t *seaudit_sort_by_sport(const int direction) +{ + return sort_create("sport", sort_sport_comp, sort_sport_support, direction); +} + +static int sort_daddr_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return strcmp(a->data.avc->daddr, b->data.avc->daddr); +} + +static int sort_daddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->daddr != NULL; +} + +seaudit_sort_t *seaudit_sort_by_daddr(const int direction) +{ + return sort_create("daddr", sort_daddr_comp, sort_daddr_support, direction); +} + +static int sort_dport_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->dest - b->data.avc->dest; +} + +static int sort_dport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->dest > 0; +} + +seaudit_sort_t *seaudit_sort_by_dport(const int direction) +{ + return sort_create("dport", sort_dport_comp, sort_dport_support, direction); +} + +static int sort_key_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->key - b->data.avc->key; +} + +static int sort_key_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_key; +} + +seaudit_sort_t *seaudit_sort_by_key(const int direction) +{ + return sort_create("key", sort_key_comp, sort_key_support, direction); +} + +static int sort_cap_comp(const seaudit_sort_t * sort + __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b) +{ + return a->data.avc->capability - b->data.avc->capability; +} + +static int sort_cap_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg) +{ + return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_capability; +} + +seaudit_sort_t *seaudit_sort_by_cap(const int direction) +{ + return sort_create("cap", sort_cap_comp, sort_cap_support, direction); +} + +/******************** protected functions below ********************/ + +struct sort_name_map +{ + const char *name; + seaudit_sort_t *(*create_fn) (int); +}; + +static const struct sort_name_map create_map[] = { + {"message_type", seaudit_sort_by_message_type}, + {"date", seaudit_sort_by_date}, + {"host", seaudit_sort_by_host}, + {"permission", seaudit_sort_by_permission}, + {"source_user", seaudit_sort_by_source_user}, + {"source_role", seaudit_sort_by_source_role}, + {"source_type", seaudit_sort_by_source_type}, + {"target_user", seaudit_sort_by_target_user}, + {"target_role", seaudit_sort_by_target_role}, + {"target_type", seaudit_sort_by_target_type}, + {"object_class", seaudit_sort_by_object_class}, + {"executable", seaudit_sort_by_executable}, + {"name", seaudit_sort_by_name}, + {"command", seaudit_sort_by_command}, + {"path", seaudit_sort_by_path}, + {"device", seaudit_sort_by_device}, + {"inode", seaudit_sort_by_inode}, + {"pid", seaudit_sort_by_pid}, + {"port", seaudit_sort_by_port}, + {"laddr", seaudit_sort_by_laddr}, + {"lport", seaudit_sort_by_lport}, + {"faddr", seaudit_sort_by_faddr}, + {"fport", seaudit_sort_by_fport}, + {"saddr", seaudit_sort_by_saddr}, + {"sport", seaudit_sort_by_sport}, + {"daddr", seaudit_sort_by_daddr}, + {"dport", seaudit_sort_by_dport}, + {"key", seaudit_sort_by_key}, + {"cap", seaudit_sort_by_cap}, + {NULL, NULL} +}; + +seaudit_sort_t *sort_create_from_name(const char *name, int direction) +{ + size_t i; + for (i = 0; create_map[i].name != NULL; i++) { + if (strcmp(create_map[i].name, name) == 0) { + return create_map[i].create_fn(direction); + } + } + errno = EINVAL; + return NULL; +} + +int sort_is_supported(const seaudit_sort_t * sort, const seaudit_message_t * msg) +{ + return sort->support(sort, msg); +} + +int sort_comp(const seaudit_sort_t * sort, const seaudit_message_t * a, const seaudit_message_t * b) +{ + int retval = sort->comp(sort, a, b); + return (sort->direction >= 0 ? retval : -1 * retval); +} + +const char *sort_get_name(const seaudit_sort_t * sort) +{ + return sort->name; +} + +int sort_get_direction(const seaudit_sort_t * sort) +{ + return sort->direction; +} -- cgit