diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c
index d6d1465249c8cd1068b008a30d53745f4eea749a..458d4e2d5aff38d3f42f530e6f75d9f98c07b78a 100644
--- a/libraries/libldap/tls.c
+++ b/libraries/libldap/tls.c
@@ -150,7 +150,16 @@ ldap_pvt_tls_init( void )
 	if ( tls_initialized ) return 0;
 	tls_initialized = 1;
 
+#ifdef HAVE_EBCDIC
+	{
+		char *file = LDAP_STRDUP( tls_opt_randfile );
+		if ( file ) __atoe( file );
+		(void) tls_seed_PRNG( file );
+		LDAP_FREE( file );
+	}
+#else
 	(void) tls_seed_PRNG( tls_opt_randfile );
+#endif
 
 #ifdef LDAP_R_COMPILE
 	tls_init_threads();
@@ -171,6 +180,36 @@ int
 ldap_pvt_tls_init_def_ctx( void )
 {
 	STACK_OF(X509_NAME) *calist;
+	int rc = 0;
+	char *ciphersuite = tls_opt_ciphersuite;
+	char *cacertfile = tls_opt_cacertfile;
+	char *cacertdir = tls_opt_cacertdir;
+	char *certfile = tls_opt_certfile;
+	char *keyfile = tls_opt_keyfile;
+
+#ifdef HAVE_EBCDIC
+	/* This ASCII/EBCDIC handling is a real pain! */
+	if ( ciphersuite ) {
+		ciphersuite = LDAP_STRDUP( ciphersuite );
+		__atoe( ciphersuite );
+	}
+	if ( cacertfile ) {
+		cacertfile = LDAP_STRDUP( cacertfile );
+		__atoe( cacertfile );
+	}
+	if ( cacertdir ) {
+		cacertdir = LDAP_STRDUP( cacertdir );
+		__atoe( cacertdir );
+	}
+	if ( certfile ) {
+		certfile = LDAP_STRDUP( certfile );
+		__atoe( certfile );
+	}
+	if ( keyfile ) {
+		keyfile = LDAP_STRDUP( keyfile );
+		__atoe( keyfile );
+	}
+#endif
 
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
@@ -188,11 +227,12 @@ ldap_pvt_tls_init_def_ctx( void )
 			   "TLS: could not allocate default ctx (%lu).\n",
 				ERR_peek_error(),0,0);
 #endif
+			rc = -1;
 			goto error_exit;
 		}
 
 		if ( tls_opt_ciphersuite &&
-			!SSL_CTX_set_cipher_list( tls_def_ctx, tls_opt_ciphersuite ) )
+			!SSL_CTX_set_cipher_list( tls_def_ctx, ciphersuite ) )
 		{
 #ifdef NEW_LOGGING
 			LDAP_LOG ( TRANSPORT, ERR, "ldap_pvt_tls_init_def_ctx: "
@@ -204,12 +244,13 @@ ldap_pvt_tls_init_def_ctx( void )
 				   tls_opt_ciphersuite, 0, 0 );
 #endif
 			tls_report_error();
+			rc = -1;
 			goto error_exit;
 		}
 
 		if (tls_opt_cacertfile != NULL || tls_opt_cacertdir != NULL) {
 			if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
-					tls_opt_cacertfile, tls_opt_cacertdir ) ||
+					cacertfile, cacertdir ) ||
 				!SSL_CTX_set_default_verify_paths( tls_def_ctx ) )
 			{
 #ifdef NEW_LOGGING
@@ -227,10 +268,11 @@ ldap_pvt_tls_init_def_ctx( void )
 					0 );
 #endif
 				tls_report_error();
+				rc = -1;
 				goto error_exit;
 			}
 
-			calist = get_ca_list( tls_opt_cacertfile, tls_opt_cacertdir );
+			calist = get_ca_list( cacertfile, cacertdir );
 			if ( !calist ) {
 #ifdef NEW_LOGGING
 				LDAP_LOG ( TRANSPORT, ERR, "ldap_pvt_tls_init_def_ctx: "
@@ -245,6 +287,7 @@ ldap_pvt_tls_init_def_ctx( void )
 					0 );
 #endif
 				tls_report_error();
+				rc = -1;
 				goto error_exit;
 			}
 
@@ -253,7 +296,7 @@ ldap_pvt_tls_init_def_ctx( void )
 
 		if ( tls_opt_keyfile &&
 			!SSL_CTX_use_PrivateKey_file( tls_def_ctx,
-				tls_opt_keyfile, SSL_FILETYPE_PEM ) )
+				keyfile, SSL_FILETYPE_PEM ) )
 		{
 #ifdef NEW_LOGGING
 			LDAP_LOG ( TRANSPORT, ERR, "ldap_pvt_tls_init_def_ctx: "
@@ -264,12 +307,13 @@ ldap_pvt_tls_init_def_ctx( void )
 				tls_opt_keyfile,0,0);
 #endif
 			tls_report_error();
+			rc = -1;
 			goto error_exit;
 		}
 
 		if ( tls_opt_certfile &&
 			!SSL_CTX_use_certificate_file( tls_def_ctx,
-				tls_opt_certfile, SSL_FILETYPE_PEM ) )
+				certfile, SSL_FILETYPE_PEM ) )
 		{
 #ifdef NEW_LOGGING
 			LDAP_LOG ( TRANSPORT, ERR, "ldap_pvt_tls_init_def_ctx: "
@@ -281,6 +325,7 @@ ldap_pvt_tls_init_def_ctx( void )
 				tls_opt_certfile,0,0);
 #endif
 			tls_report_error();
+			rc = -1;
 			goto error_exit;
 		}
 
@@ -297,6 +342,7 @@ ldap_pvt_tls_init_def_ctx( void )
 				0,0,0);
 #endif
 			tls_report_error();
+			rc = -1;
 			goto error_exit;
 		}
 
@@ -319,20 +365,22 @@ ldap_pvt_tls_init_def_ctx( void )
 		SSL_CTX_set_tmp_rsa_callback( tls_def_ctx, tls_tmp_rsa_cb );
 		/* SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb ); */
 	}
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
-#endif
-	return 0;
-
 error_exit:
-	if ( tls_def_ctx != NULL ) {
+	if ( rc == -1 && tls_def_ctx != NULL ) {
 		SSL_CTX_free( tls_def_ctx );
 		tls_def_ctx = NULL;
 	}
+#ifdef HAVE_EBCDIC
+	LDAP_FREE( ciphersuite );
+	LDAP_FREE( cacertfile );
+	LDAP_FREE( cacertdir );
+	LDAP_FREE( certfile );
+	LDAP_FREE( keyfile );
+#endif
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
 #endif
-	return -1;
+	return rc;
 }
 
 static STACK_OF(X509_NAME) *
@@ -345,37 +393,14 @@ get_ca_list( char * bundle, char * dir )
 	}
 #if defined(HAVE_DIRENT_H) || defined(dirent)
 	if ( dir ) {
-		DIR *dirp;
-		struct dirent *d;
-		char buf[MAXPATHLEN];
-		int l = strlen(dir), freeit = 0;
-
-		if (l > sizeof(buf))
-			goto done;
-
-		dirp = opendir( dir );
+		int freeit = 0;
 
 		if ( !ca_list ) {
 			ca_list = sk_X509_NAME_new_null();
 			freeit = 1;
 		}
-
-		strcpy(buf, dir);
-
-		while ( dirp ) {
-			if ( ( d = readdir( dirp )) == NULL) {
-				closedir( dirp );
-				break;
-			}
-			if (l + sizeof(LDAP_DIRSEP) + NAMLEN(d) > sizeof(buf))
-				continue;
-
-			sprintf( buf+l, LDAP_DIRSEP "%s", d->d_name );
-			if ( SSL_add_file_cert_subjects_to_stack(ca_list, buf)) {
-				freeit = 0;
-			}
-		}
-		if ( freeit ) {
+		if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
+			freeit ) {
 			sk_X509_NAME_free( ca_list );
 			ca_list = NULL;
 		}
@@ -740,6 +765,9 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
 		if ((err = ERR_peek_error())) {
 			char buf[256];
 			ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
+#ifdef HAVE_EBCDIC
+			if ( ld->ld_error ) __etoa(ld->ld_error);
+#endif
 		}
 
 #ifdef NEW_LOGGING
@@ -916,7 +944,7 @@ ldap_pvt_tls_get_peer_hostname( void *s )
 }
 
 int
-ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
+ldap_pvt_tls_check_hostname( void *s, const char *name_in )
 {
 	int i, ret = LDAP_LOCAL_ERROR;
 	X509 *x;
@@ -1019,7 +1047,6 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
 				"TLS: unable to get common name from peer certificate.\n",
 				0, 0, 0 );
 #endif
-			ld->ld_error = LDAP_STRDUP("TLS: unable to get CN from peer certificate");
 
 		} else if (strcasecmp(name, buf)) {
 #ifdef NEW_LOGGING
@@ -1032,7 +1059,6 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
 				name, buf, 0 );
 #endif
 			ret = LDAP_CONNECT_ERROR;
-			ld->ld_error = LDAP_STRDUP("TLS: hostname does not match CN in peer certificate");
 
 		} else {
 			ret = LDAP_SUCCESS;
@@ -1310,7 +1336,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
 	/* 
 	 * compare host with name(s) in certificate
 	 */
-	ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
+	ld->ld_errno = ldap_pvt_tls_check_hostname( ssl, host );
 	if (ld->ld_errno != LDAP_SUCCESS) {
 		return ld->ld_errno;
 	}
@@ -1340,6 +1366,7 @@ tls_info_cb( SSL *ssl, int where, int ret )
 {
 	int w;
 	char *op;
+	char *state = SSL_state_string_long( ssl );
 
 	w = where & ~SSL_ST_MASK;
 	if ( w & SSL_ST_CONNECT ) {
@@ -1350,54 +1377,75 @@ tls_info_cb( SSL *ssl, int where, int ret )
 		op = "undefined";
 	}
 
+#ifdef HAVE_EBCDIC
+	if ( state ) {
+		state = LDAP_STRDUP( state );
+		__etoa( state );
+	}
+#endif
 	if ( where & SSL_CB_LOOP ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG ( TRANSPORT, DETAIL1, "tls_info_cb: "
-			"TLS trace: %s:%s\n", op, SSL_state_string_long( ssl ), 0 );
+			"TLS trace: %s:%s\n", op, state, 0 );
 #else
 		Debug( LDAP_DEBUG_TRACE,
 			   "TLS trace: %s:%s\n",
-			   op, SSL_state_string_long( ssl ), 0 );
+			   op, state, 0 );
 #endif
 
 	} else if ( where & SSL_CB_ALERT ) {
+		char *atype = SSL_alert_type_string_long( ret );
+		char *adesc = SSL_alert_desc_string_long( ret );
 		op = ( where & SSL_CB_READ ) ? "read" : "write";
+#ifdef HAVE_EBCDIC
+		if ( atype ) {
+			atype = LDAP_STRDUP( atype );
+			__etoa( atype );
+		}
+		if ( adesc ) {
+			adesc = LDAP_STRDUP( adesc );
+			__etoa( adesc );
+		}
+#endif
 #ifdef NEW_LOGGING
 		LDAP_LOG ( TRANSPORT, DETAIL1, 
 			"tls_info_cb: TLS trace: SSL3 alert %s:%s:%s\n", 
-			op, SSL_alert_type_string_long( ret ), 
-			SSL_alert_desc_string_long( ret) );
+			op, atype, adesc );
 #else
 		Debug( LDAP_DEBUG_TRACE,
 			   "TLS trace: SSL3 alert %s:%s:%s\n",
-			   op,
-			   SSL_alert_type_string_long( ret ),
-			   SSL_alert_desc_string_long( ret) );
+			   op, atype, adesc );
+#endif
+#ifdef HAVE_EBCDIC
+		if ( atype ) LDAP_FREE( atype );
+		if ( adesc ) LDAP_FREE( adesc );
 #endif
-
 	} else if ( where & SSL_CB_EXIT ) {
 		if ( ret == 0 ) {
 #ifdef NEW_LOGGING
 			LDAP_LOG ( TRANSPORT, ERR, 
 				"tls_info_cb: TLS trace: %s:failed in %s\n", 
-				op, SSL_state_string_long( ssl ), 0 );
+				op, state, 0 );
 #else
 			Debug( LDAP_DEBUG_TRACE,
 				   "TLS trace: %s:failed in %s\n",
-				   op, SSL_state_string_long( ssl ), 0 );
+				   op, state, 0 );
 #endif
 		} else if ( ret < 0 ) {
 #ifdef NEW_LOGGING
 			LDAP_LOG ( TRANSPORT, ERR, 
 				"tls_info_cb: TLS trace: %s:error in %s\n", 
-				op, SSL_state_string_long( ssl ), 0 );
+				op, state, 0 );
 #else
 			Debug( LDAP_DEBUG_TRACE,
 				   "TLS trace: %s:error in %s\n",
-				   op, SSL_state_string_long( ssl ), 0 );
+				   op, state, 0 );
 #endif
 		}
 	}
+#ifdef HAVE_EBCDIC
+	if ( state ) LDAP_FREE( state );
+#endif
 }
 
 static int
@@ -1410,6 +1458,7 @@ tls_verify_cb( int ok, X509_STORE_CTX *ctx )
 	X509_NAME *issuer;
 	char *sname;
 	char *iname;
+	char *certerr = NULL;
 
 	cert = X509_STORE_CTX_get_current_cert( ctx );
 	errnum = X509_STORE_CTX_get_error( ctx );
@@ -1424,6 +1473,15 @@ tls_verify_cb( int ok, X509_STORE_CTX *ctx )
 	/* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
 	sname = X509_NAME_oneline( subject, NULL, 0 );
 	iname = X509_NAME_oneline( issuer, NULL, 0 );
+	if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
+#ifdef HAVE_EBCDIC
+	if ( sname ) __etoa( sname );
+	if ( iname ) __etoa( iname );
+	if ( certerr ) {
+		certerr = LDAP_STRDUP( certerr );
+		__etoa( certerr );
+	}
+#endif
 #ifdef NEW_LOGGING
 	LDAP_LOG( TRANSPORT, ERR,
 		   "TLS certificate verification: depth: %d, err: %d, subject: %s,",
@@ -1433,7 +1491,7 @@ tls_verify_cb( int ok, X509_STORE_CTX *ctx )
 	if ( !ok ) {
 		LDAP_LOG ( TRANSPORT, ERR, 
 			"TLS certificate verification: Error, %s\n",
-			X509_verify_cert_error_string(errnum), 0, 0 );
+			certerr, 0, 0 );
 	}
 #else
 	Debug( LDAP_DEBUG_TRACE,
@@ -1444,14 +1502,16 @@ tls_verify_cb( int ok, X509_STORE_CTX *ctx )
 	if ( !ok ) {
 		Debug( LDAP_DEBUG_ANY,
 			"TLS certificate verification: Error, %s\n",
-			X509_verify_cert_error_string(errnum), 0, 0 );
+			certerr, 0, 0 );
 	}
 #endif
 	if ( sname )
 		CRYPTO_free ( sname );
 	if ( iname )
 		CRYPTO_free ( iname );
-
+#ifdef HAVE_EBCDIC
+	if ( certerr ) LDAP_FREE( certerr );
+#endif
 	return ok;
 }
 
@@ -1472,13 +1532,24 @@ tls_report_error( void )
 	int line;
 
 	while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
+		ERR_error_string_n( l, buf, sizeof( buf ) );
+#ifdef HAVE_EBCDIC
+		if ( file ) {
+			file = LDAP_STRDUP( file );
+			__etoa( (char *)file );
+		}
+		__etoa( buf );
+#endif
 #ifdef NEW_LOGGING
 		LDAP_LOG ( TRANSPORT, ERR, 
 			"tls_report_error: TLS %s %s:%d\n", 
-			ERR_error_string( l, buf ), file, line );
+			buf, file, line );
 #else
 		Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
-		   ERR_error_string( l, buf ), file, line );
+			buf, file, line );
+#endif
+#ifdef HAVE_EBCDIC
+		if ( file ) LDAP_FREE( (void *)file );
 #endif
 	}
 }