diff options
author | Ashlee Young <ashlee@wildernessvoice.com> | 2015-11-29 08:22:13 -0800 |
---|---|---|
committer | Ashlee Young <ashlee@wildernessvoice.com> | 2015-11-29 08:22:13 -0800 |
commit | df5afa4fcd9725380f94ca6476248d4cc24f889a (patch) | |
tree | 65456f62397305febf7f40778c5a413a35d094ef /framework/src/audit/audisp/audispd-builtins.c | |
parent | 76f6bf922552c00546e6e85ca471eab28f56986c (diff) |
v2.4.4 audit sources
Change-Id: I9315a7408817db51edf084fb4d27fbb492785084
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/audit/audisp/audispd-builtins.c')
-rw-r--r-- | framework/src/audit/audisp/audispd-builtins.c | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/framework/src/audit/audisp/audispd-builtins.c b/framework/src/audit/audisp/audispd-builtins.c new file mode 100644 index 00000000..f0da6475 --- /dev/null +++ b/framework/src/audit/audisp/audispd-builtins.c @@ -0,0 +1,330 @@ +/* +* audispd-builtins.c - some common builtin plugins +* Copyright (c) 2007,2010,2013 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 <dirent.h> +#include <libgen.h> +#include <ctype.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/un.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "audispd-pconfig.h" +#include "audispd-builtins.h" + +// Local data +static volatile int sock = -1, conn = -1; +static int syslog_started = 0, priority; +static char *path = NULL; + +// Local prototypes +static void init_af_unix(const plugin_conf_t *conf); +static void init_syslog(const plugin_conf_t *conf); + + +void start_builtin(plugin_conf_t *conf) +{ + if (strcasecmp("builtin_af_unix", conf->path) == 0) { + conf->type = S_AF_UNIX; + init_af_unix(conf); + } else if (strcasecmp("builtin_syslog", conf->path) == 0) { + conf->type = S_SYSLOG; + init_syslog(conf); + } else + syslog(LOG_ERR, "Unknown builtin %s", conf->path); +} + +void stop_builtin(plugin_conf_t *conf) +{ + if (conf->type == S_AF_UNIX) + destroy_af_unix(); + else if (conf->type == S_SYSLOG) + destroy_syslog(); + else + syslog(LOG_ERR, "Unknown builtin %s", conf->path); +} + +static void af_unix_accept(int fd) +{ + int cmd; + + do { + conn = accept(fd, NULL, NULL); + } while (conn < 0 && errno == EINTR); + + // De-register since this is intended to be one listener + if (conn >= 0) + remove_event(fd); + cmd = fcntl(conn, F_GETFD); + fcntl(conn, F_SETFD, cmd|FD_CLOEXEC); +} + +static int create_af_unix_socket(const char *path, int mode) +{ + struct sockaddr_un addr; + socklen_t len; + int rc, cmd; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + syslog(LOG_ERR, "Couldn't open af_unix socket (%s)", + strerror(errno)); + return -1; + } + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(&addr.sun_path[0], path); + len = sizeof(addr); + rc = bind(sock, (const struct sockaddr *)&addr, len); + if (rc < 0) { + syslog(LOG_ERR, "Couldn't bind af_unix socket (%s)", + strerror(errno)); + destroy_af_unix(); + return -1; + } + if (mode != -1) { + rc = chmod(path, mode); + if (rc < 0) { + syslog(LOG_ERR, "Couldn't chmod %s to %04o (%s)", + path, mode, strerror(errno)); + destroy_af_unix(); + return -1; + } + } + + // Put socket in nonblock mode + cmd = fcntl(sock, F_GETFL); + fcntl(sock, F_SETFL, cmd|FNDELAY); + + // don't leak the descriptor + cmd = fcntl(sock, F_GETFD); + fcntl(sock, F_SETFD, cmd|FD_CLOEXEC); + + // Make socket listening...won't block + (void)listen(sock, 5); + + // Register socket with poll + add_event(sock, af_unix_accept); + return 0; +} + +static void init_af_unix(const plugin_conf_t *conf) +{ + int i = 1, mode = -1; + char *base = NULL; + + // while args + while (conf->args[i]) { + int rc, bad = 0; + + // is all nums - do mode + base = conf->args[i]; + while (*base) { + if (!isdigit(*base)) { + bad = 1; + break; + } + base++; + } + if (!bad) { + errno = 0; + mode = strtoul(conf->args[i], NULL, 8); + if (errno) { + syslog(LOG_ERR, "Error converting %s (%s)", + conf->args[i], strerror(errno)); + mode = -1; + bad = 1; + } else if (path) { + rc = chmod(path, mode); + if (rc < 0) { + syslog(LOG_ERR, + "Couldn't chmod %s to %04o (%s)", + conf->args[i], mode, + strerror(errno)); + destroy_af_unix(); + return; + } + } + } else { + // else check for '/' + base = strchr(conf->args[i], '/'); + if (base) { + // get dirname + DIR *d; + char *dir = strdup(conf->args[i]); + base = dirname(dir); + d = opendir(base); + if (d) { + closedir(d); + unlink(conf->args[i]); + if (create_af_unix_socket( + conf->args[i], mode)<0) { + free(dir); + return; + } + path = strdup(conf->args[i]); + bad = 0; + } else + syslog(LOG_ERR, "Couldn't open %s (%s)", + base, strerror(errno)); + free(dir); + } else + syslog(LOG_ERR, "Malformed path %s", + conf->args[i]); + } + if (bad) { + destroy_af_unix(); + return; + } + i++; + } + syslog(LOG_INFO, "af_unix plugin initialized"); +} + +void send_af_unix_string(const char *s, unsigned int len) +{ + if (sock < 0) + return; + + if (conn >= 0) { + int rc; + do { + rc = write(conn, s, len); + } while (rc < 0 && errno == EINTR); + if (rc < 0 && errno == EPIPE) { + close(conn); + conn = -1; + add_event(sock, af_unix_accept); + } + } +} + +void send_af_unix_binary(event_t *e) +{ + if (sock < 0) + return; + + if (conn >= 0) { + int rc; + struct iovec vec[2]; + + vec[0].iov_base = &e->hdr; + vec[0].iov_len = sizeof(struct audit_dispatcher_header); + vec[1].iov_base = e->data; + vec[1].iov_len = MAX_AUDIT_MESSAGE_LENGTH; + do { + rc = writev(conn, vec, 2); + } while (rc < 0 && errno == EINTR); + if (rc < 0 && errno == EPIPE) { + close(conn); + conn = -1; + add_event(sock, af_unix_accept); + } + } +} + +void destroy_af_unix(void) +{ + if (conn >= 0) { + close(conn); + conn = -1; + } + if (sock >= 0) { + close(sock); + sock = -1; + } + if (path) { + unlink(path); + free(path); + path = NULL; + } +} + +static void init_syslog(const plugin_conf_t *conf) +{ + int i, facility = LOG_USER; + priority = LOG_INFO; + + for (i = 1; i<3; i++) { + if (conf->args[i]) { + if (strcasecmp(conf->args[i], "LOG_DEBUG") == 0) + priority = LOG_DEBUG; + else if (strcasecmp(conf->args[i], "LOG_INFO") == 0) + priority = LOG_INFO; + else if (strcasecmp(conf->args[i], "LOG_NOTICE") == 0) + priority = LOG_NOTICE; + else if (strcasecmp(conf->args[i], "LOG_WARNING") == 0) + priority = LOG_WARNING; + else if (strcasecmp(conf->args[i], "LOG_ERR") == 0) + priority = LOG_ERR; + else if (strcasecmp(conf->args[i], "LOG_CRIT") == 0) + priority = LOG_CRIT; + else if (strcasecmp(conf->args[i], "LOG_ALERT") == 0) + priority = LOG_ALERT; + else if (strcasecmp(conf->args[i], "LOG_EMERG") == 0) + priority = LOG_EMERG; + else if (strcasecmp(conf->args[i], "LOG_LOCAL0") == 0) + facility = LOG_LOCAL0; + else if (strcasecmp(conf->args[i], "LOG_LOCAL1") == 0) + facility = LOG_LOCAL1; + else if (strcasecmp(conf->args[i], "LOG_LOCAL2") == 0) + facility = LOG_LOCAL2; + else if (strcasecmp(conf->args[i], "LOG_LOCAL3") == 0) + facility = LOG_LOCAL3; + else if (strcasecmp(conf->args[i], "LOG_LOCAL4") == 0) + facility = LOG_LOCAL4; + else if (strcasecmp(conf->args[i], "LOG_LOCAL5") == 0) + facility = LOG_LOCAL5; + else if (strcasecmp(conf->args[i], "LOG_LOCAL6") == 0) + facility = LOG_LOCAL6; + else if (strcasecmp(conf->args[i], "LOG_LOCAL7") == 0) + facility = LOG_LOCAL7; + else { + syslog(LOG_ERR, + "Unknown log priority/facility %s", + conf->args[i]); + syslog_started = 0; + return; + } + } + } + syslog(LOG_INFO, "syslog plugin initialized"); + if (facility != LOG_USER) + openlog("audispd", 0, facility); + syslog_started = 1; +} + +void send_syslog(const char *s) +{ + if (syslog_started) + syslog(priority, "%s", s); +} + +void destroy_syslog(void) +{ + syslog_started = 0; +} + |