/** * @file * Implementation for the main libseaudit object, seaudit_log_t. * * @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 #include #include #include seaudit_log_t *seaudit_log_create(seaudit_handle_fn_t fn, void *callback_arg) { seaudit_log_t *log = NULL; int error; if ((log = calloc(1, sizeof(*log))) == NULL) { return NULL; } log->fn = fn; log->handle_arg = callback_arg; if ((log->messages = apol_vector_create(message_free)) == NULL || (log->malformed_msgs = apol_vector_create(free)) == NULL || (log->models = apol_vector_create(NULL)) == NULL || (log->types = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->classes = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->roles = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->users = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->perms = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->mls_lvl = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->mls_clr = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->hosts = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->bools = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->managers = apol_bst_create(apol_str_strcmp, free)) == NULL) { error = errno; seaudit_log_destroy(&log); errno = error; return NULL; } return log; } void seaudit_log_destroy(seaudit_log_t ** log) { size_t i; if (log == NULL || *log == NULL) { return; } for (i = 0; i < apol_vector_get_size((*log)->models); i++) { seaudit_model_t *m = apol_vector_get_element((*log)->models, i); model_remove_log(m, *log); } apol_vector_destroy(&(*log)->messages); apol_vector_destroy(&(*log)->malformed_msgs); apol_vector_destroy(&(*log)->models); apol_bst_destroy(&(*log)->types); apol_bst_destroy(&(*log)->classes); apol_bst_destroy(&(*log)->roles); apol_bst_destroy(&(*log)->users); apol_bst_destroy(&(*log)->perms); apol_bst_destroy(&(*log)->hosts); apol_bst_destroy(&(*log)->bools); apol_bst_destroy(&(*log)->managers); apol_bst_destroy(&(*log)->mls_lvl); apol_bst_destroy(&(*log)->mls_clr); free(*log); *log = NULL; } void seaudit_log_clear(seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return; } apol_vector_destroy(&log->messages); apol_vector_destroy(&log->malformed_msgs); apol_bst_destroy(&log->types); apol_bst_destroy(&log->classes); apol_bst_destroy(&log->roles); apol_bst_destroy(&log->users); apol_bst_destroy(&log->perms); apol_bst_destroy(&log->hosts); apol_bst_destroy(&log->bools); apol_bst_destroy(&log->managers); apol_bst_destroy(&log->mls_lvl); apol_bst_destroy(&log->mls_clr); if ((log->messages = apol_vector_create(message_free)) == NULL || (log->malformed_msgs = apol_vector_create(free)) == NULL || (log->types = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->classes = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->roles = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->users = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->perms = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->mls_lvl = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->mls_clr = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->hosts = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->bools = apol_bst_create(apol_str_strcmp, free)) == NULL || (log->managers = apol_bst_create(apol_str_strcmp, free)) == NULL) { /* hopefully will never get here... */ return; } for (size_t i = 0; i < apol_vector_get_size(log->models); i++) { seaudit_model_t *m = apol_vector_get_element(log->models, i); model_notify_log_changed(m, log); } } apol_vector_t *seaudit_log_get_users(const seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return NULL; } return apol_bst_get_vector(log->users, 0); } apol_vector_t *seaudit_log_get_roles(const seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return NULL; } return apol_bst_get_vector(log->roles, 0); } apol_vector_t *seaudit_log_get_types(const seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return NULL; } return apol_bst_get_vector(log->types, 0); } apol_vector_t *seaudit_log_get_mls_lvl(const seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return NULL; } return apol_bst_get_vector(log->mls_lvl, 0); } apol_vector_t *seaudit_log_get_mls_clr(const seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return NULL; } return apol_bst_get_vector(log->mls_clr, 0); } apol_vector_t *seaudit_log_get_classes(const seaudit_log_t * log) { if (log == NULL) { errno = EINVAL; return NULL; } return apol_bst_get_vector(log->classes, 0); } /******************** protected functions below ********************/ int log_append_model(seaudit_log_t * log, seaudit_model_t * model) { if (apol_vector_append(log->models, model) < 0) { int error = errno; ERR(log, "%s", strerror(error)); errno = error; return -1; } return 0; } void log_remove_model(seaudit_log_t * log, seaudit_model_t * model) { size_t i; if (apol_vector_get_index(log->models, model, NULL, NULL, &i) == 0) { apol_vector_remove(log->models, i); } } const apol_vector_t *log_get_messages(const seaudit_log_t * log) { return log->messages; } const apol_vector_t *log_get_malformed_messages(const seaudit_log_t * log) { return log->malformed_msgs; } static void seaudit_handle_default_callback(void *arg __attribute__ ((unused)), const seaudit_log_t * log __attribute__ ((unused)), int level, const char *fmt, va_list va_args) { switch (level) { case SEAUDIT_MSG_INFO: { /* by default do not display these messages */ return; } case SEAUDIT_MSG_WARN: { fprintf(stderr, "WARNING: "); break; } case SEAUDIT_MSG_ERR: default: { fprintf(stderr, "ERROR: "); break; } } vfprintf(stderr, fmt, va_args); fprintf(stderr, "\n"); } void seaudit_handle_msg(const seaudit_log_t * log, int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); if (log == NULL || log->fn == NULL) { seaudit_handle_default_callback(NULL, NULL, level, fmt, ap); } else { log->fn(log->handle_arg, log, level, fmt, ap); } va_end(ap); }