diff --git a/openldap-cacertdir-hash-only.patch b/openldap-cacertdir-hash-only.patch new file mode 100644 index 0000000..70060a9 --- /dev/null +++ b/openldap-cacertdir-hash-only.patch @@ -0,0 +1,60 @@ +Openldap should ignore files not in the openssl c_rehash format (hash.0) in TLS_CACERTDIR + +Resolves: #650288 +Upstream ITS: #6705 +Author: Rich Megginson (rmeggins@redhat.com) + +--- openldap.old/libraries/libldap/tls_m.c.2 2010-11-11 15:21:05.000000000 -0700 ++++ openldap.new/libraries/libldap/tls_m.c 2010-11-11 15:29:08.000000000 -0700 +@@ -100,16 +100,19 @@ + typedef PRFileDesc tlsm_session; + + static PRDescIdentity tlsm_layer_id; + + static const PRIOMethods tlsm_PR_methods; + + #define PEM_LIBRARY "nsspem" + #define PEM_MODULE "PEM" ++/* hash files for use with cacertdir have this file name suffix */ ++#define PEM_CA_HASH_FILE_SUFFIX ".0" ++#define PEM_CA_HASH_FILE_SUFFIX_LEN 2 + + static SECMODModule *pem_module; + + #define DEFAULT_TOKEN_NAME "default" + /* sprintf format used to create token name */ + #define TLSM_PEM_TOKEN_FMT "PEM Token #%ld" + + static int tlsm_slot_count; +@@ -1230,18 +1233,29 @@ + "TLS: could not open the CA certificate directory %s - error %d:%s.\n", + cacertdir, errcode, + PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); + goto done; + } + + do { + entry = PR_ReadDir( dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN ); +- if ( NULL != entry ) { +- char *fullpath = PR_smprintf( "%s/%s", cacertdir, entry->name ); ++ if ( ( NULL != entry ) && ( NULL != entry->name ) ) { ++ char *fullpath = NULL; ++ char *ptr; ++ ++ ptr = PL_strrstr( entry->name, PEM_CA_HASH_FILE_SUFFIX ); ++ if ( ( ptr == NULL ) || ( *(ptr + PEM_CA_HASH_FILE_SUFFIX_LEN) != '\0' ) ) { ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS: file %s does not end in [%s] - does not appear to be a CA certificate " ++ "directory file with a properly hashed file name - skipping.\n", ++ entry->name, PEM_CA_HASH_FILE_SUFFIX, 0 ); ++ continue; ++ } ++ fullpath = PR_smprintf( "%s/%s", cacertdir, entry->name ); + if ( !tlsm_add_cert_from_file( ctx, fullpath, isca ) ) { + Debug( LDAP_DEBUG_TRACE, + "TLS: loaded CA certificate file %s from CA certificate directory %s.\n", + fullpath, cacertdir, 0 ); + status = PR_SUCCESS; /* found at least 1 valid CA file in the dir */ + } else { + errcode = PR_GetError(); + Debug( LDAP_DEBUG_TRACE, diff --git a/openldap-improve-trace-messages.patch b/openldap-improve-trace-messages.patch new file mode 100644 index 0000000..314bb36 --- /dev/null +++ b/openldap-improve-trace-messages.patch @@ -0,0 +1,176 @@ +Improve misleading SSL/TLS trace messages. + +Resolves: #652818 +Upstream ITS: #6706 +Author: Rich Megginson (rmeggins@redhat.com) + +--- openldap.old/libraries/libldap/tls_m.c.3 2010-11-11 18:39:48.000000000 -0700 ++++ openldap.new/libraries/libldap/tls_m.c 2010-11-11 20:17:35.000000000 -0700 +@@ -709,16 +709,22 @@ + Debug( LDAP_DEBUG_TRACE, + "cache hits: %ld, cache misses: %ld, cache not reusable: %ld\n", + ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses, + ssl3stats->hch_sid_cache_not_ok ); + + return ""; + } + ++static void ++tlsm_handshake_complete_cb( PRFileDesc *fd, void *client_data ) ++{ ++ tlsm_dump_security_status( fd ); ++} ++ + #ifdef READ_PASSWORD_FROM_FILE + static char * + tlsm_get_pin_from_file(const char *token_name, tlsm_ctx *ctx) + { + char *pwdstr = NULL; + char *contents = NULL; + char *lasts = NULL; + char *line = NULL; +@@ -894,26 +900,32 @@ + } + + static SECStatus + tlsm_auth_cert_handler(void *arg, PRFileDesc *fd, + PRBool checksig, PRBool isServer) + { + SECStatus ret = SSL_AuthCertificate(arg, fd, checksig, isServer); + +- tlsm_dump_security_status( fd ); +- Debug( LDAP_DEBUG_TRACE, +- "TLS certificate verification: %s\n", +- ret == SECSuccess ? "ok" : "bad", 0, 0 ); +- + if ( ret != SECSuccess ) { + PRErrorCode errcode = PORT_GetError(); +- Debug( LDAP_DEBUG_ANY, +- "TLS certificate verification: Error, %d: %s\n", +- errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ) ; ++ /* we bypass NSS's hostname checks and do our own - tlsm_session_chkhost will handle it */ ++ if ( errcode == SSL_ERROR_BAD_CERT_DOMAIN ) { ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS certificate verification: defer\n", ++ 0, 0, 0 ); ++ } else { ++ Debug( LDAP_DEBUG_ANY, ++ "TLS certificate verification: Error, %d: %s\n", ++ errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ) ; ++ } ++ } else { ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS certificate verification: ok\n", ++ 0, 0, 0 ); + } + + return ret; + } + + static int + tlsm_authenticate_to_slot( tlsm_ctx *ctx, PK11SlotInfo *slot ) + { +@@ -1181,16 +1193,21 @@ + + static int + tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir ) + { + PRBool isca = PR_TRUE; + PRStatus status = PR_FAILURE; + PRErrorCode errcode = PR_SUCCESS; + ++ if ( !cacertfile && !cacertdir ) { ++ /* no checking - not good, but allowed */ ++ return 0; ++ } ++ + if ( cacertfile ) { + int rc = tlsm_add_cert_from_file( ctx, cacertfile, isca ); + if ( rc ) { + errcode = PR_GetError(); + Debug( LDAP_DEBUG_ANY, + "TLS: %s is not a valid CA certificate file - error %d:%s.\n", + cacertfile, errcode, + PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); +@@ -1394,19 +1411,21 @@ + rc = (initctx == NULL) ? SECFailure : SECSuccess; + #endif + #else + rc = NSS_Initialize( realcertdir, prefix, prefix, SECMOD_DB, NSS_INIT_READONLY ); + #endif + + if ( rc != SECSuccess ) { + errcode = PORT_GetError(); +- Debug( LDAP_DEBUG_TRACE, +- "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", +- realcertdir, prefix, errcode ); ++ if ( securitydirs[ii] != lt->lt_cacertdir) { ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", ++ realcertdir, prefix, errcode ); ++ } + } else { + /* success */ + Debug( LDAP_DEBUG_TRACE, "TLS: using moznss security dir %s prefix %s.\n", + realcertdir, prefix, 0 ); + errcode = 0; + done = 1; + } + if ( realcertdir != securitydir ) { +@@ -1453,16 +1472,31 @@ + errcode = PORT_GetError(); + Debug( LDAP_DEBUG_ANY, + "TLS: could not initialize moznss PEM module - error %d:%s.\n", + errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ); + return -1; + } + + if ( tlsm_init_ca_certs( ctx, lt->lt_cacertfile, lt->lt_cacertdir ) ) { ++ /* if we tried to use lt->lt_cacertdir as an NSS key/cert db, errcode ++ will be a value other than 1 - print an error message so that the ++ user will know that failed too */ ++ if ( ( errcode != 1 ) && ( lt->lt_cacertdir ) ) { ++ char *realcertdir = NULL; ++ char *prefix = NULL; ++ tlsm_get_certdb_prefix( lt->lt_cacertdir, &realcertdir, &prefix ); ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", ++ realcertdir, prefix ? prefix : "", errcode ); ++ if ( realcertdir != lt->lt_cacertdir ) { ++ PL_strfree( realcertdir ); ++ } ++ PL_strfree( prefix ); ++ } + return -1; + } + + ctx->tc_using_pem = PR_TRUE; + } + + #ifdef HAVE_NSS_INITCONTEXT + if ( !ctx->tc_initctx ) { +@@ -2040,16 +2074,24 @@ + ctx->tc_certdb ) != SECSuccess ) { + PRErrorCode err = PR_GetError(); + Debug( LDAP_DEBUG_ANY, + "TLS: error: could not set auth cert handler for moznss - error %d:%s\n", + err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL ); + return -1; + } + ++ if ( SSL_HandshakeCallback( ctx->tc_model, tlsm_handshake_complete_cb, ctx ) ) { ++ PRErrorCode err = PR_GetError(); ++ Debug( LDAP_DEBUG_ANY, ++ "TLS: error: could not set handshake callback for moznss - error %d:%s\n", ++ err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL ); ++ return -1; ++ } ++ + return 0; + } + + struct tls_data { + tlsm_session *session; + Sockbuf_IO_Desc *sbiod; + /* there seems to be no portable way to determine if the + sockbuf sd has been set to nonblocking mode - the diff --git a/openldap-nss-db-prefix.patch b/openldap-nss-db-prefix.patch new file mode 100644 index 0000000..cb0b846 --- /dev/null +++ b/openldap-nss-db-prefix.patch @@ -0,0 +1,286 @@ +Enhancement, support multiple cert/key databases in tha same directory with another prefix. + +Upstream ITS: #6689 + +--- openldap.old/libraries/libldap/tls_m.c 21 Jul 2010 20:57:01 -0000 1.18 ++++ openldap.new/libraries/libldap/tls_m.c 28 Oct 2010 19:55:51 -0000 +@@ -1202,16 +1202,55 @@ + return -1; + } + } + + return 0; + } + + /* ++ * NSS supports having multiple cert/key databases in the same ++ * directory, each one having a unique string prefix e.g. ++ * slapd-01-cert8.db - the prefix here is "slapd-01-" ++ * this function examines the given certdir - if it looks like ++ * /path/to/directory/prefix it will return the ++ * /path/to/directory part in realcertdir, and the prefix in prefix ++ */ ++static void ++tlsm_get_certdb_prefix( const char *certdir, char **realcertdir, char **prefix ) ++{ ++ char sep = PR_GetDirectorySeparator(); ++ char *ptr = NULL; ++ struct PRFileInfo prfi; ++ PRStatus prc; ++ ++ *realcertdir = (char *)certdir; /* default is the one passed in */ ++ ++ /* if certdir is not given, just return */ ++ if ( !certdir ) { ++ return; ++ } ++ ++ prc = PR_GetFileInfo( certdir, &prfi ); ++ /* if certdir exists (file or directory) then it cannot specify a prefix */ ++ if ( prc == PR_SUCCESS ) { ++ return; ++ } ++ ++ /* if certdir was given, and there is a '/' in certdir, see if there ++ is anything after the last '/' - if so, assume it is the prefix */ ++ if ( ( ( ptr = strrchr( certdir, sep ) ) ) && *(ptr+1) ) { ++ *realcertdir = PL_strndup( certdir, ptr-certdir ); ++ *prefix = PL_strdup( ptr+1 ); ++ } ++ ++ return; ++} ++ ++/* + * This is the part of the init we defer until we get the + * actual security configuration information. This is + * only called once, protected by a PRCallOnce + * NOTE: This must be done before the first call to SSL_ImportFD, + * especially the setting of the policy + * NOTE: This must be called after fork() + */ + static int +@@ -1223,16 +1262,17 @@ + int ii; + int nn; + PRErrorCode errcode = 1; + #ifdef HAVE_NSS_INITCONTEXT + NSSInitParameters initParams; + NSSInitContext *initctx = NULL; + #endif + SECStatus rc; ++ int done = 0; + + #ifdef HAVE_NSS_INITCONTEXT + memset( &initParams, 0, sizeof( initParams ) ); + initParams.length = sizeof( initParams ); + #endif /* HAVE_NSS_INITCONTEXT */ + + #ifndef HAVE_NSS_INITCONTEXT + if ( !NSS_IsInitialized() ) { +@@ -1246,50 +1286,61 @@ + DEFAULT_MOZNSS_DIR will only be used if the code cannot + find a security dir to use based on the current + settings + */ + nn = 0; + securitydirs[nn++] = PR_GetEnv( "MOZNSS_DIR" ); + securitydirs[nn++] = lt->lt_cacertdir; + securitydirs[nn++] = PR_GetEnv( "DEFAULT_MOZNSS_DIR" ); +- for ( ii = 0; ii < nn; ++ii ) { ++ for ( ii = 0; !done && ( ii < nn ); ++ii ) { ++ char *realcertdir = NULL; ++ const char *defprefix = ""; ++ char *prefix = (char *)defprefix; + const char *securitydir = securitydirs[ii]; + if ( NULL == securitydir ) { + continue; + } ++ ++ tlsm_get_certdb_prefix( securitydir, &realcertdir, &prefix ); + #ifdef HAVE_NSS_INITCONTEXT + #ifdef INITCONTEXT_HACK + if ( !NSS_IsInitialized() && ctx->tc_is_server ) { +- rc = NSS_Initialize( securitydir, "", "", SECMOD_DB, NSS_INIT_READONLY ); ++ rc = NSS_Initialize( realcertdir, prefix, prefix, SECMOD_DB, NSS_INIT_READONLY ); + } else { +- initctx = NSS_InitContext( securitydir, "", "", SECMOD_DB, ++ initctx = NSS_InitContext( realcertdir, prefix, prefix, SECMOD_DB, + &initParams, NSS_INIT_READONLY ); + rc = (initctx == NULL) ? SECFailure : SECSuccess; + } + #else +- initctx = NSS_InitContext( securitydir, "", "", SECMOD_DB, ++ initctx = NSS_InitContext( realcertdir, prefix, prefix, SECMOD_DB, + &initParams, NSS_INIT_READONLY ); + rc = (initctx == NULL) ? SECFailure : SECSuccess; + #endif + #else +- rc = NSS_Initialize( securitydir, "", "", SECMOD_DB, NSS_INIT_READONLY ); ++ rc = NSS_Initialize( realcertdir, prefix, prefix, SECMOD_DB, NSS_INIT_READONLY ); + #endif + + if ( rc != SECSuccess ) { + errcode = PORT_GetError(); + Debug( LDAP_DEBUG_TRACE, +- "TLS: could not initialize moznss using security dir %s - error %d:%s.\n", +- securitydir, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); ++ "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", ++ realcertdir, prefix, errcode ); + } else { + /* success */ +- Debug( LDAP_DEBUG_TRACE, "TLS: using moznss security dir %s.\n", +- securitydir, 0, 0 ); ++ Debug( LDAP_DEBUG_TRACE, "TLS: using moznss security dir %s prefix %s.\n", ++ realcertdir, prefix, 0 ); + errcode = 0; +- break; ++ done = 1; ++ } ++ if ( realcertdir != securitydir ) { ++ PL_strfree( realcertdir ); ++ } ++ if ( prefix != defprefix ) { ++ PL_strfree( prefix ); + } + } + + if ( errcode ) { /* no moznss db found, or not using moznss db */ + #ifdef HAVE_NSS_INITCONTEXT + int flags = NSS_INIT_READONLY|NSS_INIT_NOCERTDB|NSS_INIT_NOMODDB; + #ifdef INITCONTEXT_HACK + if ( !NSS_IsInitialized() && ctx->tc_is_server ) { +@@ -2038,19 +2089,16 @@ + + errno = 0; + rc = SSL_ForceHandshake( s ); + if (rc == SECSuccess) { + rc = 0; + break; /* done */ + } + err = PR_GetError(); +- Debug( LDAP_DEBUG_TRACE, +- "TLS: error: accept - force handshake failure %d - error %d waitcounter %d\n", +- errno, err, waitcounter ); + if ( errno == EAGAIN || errno == EWOULDBLOCK ) { + waitcounter++; + in_flags = PR_POLL_READ | PR_POLL_EXCEPT; + out_flags = 0; + errno = 0; + filesReady = tlsm_is_io_ready( s, in_flags, &out_flags ); + if ( filesReady < 0 ) { + err = PR_GetError(); +@@ -2155,49 +2203,49 @@ + tlsm_session_my_dn( tls_session *session, struct berval *der_dn ) + { + tlsm_session *s = (tlsm_session *)session; + CERTCertificate *cert; + + cert = SSL_LocalCertificate( s ); + if (!cert) return LDAP_INVALID_CREDENTIALS; + +- der_dn->bv_val = cert->derSubject.data; ++ der_dn->bv_val = (char *)cert->derSubject.data; + der_dn->bv_len = cert->derSubject.len; + CERT_DestroyCertificate( cert ); + return 0; + } + + static int + tlsm_session_peer_dn( tls_session *session, struct berval *der_dn ) + { + tlsm_session *s = (tlsm_session *)session; + CERTCertificate *cert; + + cert = SSL_PeerCertificate( s ); + if (!cert) return LDAP_INVALID_CREDENTIALS; + +- der_dn->bv_val = cert->derSubject.data; ++ der_dn->bv_val = (char *)cert->derSubject.data; + der_dn->bv_len = cert->derSubject.len; + CERT_DestroyCertificate( cert ); + return 0; + } + + /* what kind of hostname were we given? */ + #define IS_DNS 0 + #define IS_IP4 1 + #define IS_IP6 2 + + static int + tlsm_session_chkhost( LDAP *ld, tls_session *session, const char *name_in ) + { + tlsm_session *s = (tlsm_session *)session; + CERTCertificate *cert; + const char *name, *domain = NULL, *ptr; +- int i, ret, ntype = IS_DNS, nlen, dlen; ++ int ret, ntype = IS_DNS, nlen, dlen; + #ifdef LDAP_PF_INET6 + struct in6_addr addr; + #else + struct in_addr addr; + #endif + SECItem altname; + SECStatus rv; + +@@ -2259,17 +2307,17 @@ + + do { + char *host; + int hlen; + + /* ignore empty */ + if ( !cur->name.other.len ) continue; + +- host = cur->name.other.data; ++ host = (char *)cur->name.other.data; + hlen = cur->name.other.len; + + if ( cur->type == certDNSName ) { + if ( ntype != IS_DNS ) continue; + + /* is this an exact match? */ + if ( nlen == hlen && !strncasecmp( name, host, nlen )) { + ret = LDAP_SUCCESS; +@@ -2317,21 +2365,21 @@ + while ( avas && ( ava = *avas++ )) { + if ( CERT_GetAVATag( ava ) == SEC_OID_AVA_COMMON_NAME ) + lastava = ava; + } + } + if ( lastava ) { + SECItem *av = CERT_DecodeAVAValue( &lastava->value ); + if ( av ) { +- if ( av->len == nlen && !strncasecmp( name, av->data, nlen )) { ++ if ( av->len == nlen && !strncasecmp( name, (char *)av->data, nlen )) { + ret = LDAP_SUCCESS; + } else if ( av->data[0] == '*' && av->data[1] == '.' && + domain && dlen == av->len - 1 && !strncasecmp( name, +- av->data+1, dlen )) { ++ (char *)(av->data+1), dlen )) { + ret = LDAP_SUCCESS; + } else { + int len = av->len; + if ( len >= sizeof(buf) ) + len = sizeof(buf)-1; + memcpy( buf, av->data, len ); + buf[len] = '\0'; + } +@@ -2479,17 +2527,16 @@ + { + return tlsm_PR_Send( fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT ); + } + + static PRStatus PR_CALLBACK + tlsm_PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) + { + struct tls_data *p; +- int rc; + ber_socklen_t len; + + p = (struct tls_data *)fd->secret; + + if ( p == NULL || p->sbiod == NULL ) { + return PR_FAILURE; + } + len = sizeof(PRNetAddr); diff --git a/openldap-reject-non-file-keyfiles.patch b/openldap-reject-non-file-keyfiles.patch new file mode 100644 index 0000000..5d2ff92 --- /dev/null +++ b/openldap-reject-non-file-keyfiles.patch @@ -0,0 +1,84 @@ +This workarounds Mozilla NSS bug. libldap crashes when TLS_CACERTDIR contains a subdirectory. +Skip all non-file entries in CA_CERTDIR. + +Resolves: #652315 +Upstream ITS: #6703 +Author: Rich Megginson (rmeggins@redhat.com) + +diff -u -8 -r1.19 tls_m.c +--- openldap.old/libraries/libldap/tls_m.c 29 Oct 2010 08:30:30 -0000 1.19 ++++ openldap.new/libraries/libldap/tls_m.c 11 Nov 2010 20:18:20 -0000 +@@ -1011,16 +1011,36 @@ + CK_ATTRIBUTE theTemplate[20]; + CK_BBOOL cktrue = CK_TRUE; + CK_BBOOL ckfalse = CK_FALSE; + CK_OBJECT_CLASS objClass = CKO_CERTIFICATE; + char tmpslotname[64]; + char *slotname = NULL; + const char *ptr = NULL; + char sep = PR_GetDirectorySeparator(); ++ PRFileInfo fi; ++ PRStatus status; ++ ++ memset( &fi, 0, sizeof(fi) ); ++ status = PR_GetFileInfo( filename, &fi ); ++ if ( PR_SUCCESS != status) { ++ PRErrorCode errcode = PR_GetError(); ++ Debug( LDAP_DEBUG_ANY, ++ "TLS: could not read certificate file %s - error %d:%s.\n", ++ filename, errcode, ++ PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); ++ return -1; ++ } ++ ++ if ( fi.type != PR_FILE_FILE ) { ++ Debug( LDAP_DEBUG_ANY, ++ "TLS: error: the certificate file %s is not a file.\n", ++ filename, 0 ,0 ); ++ return -1; ++ } + + attrs = theTemplate; + + if ( isca ) { + slotID = 0; /* CA and trust objects use slot 0 */ + PR_snprintf( tmpslotname, sizeof(tmpslotname), TLSM_PEM_TOKEN_FMT, slotID ); + slotname = tmpslotname; + } else { +@@ -1083,16 +1103,36 @@ + CK_SLOT_ID slotID; + PK11SlotInfo * slot = NULL; + PK11GenericObject *rv; + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE theTemplate[20]; + CK_BBOOL cktrue = CK_TRUE; + CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY; + int retcode = 0; ++ PRFileInfo fi; ++ PRStatus status; ++ ++ memset( &fi, 0, sizeof(fi) ); ++ status = PR_GetFileInfo( filename, &fi ); ++ if ( PR_SUCCESS != status) { ++ PRErrorCode errcode = PR_GetError(); ++ Debug( LDAP_DEBUG_ANY, ++ "TLS: could not read key file %s - error %d:%s.\n", ++ filename, errcode, ++ PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); ++ return -1; ++ } ++ ++ if ( fi.type != PR_FILE_FILE ) { ++ Debug( LDAP_DEBUG_ANY, ++ "TLS: error: the key file %s is not a file.\n", ++ filename, 0 ,0 ); ++ return -1; ++ } + + attrs = theTemplate; + + if ( ctx->tc_slotname == NULL ) { /* need new slot */ + slotID = ++tlsm_slot_count; + ctx->tc_slotname = PR_smprintf( TLSM_PEM_TOKEN_FMT, slotID ); + } + slot = PK11_FindSlotByName( ctx->tc_slotname ); diff --git a/openldap-use-cacert-dir-and-file.patch b/openldap-use-cacert-dir-and-file.patch new file mode 100644 index 0000000..0d1cf56 --- /dev/null +++ b/openldap-use-cacert-dir-and-file.patch @@ -0,0 +1,136 @@ +TLS_CACERTDIR takes precedence over TLS_CACERTFILE + +Resolves: #652304 +Upstream ITS: #6704 +Author: Rich Megginson (rmeggins@redhat.com) + +diff -uNPrp openldap-2.4.23.old/libraries/libldap/tls_m.c openldap-2.4.23.new/libraries/libldap/tls_m.c +--- openldap-2.4.23.old/libraries/libldap/tls_m.c 2010-11-18 11:01:36.129392116 +0100 ++++ openldap-2.4.23.new/libraries/libldap/tls_m.c 2010-11-18 11:02:19.466387205 +0100 +@@ -1031,6 +1031,7 @@ tlsm_add_cert_from_file( tlsm_ctx *ctx, + } + + if ( fi.type != PR_FILE_FILE ) { ++ PR_SetError(PR_IS_DIRECTORY_ERROR, 0); + Debug( LDAP_DEBUG_ANY, + "TLS: error: the certificate file %s is not a file.\n", + filename, 0 ,0 ); +@@ -1123,6 +1124,7 @@ tlsm_add_key_from_file( tlsm_ctx *ctx, c + } + + if ( fi.type != PR_FILE_FILE ) { ++ PR_SetError(PR_IS_DIRECTORY_ERROR, 0); + Debug( LDAP_DEBUG_ANY, + "TLS: error: the key file %s is not a file.\n", + filename, 0 ,0 ); +@@ -1178,69 +1180,91 @@ static int + tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir ) + { + PRBool isca = PR_TRUE; ++ PRStatus status = PR_FAILURE; ++ PRErrorCode errcode = PR_SUCCESS; + + if ( cacertfile ) { + int rc = tlsm_add_cert_from_file( ctx, cacertfile, isca ); + if ( rc ) { +- return rc; ++ errcode = PR_GetError(); ++ Debug( LDAP_DEBUG_ANY, ++ "TLS: %s is not a valid CA certificate file - error %d:%s.\n", ++ cacertfile, errcode, ++ PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); ++ } else { ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS: loaded CA certificate file %s.\n", ++ cacertfile, 0, 0 ); ++ status = PR_SUCCESS; /* have at least one good CA - we can proceed */ + } + } + + if ( cacertdir ) { + PRFileInfo fi; +- PRStatus status; + PRDir *dir; + PRDirEntry *entry; ++ PRStatus fistatus = PR_FAILURE; + + memset( &fi, 0, sizeof(fi) ); +- status = PR_GetFileInfo( cacertdir, &fi ); +- if ( PR_SUCCESS != status) { +- PRErrorCode errcode = PR_GetError(); ++ fistatus = PR_GetFileInfo( cacertdir, &fi ); ++ if ( PR_SUCCESS != fistatus) { ++ errcode = PR_GetError(); + Debug( LDAP_DEBUG_ANY, + "TLS: could not get info about the CA certificate directory %s - error %d:%s.\n", + cacertdir, errcode, + PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); +- return -1; ++ goto done; + } + + if ( fi.type != PR_FILE_DIRECTORY ) { + Debug( LDAP_DEBUG_ANY, + "TLS: error: the CA certificate directory %s is not a directory.\n", + cacertdir, 0 ,0 ); +- return -1; ++ goto done; + } + + dir = PR_OpenDir( cacertdir ); + if ( NULL == dir ) { +- PRErrorCode errcode = PR_GetError(); ++ errcode = PR_GetError(); + Debug( LDAP_DEBUG_ANY, + "TLS: could not open the CA certificate directory %s - error %d:%s.\n", + cacertdir, errcode, + PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); +- return -1; ++ goto done; + } + +- status = -1; + do { + entry = PR_ReadDir( dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN ); + if ( NULL != entry ) { + char *fullpath = PR_smprintf( "%s/%s", cacertdir, entry->name ); + if ( !tlsm_add_cert_from_file( ctx, fullpath, isca ) ) { +- status = 0; /* found at least 1 valid CA file in the dir */ ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS: loaded CA certificate file %s from CA certificate directory %s.\n", ++ fullpath, cacertdir, 0 ); ++ status = PR_SUCCESS; /* found at least 1 valid CA file in the dir */ ++ } else { ++ errcode = PR_GetError(); ++ Debug( LDAP_DEBUG_TRACE, ++ "TLS: %s is not a valid CA certificate file - error %d:%s.\n", ++ fullpath, errcode, ++ PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); + } + PR_smprintf_free( fullpath ); + } + } while ( NULL != entry ); + PR_CloseDir( dir ); +- +- if ( status ) { +- PRErrorCode errcode = PR_GetError(); +- Debug( LDAP_DEBUG_ANY, +- "TLS: did not find any valid CA certificate files in the CA certificate directory %s - error %d:%s.\n", +- cacertdir, errcode, +- PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); +- return -1; ++ } ++done: ++ if ( status != PR_SUCCESS ) { ++ const char *fmtstr = NULL; ++ if ( cacertfile && cacertdir ) { ++ fmtstr = "TLS: did not find any valid CA certificates in %s or %s\n"; ++ } else { ++ fmtstr = "TLS: did not find any valid CA certificates in %s%s\n"; + } ++ Debug( LDAP_DEBUG_ANY, fmtstr, cacertdir ? cacertdir : "", ++ cacertfile ? cacertfile : "", 0 ); ++ return -1; + } + + return 0; diff --git a/openldap.spec b/openldap.spec index 4f17f6f..c0ec47b 100644 --- a/openldap.spec +++ b/openldap.spec @@ -7,7 +7,7 @@ Name: openldap Version: 2.4.23 -Release: 2%{?dist} +Release: 3%{?dist} Summary: LDAP support libraries Group: System Environment/Daemons License: OpenLDAP @@ -31,6 +31,11 @@ Patch8: openldap-userconfig-setgid.patch # already merged upstream Patch100: openldap-nss-ca-selfsigned.patch Patch101: openldap-nss-delay-token-auth.patch +Patch102: openldap-nss-db-prefix.patch +Patch103: openldap-reject-non-file-keyfiles.patch +Patch104: openldap-use-cacert-dir-and-file.patch +Patch105: openldap-cacertdir-hash-only.patch +Patch106: openldap-improve-trace-messages.patch # patches for the evolution library (see README.evolution) Patch200: openldap-evolution-ntlm.patch @@ -134,6 +139,11 @@ pushd openldap-%{version} %patch100 -p1 -b .nss-ca-selfsigned %patch101 -p1 -b .nss-delay-token-auth +%patch102 -p1 -b .nss-db-prefix +%patch103 -p1 -b .reject-non-file-keyfiles +%patch104 -p1 -b .use-cacert-dir-and-file-dir +%patch105 -p1 -b .cacertdir-hash-only +%patch106 -p1 -b .improve-trace-messages cp %{_datadir}/libtool/config/config.{sub,guess} build/ @@ -641,6 +651,13 @@ exit 0 %attr(0644,root,root) %{evolution_connector_libdir}/*.a %changelog +* Thu Nov 18 2010 Jan Vcelak 2.4.23-3 +- add support for multiple prefixed Mozilla NSS database files in TLS_CACERTDIR +- reject non-file keyfiles in TLS_CACERTDIR (#652315) +- TLS_CACERTDIR precedence over TLS_CACERT (#652304) +- accept only files in hash.0 format in TLS_CACERTDIR (#650288) +- improve SSL/TLS trace messages (#652818) + * Mon Nov 01 2010 Jan Vcelak 2.4.23-2 - fix possible infinite loop when checking permissions of TLS files (#641946) - removed outdated autofs.schema (#643045)