aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c')
-rw-r--r--framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c608
1 files changed, 0 insertions, 608 deletions
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
deleted file mode 100644
index 209743f3..00000000
--- a/framework/src/audit/audisp/plugins/zos-remote/zos-remote-ldap.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/***************************************************************************
- * 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@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, 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 '<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;
-}