ldap/servers/slapd/ldaputil.c | 101 +++++++++++++++++++++++++++---------------
1 file changed, 65 insertions(+), 36 deletions(-)
New commits:
commit e7d9bdd341b360048e62c0d01894da0281503488
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Tue Feb 21 20:21:36 2012 -0700
Ticket #281 - TLS not working with latest openldap
https://fedorahosted.org/389/ticket/281
Resolves: Ticket #281
Bug Description: TLS not working with latest openldap
Reviewed by: nkinder (Thanks!)
Branch: master
Fix Description: The previous fix did not take into account ssl client
auth. The way openldap ssl init works now is that you must set all of the
ssl parameters before creating the new ctx. Since slapi_ldap_init_ext()
does not know if client auth will be used, we have to do all of the ssl
init in slapi_ldap_bind. Doing setup_ol_tls_conn() again will free the
old TLS context and parameters. It is a little more time consuming in
the clientauth case, but is safer and saves time in the other cases.
Platforms tested: RHEL6 x86_64, Fedora 16
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
index 10d7907..545c703 100644
--- a/ldap/servers/slapd/ldaputil.c
+++ b/ldap/servers/slapd/ldaputil.c
@@ -557,6 +557,59 @@ slapi_ldif_parse_line(
return rc;
}
+#if defined(USE_OPENLDAP)
+static int
+setup_ol_tls_conn(LDAP *ld, int clientauth)
+{
+ char *certdir = config_get_certdir();
+ int optval = 0;
+ int ssl_strength = 0;
+ int rc = 0;
+
+ if (config_get_ssl_check_hostname()) {
+ ssl_strength = LDAP_OPT_X_TLS_HARD;
+ } else {
+ /* verify certificate only */
+ ssl_strength = LDAP_OPT_X_TLS_NEVER;
+ }
+
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &ssl_strength))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn",
+ "failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength);
+ }
+ /* tell it where our cert db is */
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTDIR, certdir))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn",
+ "failed: unable to set CACERTDIR option to %s\n", certdir);
+ }
+ slapi_ch_free_string(&certdir);
+#if defined(LDAP_OPT_X_TLS_PROTOCOL_MIN)
+ optval = LDAP_OPT_X_TLS_PROTOCOL_SSL3;
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &optval))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn",
+ "failed: unable to set minimum TLS protocol level to SSL3\n");
+ }
+#endif /* LDAP_OPT_X_TLS_PROTOCOL_MIN */
+ if (clientauth) {
+ rc = slapd_SSL_client_auth(ld);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn",
+ "failed: unable to setup connection for TLS/SSL EXTERNAL client cert
authentication - %d\n", rc);
+ }
+ }
+
+ /* have to do this last - this creates the new TLS handle and sets/copies
+ all of the parameters set above into that TLS handle context - note
+ that optval is ignored - what matters is that it is not NULL */
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &optval))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn",
+ "failed: unable to create new TLS context\n");
+ }
+
+ return rc;
+}
+#endif /* defined(USE_OPENLDAP) */
+
/*
Perform LDAP init and return an LDAP* handle. If ldapurl is given,
that is used as the basis for the protocol, host, port, and whether
@@ -784,9 +837,11 @@ slapi_ldap_init_ext(
*/
if (secure > 0) {
#if defined(USE_OPENLDAP)
- char *certdir = config_get_certdir();
- int optval = 0;
-#endif /* !USE_OPENLDAP */
+ if (setup_ol_tls_conn(ld, 0)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set SSL/TLS options\n");
+ }
+#else
int ssl_strength = 0;
LDAP *myld = NULL;
@@ -799,43 +854,12 @@ slapi_ldap_init_ext(
if (config_get_ssl_check_hostname()) {
/* check hostname against name in certificate */
-#if defined(USE_OPENLDAP)
- ssl_strength = LDAP_OPT_X_TLS_HARD;
-#else /* !USE_OPENLDAP */
ssl_strength = LDAPSSL_AUTH_CNCHECK;
-#endif /* !USE_OPENLDAP */
} else {
/* verify certificate only */
-#if defined(USE_OPENLDAP)
- ssl_strength = LDAP_OPT_X_TLS_NEVER;
-#else /* !USE_OPENLDAP */
ssl_strength = LDAPSSL_AUTH_CERT;
-#endif /* !USE_OPENLDAP */
}
-#if defined(USE_OPENLDAP)
- if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &ssl_strength))) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength);
- }
- /* tell it where our cert db is */
- if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTDIR, certdir))) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "failed: unable to set CACERTDIR option to %s\n", certdir);
- }
- slapi_ch_free_string(&certdir);
-#if defined(LDAP_OPT_X_TLS_PROTOCOL_MIN)
- optval = LDAP_OPT_X_TLS_PROTOCOL_SSL3;
- if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &optval))) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "failed: unable to set minimum TLS protocol level to SSL3\n");
- }
-#endif /* LDAP_OPT_X_TLS_PROTOCOL_MIN */
- if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &optval))) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "failed: unable to create new TLS context\n");
- }
-#else /* !USE_OPENLDAP */
if ((rc = ldapssl_set_strength(myld, ssl_strength)) ||
(rc = ldapssl_set_option(myld, SSL_ENABLE_SSL2, PR_FALSE)) ||
(rc = ldapssl_set_option(myld, SSL_ENABLE_SSL3, PR_TRUE)) ||
@@ -960,10 +984,15 @@ slapi_ldap_bind(
ldap_set_option(ld, LDAP_OPT_CLIENT_CONTROLS, NULL);
if ((secure > 0) && mech && !strcmp(mech, LDAP_SASL_EXTERNAL)) {
+#if defined(USE_OPENLDAP)
+ /* we already set up a tls context in slapi_ldap_init_ext() - this will
+ free those old settings and context and create a new one */
+ rc = setup_ol_tls_conn(ld, 1);
+#else
/* SSL connections will use the server's security context
and cert for client auth */
rc = slapd_SSL_client_auth(ld);
-
+#endif
if (rc != 0) {
slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
"Error: could not configure the server for cert "
@@ -973,7 +1002,7 @@ slapi_ldap_bind(
} else {
slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
"Set up conn to use client auth\n");
- }
+ }
bvcreds.bv_val = NULL; /* ignore username and passed in creds */
bvcreds.bv_len = 0; /* for external auth */
bindid = NULL;