static int  tls_opt_trace = 1;
 static char *tls_opt_certfile = NULL;
 static char *tls_opt_keyfile = NULL;
-static char *tls_opt_dhparamdir = NULL;
+static char *tls_opt_dhfile = NULL;
 static char *tls_opt_cacertfile = NULL;
 static char *tls_opt_cacertdir = NULL;
 static int  tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND;
 #endif
 static char *tls_opt_ciphersuite = NULL;
 static char *tls_opt_randfile = NULL;
-static int tls_opt_dhparamdirlen;
 
 #define HAS_TLS( sb )  ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
                                (void *)&sb_tls_sbio )
 
 static SSL_CTX *tls_def_ctx = NULL;
 
+typedef struct dhplist {
+       struct dhplist *next;
+       int keylength;
+       DH *param;
+} dhplist;
+
+static dhplist *dhparams;
+
 static int tls_seed_PRNG( const char *randfile );
 
 #ifdef LDAP_R_COMPILE
                LDAP_FREE( tls_opt_keyfile );
                tls_opt_keyfile = NULL;
        }
-       if ( tls_opt_dhparamdir ) {
-               LDAP_FREE( tls_opt_dhparamdir );
-               tls_opt_dhparamdir = NULL;
+       if ( tls_opt_dhfile ) {
+               LDAP_FREE( tls_opt_dhfile );
+               tls_opt_dhfile = NULL;
        }
        if ( tls_opt_cacertfile ) {
                LDAP_FREE( tls_opt_cacertfile );
        char *cacertdir = tls_opt_cacertdir;
        char *certfile = tls_opt_certfile;
        char *keyfile = tls_opt_keyfile;
+       char *dhfile = tls_opt_dhfile;
 
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
                keyfile = LDAP_STRDUP( keyfile );
                __atoe( keyfile );
        }
+       if ( dhfile ) {
+               dhfile = LDAP_STRDUP( dhfile );
+               __atoe( dhfile );
+       }
 #endif
        if ( tls_def_ctx == NULL ) {
                int i;
                        goto error_exit;
                }
 
+               if ( tls_opt_dhfile ) {
+                       DH *dh = NULL;
+                       BIO *bio;
+                       dhplist *p;
+
+                       if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "TLS: could not use DH parameters file `%s'.\n",
+                                       tls_opt_dhfile,0,0);
+                               tls_report_error();
+                               rc = -1;
+                               goto error_exit;
+                       }
+                       while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
+                               p = LDAP_MALLOC( sizeof(dhplist) );
+                               if ( p != NULL ) {
+                                       p->keylength = DH_size( dh ) * 8;
+                                       p->param = dh;
+                                       p->next = dhparams;
+                                       dhparams = p;
+                               }
+                       }
+                       BIO_free( bio );
+               }
+
                if ( tls_opt_trace ) {
                        SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
                }
        LDAP_FREE( cacertdir );
        LDAP_FREE( certfile );
        LDAP_FREE( keyfile );
+       LDAP_FREE( dhfile );
 #endif
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
        case LDAP_OPT_X_TLS_KEYFILE:
        case LDAP_OPT_X_TLS_RANDOM_FILE:
        case LDAP_OPT_X_TLS_CIPHER_SUITE:
-       case LDAP_OPT_X_TLS_DHPARAMDIR:
+       case LDAP_OPT_X_TLS_DHFILE:
                return ldap_pvt_tls_set_option( ld, option, (void *) arg );
 
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
                *(char **)arg = tls_opt_keyfile ?
                        LDAP_STRDUP( tls_opt_keyfile ) : NULL;
                break;
-       case LDAP_OPT_X_TLS_DHPARAMDIR:
-               *(char **)arg = tls_opt_dhparamdir ?
-                       LDAP_STRDUP( tls_opt_dhparamdir ) : NULL;
+       case LDAP_OPT_X_TLS_DHFILE:
+               *(char **)arg = tls_opt_dhfile ?
+                       LDAP_STRDUP( tls_opt_dhfile ) : NULL;
                break;
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
                *(int *)arg = tls_opt_require_cert;
                if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
                tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
                break;
-       case LDAP_OPT_X_TLS_DHPARAMDIR:
-               if ( tls_opt_dhparamdir ) LDAP_FREE( tls_opt_dhparamdir );
-               tls_opt_dhparamdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-               if ( tls_opt_dhparamdir )
-                       tls_opt_dhparamdirlen = strlen( tls_opt_dhparamdir );
+       case LDAP_OPT_X_TLS_DHFILE:
+               if ( tls_opt_dhfile ) LDAP_FREE( tls_opt_dhfile );
+               tls_opt_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
                break;
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
                switch( *(int *) arg ) {
        size_t size;
 };
 
-struct dhplist {
-       struct dhplist *next;
-       int keylength;
-       DH *param;
-};
-
-static struct dhplist *dhparams;
 
 /* From the OpenSSL 0.9.7 distro */
 static const char dhpem512[] =
        { 0, NULL, 0 }
 };
 
-#define MAXDIGITS      12
-
-#define        DHFILEPATTERN   "dh%d.pem"
-
 static DH *
 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
 {
        struct dhplist *p = NULL;
        BIO *b = NULL;
-       FILE *f;
-       char *file;
        DH *dh = NULL;
+       int i;
 
        /* Do we have params of this length already? */
 #ifdef LDAP_R_COMPILE
                }
        }
 
-       /* See if there's a file to load */
-       if ( tls_opt_dhparamdir ) {
-               file = LDAP_MALLOC( tls_opt_dhparamdirlen + 1 + MAXDIGITS +
-                       sizeof(DHFILEPATTERN) );
-               if ( file == NULL )
-                       goto done;
-               sprintf( file, "%s/" DHFILEPATTERN, tls_opt_dhparamdir, key_length );
-       } else {
-               file = LDAP_MALLOC( STRLENOF(LDAP_SYSCONFDIR) + 1 + MAXDIGITS +
-                       sizeof(DHFILEPATTERN) );
-               if ( file == NULL )
-                       goto done;
-               sprintf( file, LDAP_SYSCONFDIR "/" DHFILEPATTERN, key_length );
-       }
-       f = fopen(file,"r");
-       /* Did we get the file? */
-       if ( f ) {
-               b = BIO_new_fp( f, BIO_CLOSE );
-               if ( b == NULL )
-                       fclose( f );
-       } else {
-               /* No - check for hardcoded params */
-               int i;
+       /* No - check for hardcoded params */
 
-               for (i=0; dhpem[i].keylength; i++) {
-                       if ( dhpem[i].keylength == key_length ) {
-                               b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size );
-                               break;
-                       }
+       for (i=0; dhpem[i].keylength; i++) {
+               if ( dhpem[i].keylength == key_length ) {
+                       b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size );
+                       break;
                }
        }
+
        if ( b ) {
                dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
                BIO_free( b );
 
        CFG_TLS_CERT_KEY,
        CFG_TLS_CA_PATH,
        CFG_TLS_CA_FILE,
-       CFG_TLS_DH_DIR,
+       CFG_TLS_DH_FILE,
        CFG_TLS_VERIFY,
        CFG_TLS_CRLCHECK,
        CFG_CONCUR,
 #endif
                "( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-       { "TLSDHParamDir", NULL, 0, 0, 0,
+       { "TLSDHParamFile", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_DH_DIR|ARG_STRING|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_DH_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
-               "( OLcfgGlAt:77 NAME 'olcTLSDHParamDir' "
+               "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
        { "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS,
                &config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' "
                 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
                 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
                 "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
-                "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamDir $ "
+                "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
                 "olcToolThreads $ "
                 "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
                 "olcDitContentRules ) )", Cft_Global },
        case CFG_TLS_CERT_KEY:  flag = LDAP_OPT_X_TLS_KEYFILE;          break;
        case CFG_TLS_CA_PATH:   flag = LDAP_OPT_X_TLS_CACERTDIR;        break;
        case CFG_TLS_CA_FILE:   flag = LDAP_OPT_X_TLS_CACERTFILE;       break;
-       case CFG_TLS_DH_DIR:    flag = LDAP_OPT_X_TLS_DHPARAMDIR;       break;
+       case CFG_TLS_DH_FILE:   flag = LDAP_OPT_X_TLS_DHFILE;   break;
        default:                Debug(LDAP_DEBUG_ANY, "%s: "
                                        "unknown tls_option <0x%x>\n",
                                        c->log, c->type, 0);