]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#6248 support multiple CAcert dirs
authorHoward Chu <hyc@openldap.org>
Thu, 22 Jul 2021 20:07:21 +0000 (21:07 +0100)
committerHoward Chu <hyc@openldap.org>
Thu, 22 Jul 2021 20:07:21 +0000 (21:07 +0100)
doc/man/man3/ldap_get_option.3
doc/man/man5/ldap.conf.5
doc/man/man5/slapd-config.5
doc/man/man5/slapd.conf.5
libraries/libldap/ldap-tls.h
libraries/libldap/tls_g.c
libraries/libldap/tls_o.c

index 25027ac7f290f72187e9b0c92ec4d1b64916e63b..fc5311e54367a0900d6ddbdaefc80326dd20dbb5 100644 (file)
@@ -642,7 +642,8 @@ The TLS options are OpenLDAP specific.
 .\"Sets/gets the TLS mode.
 .TP
 .B LDAP_OPT_X_TLS_CACERTDIR
-Sets/gets the path of the directory containing CA certificates.
+Sets/gets the path of the directories containing CA certificates.
+Multiple directories may be specified, separated by a semi-colon.
 .BR invalue
 must be
 .BR "const char *" ;
index 17b71549919c82151dc6c21d7685713f26937826..3173014238f342433b254a82678cdbf6b211fae0 100644 (file)
@@ -333,8 +333,9 @@ Specifies the file that contains certificates for all of the Certificate
 Authorities the client will recognize.
 .TP
 .B TLS_CACERTDIR <path>
-Specifies the path of a directory that contains Certificate Authority
-certificates in separate individual files. The
+Specifies the path of directories that contain Certificate Authority
+certificates in separate individual files. Multiple directories may
+be specified, separated by a semi-colon.  The
 .B TLS_CACERT
 is always used before
 .B TLS_CACERTDIR.
index f7e9029ffc26fe173ecd90b4bddab2e0f4862a7c..fdf0ae744d493c10a5a2a5ec498f6dddcd40e53f 100644 (file)
@@ -926,10 +926,11 @@ the top-level CA should be present. Multiple certificates are simply
 appended to the file; the order is not significant.
 .TP
 .B olcTLSCACertificatePath: <path>
-Specifies the path of a directory that contains Certificate Authority
+Specifies the path of directories that contain Certificate Authority
 certificates in separate individual files. Usually only one of this
 or the olcTLSCACertificateFile is defined. If both are specified, both
-locations will be used.
+locations will be used. Multiple directories may be specified,
+separated by a semi-colon.
 .TP
 .B olcTLSCertificateFile: <filename>
 Specifies the file that contains the
index b0b2f4a9012527b71fbf1addcf56fa5c7865bff7..d0b8f18dc66e113ce024730625bd549b9b664dd6 100644 (file)
@@ -1156,10 +1156,11 @@ the top-level CA should be present. Multiple certificates are simply
 appended to the file; the order is not significant.
 .TP
 .B TLSCACertificatePath <path>
-Specifies the path of a directory that contains Certificate Authority
+Specifies the path of directories that contain Certificate Authority
 certificates in separate individual files. Usually only one of this
 or the TLSCACertificateFile is used. If both are specified, both
-locations will be used.
+locations will be used. Multiple directories may be specified,
+separated by a semi-colon.
 .TP
 .B TLSCertificateFile <filename>
 Specifies the file that contains the
index 423d18195f5f16831c492e9ff2d1b7588676fe1b..5ee28b964d06f7aa0ec2d1c6904bbf4a7b787a8e 100644 (file)
@@ -22,6 +22,8 @@ struct tls_impl;
 struct tls_ctx;
 struct tls_session;
 
+#define CERTPATHSEP    ";"
+
 typedef struct tls_ctx tls_ctx;
 typedef struct tls_session tls_session;
 
index 17bcc69f153bf3a5af4c912902c131004b9a476b..14a700f24b05ed398f36c725ce0b1dd67122c107 100644 (file)
@@ -195,21 +195,26 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server, char *
        }
 
        if (lo->ldo_tls_cacertdir != NULL) {
-               rc = gnutls_certificate_set_x509_trust_dir(
-                       ctx->cred,
-                       lt->lt_cacertdir,
-                       GNUTLS_X509_FMT_PEM );
-               if ( rc > 0 ) {
-                       Debug2( LDAP_DEBUG_TRACE,
-                               "TLS: loaded %d CA certificates from directory `%s'.\n",
-                               rc, lt->lt_cacertdir );
-               } else {
-                       Debug1( LDAP_DEBUG_ANY,
-                               "TLS: warning: no certificate found in CA certificate directory `%s'.\n",
-                               lt->lt_cacertdir );
-                       /* only warn, no return */
-                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
+               char **dirs = ldap_str2charray( lt->lt_cacertdir, CERTPATHSEP );
+               int i;
+               for ( i=0; dirs[i]; i++ ) {
+                       rc = gnutls_certificate_set_x509_trust_dir(
+                               ctx->cred,
+                               dirs[i],
+                               GNUTLS_X509_FMT_PEM );
+                       if ( rc > 0 ) {
+                               Debug2( LDAP_DEBUG_TRACE,
+                                       "TLS: loaded %d CA certificates from directory `%s'.\n",
+                                       rc, dirs[i] );
+                       } else {
+                               Debug1( LDAP_DEBUG_ANY,
+                                       "TLS: warning: no certificate found in CA certificate directory `%s'.\n",
+                                       dirs[i] );
+                               /* only warn, no return */
+                               strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
+                       }
                }
+               ldap_charray_free( dirs );
        }
 
        if (lo->ldo_tls_cacertfile != NULL) {
index 175bb141815a42aba15c11cc781979ee62ef810e..9c1f019499d8a1097d0ecc40b502d32c8635c64a 100644 (file)
@@ -170,21 +170,24 @@ tlso_ca_list( char * bundle, char * dir, X509 *cert )
        if ( bundle ) {
                ca_list = SSL_load_client_CA_file( bundle );
        }
-#if defined(HAVE_DIRENT_H) || defined(dirent)
        if ( dir ) {
-               int freeit = 0;
+               char **dirs = ldap_str2charray( dir, CERTPATHSEP );
+               int freeit = 0, i;
 
                if ( !ca_list ) {
                        ca_list = sk_X509_NAME_new_null();
                        freeit = 1;
                }
-               if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
-                       freeit ) {
-                       sk_X509_NAME_free( ca_list );
-                       ca_list = NULL;
+               for ( i=0; dirs[i]; i++ ) {
+                       if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
+                               freeit ) {
+                               sk_X509_NAME_free( ca_list );
+                               ca_list = NULL;
+                               break;
+                       }
                }
+               ldap_charray_free( dirs );
        }
-#endif
        if ( cert ) {
                X509_NAME *xn = X509_get_subject_name( cert );
                xn = X509_NAME_dup( xn );
@@ -445,15 +448,37 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server, char *
                                return -1;
                        }
                }
-               if (( lt->lt_cacertfile || lt->lt_cacertdir ) && !SSL_CTX_load_verify_locations( ctx,
-                               lt->lt_cacertfile, lt->lt_cacertdir ) )
-               {
-                       Debug2( LDAP_DEBUG_ANY, "TLS: "
-                               "could not load verify locations (file:`%s',dir:`%s').\n",
-                               lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
-                               lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "" );
-                       tlso_report_error( errmsg );
-                       return -1;
+               if ( lt->lt_cacertfile || lt->lt_cacertdir ) {
+                       char **dirs, *dummy = NULL;
+                       if ( lt->lt_cacertdir ) {
+                               dirs = ldap_str2charray( lt->lt_cacertdir, CERTPATHSEP );
+                       } else {
+                               dirs = &dummy;
+                       }
+                       /* Start with the first dir in path */
+                       if ( !SSL_CTX_load_verify_locations( ctx,
+                               lt->lt_cacertfile, dirs[0] ) )
+                       {
+                               Debug2( LDAP_DEBUG_ANY, "TLS: "
+                                       "could not load verify locations (file:`%s',dir:`%s').\n",
+                                       lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
+                                       dirs[0] ? dirs[0] : "" );
+                               tlso_report_error( errmsg );
+                               if ( dirs != &dummy )
+                                       ldap_charray_free( dirs );
+                               return -1;
+                       }
+                       /* Then additional dirs, if any */
+                       if ( dirs != &dummy ) {
+                               if ( dirs[1] ) {
+                                       int i;
+                                       X509_STORE *store = SSL_CTX_get_cert_store( ctx );
+                                       X509_LOOKUP *lookup = X509_STORE_add_lookup( store, X509_LOOKUP_hash_dir() );
+                                       for ( i=1; dirs[i]; i++ )
+                                               X509_LOOKUP_add_dir( lookup, dirs[i], X509_FILETYPE_PEM );
+                               }
+                               ldap_charray_free( dirs );
+                       }
                }
 
                if ( is_server ) {