From df5afa4fcd9725380f94ca6476248d4cc24f889a Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Sun, 29 Nov 2015 08:22:13 -0800 Subject: v2.4.4 audit sources Change-Id: I9315a7408817db51edf084fb4d27fbb492785084 Signed-off-by: Ashlee Young --- .../audit/audisp/plugins/zos-remote/Makefile.am | 52 ++ .../plugins/zos-remote/audispd-zos-remote.conf | 14 + .../audisp/plugins/zos-remote/zos-remote-config.c | 443 +++++++++++++++ .../audisp/plugins/zos-remote/zos-remote-config.h | 48 ++ .../audisp/plugins/zos-remote/zos-remote-ldap.c | 608 +++++++++++++++++++++ .../audisp/plugins/zos-remote/zos-remote-ldap.h | 312 +++++++++++ .../audisp/plugins/zos-remote/zos-remote-log.c | 109 ++++ .../audisp/plugins/zos-remote/zos-remote-log.h | 58 ++ .../audisp/plugins/zos-remote/zos-remote-plugin.c | 580 ++++++++++++++++++++ .../audisp/plugins/zos-remote/zos-remote-queue.c | 144 +++++ .../audisp/plugins/zos-remote/zos-remote-queue.h | 38 ++ .../audisp/plugins/zos-remote/zos-remote.conf | 10 + 12 files changed, 2416 insertions(+) create mode 100644 framework/src/audit/audisp/plugins/zos-remote/Makefile.am create mode 100644 framework/src/audit/audisp/plugins/zos-remote/audispd-zos-remote.conf create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.c create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.h create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.h create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.c create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.h create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-plugin.c create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-queue.c create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote-queue.h create mode 100644 framework/src/audit/audisp/plugins/zos-remote/zos-remote.conf (limited to 'framework/src/audit/audisp/plugins/zos-remote') diff --git a/framework/src/audit/audisp/plugins/zos-remote/Makefile.am b/framework/src/audit/audisp/plugins/zos-remote/Makefile.am new file mode 100644 index 00000000..ac83a74d --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/Makefile.am @@ -0,0 +1,52 @@ +# Makefile.am-- +# Copyright (C) 2007,2008 International Business Machines Corp. +# Copyright (C) 2011, 2015 Red Hat., 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: +# Klaus Heinrich Kiwi +# + +AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/auparse +CONFIG_CLEAN_FILES = *.rej *.orig +AUTOMAKE_OPTIONS = no-dependencies +EXTRA_DIST = zos-remote.conf audispd-zos-remote.conf +LIBS = -L${top_builddir}/auparse -lauparse +LDADD = -lpthread -lldap -llber $(CAPNG_LDADD) +dispatcher_confdir = $(sysconfdir)/audisp +plugin_confdir=$(dispatcher_confdir)/plugins.d +plugin_conf = zos-remote.conf +dispatcher_conf = audispd-zos-remote.conf +sbin_PROGRAMS = audispd-zos-remote + +noinst_HEADERS = zos-remote-log.h zos-remote-ldap.h zos-remote-config.h \ + zos-remote-queue.h +audispd_zos_remote_SOURCES = zos-remote-plugin.c zos-remote-log.c \ + zos-remote-ldap.c zos-remote-config.c zos-remote-queue.c +audispd_zos_remote_CFLAGS = -W -Wall -Wundef -D_GNU_SOURCE -fPIE -DPIE +audispd_zos_remote_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now + +install-data-hook: + mkdir -p -m 0750 ${DESTDIR}${plugin_confdir} + $(INSTALL_DATA) -D -m 640 ${srcdir}/$(plugin_conf) \ + ${DESTDIR}${dispatcher_confdir} + $(INSTALL_DATA) -D -m 640 ${srcdir}/$(dispatcher_conf) \ + ${DESTDIR}${plugin_confdir} + +uninstall-hook: + rm ${DESTDIR}${plugin_confdir}/$(dispatcher_conf) + rm ${DESTDIR}${dispatcher_confdir}/$(plugin_conf) diff --git a/framework/src/audit/audisp/plugins/zos-remote/audispd-zos-remote.conf b/framework/src/audit/audisp/plugins/zos-remote/audispd-zos-remote.conf new file mode 100644 index 00000000..13aef2ce --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/audispd-zos-remote.conf @@ -0,0 +1,14 @@ +# This is the configuration for the audispd-zos-remote +# audit dispatcher plugin - See audispd(8) +# +# Note that this specific plugin has a configuration file of +# its own. The complete path for this file must be entered as +# the argument for the plugin in the 'args' field below +# See audispd-zos-remote(8) + +active = no +direction = out +path = /sbin/audispd-zos-remote +type = always +args = /etc/audisp/zos-remote.conf +format = string diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.c b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.c new file mode 100644 index 00000000..b92dc778 --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.c @@ -0,0 +1,443 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + * based on code by Steve Grubb * + ***************************************************************************/ + +#include "zos-remote-config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "zos-remote-log.h" + +/* Local prototypes */ +struct nv_pair +{ + const char *name; + const char *value; + const char *option; +}; + +struct kw_pair +{ + const char *name; + int (*parser) (struct nv_pair *, int, plugin_conf_t *); + int max_options; +}; + +struct nv_list +{ + const char *name; + int option; +}; + +static char *get_line(FILE *, char *); +static int nv_split(char *, struct nv_pair *); +static const struct kw_pair *kw_lookup(const char *); +static int server_parser(struct nv_pair *, int, plugin_conf_t *); +static int port_parser(struct nv_pair *, int, plugin_conf_t *); +static int timeout_parser(struct nv_pair *, int, plugin_conf_t *); +static int user_parser(struct nv_pair *, int, plugin_conf_t *); +static int password_parser(struct nv_pair *, int, plugin_conf_t *); +static int q_depth_parser(struct nv_pair *, int, plugin_conf_t *); +static int sanity_check(plugin_conf_t *); + +static const struct kw_pair keywords[] = { + {"server", server_parser, 0}, + {"port", port_parser, 0}, + {"timeout", timeout_parser, 0}, + {"user", user_parser, 0}, + {"password", password_parser, 0}, + {"q_depth", q_depth_parser, 0}, + {NULL, NULL, 0} +}; + +#define UNUSED(x) (void)(x) + +/* + * Set everything to its default value +*/ +void plugin_clear_config(plugin_conf_t * c) +{ + c->server = NULL; + c->port = 0; + c->user = NULL; + c->password = NULL; + c->timeout = 15; + c->q_depth = 64; + /* not re-setting counter */ +} + +int plugin_load_config(plugin_conf_t * c, const char *file) +{ + int fd, rc, mode, lineno = 1; + struct stat st; + FILE *f; + char buf[128]; + + plugin_clear_config(c); + + /* open the file */ + mode = O_RDONLY; + rc = open(file, mode); + if (rc < 0) { + if (errno != ENOENT) { + log_err("Error opening %s (%s)", file, + strerror(errno)); + return 1; + } + log_warn("Config file %s doesn't exist, skipping", file); + return 1; + } + fd = rc; + + /* check the file's permissions: owned by root, not world anything, + * not symlink. + */ + if (fstat(fd, &st) < 0) { + log_err("Error fstat'ing config file (%s)", + strerror(errno)); + close(fd); + return 1; + } + if (st.st_uid != 0) { + log_err("Error - %s isn't owned by root", file); + close(fd); + return 1; + } + if ((st.st_mode & (S_IRUSR | S_IWUSR | S_IRGRP)) != + (S_IRUSR | S_IWUSR | S_IRGRP)) { + log_err("%s permissions should be 0640", file); + close(fd); + return 1; + } + if (!S_ISREG(st.st_mode)) { + log_err("Error - %s is not a regular file", file); + close(fd); + return 1; + } + + /* it's ok, read line by line */ + f = fdopen(fd, "r"); + if (f == NULL) { + log_err("Error - fdopen failed (%s)", strerror(errno)); + close(fd); + return 1; + } + + while (get_line(f, buf)) { + /* convert line into name-value pair */ + const struct kw_pair *kw; + struct nv_pair nv; + + rc = nv_split(buf, &nv); + switch (rc) { + case 0: /* fine */ + break; + case 1: /* not the right number of tokens. */ + log_err("Wrong number of arguments for line %d in %s", lineno, file); + break; + case 2: /* no '=' sign */ + log_err("Missing equal sign for line %d in %s", + lineno, file); + break; + default: /* something else went wrong... */ + log_err("Unknown error for line %d in %s", + lineno, file); + break; + } + if (nv.name == NULL) { + lineno++; + continue; + } + if (nv.value == NULL) { + fclose(f); + return 1; + } + + /* identify keyword or error */ + kw = kw_lookup(nv.name); + if (kw->name == NULL) { + log_err("Unknown keyword \"%s\" in line %d of %s", + nv.name, lineno, file); + fclose(f); + return 1; + } + + /* Check number of options */ + if (kw->max_options == 0 && nv.option != NULL) { + log_err("Keyword \"%s\" has invalid option " + "\"%s\" in line %d of %s", + nv.name, nv.option, lineno, file); + fclose(f); + return 1; + } + + /* dispatch to keyword's local parser */ + rc = kw->parser(&nv, lineno, c); + if (rc != 0) { + fclose(f); + return 1; /* local parser puts message out */ + } + + lineno++; + } + + fclose(f); + c->name = strdup(basename(file)); + if (lineno > 1) + return sanity_check(c); + return 0; +} + +static char *get_line(FILE * f, char *buf) +{ + if (fgets_unlocked(buf, 128, f)) { + /* remove newline */ + char *ptr = strchr(buf, 0x0a); + + if (ptr) + *ptr = 0; + return buf; + } + return NULL; +} + +static int nv_split(char *buf, struct nv_pair *nv) +{ + /* Get the name part */ + char *ptr, *saved; + + nv->name = NULL; + nv->value = NULL; + nv->option = NULL; + ptr = strtok_r(buf, " ", &saved); + if (ptr == NULL) + return 0; /* If there's nothing, go to next line */ + if (ptr[0] == '#') + return 0; /* If there's a comment, go to next line */ + nv->name = ptr; + + /* Check for a '=' */ + ptr = strtok_r(NULL, " ", &saved); + if (ptr == NULL) + return 1; + if (strcmp(ptr, "=") != 0) + return 2; + + /* get the value */ + ptr = strtok_r(NULL, " ", &saved); + if (ptr == NULL) + return 1; + nv->value = ptr; + + /* See if there's an option */ + ptr = strtok_r(NULL, " ", &saved); + if (ptr) { + nv->option = ptr; + + /* Make sure there's nothing else */ + ptr = strtok_r(NULL, " ", &saved); + if (ptr) + return 1; + } + + /* Everything is OK */ + return 0; +} + +static const struct kw_pair *kw_lookup(const char *val) +{ + int i = 0; + + while (keywords[i].name != NULL) { + if (strcasecmp(keywords[i].name, val) == 0) + break; + i++; + } + return &keywords[i]; +} + + +static int server_parser(struct nv_pair *nv, int line, plugin_conf_t * c) +{ + UNUSED(line); + if (nv->value == NULL) + c->server = NULL; + else + c->server = strdup(nv->value); + + return 0; +} + +static int port_parser(struct nv_pair *nv, int line, plugin_conf_t * c) +{ + const char *ptr = nv->value; + unsigned long i; + + /* check that all chars are numbers */ + for (i = 0; ptr[i]; i++) { + if (!isdigit(ptr[i])) { + log_err("Value %s should only be numbers - line %d", nv->value, line); + return 1; + } + } + + /* convert to unsigned long */ + errno = 0; + i = strtoul(nv->value, NULL, 10); + if (errno) { + log_err("Error converting string to a number (%s) - line %d", strerror(errno), line); + return 1; + } + + c->port = i; + return 0; + +} + +static int timeout_parser(struct nv_pair *nv, int line, plugin_conf_t * c) +{ + const char *ptr = nv->value; + unsigned long i; + + /* check that all chars are numbers */ + for (i = 0; ptr[i]; i++) { + if (!isdigit(ptr[i])) { + log_err("Value %s should only be numbers - line %d", nv->value, line); + return 1; + } + } + + /* convert to unsigned long */ + errno = 0; + i = strtoul(nv->value, NULL, 10); + if (errno) { + log_err("Error converting string to a number (%s) - line %d", strerror(errno), line); + return 1; + } + + c->timeout = i; + return 0; + +} + + +static int user_parser(struct nv_pair *nv, int line, plugin_conf_t * c) +{ + UNUSED(line); + if (nv->value == NULL) + c->user = NULL; + else + c->user = strdup(nv->value); + + return 0; +} + +static int password_parser(struct nv_pair *nv, int line, plugin_conf_t * c) +{ + UNUSED(line); + if (nv->value == NULL) + c->password = NULL; + else + c->password = strdup(nv->value); + + return 0; +} + +static int q_depth_parser(struct nv_pair *nv, int line, plugin_conf_t * c) +{ + const char *ptr = nv->value; + unsigned long i; + + /* check that all chars are numbers */ + for (i = 0; ptr[i]; i++) { + if (!isdigit(ptr[i])) { + log_err("Value %s should only be numbers - line %d", nv->value, line); + return 1; + } + } + + /* convert to unsigned long */ + errno = 0; + i = strtoul(nv->value, NULL, 10); + if (errno) { + log_err("Error converting string to a number (%s) - line %d", strerror(errno), line); + return 1; + } + + if (i < 16 || i > 99999) { + log_err("q_depth must be between 16 and 99999"); + return 1; + } + + c->q_depth = i; + return 0; + +} + + +/* + * Check configuration.At this point, all fields have been read. + * Returns 0 if no problems and 1 if problems detected. + */ +static int sanity_check(plugin_conf_t * c) +{ + /* Error checking */ + if (!c->server) { + log_err("Error - no server hostname given"); + return 1; + } + + if (!c->user) { + log_err("Error - no bind user given"); + return 1; + } + + if (!c->password) { + log_err("Error - no password given"); + return 1; + } + + if (!c->timeout) { + log_err("Error - timeout can't be zero"); + return 1; + } + return 0; +} + +void plugin_free_config(plugin_conf_t * c) +{ + + if (c == NULL) + return; + + free((void *) c->server); + free((void *) c->user); + free((void *) c->password); + free((void *) c->name); +} diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.h b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.h new file mode 100644 index 00000000..82bf365f --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-config.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + * based on code by Steve Grubb * + ***************************************************************************/ + +#ifndef _ZOS_REMOTE_CONFIG_H +#define _ZOS_REMOTE_CONFIG_H + + +/*************************************************************************** + * z/OS Remote-services Plugin configuration * + ***************************************************************************/ +typedef struct plugin_conf +{ + char *name; + char *server; + unsigned int port; + char *user; + char *password; + long timeout; + unsigned int q_depth; + unsigned int counter; +} plugin_conf_t; + +void plugin_clear_config(plugin_conf_t *); +int plugin_load_config(plugin_conf_t *, const char *); +void plugin_free_config(plugin_conf_t *); + +#endif /* _ZOS_REMOTE_CONFIG_H */ diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c new file mode 100644 index 00000000..209743f3 --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c @@ -0,0 +1,608 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + ***************************************************************************/ + +#include "zos-remote-ldap.h" + +#include +#include +#include +#include +#include "zos-remote-log.h" + +/*************************************************************************** + * Audit response struct * + ***************************************************************************/ +typedef struct audit_resp_item +{ + ber_int_t version; /* Version of Response data itself */ + ber_int_t itemTag; /* Copy of itemTag from Operation */ + ber_int_t majorCode; /* Majorcode. Main return code of this Outcome */ + ber_int_t minorCode1; /* minorCode1. SAFRc or other Rc */ + ber_int_t minorCode2; /* minorCode2. RacfRc or other Rc */ + ber_int_t minorCode3; /* minorCode3. RacfRsn or other Rc */ +} audit_resp_item_t; + +typedef struct audit_response +{ + ber_int_t respVersion; /* Overall version */ + ber_int_t respMajor; /* Overall major code */ + unsigned int numItems; /* Number of response items */ + audit_resp_item_t **itemList; /* response ItemList */ +} audit_response_t; + + +/*************************************************************************** + * z/OS Remote-services Major return code handling * + ***************************************************************************/ +struct zos_remote_error +{ + int code; + char *str; +}; + +static struct zos_remote_error zos_remote_errlist[] = { + {ZOS_REMOTE_MAJOR_SUCCESS, "Success"}, + {ZOS_REMOTE_MAJOR_WARNINGMODE, "WARNINGMODE - Event was logged, with warnings"}, + {ZOS_REMOTE_MAJOR_NOTREQ, "NOTREQ - No logging required"}, + {ZOS_REMOTE_MAJOR_UNDETERMINED, "UNDETERMINED - Undetermined result"}, + {ZOS_REMOTE_MAJOR_UNAUTHORIZED, "UNAUTHORIZED - The user does not have authority the R_auditx service"}, + {ZOS_REMOTE_MAJOR_RACROUTE, "RACROUTE - The R_auditx service returned an unexpected error"}, + {ZOS_REMOTE_MAJOR_VAL_ERR, "VAL_ERR - Value error in request"}, + {ZOS_REMOTE_MAJOR_ENC_ERR, "ENC_ERR - DER decoding error in request"}, + {ZOS_REMOTE_MAJOR_UNSUF_AUTH, "UNSUF_AUTH - The user has unsuficient authority for the requested function"}, + {ZOS_REMOTE_MAJOR_EMPTY, "EMPTY - Empty request received - No items found within the ItemList"}, + {ZOS_REMOTE_MAJOR_INVALID_VER, "INVALID_VER - Invalid RequestVersion"}, + {ZOS_REMOTE_MAJOR_INTERNAL_ERR, "INTERNAL_ERR - An internal error was encountered within the ICTX component"}, + {-1, NULL} +}; + +/*************************************************************************** + * Internal functions prototypes * + ***************************************************************************/ +static int _zos_remote_init(ZOS_REMOTE *); +static void _zos_remote_destroy(ZOS_REMOTE *); +static int zos_remote_connect(ZOS_REMOTE *); +static void zos_remote_disconnect(ZOS_REMOTE *); +static int submit_xop_s(ZOS_REMOTE *, struct berval *); +static int decode_response(audit_response_t *, struct berval *); + +/*************************************************************************** + * Exported functions * + ***************************************************************************/ +int submit_request_s(ZOS_REMOTE *zos_remote, BerElement *ber) +{ + int rc, retry = 1; /* retry once and give up */ + struct berval bv; + + rc = ber_flatten2(ber, &bv, 0); /* 0 = Use ber's buffer */ + if (rc == -1) { + log_err("Error flattening BER element"); + return ICTX_E_ABORT; + } + +retry: + rc = submit_xop_s(zos_remote, &bv); + switch (rc) { + case ICTX_SUCCESS: + break; + case ICTX_E_TRYAGAIN: + /* + * Usually means that the server connection timed-out + * So we flush the LDAP connection by unsetting the + * 'connected' flag and trying again. + */ + if (retry > 0) { + log_debug("Connection seems down - retrying"); + retry--; + _zos_remote_destroy(zos_remote); + rc = _zos_remote_init(zos_remote); + if (rc != ICTX_SUCCESS) + log_err("Error - failed to re-initialize LDAP session"); + else + goto retry; /* go to submit_xop_s once more */ + } + log_err("Can't establish connection"); + break; + case ICTX_E_ABORT: + break; + default: + log_err("Event resulted failure, code: 0x%x", rc); + } + + return rc; +} + +int zos_remote_init(ZOS_REMOTE *zos_remote, const char *server, int port, + const char *user, const char *password, int timeout) +{ + zos_remote->server = strdup(server); + zos_remote->port = port; + zos_remote->user = strdup(user); + zos_remote->password = strdup(password); + zos_remote->timeout = timeout; + zos_remote->connected = 0; + + if (!zos_remote->server || !zos_remote->user || !zos_remote->password) { + log_err("Error allocating memory for session members"); + return ICTX_E_FATAL; + } + + return _zos_remote_init(zos_remote); +} + +void zos_remote_destroy(ZOS_REMOTE *zos_remote) +{ + _zos_remote_destroy(zos_remote); + + free(zos_remote->server); + free(zos_remote->user); + free(zos_remote->password); +} + +char *zos_remote_err2string(int err) +{ + int i; + + for (i = 0; zos_remote_errlist[i].str != NULL; i++) { + if (err == zos_remote_errlist[i].code) + return zos_remote_errlist[i].str; + } + return "Unknown error"; +} + +/*************************************************************************** + * Internal Functions * + ***************************************************************************/ +static int _zos_remote_init(ZOS_REMOTE *zos_remote) +{ + int version, rc; + char *uri = NULL; + +#ifdef LDAP_DEPRECATED + + log_debug("Initializing z/OS Remote-services LDAP connection at ldap://%s:%d", + zos_remote->server, zos_remote->port); + zos_remote->ld = ldap_init(zos_remote->server + zos_remote->port ? zos_remote->port : LDAP_PORT); + if (zos_remote->ld == NULL) { + log_err("Error initializing LDAP session: %s", + strerror(errno)); + rc = ICTX_E_FATAL; + goto end; + } +#else + /* build ldap URI */ + if (zos_remote->port == 0 || zos_remote->port == LDAP_PORT) + rc = asprintf(&uri, "ldap://%s", zos_remote->server); + else + rc = asprintf(&uri, "ldap://%s:%d", zos_remote->server, + zos_remote->port); + + if (rc == -1) { + log_err("Out of memory building LDAP server URI"); + rc = ICTX_E_FATAL; + uri = NULL; + goto end; + } + + log_debug("Initializing z/OS Remote-services LDAP connection at %s", uri); + /* Get a handle to an LDAP connection */ + rc = ldap_initialize(&zos_remote->ld, uri); + if (rc != LDAP_SUCCESS) { + log_err("Error initializing LDAP session: %s", + ldap_err2string(rc)); + rc = ICTX_E_FATAL; + goto free_uri; + } +#endif + + /* + * Ensure the LDAP protocol version supported by the client + * to 3. (Extended operations are part of version 3). + */ + rc = ldap_get_option(zos_remote->ld, LDAP_OPT_PROTOCOL_VERSION, + &version); + if (rc != LDAP_OPT_SUCCESS) { + log_err("Error getting LDAP session options"); + rc = ICTX_E_FATAL; + goto unbind; + } + + if (version < LDAP_VERSION3) { + log_debug("Setting LDAP session version to %d", + LDAP_VERSION3); + version = LDAP_VERSION3; + rc = ldap_set_option(zos_remote->ld, LDAP_OPT_PROTOCOL_VERSION, + &version); + if (rc != LDAP_OPT_SUCCESS) { + log_err("Error setting LDAP session version"); + rc = ICTX_E_FATAL; + goto unbind; + } + } + + goto free_uri; + +unbind: + ldap_unbind_ext_s(zos_remote->ld, NULL, NULL); + zos_remote->ld = NULL; + +free_uri: + free(uri); + +end: + return rc; +} + +static void _zos_remote_destroy(ZOS_REMOTE *zos_remote) +{ + zos_remote_disconnect(zos_remote); + zos_remote->ld = NULL; +} + +static int zos_remote_connect(ZOS_REMOTE *zos_remote) +{ + struct berval cred; + int rc; + char bindusr[255]; + + snprintf(bindusr, 255, "racfid=%s,cn=ictx", zos_remote->user); + + log_debug("Attempting BIND. User '%s', password ''", + bindusr); + + cred.bv_val = (char *) zos_remote->password; + cred.bv_len = strlen(zos_remote->password); + + rc = ldap_sasl_bind_s(zos_remote->ld, bindusr, + LDAP_SASL_SIMPLE, &cred, + NULL, NULL, NULL); + + + switch (rc) { + case LDAP_SUCCESS: + log_debug("LDAP BIND succeeded"); + zos_remote->connected = 1; + rc = ICTX_SUCCESS; + break; + case LDAP_SERVER_DOWN: + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + case LDAP_TIMEOUT: + case LDAP_CONNECT_ERROR: + log_warn("z/OS Remote-services connection failed: %s", + ldap_err2string(rc)); + rc = ICTX_E_TRYAGAIN; + break; + default: + log_err("Error - z/OS Remote-services initialization failed: %s", + ldap_err2string(rc)); + rc = ICTX_E_FATAL; + } + + return rc; +} + + +static void zos_remote_disconnect(ZOS_REMOTE *zos_remote) +{ + if (zos_remote->ld) { + log_debug("Unbinding LDAP session"); + +#ifdef LDAP_DEPRECATED + ldap_unbind(zos_remote->ld); +#else + ldap_unbind_ext_s(zos_remote->ld, NULL, NULL); +#endif + } + zos_remote->connected = 0; + +} + +/* + * Sync-submit extended operation given in *bv + * return ICTX_SUCCESS if submission (and response) + * succeeded. + * Log errors using log_err() functions + */ +int submit_xop_s(ZOS_REMOTE *zos_remote, struct berval *bv) +{ + LDAPMessage *result; + audit_response_t response; + int rc, errcode, msgId; + unsigned int i; + char *errmsg, *oid; + struct berval *bv_response; + struct timeval t; + + if (zos_remote->connected == 0) { + rc = zos_remote_connect(zos_remote); + if (rc != ICTX_SUCCESS) + return rc; + } + + /* call LDAP - won't block */ + rc = ldap_extended_operation(zos_remote->ld, ICTX_OIDAUDITREQUEST, + bv, NULL, NULL, &msgId); + if (rc == LDAP_SERVER_DOWN) { + zos_remote->connected = 0; + return ICTX_E_TRYAGAIN; + } else if (rc != LDAP_SUCCESS) { + log_err("LDAP extended operation submission failure: %s", + ldap_err2string(rc)); + return ICTX_E_ABORT; + } else { + log_debug("Sent LDAP extended operation request, msgId=0x%x", + msgId); + } + + /* call blocking ldap_result with specified timeout */ + t.tv_sec = zos_remote->timeout; + t.tv_usec = 0; + rc = ldap_result(zos_remote->ld, msgId, 1, &t, &result); + + if (rc == -1) { + /* error in ldap operation */ + ldap_get_option(zos_remote->ld, LDAP_OPT_ERROR_NUMBER, &errcode); + switch (errcode) { + case LDAP_SERVER_DOWN: + /* Connection may have timed out, let's retry */ + zos_remote->connected = 0; + rc = ICTX_E_TRYAGAIN; + break; + default: + log_err("ldap_result unexpected failure: %s (0x%x)", + ldap_err2string(rc), rc); + rc = ICTX_E_ABORT; + } + goto end; + } else if (rc == 0) { + /* timeout reached */ + log_warn("LDAP extended operation timed out"); + rc = ICTX_E_ABORT; + goto end; + } else if (rc != LDAP_RES_EXTENDED) { + /* not an extended operation response! */ + log_err("LDAP extended operation resulted in unexpected answer: 0x%x", rc); + rc = ICTX_E_ABORT; + goto free_result; + } + + log_debug("Got LDAP Extended result"); + /* + * we have an extended operation result + * first parse_result will check for errcode, later + * parse_extended_result will give us the oid and the BER value + */ + rc = ldap_parse_result(zos_remote->ld, result, &errcode, NULL, + &errmsg, NULL, NULL, 0); + if (rc != LDAP_SUCCESS) { + log_err("LDAP parse result internal failure (code 0x%x)", + rc); + rc = ICTX_E_ABORT; + goto free_result; + } + + if (errcode != LDAP_SUCCESS) { + log_err("LDAP extended operation failed: %s", errmsg); + rc = ICTX_E_ABORT; + goto free_errmsg; + } + + rc = ldap_parse_extended_result(zos_remote->ld, result, &oid, + &bv_response, 0); + if (rc != LDAP_SUCCESS) { + log_err("Failed to parse ldap extended result (code 0x%x)", + rc); + rc = ICTX_E_ABORT; + goto free_errmsg; + } + + if (oid && strcmp(oid, ICTX_OIDAUDITRESPONSE) != 0) { + /* oid == null shouldn't be a problem to log_err */ + log_err("LDAP extended operation returned an invalid oid: %s", oid); + rc = ICTX_E_ABORT; + goto free_bv; + } + + rc = decode_response(&response, bv_response); + if (rc != ICTX_SUCCESS) { + log_err("Error decoding extended operation response"); + goto free_bv; + } + + if (response.respMajor == ZOS_REMOTE_MAJOR_SUCCESS) { + /* submission was successful, no further processing needed */ + log_debug("Successfully submited Remote audit Request"); + rc = ICTX_SUCCESS; + goto free_response; + } else if (response.respMajor == ZOS_REMOTE_MAJOR_EMPTY) { + /* something is going on. Set error and stop processing */ + log_warn("Warning - LDAP extended operation returned empty result"); + rc = ICTX_E_ABORT; + goto free_response; + } else if (response.respMajor == ZOS_REMOTE_MAJOR_WARNINGMODE || + response.respMajor == ZOS_REMOTE_MAJOR_NOTREQ) + rc = ICTX_SUCCESS; /* don't fail, but continue processing */ + else + rc = ICTX_E_ABORT; /* set return code and continue processing */ + + /* If it's not success nor empty, let's check for errors in the response */ + for (i = 0; i < response.numItems; i++) { + switch ((response.itemList[i])->majorCode) { + /* 0 <= Major Code <= 14 */ + case ZOS_REMOTE_MAJOR_SUCCESS: + break; + case ZOS_REMOTE_MAJOR_WARNINGMODE: + case ZOS_REMOTE_MAJOR_NOTREQ: + log_debug("Warning - LDAP extended operation returned '%s' for item %d", + zos_remote_err2string((response.itemList[i])->majorCode), + (response.itemList[i])->itemTag); + log_debug("SAF code: 0x%x, RACF code: 0x%x, RACF reason: 0x%x", + (response.itemList[i])->minorCode1, + (response.itemList[i])->minorCode2, + (response.itemList[i])->minorCode3); + break; + case ZOS_REMOTE_MAJOR_UNDETERMINED: + case ZOS_REMOTE_MAJOR_UNAUTHORIZED: + case ZOS_REMOTE_MAJOR_RACROUTE: + log_err("Error - LDAP extended operation returned '%s' for item %d", + zos_remote_err2string((response.itemList[i])->majorCode), + (response.itemList[i])->itemTag); + log_err("SAF code: 0x%x, RACF code: 0x%x, RACF reason: 0x%x", + (response.itemList[i])->minorCode1, + (response.itemList[i])->minorCode2, + (response.itemList[i])->minorCode3); + break; + /* 16 <= Major Code <= 20 */ + case ZOS_REMOTE_MAJOR_VAL_ERR: + case ZOS_REMOTE_MAJOR_ENC_ERR: + log_err("Error - LDAP extended operation returned '%s' for item %d", + zos_remote_err2string((response.itemList[i])->majorCode), + (response.itemList[i])->itemTag); + log_err("Item field: %d, reson %d", + (response.itemList[i])-> + minorCode1, + (response.itemList[i])->minorCode2); + break; + /* 24 <= Major code <= 100 */ + case ZOS_REMOTE_MAJOR_UNSUF_AUTH: + case ZOS_REMOTE_MAJOR_EMPTY: + case ZOS_REMOTE_MAJOR_INVALID_VER: + case ZOS_REMOTE_MAJOR_INTERNAL_ERR: + log_err("Error - LDAP extended operation returned '%s' for item %d", + zos_remote_err2string((response.itemList[i])->majorCode), + (response.itemList[i])->itemTag); + break; + default: + log_err("Error - LDAP extended operation returned an unknown Major code for item %d", + (response.itemList[i])->majorCode); + } + } + +free_response: + for (; response.numItems > 0; response.numItems--) + free(response.itemList[response.numItems - 1]); + free(response.itemList); + +free_bv: + if (bv_response) + ber_bvfree(bv_response); + if (oid) + ldap_memfree(oid); + +free_errmsg: + ldap_memfree(errmsg); + +free_result: + ldap_msgfree(result); + +end: + return rc; +} + +static int decode_response(audit_response_t * r, struct berval *bv) +{ + BerElement *ber; + ber_len_t len; + int rc; + + if (!bv) { + log_err("LDAP extended operation returned NULL message"); + return ICTX_E_ABORT; + } else if ((ber = ber_init(bv)) == NULL) { + log_err("Error initializing BER response data"); + return ICTX_E_ABORT; + } + + log_debug("---Got an encoded request response:"); + debug_bv(bv); + + r->respVersion = 0; + r->respMajor = 0; + r->numItems = 0; + r->itemList = NULL; + + rc = ber_scanf(ber, "{ii", &r->respVersion, &r->respMajor); + if (r->respVersion != ICTX_REQUESTVER) { + log_err("Invalid version returned by z/OS Remote-services server"); + log_err("Should be %d, got %d", ICTX_REQUESTVER, + r->respVersion); + rc = ICTX_E_ABORT; + goto free_ber; + } + + if (r->respMajor == ZOS_REMOTE_MAJOR_SUCCESS || + r->respMajor == ZOS_REMOTE_MAJOR_EMPTY) { + rc = ICTX_SUCCESS; + /* No further processing required */ + goto free_ber; + } + + /* Inspect ber response otherwise */ + while (ber_peek_tag(ber, &len) == LBER_SEQUENCE) { + r->numItems++; + r->itemList = (audit_resp_item_t **) realloc(r->itemList, + r->numItems * + sizeof + (audit_resp_item_t + *)); + if (errno == ENOMEM) { + if (r->itemList) + free(r->itemList); + rc = ICTX_E_FATAL; + goto free_ber; + } + + audit_resp_item_t *item = (audit_resp_item_t *) + malloc(sizeof(audit_resp_item_t)); + + if (!item) { + rc = ICTX_E_FATAL; + goto free_ber; + } + + rc |= ber_scanf(ber, "{{iiiiii}}", + &item->version, + &item->itemTag, + &item->majorCode, + &item->minorCode1, &item->minorCode2, + &item->minorCode3); + r->itemList[r->numItems - 1] = item; + } + rc |= ber_scanf(ber, "}"); + + if (rc == -1) { + for (; r->numItems > 0; r->numItems--) + free(r->itemList[r->numItems - 1]); + free(r->itemList); + rc = ICTX_E_ABORT; + } + else + rc = ICTX_SUCCESS; + +free_ber: + ber_free(ber, 1); + + return rc; +} diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.h b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.h new file mode 100644 index 00000000..5767b96e --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.h @@ -0,0 +1,312 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + ***************************************************************************/ + +#ifndef _ZOS_REMOTE_LDAP_H +#define _ZOS_REMOTE_LDAP_H + +#include +#include + + +/*************************************************************************** + * LDAP Extended Op OID for ICTX Audit * + ***************************************************************************/ +/* ICTX EIM component AUDIT Request OID */ +#define ICTX_OIDAUDITREQUEST "1.3.18.0.2.12.68" + +/* The AUDIT Response OID */ +#define ICTX_OIDAUDITRESPONSE "1.3.18.0.2.12.69" + +/* This implementation version + Request and response must match this */ +#define ICTX_REQUESTVER 0x1 + +/* Needed for BER-encoding */ +#define ASN1_IA5STRING_TAG 0x16 + +/*************************************************************************** + * the ASN.1 struct for the remote audit request and response: * + * * + * RequestValue ::= SEQUENCE { * + * RequestVersion INTEGER, * + * ItemList SEQUENCE OF * + * Item SEQUENCE { * + * ItemVersion INTEGER, * + * ItemTag INTEGER, * + * LinkValue OCTET STRING SIZE(8), * + * Violation BOOLEAN, * + * Event INTEGER, * + * Qualifier INTEGER, * + * Class IA5String, * + * Resource IA5String, * + * LogString IA5String, * + * DatafieldList SEQUENCE OF * + * DataField SEQUENCE { * + * TYPE INTEGER, * + * VALUE IA5STRING * + * } * + * } * + * } * + * * + * Response ::= SEQUENCE { * + * Version INTEGER, * + * ResponseCode INTEGER, * + * ItemList SEQUENCE OF * + * Item SEQUENCE { * + * ItemVersion INTEGER, * + * ItemTag INTEGER, * + * MajorCode INTEGER, * + * MinorCode1 INTEGER, * + * MinorCode2 INTEGER, * + * MinorCode3 INTEGER * + * } * + * } * + ***************************************************************************/ + +/*************************************************************************** + * z/OS Remote-services Audit Minor return codes meaning + +Major Code Meaning +---------- --------------------------------------------------------- +0-14 - MinorCode1 is the SAF return code + - MinorCode2 is the RACF return code + - MinorCode3 is the RACF reason code + +16-20 - MinorCode1 identifies the extended operation request + parameter number (see audit request ASN.1 definition): + 0 - Item + 1 - ItemVersion + 2 - ItemTag + 3 - LinkValue + 4 - Violation + 5 - Event + 6 - Qualifier + 7 - Class + 8 - Resource + 9 - LogString + 10 - DataFieldList + 11 - DataField * + 12 - TYPE * + 13 - VALUE * + - MinorCode2 indicates one of the Following: + 32 - incorrect length + 36 - incorrect value + 40 - encoding error + - MinorCode3 has no defined meaning + +24-100 - MinorCode1 has no defined meaning + - MinorCode2 has no defined meaning + - MinorCode3 has no defined meaning + +* There can be multiple DataField, TYPEs and VALUEs in a request. If any of them is bad + you get the same 11, 12 or 13 MinorCode1. There is no further breakdown of which one + is bad. + + ***************************************************************************/ + +/*************************************************************************** + * Audit Request 'event' field meaning * + ***************************************************************************/ +#define ZOS_REMOTE_EVENT_AUTHENTICATION 0x1 +#define ZOS_REMOTE_EVENT_AUTHORIZATION 0x2 +#define ZOS_REMOTE_EVENT_AUTHORIZATION_MAPPING 0x3 +#define ZOS_REMOTE_EVENT_KEY_MGMT 0x4 +#define ZOS_REMOTE_EVENT_POLICY_MGMT 0x5 +#define ZOS_REMOTE_EVENT_ADMIN_CONFIG 0x6 +#define ZOS_REMOTE_EVENT_ADMIN_ACTION 0x7 + +/*************************************************************************** + * Audit Request 'qualifier' field meaning * + ***************************************************************************/ +#define ZOS_REMOTE_QUALIF_SUCCESS 0x0 +#define ZOS_REMOTE_QUALIF_INFO 0x1 +#define ZOS_REMOTE_QUALIF_WARN 0x2 +#define ZOS_REMOTE_QUALIF_FAIL 0x3 + +/*************************************************************************** + * Relocate types for Audit Request * + ***************************************************************************/ +/* SAF identifier for bind user */ +#define ZOS_REMOTE_RELOC_SAF_BIND_USER 100 + +/* Reguestor's bind user identifier */ +#define ZOS_REMOTE_RELOC_REQ_BIND_USER 101 + +/* Originating security domain */ +#define ZOS_REMOTE_RELOC_ORIG_SECURITY 102 + +/* Originating registry / realm */ +#define ZOS_REMOTE_RELOC_ORIG_REALM 103 + +/* Originating user name */ +#define ZOS_REMOTE_RELOC_ORIG_USER 104 + +/* Mapped security domain */ +#define ZOS_REMOTE_RELOC_MAPPED_SECURITY 105 + +/* Mapped registry / realm */ +#define ZOS_REMOTE_RELOC_MAPPED_REALM 106 + +/* Mapped user name */ +#define ZOS_REMOTE_RELOC_MAPPED_USER 107 + +/* Operation performed */ +#define ZOS_REMOTE_RELOC_OPERATION 108 + +/* Mechanism / object name */ +#define ZOS_REMOTE_RELOC_OBJECT 109 + +/* Method / function used */ +#define ZOS_REMOTE_RELOC_FUNCTION 110 + +/* Key / certificate name */ +#define ZOS_REMOTE_RELOC_CERTIFICATE 111 + +/* Caller subject initiating security event */ +#define ZOS_REMOTE_RELOC_INITIATING_EVENT 112 + +/* Date and time security event occurred */ +#define ZOS_REMOTE_RELOC_TIMESTAMP 113 + +/* Application specific data. (i.e. Other) */ +#define ZOS_REMOTE_RELOC_OTHER 114 + +/*************************************************************************** + * z/OS Remote-services Audit Major return codes * + ***************************************************************************/ +#define ZOS_REMOTE_MAJOR_SUCCESS 0 + +/* Event was logged, with warnings */ +#define ZOS_REMOTE_MAJOR_WARNINGMODE 2 + +/* No logging required + No audit controls are set to require it */ +#define ZOS_REMOTE_MAJOR_NOTREQ 3 + +/* Class not active/ractlisted, + covering profile not found or + RACF is not installed */ +#define ZOS_REMOTE_MAJOR_UNDETERMINED 4 + +/* The user does not have authority the R_auditx service. + The userid associated with the LDAP server must have + at least READ access to the FACILITY class profile IRR.RAUDITX. */ +#define ZOS_REMOTE_MAJOR_UNAUTHORIZED 8 + + +/* The R_auditx service returned an unexpected error. + Compare the returned minor codes with the SAF RACF codes + documented in Security Server Callable Services */ +#define ZOS_REMOTE_MAJOR_RACROUTE 12 + +/* A value specified in the extended operation request is + incorrect or unsupported. Check the returned minor codes + to narrow the reason */ +#define ZOS_REMOTE_MAJOR_VAL_ERR 16 + +/* A DER decoding error was encountered in an item. + Processing Terminated. Partial results may be returned */ +#define ZOS_REMOTE_MAJOR_ENC_ERR 20 + +/* The requestor does not have sufficient authority for the + requested function. The userid associated with the LDAP bind + user must have at least READ access to the FACILITY class + profile IRR.LDAP.REMOTE.AUDIT. */ +#define ZOS_REMOTE_MAJOR_UNSUF_AUTH 24 + +/* No items are found within the ItemList sequence of the extended + operation request, so no response items are returned */ +#define ZOS_REMOTE_MAJOR_EMPTY 28 + +/* Invalid RequestVersion */ +#define ZOS_REMOTE_MAJOR_INVALID_VER 61 + +/* An internal error was encountered within the ICTX component */ +#define ZOS_REMOTE_MAJOR_INTERNAL_ERR 100 + +/*************************************************************************** + * Some standard sizes for remote audit request items * + ***************************************************************************/ +#define ZOS_REMOTE_LINK_VALUE_SIZE 8 +#define ZOS_REMOTE_CLASS_SIZE 8 +#define ZOS_REMOTE_RESOURCE_SIZE 240 +#define ZOS_REMOTE_LOGSTRING_SIZE 200 + + +/*************************************************************************** + * Some standard Error defines * + ***************************************************************************/ +#define ICTX_SUCCESS 0x00 + +/* maybe a temporary failure? */ +#define ICTX_E_TRYAGAIN 0x01 + +/* permanent failure - abort event submission */ +#define ICTX_E_ABORT 0x02 + +/* Fatal failure - abort program */ +#define ICTX_E_FATAL 0x03 + +/* generic error */ +#define ICTX_E_ERROR 0x10 + +/*************************************************************************** + * structure representing an z/OS Remote-services session * + ***************************************************************************/ +typedef struct opaque +{ + char *server; + unsigned int port; + char *user; + char *password; + unsigned int timeout; + LDAP *ld; + int connected; +} ZOS_REMOTE; + +/*************************************************************************** + * LDAP XOP operations * + ***************************************************************************/ +/* + * Initializes z/OS Remote-services (LDAP to ITDS) connection, + * binds to ITDS Server using configured RACF ID + * Args are: + * server, bind user, bind password, server port, timeout + * Caller must call zos_remote_destroy() to free memory allocation + */ +int zos_remote_init(ZOS_REMOTE *, const char *, int, const char *, + const char *, int); + +/* + * Uninitializes z/OS Remote-services (LDAP) connection + */ +void zos_remote_destroy(ZOS_REMOTE *); + +/* + * sync submit request - possibly reconnect to server + * if the connection if found to be dead + */ +int submit_request_s(ZOS_REMOTE *, BerElement *); + + +#endif /* _ZOS_REMOTE_LDAP_H */ diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.c b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.c new file mode 100644 index 00000000..a272078e --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.c @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + ***************************************************************************/ +#include "zos-remote-log.h" + +#include +#include +#include +#include "auparse.h" + + +static void vlog_prio(int prio, const char *fmt, va_list ap) +{ + char *str; + + if (asprintf(&str, "pid=%d: %s", mypid, fmt) != -1) { + vsyslog(LOG_DAEMON | prio, str, ap); + free(str); + } +} + +void log_err(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vlog_prio(LOG_ERR, fmt, ap); + va_end(ap); +} + +void log_warn(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vlog_prio(LOG_WARNING, fmt, ap); + va_end(ap); +} + +void log_info(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vlog_prio(LOG_INFO, fmt, ap); + va_end(ap); +} + +void _log_debug(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vlog_prio(LOG_INFO, fmt, ap); + va_end(ap); +} + +void _debug_ber(BerElement * ber) +{ + struct berval bv; + + if (ber_flatten2(ber, &bv, 0) != -1) { + debug_bv(&bv); + } +} + +void _debug_bv(struct berval *bv) +{ + char *out; + char octet[4]; + ber_len_t i; + + log_debug("---BER value HEX dump (size %u bytes)", + (unsigned int) bv->bv_len); + + if (bv->bv_len > 0) { + out = (char *) calloc((3 * (bv->bv_len)) + 1, sizeof(char)); + if (!out) return; + + for (i = 1; i <= bv->bv_len; i++) { + snprintf(octet, 4, "%02x ", + (unsigned char) bv->bv_val[i - 1]); + strcat(out, octet); + } + log_debug(out); + free(out); + } +} + + diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.h b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.h new file mode 100644 index 00000000..c5722cbe --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-log.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + ***************************************************************************/ + +#ifndef _ZOS_REMOTE_LOG_H +#define _ZOS_REMOTE_LOG_H + +#include "zos-remote-ldap.h" + +#include +#include +#include +#include + +extern pid_t mypid; + +void log_err(const char *, ...); +void log_warn(const char *, ...); +void log_info(const char *, ...); +void _log_debug(const char *, ...); +void _debug_bv(struct berval *); +void _debug_ber(BerElement *); + +#ifdef DEBUG + +#define log_debug(fmt, ...) _log_debug(fmt, ## __VA_ARGS__) +#define debug_bv(bv) _debug_bv(bv) +#define debug_ber(ber) _debug_ber(ber) + +#else + +#define log_debug(fmt, ...) +#define debug_bv(bv) +#define debug_ber(ber) + +#endif /* DEBUG */ + + +#endif /* _ZOS_REMOTE_LOG_H */ diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-plugin.c b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-plugin.c new file mode 100644 index 00000000..8234a273 --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-plugin.c @@ -0,0 +1,580 @@ +/*************************************************************************** +* Copyright (C) 2007 International Business Machines Corp. * +* 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: * +* Klaus Heinrich Kiwi * +***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LIBCAP_NG +#include +#endif +#include "auparse.h" +#include "zos-remote-log.h" +#include "zos-remote-ldap.h" +#include "zos-remote-config.h" +#include "zos-remote-queue.h" + +#define UNUSED(x) (void)(x) + +/* + * Global vars + */ +volatile int stop = 0; +volatile int hup = 0; +volatile ZOS_REMOTE zos_remote_inst; +static plugin_conf_t conf; +static const char *def_config_file = "/etc/audisp/zos-remote.conf"; +static pthread_t submission_thread; +pid_t mypid = 0; + +/* + * SIGTERM handler + */ +static void term_handler(int sig) +{ + UNUSED(sig); + log_info("Got Termination signal - shutting down plugin"); + stop = 1; + nudge_queue(); +} + +/* + * SIGHUP handler - re-read config, reconnect to ITDS + */ +static void hup_handler(int sig) +{ + UNUSED(sig); + log_info("Got Hangup signal - flushing plugin configuration"); + hup = 1; + nudge_queue(); +} + +/* + * SIGALRM handler - help force exit when terminating daemon + */ +static void alarm_handler(int sig) +{ + UNUSED(sig); + log_err("Timeout waiting for submission thread - Aborting (some events may have been dropped)"); + pthread_cancel(submission_thread); +} + +/* + * The submission thread + * It's job is to dequeue the events from the queue + * and sync submit them to ITDS + */ +static void *submission_thread_main(void *arg) +{ + int rc; + + UNUSED(arg); + log_debug("Starting event submission thread"); + + rc = zos_remote_init(&zos_remote_inst, conf.server, + conf.port, conf.user, + conf.password, + conf.timeout); + + if (rc != ICTX_SUCCESS) { + log_err("Error - Failed to initialize session to z/OS ITDS Server"); + stop = 1; + return 0; + } + + while (stop == 0) { + /* block until we have an event */ + BerElement *ber = dequeue(); + + if (ber == NULL) { + if (hup) { + break; + } + continue; + } + debug_ber(ber); + rc = submit_request_s(&zos_remote_inst, ber); + if (rc == ICTX_E_FATAL) { + log_err("Error - Fatal error in event submission. Aborting"); + stop = 1; + } else if (rc != ICTX_SUCCESS) { + log_warn("Warning - Event submission failure - event dropped"); + } + else { + log_debug("Event submission success"); + } + ber_free(ber, 1); /* also free BER buffer */ + } + log_debug("Stopping event submission thread"); + zos_remote_destroy(&zos_remote_inst); + + return 0; +} + + +/* + * auparse library callback that's called when an event is ready + */ +void +push_event(auparse_state_t * au, auparse_cb_event_t cb_event_type, + void *user_data) +{ + int rc; + BerElement *ber; + int qualifier; + char timestamp[26]; + char linkValue[ZOS_REMOTE_LINK_VALUE_SIZE]; + char logString[ZOS_REMOTE_LOGSTRING_SIZE]; + unsigned long linkValue_tmp; + + UNUSED(user_data); + if (cb_event_type != AUPARSE_CB_EVENT_READY) + return; + + const au_event_t *e = auparse_get_timestamp(au); + if (e == NULL) + return; + /* + * we have an event. Each record will result in a different 'Item' + * (refer ASN.1 definition in zos-remote-ldap.h) + */ + + /* + * Create a new BER element to encode the request + */ + ber = ber_alloc_t(LBER_USE_DER); + if (ber == NULL) { + log_err("Error allocating memory for BER element"); + goto fatal; + } + + /* + * Collect some information to fill in every item + */ + const char *node = auparse_get_node(au); + const char *orig_type = auparse_find_field(au, "type"); + /* roll back event to get 'success' */ + auparse_first_record(au); + const char *success = auparse_find_field(au, "success"); + /* roll back event to get 'res' */ + auparse_first_record(au); + const char *res = auparse_find_field(au, "res"); + + /* check if this event is a success or failure one */ + if (success) { + if (strncmp(success, "0", 1) == 0 || + strncmp(success, "no", 2) == 0) + qualifier = ZOS_REMOTE_QUALIF_FAIL; + else + qualifier = ZOS_REMOTE_QUALIF_SUCCESS; + } else if (res) { + if (strncmp(res, "0", 1) == 0 + || strncmp(res, "failed", 6) == 0) + qualifier = ZOS_REMOTE_QUALIF_FAIL; + else + qualifier = ZOS_REMOTE_QUALIF_SUCCESS; + } else + qualifier = ZOS_REMOTE_QUALIF_INFO; + + /* get timestamp text */ + ctime_r(&e->sec, timestamp); + timestamp[24] = '\0'; /* strip \n' */ + + /* prepare linkValue which will be used for every item */ + linkValue_tmp = htonl(e->serial); /* padronize to use network + * byte order + */ + memset(&linkValue, 0, ZOS_REMOTE_LINK_VALUE_SIZE); + memcpy(&linkValue, &linkValue_tmp, sizeof(unsigned long)); + + /* + * Prepare the logString with some meaningful text + * We assume the first record type found is the + * 'originating' audit record + */ + sprintf(logString, "Linux (%s): type: %s", node, orig_type); + free((void *)node); + + /* + * Start writing to BER element. + * There's only one field (version) out of the item sequence. + * Also open item sequence + */ + rc = ber_printf(ber, "{i{", ICTX_REQUESTVER); + if (rc < 0) + goto skip_event; + + /* + * Roll back to first record and iterate through all records + */ + auparse_first_record(au); + do { + const char *type = auparse_find_field(au, "type"); + if (type == NULL) + goto skip_event; + + log_debug("got record: %s", auparse_get_record_text(au)); + + /* + * First field is item Version, same as global version + */ + rc = ber_printf(ber, "{i", ICTX_REQUESTVER); + + /* + * Second field is the itemTag + * use our internal event counter, increasing it + */ + rc |= ber_printf(ber, "i", conf.counter++); + + /* + * Third field is the linkValue + * using ber_put_ostring since it is not null-terminated + */ + rc |= ber_put_ostring(ber, linkValue, + ZOS_REMOTE_LINK_VALUE_SIZE, + LBER_OCTETSTRING); + /* + * Fourth field is the violation + * Don't have anything better yet to put here + */ + rc |= ber_printf(ber, "b", 0); + + /* + * Fifth field is the event. + * FIXME: this might be the place to switch on the + * audit record type and map to a more meaningful + * SMF type 83, subtype 4 event here + */ + rc |= ber_printf(ber, "i", ZOS_REMOTE_EVENT_AUTHORIZATION); + + /* + * Sixth field is the qualifier. We map 'success' or + * 'res' to this field + */ + rc |= ber_printf(ber, "i", qualifier); + + /* + * Seventh field is the Class + * always use '@LINUX' for this version + * max size ZOS_REMOTE_CLASS_SIZE + */ + rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG); + rc |= ber_printf(ber, "s", "@LINUX"); + + /* + * Eighth field is the resource + * use the record type (name) as the resource + * max size ZOS_REMOTE_RESOURCE_SIZE + */ + rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG); + rc |= ber_printf(ber, "s", type); + + /* + * Nineth field is the LogString + * we try to put something meaningful here + * we also start the relocations sequence + */ + rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG); + rc |= ber_printf(ber, "s{", logString); + + /* + * Now we start adding the relocations. + * Let's add the timestamp as the first one + * so it's out of the field loop + */ + rc |= ber_printf(ber, "{i", ZOS_REMOTE_RELOC_TIMESTAMP); + rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG); + rc |= ber_printf(ber, "s}", timestamp); + + /* + * Check that encoding is going OK until now + */ + if (rc < 0) + goto skip_event; + + /* + * Now go to first field, + * and iterate through all fields + */ + auparse_first_field(au); + do { + /* + * we set a maximum of 1024 chars for + * relocation data (field=value pairs) + * Hopefuly this wont overflow too often + */ + char data[1024]; + const char *name = auparse_get_field_name(au); + const char *value = auparse_interpret_field(au); + if (name == NULL || value == NULL) + goto skip_event; + + /* + * First reloc field is the Relocation type + * We use 'OTHER' here since we don't have + * anything better + */ + rc |= ber_printf(ber, "{i", ZOS_REMOTE_RELOC_OTHER); + + /* + * Second field is the relocation data + * We use a 'name=value' pair here + * Use up to 1023 chars (one char left for '\0') + */ + snprintf(data, 1023, "%s=%s", name, value); + rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG); + rc |= ber_printf(ber, "s}", data); + + /* + * Check encoding status + */ + if (rc < 0) + goto skip_event; + } while (auparse_next_field(au) > 0); + + /* + * After adding all relocations we are done with + * this item - finalize relocs and item + */ + rc |= ber_printf(ber, "}}"); + + /* + * Check if we are doing well with encoding + */ + if (rc < 0) + goto skip_event; + + } while (auparse_next_record(au) > 0); + + /* + * We have all items in - finalize item sequence & request + */ + rc |= ber_printf(ber, "}}"); + + /* + * Check if everything went alright with encoding + */ + if (rc < 0) + goto skip_event; + + /* + * finally, enqueue request and let the other + * thread process it + */ + log_debug("Encoding done, enqueuing event"); + enqueue(ber); + + return; + +skip_event: + log_warn("Warning - error encoding request, skipping event"); + ber_free(ber, 1); /* free it since we're not enqueuing it */ + return; + +fatal: + log_err("Error - Fatal error while encoding request. Aborting"); + stop = 1; +} + +int main(int argc, char *argv[]) +{ + int rc; + const char *cpath; + char buf[1024]; + struct sigaction sa; + sigset_t ss; + auparse_state_t *au; + ssize_t len; + + mypid = getpid(); + + log_info("starting with pid=%d", mypid); + + /* + * install signal handlers + */ + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sa.sa_handler = term_handler; + sigaction(SIGTERM, &sa, NULL); + sa.sa_handler = hup_handler; + sigaction(SIGHUP, &sa, NULL); + sa.sa_handler = alarm_handler; + sigaction(SIGALRM, &sa, NULL); + + /* + * the main program accepts a single (optional) argument: + * it's configuration file (this is NOT the plugin configuration + * usually located at /etc/audisp/plugin.d) + * We use the default (def_config_file) if no arguments are given + */ + if (argc == 1) { + cpath = def_config_file; + log_warn("No configuration file specified - using default (%s)", cpath); + } else if (argc == 2) { + cpath = argv[1]; + log_info("Using configuration file: %s", cpath); + } else { + log_err("Error - invalid number of parameters passed. Aborting"); + return 1; + } + + /* initialize record counter */ + conf.counter = 1; + + /* initialize configuration with default values */ + plugin_clear_config(&conf); + + /* initialize the submission queue */ + if (init_queue(conf.q_depth) != 0) { + log_err("Error - Can't initialize event queue. Aborting"); + return -1; + } + +#ifdef HAVE_LIBCAP_NG + // Drop all capabilities + capng_clear(CAPNG_SELECT_BOTH); + capng_apply(CAPNG_SELECT_BOTH); +#endif + + /* set stdin to O_NONBLOCK */ + if (fcntl(0, F_SETFL, O_NONBLOCK) == -1) { + log_err("Error - Can't set input to Non-blocking mode: %s. Aborting", + strerror(errno)); + return -1; + } + + do { + + hup = 0; /* don't flush unless hup == 1 */ + + /* + * initialization is done in 4 steps: + */ + + /* + * load configuration and + * increase queue depth if needed + */ + rc = plugin_load_config(&conf, cpath); + if (rc != 0) { + log_err("Error - Can't load configuration. Aborting"); + return -1; + } + increase_queue_depth(conf.q_depth); /* 1 */ + + /* initialize auparse */ + au = auparse_init(AUSOURCE_FEED, 0); /* 2 */ + if (au == NULL) { + log_err("Error - exiting due to auparse init errors"); + return -1; + } + + /* + * Block signals for everyone, + * Initialize submission thread, and + * Unblock signals for this thread + */ + sigfillset(&ss); + pthread_sigmask(SIG_BLOCK, &ss, NULL); + pthread_create(&submission_thread, NULL, + submission_thread_main, NULL); + pthread_sigmask(SIG_UNBLOCK, &ss, NULL); /* 3 */ + + /* add our event consumer callback */ + auparse_add_callback(au, push_event, NULL, NULL); /* 4 */ + + /* main loop */ + while (hup == 0 && stop == 0) { + fd_set rfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_SET(0, &rfds); + tv.tv_sec = 5; + tv.tv_usec = 0; + rc = select(1, &rfds, NULL, NULL, &tv); + if (rc == -1) { + if (errno == EINTR) { + log_debug("Select call interrupted"); + continue; + } + else { + log_err("Error - Fatal error while monitoring input: %s. Aborting", + strerror(errno)); + stop = 1; + } + } + else if (rc) { + len = read(0, buf, 1024); + if (len > 0) + /* let our callback know of the new data */ + auparse_feed(au, buf, len); + else if (len == 0) { + log_debug("End of input - Exiting"); + stop = 1; + } + else { + /* ignore interrupted call or empty pipe */ + if (errno != EINTR && errno != EAGAIN) { + log_err("Error - Fatal error while reading input: %s. Aborting", + strerror(errno)); + stop = 1; + } + else { + log_debug("Ignoring read interruption: %s", + strerror(errno)); + } + } + } + } + /* flush everything, in order */ + auparse_flush_feed(au); /* 4 */ + alarm(10); /* 10 seconds to clear the queue */ + pthread_join(submission_thread, NULL); /* 3 */ + alarm(0); /* cancel any pending alarm */ + auparse_destroy(au); /* 2 */ + plugin_free_config(&conf); /* 1 */ + } + while (hup && stop == 0); + + /* destroy queue before leaving */ + destroy_queue(); + + log_info("Exiting"); + + return 0; +} diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-queue.c b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-queue.c new file mode 100644 index 00000000..8071dca4 --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote-queue.c @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (C) 2007 International Business Machines Corp. * + * 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: * + * Klaus Heinrich Kiwi * + * based on code by Steve Grubb * + ***************************************************************************/ + +#include "zos-remote-queue.h" + +#include +#include +#include +#include "zos-remote-log.h" + +static volatile BerElement **q; +static pthread_mutex_t queue_lock; +static pthread_cond_t queue_nonempty; +static unsigned int q_next, q_last, q_depth; + + +int init_queue(unsigned int size) +{ + unsigned int i; + + q_next = 0; + q_last = 0; + q_depth = size; + q = malloc(q_depth * sizeof(BerElement *)); + if (q == NULL) + return -1; + + for (i=0; i 3) { + log_err("queue is full - dropping event"); + return; + } + pthread_mutex_lock(&queue_lock); + + /* OK, have lock add event */ + n = q_next%q_depth; + if (q[n] == NULL) { + q[n] = ber; + q_next = (n+1) % q_depth; + pthread_cond_signal(&queue_nonempty); + pthread_mutex_unlock(&queue_lock); + } else { + pthread_mutex_unlock(&queue_lock); + pthread_yield(); /* Let dequeue thread run to clear queue */ + retry_cnt++; + goto retry; + } +} + +BerElement *dequeue(void) +{ + BerElement *ber; + unsigned int n; + + /* Wait until its got something in it */ + pthread_mutex_lock(&queue_lock); + n = q_last%q_depth; + if (q[n] == NULL) { + pthread_cond_wait(&queue_nonempty, &queue_lock); + n = q_last%q_depth; + } + + /* OK, grab the next event */ + if (q[n] != NULL) { + ber = (BerElement *) q[n]; + q[n] = NULL; + q_last = (n+1) % q_depth; + } else + ber = NULL; + + pthread_mutex_unlock(&queue_lock); + + /* Process the event */ + return ber; +} + +void nudge_queue(void) +{ + pthread_cond_signal(&queue_nonempty); +} + +void increase_queue_depth(unsigned int size) +{ + pthread_mutex_lock(&queue_lock); + if (size > q_depth) { + unsigned int i; + void *tmp_q; + + tmp_q = realloc(q, size * sizeof(BerElement *)); + q = tmp_q; + for (i=q_depth; i * + * based on code by Steve Grubb * + ***************************************************************************/ + +#ifndef _ZOS_REMOTE_QUEUE_H +#define _ZOS_REMOTE_QUEUE_H + +#include + +int init_queue(unsigned int size); +void enqueue(BerElement *); +BerElement *dequeue(void); +void nudge_queue(void); +void increase_queue_depth(unsigned int size); +void destroy_queue(void); + +#endif /* _ZOS_REMOTE_QUEUE_H */ + diff --git a/framework/src/audit/audisp/plugins/zos-remote/zos-remote.conf b/framework/src/audit/audisp/plugins/zos-remote/zos-remote.conf new file mode 100644 index 00000000..8cf85f71 --- /dev/null +++ b/framework/src/audit/audisp/plugins/zos-remote/zos-remote.conf @@ -0,0 +1,10 @@ +## This is the configuration file for the audispd-zos-remote +## Audit dispatcher plugin. +## See zos-remote.conf(5) for more information + +server = zos_server.localdomain +port = 389 +user = RACF_ID +password = racf_password +timeout = 15 +q_depth = 64 -- cgit 1.2.3-korg