Re: [PATCH, v3 5/8] audispd-zos-remote plugin - queue interface
by Klaus Heinrich Kiwi
This patch implements a queue for already-encoded BER elements for the
zos-remote plugin.
This is entirely based on audit dispatcher code by Steve Grubb.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-queue.c audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-queue.c
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-queue.c 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-queue.c 2007-12-04 11:33:00.000000000 -0200
@@ -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 <klausk(a)br.ibm.com> *
+ * based on code by Steve Grubb <sgrubb(a)redhat.com> *
+ ***************************************************************************/
+
+#include "zos-remote-queue.h"
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <syslog.h>
+#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<q_depth; i++)
+ q[i] = NULL;
+
+ /* Setup IPC mechanisms */
+ pthread_mutex_init(&queue_lock, NULL);
+ pthread_cond_init(&queue_nonempty, NULL);
+
+ return 0;
+}
+
+void enqueue(BerElement *ber)
+{
+ unsigned int n, retry_cnt = 0;
+
+retry:
+ /* We allow 3 retries and then its over */
+ if (retry_cnt > 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<size; i++)
+ q[i] = NULL;
+ q_depth = size;
+ }
+ pthread_mutex_unlock(&queue_lock);
+}
+
+void destroy_queue(void)
+{
+ unsigned int i;
+
+ for (i=0; i<q_depth; i++) {
+ ber_free(q[i], 1);
+ }
+
+ free(q);
+}
+
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-queue.h audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-queue.h
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-queue.h 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-queue.h 2007-12-04 11:33:25.000000000 -0200
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * 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 <klausk(a)br.ibm.com> *
+ * based on code by Steve Grubb <sgrubb(a)redhat.com> *
+ ***************************************************************************/
+
+#ifndef _ZOS_REMOTE_QUEUE_H
+#define _ZOS_REMOTE_QUEUE_H
+
+#include <lber.h>
+
+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 */
+
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
16 years, 10 months
Re: [PATCH, v3 4/8] audispd-zos-remote plugin - logging interface
by Klaus Heinrich Kiwi
This patch implements a simple logging interface for the zos-remote
plugin. There's also some debugging code that's completely disabled if
'DEBUG' symbol isn't defined.
Messages are logged to the syslog (DAEMON facility) with info, warn and
err priorities.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-log.c audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-log.c
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-log.c 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-log.c 2007-12-04 11:08:43.000000000 -0200
@@ -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 <klausk(a)br.ibm.com> *
+ ***************************************************************************/
+#include "zos-remote-log.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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 -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-log.h audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-log.h
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-log.h 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-log.h 2007-12-04 11:45:55.000000000 -0200
@@ -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 <klausk(a)br.ibm.com> *
+ ***************************************************************************/
+
+#ifndef _ZOS_REMOTE_LOG_H
+#define _ZOS_REMOTE_LOG_H
+
+#include "zos-remote-ldap.h"
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <lber.h>
+
+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 */
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
16 years, 10 months
Re: [PATCH, v3 3/8] audispd-zos-remote plugin - ITDS LDAP interface
by Klaus Heinrich Kiwi
This patch brings the LDAP interface for the zos-remote plugin.
Functions here aim to initialize (read as: take necessary arguments),
connect and submit the LDAP extended operation to the RACF server.
There's also code to get the z/OS server response, filling an
internally-defined struct that is then checked for errors.
The connection itself can be reestablished if the plugin thinks it timed
out, after trying to submit the event directly. In case of event bursts,
this prevents the plugin of trying a connection upon every event
arrival, avoiding at the same time a synchronous keepalive operation.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-ldap.c audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-ldap.c
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-ldap.c 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-ldap.c 2007-12-04 10:57:15.000000000 -0200
@@ -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 <klausk(a)br.ibm.com> *
+ ***************************************************************************/
+
+#include "zos-remote-ldap.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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, char *server, int port,
+ char *user, 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 '<not shown>'",
+ 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 -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-ldap.h audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-ldap.h
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-ldap.h 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-ldap.h 2007-12-04 11:07:26.000000000 -0200
@@ -0,0 +1,311 @@
+/***************************************************************************
+ * 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 <klausk(a)br.ibm.com> *
+ ***************************************************************************/
+
+#ifndef _ZOS_REMOTE_LDAP_H
+#define _ZOS_REMOTE_LDAP_H
+
+#include <lber.h>
+#include <ldap.h>
+
+
+/***************************************************************************
+ * 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 *, char *, int, char *, 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 */
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
16 years, 10 months
Re: [PATCH, v3 2/8] audispd-zos-remote plugin - configuration interface
by Klaus Heinrich Kiwi
This patch brings the configuration interface for the zos-remote plugin
This is taken directly from Steve's audit dispatcher code, only adapted
for this specific plugin.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-config.c audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-config.c
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-config.c 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-config.c 2007-12-04 15:33:06.000000000 -0200
@@ -0,0 +1,442 @@
+/***************************************************************************
+ * 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 <klausk(a)br.ibm.com> *
+ * based on code by Steve Grubb <sgrubb(a)redhat.com> *
+ ***************************************************************************/
+
+#include "zos-remote-config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#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 *, const char *);
+
+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}
+};
+
+
+
+/*
+ * 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, 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);
+ 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, file);
+ 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;
+
+ nv->name = NULL;
+ nv->value = NULL;
+ nv->option = NULL;
+ ptr = strtok(buf, " ");
+ 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(NULL, " ");
+ if (ptr == NULL)
+ return 1;
+ if (strcmp(ptr, "=") != 0)
+ return 2;
+
+ /* get the value */
+ ptr = strtok(NULL, " ");
+ if (ptr == NULL)
+ return 1;
+ nv->value = ptr;
+
+ /* See if there's an option */
+ ptr = strtok(NULL, " ");
+ if (ptr) {
+ nv->option = ptr;
+
+ /* Make sure there's nothing else */
+ ptr = strtok(NULL, " ");
+ 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)
+{
+
+ 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)
+{
+
+ 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)
+{
+
+ 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, const char *file)
+{
+ /* 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 -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-config.h audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-config.h
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-config.h 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-config.h 2007-12-04 10:40:56.000000000 -0200
@@ -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 <klausk(a)br.ibm.com> *
+ * based on code by Steve Grubb <sgrubb(a)redhat.com> *
+ ***************************************************************************/
+
+#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 *, char *);
+void plugin_free_config(plugin_conf_t *);
+
+#endif /* _ZOS_REMOTE_CONFIG_H */
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
16 years, 10 months
Re: [PATCH, v3 1/8] audispd-zos-remote plugin - Configuration and policy files
by Klaus Heinrich Kiwi
This patch adds the configuration files and policy module sources needed
by the plugin.
The policy is not using newer interfaces so that it can be build for
RHEL5 GA.
There is a need for two separate configuration files: one for the audit
dispatcher and another for the plugin itself.
The plugin configuration includes server and authentication information,
thus it should not be readable by anyone but root. The default queue
size is to allow event bursts avoiding events drop.
The plugin comes disabled by default.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/zos-remote/audispd-zos-remote.conf audit-1.6.2_zos-remote/audisp/plugins/zos-remote/audispd-zos-remote.conf
--- audit-1.6.2/audisp/plugins/zos-remote/audispd-zos-remote.conf 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/audispd-zos-remote.conf 2007-12-13 13:09:44.000000000 -0200
@@ -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 -purN audit-1.6.2/audisp/plugins/zos-remote/policy/audispd-zos-remote.fc audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/audispd-zos-remote.fc
--- audit-1.6.2/audisp/plugins/zos-remote/policy/audispd-zos-remote.fc 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/audispd-zos-remote.fc 2007-12-04 11:43:24.000000000 -0200
@@ -0,0 +1,2 @@
+
+/sbin/audispd-zos-remote -- gen_context(system_u:object_r:zos_remote_exec_t,s0)
diff -purN audit-1.6.2/audisp/plugins/zos-remote/policy/audispd-zos-remote.if audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/audispd-zos-remote.if
--- audit-1.6.2/audisp/plugins/zos-remote/policy/audispd-zos-remote.if 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/audispd-zos-remote.if 2007-12-04 11:43:49.000000000 -0200
@@ -0,0 +1,58 @@
+## <summary>policy for z/OS Remote-services Audit dispatcher plugin</summary>
+
+########################################
+## <summary>
+## Execute a domain transition to run audispd-zos-remote.
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed to transition.
+## </summary>
+## </param>
+#
+interface(`zos_remote_domtrans',`
+ gen_require(`
+ type zos_remote_t;
+ type zos_remote_exec_t;
+ ')
+
+ domain_auto_trans($1,zos_remote_exec_t,zos_remote_t);
+
+ allow $1 zos_remote_t:fd use;
+ allow zos_remote_t $1:fd use;
+ allow zos_remote_t $1:fifo_file rw_file_perms;
+ allow zos_remote_t $1:process sigchld;
+')
+
+########################################
+## <summary>
+## Allow specified type and role to transition and
+## run in the zos_remote_t domain. Allow specified type
+## to use zos_remote_t terminal.
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed the zos_remote domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the role's terminal.
+## </summary>
+## </param>
+#
+interface(`zos_remote_run',`
+ gen_require(`
+ type zos_remote_t;
+ ')
+
+ zos_remote_domtrans($1)
+ role $2 types zos_remote_t;
+ dontaudit zos_remote_t $3:chr_file rw_term_perms;
+')
+
diff -purN audit-1.6.2/audisp/plugins/zos-remote/policy/audispd-zos-remote.te audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/audispd-zos-remote.te
--- audit-1.6.2/audisp/plugins/zos-remote/policy/audispd-zos-remote.te 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/audispd-zos-remote.te 2007-12-04 11:44:07.000000000 -0200
@@ -0,0 +1,54 @@
+policy_module(zos_remote,1.0.0)
+
+########################################
+#
+# Declarations
+#
+
+type zos_remote_t;
+type zos_remote_exec_t;
+
+## use below if selinux-policy_devel > 3:
+## zos_remote_application_domain(zos_remote_t, zos_remote_exec_t)
+
+## use below for RHEL5 series:
+init_system_domain(zos_remote_t, zos_remote_exec_t)
+
+role system_r types zos_remote_t;
+
+
+########################################
+#
+# zos_remote local policy
+#
+
+## internal communication is often done using fifo and unix sockets.
+allow zos_remote_t self:fifo_file rw_file_perms;
+allow zos_remote_t self:unix_stream_socket create_stream_socket_perms;
+## allow signals to self
+allow zos_remote_t self:process signal;
+
+## audispd is in the auditd_t domain
+gen_require(`
+ type auditd_t;
+')
+
+## Allow auditd_t->zos_remote_t transition
+zos_remote_domtrans(auditd_t);
+
+## audispd execve pipe?
+allow zos_remote_t auditd_t:unix_stream_socket { read write getattr };
+
+## audispd must be able to send signals to audispd-zos-remote
+allow auditd_t zos_remote_t:process signal;
+
+## Allow network access, name resolv
+auth_use_nsswitch(zos_remote_t);
+corenet_tcp_connect_generic_port(zos_remote_t);
+
+## Allow use of misc files and libraries
+files_read_etc_files(zos_remote_t)
+libs_use_ld_so(zos_remote_t)
+libs_use_shared_libs(zos_remote_t)
+miscfiles_read_localization(zos_remote_t)
+logging_send_syslog_msg(zos_remote_t)
diff -purN audit-1.6.2/audisp/plugins/zos-remote/policy/build.sh audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/build.sh
--- audit-1.6.2/audisp/plugins/zos-remote/policy/build.sh 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/build.sh 2007-10-10 10:26:18.000000000 -0300
@@ -0,0 +1,3 @@
+
+#!/bin/sh
+make -f /usr/share/selinux/devel/Makefile
diff -purN audit-1.6.2/audisp/plugins/zos-remote/policy/install.sh audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/install.sh
--- audit-1.6.2/audisp/plugins/zos-remote/policy/install.sh 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/policy/install.sh 2007-12-04 10:31:28.000000000 -0200
@@ -0,0 +1,4 @@
+/usr/sbin/semodule -i audispd-zos-remote.pp
+
+/sbin/restorecon -F -v /sbin/audispd-zos-remote
+
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote.conf audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote.conf
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote.conf 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote.conf 2007-12-04 11:45:21.000000000 -0200
@@ -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
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
16 years, 10 months
audit event parsing library
by Abhishek Gupta
can anyone give me details of audit event parsing library.?
What are the library functions and their purpose?
16 years, 10 months
[PATCH] XFRM: Display the audited SPI value in host byte order
by Paul Moore
Currently the IPsec protocol SPI values are written to the audit log in
network byte order which is different from almost all other values which
are recorded in host byte order. This patch corrects this inconsistency
by writing the SPI values to the audit record in host byte order.
Signed-off-by: Paul Moore <paul.moore(a)hp.com>
---
net/xfrm/xfrm_state.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index cf43c49..1af522b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2028,6 +2028,7 @@ void
xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
{
struct audit_buffer *audit_buf;
+ u32 spi;
extern int audit_enabled;
if (audit_enabled == 0)
@@ -2037,8 +2038,8 @@ xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
return;
audit_log_format(audit_buf, " op=SAD-add res=%u",result);
xfrm_audit_common_stateinfo(x, audit_buf);
- audit_log_format(audit_buf, " spi=%lu(0x%lx)",
- (unsigned long)x->id.spi, (unsigned long)x->id.spi);
+ spi = ntohl(x->id.spi);
+ audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
@@ -2047,6 +2048,7 @@ void
xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
{
struct audit_buffer *audit_buf;
+ u32 spi;
extern int audit_enabled;
if (audit_enabled == 0)
@@ -2056,8 +2058,8 @@ xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
return;
audit_log_format(audit_buf, " op=SAD-delete res=%u",result);
xfrm_audit_common_stateinfo(x, audit_buf);
- audit_log_format(audit_buf, " spi=%lu(0x%lx)",
- (unsigned long)x->id.spi, (unsigned long)x->id.spi);
+ spi = ntohl(x->id.spi);
+ audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
16 years, 10 months
[PATCH -v2] Audit: add uid, loginuid, and comm to OBJ_PID records
by Eric Paris
Add uid, loginuid, and comm collection to OBJ_PID records. This just
gives users a little more information about the task that received a
signal. pid is rather meaningless after the fact, and even though comm
isn't great we can't collect exe reasonably on this code path for
performance reasons.
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
#kill a program in a different domain, running as a test user originally logged in as root
type=OBJ_PID msg=audit(12/12/2007 14:21:37.718:45) : opid=2314 obj=root:system_r:httpd_t:s0-s0:c0.c1023 uid=test auid=root comm=bash
type=SYSCALL msg=audit(12/12/2007 14:21:37.718:45) : arch=x86_64 syscall=kill success=yes exit=0 a0=90a a1=f a2=0 a3=0 items=0 ppid=2233 pid=2238 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts1 comm=bash exe=/bin/bash subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
#signal 2 threads in a thread group
type=OBJ_PID msg=audit(12/12/2007 13:56:29.104:18) : opid=2231 obj=root:system_r:unconfined_t:s0-s0:c0.c1023 uid=root auid=root comm=tmp
type=OBJ_PID msg=audit(12/12/2007 13:56:29.104:18) : opid=2230 obj=root:system_r:unconfined_t:s0-s0:c0.c1023 uid=root auid=root comm=tmp
type=SYSCALL msg=audit(12/12/2007 13:56:29.104:18) : arch=x86_64 syscall=kill success=yes exit=0 a0=fffff74a a1=9 a2=0 a3=0 items=0 ppid=2195 pid=2229 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 comm=tmp exe=/tmp/tmp subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
kernel/auditsc.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index bce9ecd..b548044 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -176,7 +176,10 @@ struct audit_aux_data_fd_pair {
struct audit_aux_data_pids {
struct audit_aux_data d;
pid_t target_pid[AUDIT_AUX_PIDS];
+ pid_t target_uid[AUDIT_AUX_PIDS];
+ pid_t target_auid[AUDIT_AUX_PIDS];
u32 target_sid[AUDIT_AUX_PIDS];
+ char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
int pid_count;
};
@@ -215,7 +218,10 @@ struct audit_context {
int arch;
pid_t target_pid;
+ pid_t target_uid;
+ pid_t target_auid;
u32 target_sid;
+ char target_comm[TASK_COMM_LEN];
struct audit_tree_refs *trees, *first_trees;
int tree_count;
@@ -922,7 +928,7 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
}
static int audit_log_pid_context(struct audit_context *context, pid_t pid,
- u32 sid)
+ pid_t uid, pid_t auid, u32 sid, char *comm)
{
struct audit_buffer *ab;
char *s = NULL;
@@ -937,7 +943,9 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
audit_log_format(ab, "opid=%d obj=(none)", pid);
rc = 1;
} else
- audit_log_format(ab, "opid=%d obj=%s", pid, s);
+ audit_log_format(ab, "opid=%d obj=%s", pid, s);
+ audit_log_format(ab, " uid=%d auid=%d comm=", uid, auid);
+ audit_log_untrustedstring(ab, comm);
audit_log_end(ab);
kfree(s);
@@ -1168,13 +1176,17 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
for (i = 0; i < axs->pid_count; i++)
if (audit_log_pid_context(context, axs->target_pid[i],
- axs->target_sid[i]))
+ axs->target_uid[i],
+ axs->target_auid[i],
+ axs->target_sid[i],
+ axs->target_comm[i]))
call_panic = 1;
}
if (context->target_pid &&
audit_log_pid_context(context, context->target_pid,
- context->target_sid))
+ context->target_uid, context->target_auid,
+ context->target_sid, context->target_comm))
call_panic = 1;
if (context->pwd && context->pwdmnt) {
@@ -2193,7 +2205,10 @@ void __audit_ptrace(struct task_struct *t)
struct audit_context *context = current->audit_context;
context->target_pid = t->pid;
+ context->target_uid = t->uid;
+ context->target_auid = audit_get_loginuid(t->audit_context);
selinux_get_task_sid(t, &context->target_sid);
+ memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
}
/**
@@ -2230,7 +2245,10 @@ int __audit_signal_info(int sig, struct task_struct *t)
* in audit_context */
if (!ctx->target_pid) {
ctx->target_pid = t->tgid;
+ ctx->target_uid = t->uid;
+ ctx->target_auid = audit_get_loginuid(t->audit_context);
selinux_get_task_sid(t, &ctx->target_sid);
+ memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
return 0;
}
@@ -2247,7 +2265,10 @@ int __audit_signal_info(int sig, struct task_struct *t)
BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
axp->target_pid[axp->pid_count] = t->tgid;
+ axp->target_uid[axp->pid_count] = t->uid;
+ axp->target_auid[axp->pid_count] = audit_get_loginuid(t->audit_context);
selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
+ memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
axp->pid_count++;
return 0;
16 years, 10 months
[PATCH v2] XFRM: assorted IPsec fixups
by Paul Moore
This patch fixes a number of small but potentially troublesome things in the
XFRM/IPsec code:
* Use the 'audit_enabled' variable already in include/linux/audit.h
Removed the need for extern declarations local to each XFRM audit fuction
* Convert 'sid' to 'secid'
The 'sid' name is specific to SELinux, 'secid' is the common naming
convention used by the kernel when refering to tokenized LSM labels
* Convert address display to use standard NIP* macros
Similar to what was recently done with the SPD audit code, this also also
includes the removal of some unnecessary memcpy() calls
* Move common code to xfrm_audit_common_stateinfo()
Code consolidation from the "less is more" book on software development
* Convert the SPI in audit records to host byte order
The current SPI values in the audit record are being displayed in network
byte order, probably not what was intended
* Proper spacing around commas in function arguments
Minor style tweak since I was already touching the code
Signed-off-by: Paul Moore <paul.moore(a)hp.com>
---
include/linux/xfrm.h | 2 +
include/net/xfrm.h | 18 ++++++------
net/xfrm/xfrm_policy.c | 15 +++++-----
net/xfrm/xfrm_state.c | 69 +++++++++++++++++++++--------------------------
security/selinux/xfrm.c | 20 +++++++-------
5 files changed, 58 insertions(+), 66 deletions(-)
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b58adc5..f75a337 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -31,7 +31,7 @@ struct xfrm_sec_ctx {
__u8 ctx_doi;
__u8 ctx_alg;
__u16 ctx_len;
- __u32 ctx_sid;
+ __u32 ctx_secid;
char ctx_str[0];
};
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0c380d9..3134ba6 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -547,7 +547,7 @@ struct xfrm_audit
};
#ifdef CONFIG_AUDITSYSCALL
-static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
+static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 secid)
{
struct audit_buffer *audit_buf = NULL;
char *secctx;
@@ -560,8 +560,8 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
audit_log_format(audit_buf, "auid=%u", auid);
- if (sid != 0 &&
- security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
+ if (secid != 0 &&
+ security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
security_release_secctx(secctx, secctx_len);
} else
@@ -570,13 +570,13 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
}
extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
#else
#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
@@ -706,13 +706,13 @@ extern int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
#ifdef CONFIG_SECURITY_NETWORK_XFRM
/* If neither has a context --> match
- * Otherwise, both must have a context and the sids, doi, alg must match
+ * Otherwise, both must have a context and the secids, doi, alg must match
*/
static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
{
return ((!s1 && !s2) ||
(s1 && s2 &&
- (s1->ctx_sid == s2->ctx_sid) &&
+ (s1->ctx_secid == s2->ctx_secid) &&
(s1->ctx_doi == s2->ctx_doi) &&
(s1->ctx_alg == s2->ctx_alg)));
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d9bde91..8a89e2c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -24,6 +24,7 @@
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/cache.h>
+#include <linux/audit.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -2298,15 +2299,14 @@ static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
}
}
-void
-xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SPD-add res=%u", result);
@@ -2315,15 +2315,14 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
}
EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
-void
-xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SPD-delete res=%u", result);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 5b860b6..e2a3dd1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -19,6 +19,7 @@
#include <linux/ipsec.h>
#include <linux/module.h>
#include <linux/cache.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include "xfrm_hash.h"
@@ -1994,67 +1995,59 @@ void __init xfrm_state_init(void)
static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
struct audit_buffer *audit_buf)
{
- if (x->security)
- audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
- x->security->ctx_alg, x->security->ctx_doi,
- x->security->ctx_str);
+ struct xfrm_sec_ctx *ctx = x->security;
+ u32 spi = ntohl(x->id.spi);
- switch(x->props.family) {
- case AF_INET:
- audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
- NIPQUAD(x->props.saddr.a4),
- NIPQUAD(x->id.daddr.a4));
- break;
- case AF_INET6:
- {
- struct in6_addr saddr6, daddr6;
-
- memcpy(&saddr6, x->props.saddr.a6,
- sizeof(struct in6_addr));
- memcpy(&daddr6, x->id.daddr.a6,
- sizeof(struct in6_addr));
- audit_log_format(audit_buf,
- " src=" NIP6_FMT " dst=" NIP6_FMT,
- NIP6(saddr6), NIP6(daddr6));
- }
- break;
- }
+ if (ctx)
+ audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
+ ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
+
+ switch(x->props.family) {
+ case AF_INET:
+ audit_log_format(audit_buf,
+ " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
+ NIPQUAD(x->props.saddr.a4),
+ NIPQUAD(x->id.daddr.a4));
+ break;
+ case AF_INET6:
+ audit_log_format(audit_buf,
+ " src=" NIP6_FMT " dst=" NIP6_FMT,
+ NIP6(*(struct in6_addr *)x->props.saddr.a6),
+ NIP6(*(struct in6_addr *)x->id.daddr.a6));
+ break;
+ }
+
+ audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
}
-void
-xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
+void xfrm_audit_state_add(struct xfrm_state *x, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
- audit_log_format(audit_buf, " op=SAD-add res=%u",result);
+ audit_log_format(audit_buf, " op=SAD-add res=%u", result);
xfrm_audit_common_stateinfo(x, audit_buf);
- audit_log_format(audit_buf, " spi=%lu(0x%lx)",
- (unsigned long)x->id.spi, (unsigned long)x->id.spi);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
-void
-xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
+void xfrm_audit_state_delete(struct xfrm_state *x, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
- audit_log_format(audit_buf, " op=SAD-delete res=%u",result);
+ audit_log_format(audit_buf, " op=SAD-delete res=%u", result);
xfrm_audit_common_stateinfo(x, audit_buf);
- audit_log_format(audit_buf, " spi=%lu(0x%lx)",
- (unsigned long)x->id.spi, (unsigned long)x->id.spi);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index e076039..c925880 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -85,7 +85,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
if (!selinux_authorizable_ctx(ctx))
return -EINVAL;
- sel_sid = ctx->ctx_sid;
+ sel_sid = ctx->ctx_secid;
}
else
/*
@@ -132,7 +132,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
/* Not a SELinux-labeled SA */
return 0;
- state_sid = x->security->ctx_sid;
+ state_sid = x->security->ctx_secid;
if (fl->secid != state_sid)
return 0;
@@ -175,13 +175,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
struct xfrm_sec_ctx *ctx = x->security;
if (!sid_set) {
- *sid = ctx->ctx_sid;
+ *sid = ctx->ctx_secid;
sid_set = 1;
if (!ckall)
break;
}
- else if (*sid != ctx->ctx_sid)
+ else if (*sid != ctx->ctx_secid)
return -EINVAL;
}
}
@@ -232,7 +232,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
ctx->ctx_str[str_len] = 0;
rc = security_context_to_sid(ctx->ctx_str,
str_len,
- &ctx->ctx_sid);
+ &ctx->ctx_secid);
if (rc)
goto out;
@@ -240,7 +240,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
/*
* Does the subject have permission to set security context?
*/
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+ rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
if (rc)
@@ -264,7 +264,7 @@ not_from_user:
ctx->ctx_doi = XFRM_SC_DOI_LSM;
ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
- ctx->ctx_sid = sid;
+ ctx->ctx_secid = sid;
ctx->ctx_len = str_len;
memcpy(ctx->ctx_str,
ctx_str,
@@ -341,7 +341,7 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
int rc = 0;
if (ctx)
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+ rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
@@ -383,7 +383,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
int rc = 0;
if (ctx)
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+ rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
@@ -412,7 +412,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
if (x && selinux_authorizable_xfrm(x)) {
struct xfrm_sec_ctx *ctx = x->security;
- sel_sid = ctx->ctx_sid;
+ sel_sid = ctx->ctx_secid;
break;
}
}
16 years, 10 months