Fix various MozNSS compatibility layer issues

+ Force write file with fsync to avoid race conditions
+ Always filestamp both sql and dbm NSS DB variants to not rely on default DB type prefix
+ Allow missing cert and key which is a valid usecase
+ Create extraction folder only in /tmp to simplify selinux rules
+ Fix Covscan issues

Related: #1400570
This commit is contained in:
Matúš Honěk 2017-12-06 15:13:49 +01:00
parent d8e109406e
commit d181b0472d
2 changed files with 123 additions and 265 deletions

View File

@ -1,5 +1,8 @@
MozNSS Interception Code
Author: Matus Honek <mhonek@redhat.com>
Date: Mon Nov 27 16:03:42 CET 2017
diff --git a/configure.in b/configure.in
index b251b6b06..8a836eabb 100644
--- a/configure.in
+++ b/configure.in
@@ -237,6 +237,7 @@ dnl OL_ARG_ENABLE(referrals,[ --enable-referrals enable LDAPv2+ Referrals (ex
@ -38,7 +41,6 @@ index b251b6b06..8a836eabb 100644
if test $ol_link_tls = yes ; then
AC_DEFINE(HAVE_TLS, 1, [define if you have TLS])
diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
index 389e1c4fd..60c7d05a5 100644
--- a/doc/man/man3/ldap_get_option.3
+++ b/doc/man/man3/ldap_get_option.3
@@ -772,6 +772,19 @@ must be
@ -62,7 +64,6 @@ index 389e1c4fd..60c7d05a5 100644
On success, the functions return
.BR LDAP_OPT_SUCCESS ,
diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5
index b6735bab5..612b63a2b 100644
--- a/doc/man/man5/ldap.conf.5
+++ b/doc/man/man5/ldap.conf.5
@@ -483,6 +483,11 @@ Check the CRL for a whole certificate chain
@ -78,7 +79,6 @@ index b6735bab5..612b63a2b 100644
.TP
LDAPNOINIT
diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5
index 6afbd7d6b..2893cd4a5 100644
--- a/doc/man/man5/slapd-config.5
+++ b/doc/man/man5/slapd-config.5
@@ -1004,6 +1004,11 @@ Check the CRL for a whole certificate chain
@ -94,7 +94,6 @@ index 6afbd7d6b..2893cd4a5 100644
If
.B slapd
diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
index 86abeca80..742568393 100644
--- a/doc/man/man5/slapd.conf.5
+++ b/doc/man/man5/slapd.conf.5
@@ -1235,6 +1235,11 @@ Check the CRL for a whole certificate chain
@ -110,7 +109,6 @@ index 86abeca80..742568393 100644
Options in this section only apply to the configuration file section
for the specified backend. They are supported by every
diff --git a/include/ldap.h b/include/ldap.h
index db6869da8..aae8bebd8 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -158,6 +158,10 @@ LDAP_BEGIN_DECL
@ -125,7 +123,6 @@ index db6869da8..aae8bebd8 100644
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in
index 636b15506..a1445312f 100644
--- a/libraries/libldap/Makefile.in
+++ b/libraries/libldap/Makefile.in
@@ -26,7 +26,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
@ -147,7 +144,6 @@ index 636b15506..a1445312f 100644
assertion.lo deref.lo ldif.lo fetch.lo
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 39ad7ce7c..689144ca3 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -137,7 +137,9 @@ static const struct ol_attribute {
@ -172,7 +168,6 @@ index 39ad7ce7c..689144ca3 100644
gopts->ldo_keepalive_probes = 0;
gopts->ldo_keepalive_interval = 0;
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index bcc58f367..d42b82627 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -260,7 +260,8 @@ struct ldapoptions {
@ -186,7 +181,6 @@ index bcc58f367..d42b82627 100644
#define LDAP_LDO_TLS_NULLARG
#endif
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index 8f842278a..878e1a0a8 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -37,6 +37,8 @@
@ -287,10 +281,9 @@ index 8f842278a..878e1a0a8 100644
}
diff --git a/libraries/libldap/tls_mc.c b/libraries/libldap/tls_mc.c
new file mode 100644
index 000000000..8383cb4ec
--- /dev/null
+++ b/libraries/libldap/tls_mc.c
@@ -0,0 +1,1323 @@
@@ -0,0 +1,1179 @@
+#include "portable.h"
+
+#ifdef HAVE_MOZNSS_COMPATIBILITY
@ -382,10 +375,16 @@ index 000000000..8383cb4ec
+ perror("IO ERROR: could not set file mode");
+ goto bail;
+ }
+ if ( 0 > close( fd ) ) {
+ perror("IO ERROR: could not close file");
+ if ( -1 >= fsync( fd ) ) {
+ perror("IO ERROR: could not fsync the file");
+ goto bail;
+ }
+ if ( 0 > close( fd ) ) {
+ perror("IO ERROR: could not close file");
+ fd = -1;
+ goto bail;
+ }
+ fd = -1;
+ rv = 1;
+bail:
+ if ( fd > -1 ) close( fd );
@ -393,23 +392,6 @@ index 000000000..8383cb4ec
+}
+
+
+void
+tlsmc_debug_nspr_msg()
+{
+ int _errno = errno;
+ PRInt32 oserror = PR_GetOSError();
+ char *errno_str = strerror(_errno);
+ char *errstr = PR_Malloc( PR_GetErrorTextLength() + 1 );
+ PR_GetErrorText( errstr );
+ Debug( LDAP_DEBUG_ANY,
+ "... NSPR error %d:`%s'\n",
+ PR_GetError(), errstr, 0 );
+ Debug( LDAP_DEBUG_ANY,
+ "... NSPR OS-error %d, errno %d:%s\n",
+ oserror, _errno, errno_str );
+ PR_Free( errstr );
+}
+
+/* BORROWED FROM tls_m.c */
+static void
+tlsmc_get_certdb_prefix( const char *certdir, char **realcertdir, char **prefix )
@ -444,6 +426,7 @@ index 000000000..8383cb4ec
+}
+
+
+/* BORROWED FROM tls_m.c */
+static char *
+tlsmc_get_pin_from_file(const char *token_name, char *filename)
+{
@ -530,6 +513,7 @@ index 000000000..8383cb4ec
+}
+
+
+/* BORROWED FROM tls_m.c */
+/*
+ * Turn the echoing off on a tty.
+ */
@ -544,6 +528,7 @@ index 000000000..8383cb4ec
+ }
+}
+
+/* BORROWED FROM tls_m.c */
+/*
+ * Turn the echoing on on a tty.
+ */
@ -560,7 +545,7 @@ index 000000000..8383cb4ec
+}
+
+
+/* Borrowed from tlsm_get_pin() */
+/* BORROWED FROM tls_m.c */
+char *
+tlsmc_get_pin( PK11SlotInfo *slot, PRBool retry, void * filename)
+{
@ -605,7 +590,7 @@ index 000000000..8383cb4ec
+
+
+int
+tlsmc_hash( unsigned char **dest, char *src )
+tlsmc_hash( char **dest, const char *src )
+{
+ int rv = 0;
+ unsigned char fp[SHA256_LENGTH];
@ -633,35 +618,6 @@ index 000000000..8383cb4ec
+
+
+/* BORROWED FROM tls_m.c */
+static PK11SlotInfo *
+tlsmc_init_open_certdb( const char *nssdb_dir, const char *prefix )
+{
+ PK11SlotInfo *slot = NULL;
+ char *config = NULL;
+
+ config = PR_smprintf( "configDir='%s' tokenDescription='%s' "
+ "certPrefix='%s' keyPrefix='%s' flags=readOnly",
+ nssdb_dir, TLSM_CERTDB_DESC,
+ prefix, prefix );
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_init_open_certdb: INFO: certdb config: `%s`.\n",
+ config, 0, 0 );
+
+ slot = SECMOD_OpenUserDB( config );
+ if ( !slot ) {
+ PRErrorCode errcode = PR_GetError();
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_init_open_certdb: ERROR: cannot open certdb `%s`, error `%d:%s`.\n",
+ nssdb_dir, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
+ }
+
+ if ( config ) PR_smprintf_free( config );
+
+ return slot;
+}
+
+
+/* Borrowed from tlsm_deferred_init */
+int
+tlsmc_open_nssdb( char *ld_cacertdir, NSSInitContext **out_initctx, char **out_nssdb_dir, char **out_nssdb_prefix )
+{
@ -754,17 +710,6 @@ index 000000000..8383cb4ec
+}
+
+
+static int
+tlsmc_is_sql_nssdb( const char *ld_cacertdir )
+{
+ if ( 0 == strncmp( "sql:", ld_cacertdir, 4 ) ) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+int
+tlsmc_filestamp( char **filestamp, char *path )
+{
@ -773,7 +718,7 @@ index 000000000..8383cb4ec
+ char stime[20];
+
+ if ( 0 != stat( path, &attr ) ) {
+ perror("IO ERROR: could not stat file");
+ rv = -1;
+ goto bail;
+ }
+ if ( 0 == strftime(stime, sizeof(stime), "%FT%T", localtime(&attr.st_mtime)) ) {
@ -812,31 +757,28 @@ index 000000000..8383cb4ec
+ "FILES:\n",
+ nssdb_dir, nssdb_prefix, ld_cacertdir, ld_cert, ld_key, geteuid() );
+
+ char *bdb_files[] = { "cert8.db", "key3.db", "secmod.db", NULL };
+ char *sql_files[] = { "cert9.db", "key4.db", "secmod.db", NULL };
+ char **files = ( 1 == tlsmc_is_sql_nssdb( ld_cacertdir ) ) ? sql_files : bdb_files; // FIXME we should do all files as default prefix may (and will) change and thus change the semantics of the ld_cacertdir
+ char *file = *files;
+ while ( NULL != ( file = *(files++) ) ) {
+ char *files[] = { "cert8.db", "cert9.db", "key3.db", "key4.db", "secmod.db", NULL };
+ char **filep = NULL;
+ for ( filep = files; NULL != *filep; filep++ ) {
+ char *filestamp = NULL;
+ char *path = NULL;
+ path = PR_smprintf( "%s/%s%s", nssdb_dir, nssdb_prefix, file );
+ path = PR_smprintf( "%s/%s%s", nssdb_dir, nssdb_prefix, *filep );
+ if ( 0 == tlsmc_filestamp( &filestamp, path ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_compute_checksum: ERROR: could not stat file `%s'.\n",
+ "tlsmc_compute_checksum: INFO: could not check file `%s'.\n",
+ path, 0, 0 );
+ rv = -1;
+ } else {
+ data = PR_sprintf_append( data, "%s: %s\n", file, filestamp );
+ data = PR_sprintf_append( data, "%s: %s\n", *filep, filestamp );
+ }
+ bail_one:
+ if ( filestamp ) PR_smprintf_free( filestamp );
+ if ( path ) PR_smprintf_free( path );
+ if ( -1 == rv ) goto bail;
+ }
+
+ /* compute data checksum */
+ unsigned char *checksum = NULL;
+ if ( 1 != tlsmc_hash( &checksum, data ) ) {
+ char *checksum = NULL;
+ if ( 1 != tlsmc_hash( &checksum, (const char*) data ) ) {
+ checksum = NULL;
+ goto bail;
+ }
@ -857,8 +799,6 @@ index 000000000..8383cb4ec
+tlsmc_prepare_dir( char *dir )
+{
+ int rv = 0;
+ PRFileInfo info;
+ PRStatus prv;
+ char *cacerts_dir = NULL;
+
+ Debug( LDAP_DEBUG_TRACE,
@ -897,6 +837,8 @@ index 000000000..8383cb4ec
+ return rv;
+}
+
+
+/* BORROWED FROM 389ds: ssl.c */
+int
+tlsmc_extract_cert_to_file(CERTCertDBHandle *certdb_handle, CERTCertificate *cert, char *file_path)
+{
@ -949,8 +891,7 @@ index 000000000..8383cb4ec
+}
+
+
+
+/* borrowed from 389-ds-base, ssl.c, DecryptKey */
+/* BORROWED FROM 389ds: ssl.c */
+int
+tlsmc_decrypt_key(SECKEYEncryptedPrivateKeyInfo *epki,
+ SECOidTag algTag,
@ -1020,7 +961,7 @@ index 000000000..8383cb4ec
+}
+
+
+
+/* BORROWED FROM 389ds: ssl.c */
+int
+tlsmc_extract_key_of_cert_to_file(CERTCertificate *cert,
+ char *pin_filename,
@ -1034,7 +975,6 @@ index 000000000..8383cb4ec
+ SECItem clearKeyDER;
+ char *b64 = NULL;
+ char *output = NULL;
+ //SECItem *data = PK11_ExportDERPrivateKeyInfo(key, (void *)pin_filename); // FIXME NULL? // probably won't work
+
+ // establish password
+ pwitem.data = "secretpw"; // FIXME use pin_filename
@ -1110,17 +1050,24 @@ index 000000000..8383cb4ec
+ return rv;
+}
+
+//TODO drop?
+
+/* BORROWED FROM 389ds: ssl.c */
+int
+tlsmc_extract_cert_key_pair(char *nickname, char *pin_filename, char *dir_name)
+{
+ int rv = 0;
+ int fd = -1;
+ CERTCertDBHandle *certHandle = NULL;
+ CERTCertificate *cert = NULL;
+ char *cert_file_path = NULL;
+ char *key_file_path = NULL;
+
+ if ( NULL == nickname ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_extract_cert_key_pair: WARN: supplied nickname is empty (NULL).\n",
+ 0, 0, 0 );
+ rv = 1;
+ goto bail;
+ }
+ if ( NULL == ( certHandle = CERT_GetDefaultCertDB() ) ) {
+ // FIXME see same in tlsmc_extract_cacerts()
+ Debug( LDAP_DEBUG_ANY,
@ -1169,106 +1116,7 @@ index 000000000..8383cb4ec
+}
+
+
+/* Adopted from 389DS. */
+static int
+tlsmc_list_certs(CERTCertDBHandle *handle,
+ CERTCertificate *cert,
+ PK11SlotInfo *slot,
+ PRFileDesc *outfile,
+ void *pwarg)
+{
+ SECItem data;
+ int rv = 0;
+ CERTCertList *certs;
+ CERTCertListNode *node;
+ CERTCertificate *the_cert = NULL;
+ char *name = NULL;
+
+ if (!cert) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: no cert given.\n",
+ 0, 0, 0 );
+ return rv;
+ }
+ name = cert->nickname;
+
+ if (!name) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: no cert nickname.\n",
+ 0, 0, 0 );
+ return rv;
+ }
+ the_cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+ if (!the_cert) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: could not find cert: %s.\n",
+ name, 0, 0 );
+ return 0;
+ }
+
+ PR_fprintf(outfile, "%s\n", DONOTEDIT);
+ /* Here, we have one cert with the desired nickname or email
+ * address. Now, we will attempt to get a list of ALL certs
+ * with the same subject name as the cert we have. That list
+ * should contain, at a minimum, the one cert we have already found.
+ * If the list of certs is empty (NULL), the libraries have failed.
+ */
+ certs = CERT_CreateSubjectCertList(NULL, handle, &the_cert->derSubject,
+ PR_Now(), PR_FALSE);
+ CERT_DestroyCertificate(the_cert);
+ if (!certs) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: problem printing certificates.\n",
+ 0, 0, 0 );
+ return 0;
+ }
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs); node = CERT_LIST_NEXT(node)) {
+ the_cert = node->cert;
+ PR_fprintf(outfile, "Issuer: %s\n", the_cert->issuerName);
+ PR_fprintf(outfile, "Subject: %s\n", the_cert->subjectName);
+ /* now get the subjectList that matches this cert */
+ data.data = the_cert->derCert.data;
+ data.len = the_cert->derCert.len;
+ PR_fprintf(outfile, "\n%s\n%s\n%s\n",
+ PEM_CERT_HEADER,
+ BTOA_DataToAscii(data.data, data.len),
+ PEM_CERT_FOOTER);
+ rv = 1;
+ }
+ if (certs) {
+ CERT_DestroyCertList(certs);
+ }
+ if (rv) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: problem printing certificate nicknames.\n",
+ 0, 0, 0 );
+ return 0;
+ }
+
+ return rv;
+}
+
+static char*
+tlsmc_extract_key()
+{
+ return NULL;
+}
+
+/* Adopted from 389DS. */
+static int
+tlsmc_extract_cert(char *token_colon_name, char *filename)
+{
+ CERTCertListNode *node;
+ CERTCertList *list = PK11_ListCerts(PK11CertListAll, NULL);
+ for (node = CERT_LIST_HEAD(list);
+ !CERT_LIST_END(node, list);
+ node = CERT_LIST_NEXT(node)) {
+ CERTCertificate *cert = node->cert;
+ CERTCertTrust trust;
+ }
+ return 0;
+}
+
+/* BORROWED FROM 389ds: ssl.c */
+int
+tlsmc_extract_cacerts( char *dir_name )
+{
@ -1376,14 +1224,6 @@ index 000000000..8383cb4ec
+ 0, 0, 0 );
+ }
+
+ if ( ( ! *ld_cert ) || ( ! *ld_key ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_extract_nssdb: ERROR: cert or key empty.\n",
+ 0, 0, 0 );
+ rv = -1;
+ goto bail;
+ }
+
+ if ( 0 == tlsmc_extract_cert_key_pair( *ld_cert, *ld_key, dir_name ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_extract_nssdb: ERROR: could not export user cert and/or key.\n",
@ -1397,6 +1237,8 @@ index 000000000..8383cb4ec
+ return rv;
+}
+
+
+/* BORROWED FROM tls_m.c */
+int
+tlsmc_close_nssdb(NSSInitContext **initctx)
+{
@ -1411,6 +1253,7 @@ index 000000000..8383cb4ec
+ }
+}
+
+
+int
+tlsmc_convert( char **ld_cacertdir, char **ld_cert, char **ld_key )
+{
@ -1419,14 +1262,11 @@ index 000000000..8383cb4ec
+
+ NSSInitContext *nss_ctx = NULL;
+ char *nssdb_dir_path = NULL;
+ char *nssdb_dir_name = NULL;
+ char *nssdb_prefix = NULL;
+ char *pem_dirs[] = { NULL, NULL, NULL };
+ char *pem_dir = NULL;
+ char *readme_path = NULL;
+ char *data = NULL; // data before checksum
+ char *checksum = NULL; // checksummed data
+ char **dirs = pem_dirs;
+ char *dir = *dirs;
+ struct stat stat_buf;
+
+#ifdef LDAP_R_COMPILE
@ -1436,6 +1276,13 @@ index 000000000..8383cb4ec
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: trying to open NSS DB with CACertDir = `%s'.\n",
+ *ld_cacertdir, 0, 0 );
+ if ( NULL == ld_cacertdir || NULL == ld_cert || NULL == ld_key ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: ERROR: cannot proceed, some of the arguments are NULL.\n",
+ 0, 0, 0 );
+ rv = 1;
+ goto bail;
+ }
+ if ( 0 == tlsmc_open_nssdb( *ld_cacertdir, &nss_ctx, &nssdb_dir_path, &nssdb_prefix ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: INFO: cannot open the NSS DB, expecting PEM configuration is present.\n",
@ -1453,58 +1300,61 @@ index 000000000..8383cb4ec
+ goto bail;
+ }
+
+ pem_dirs[0] = PR_smprintf( "%s-%s-tlsmc-%s", nssdb_dir_path, nssdb_prefix, checksum );
+ pem_dirs[1] = PR_smprintf( "/tmp/%s", tlsmc_path2name( pem_dirs[0] ) );
+
+ int i=0;
+ while ( NULL != ( dir = *(dirs++) ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: trying with PEM dir = `%s'.\n",
+ dir, 0, 0 );
+ if ( 0 == stat( dir, &stat_buf ) ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: using the existing PEM dir.\n",
+ 0, 0, 0 );
+ break;
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: WARN: tried to stat the PEM dir but it is not a directory, will try another one.\n",
+ 0, 0, 0 );
+ continue;
+ }
+ }
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: WARN: could not stat PEM dir, will try to create it.\n",
+ 0, 0, 0 );
+ if ( 0 == tlsmc_prepare_dir( dir ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: WARN: cannot prepare the PEM dir, will try another one.\n",
+ 0, 0, 0 );
+ continue;
+ }
+ if ( 0 == tlsmc_extract_nssdb( dir, ld_cacertdir, ld_cert, ld_key ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: could not extract from the NSS DB.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+
+ readme_path = PR_smprintf( "%s/" TLSMC_README_FILE_NAME, dir );
+ tlsmc_write_file( readme_path, data, S_IRUSR );
+ rv = 1;
+ break;
+ }
+
+ if ( dir == NULL ) {
+ if ( NULL == ( pem_dir = PR_smprintf( "/tmp/openldap-tlsmc-%s-%s-%s",
+ tlsmc_path2name( nssdb_dir_path ),
+ nssdb_prefix,
+ checksum) ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: no usable PEM dir.\n",
+ "tlsmc_convert: FATAL: could not allocate memory.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: trying with PEM dir = `%s'.\n",
+ pem_dir, 0, 0 );
+ if ( 0 == stat( pem_dir, &stat_buf ) ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: using the existing PEM dir.\n",
+ 0, 0, 0 );
+ goto pem_dir_exists;
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: tried to stat the PEM dir but it is not a directory.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ }
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: WARN: could not find the PEM dir, will try to create it.\n",
+ 0, 0, 0 );
+ if ( 0 == tlsmc_prepare_dir( pem_dir ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: cannot prepare the PEM dir.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ if ( 0 == tlsmc_extract_nssdb( pem_dir, ld_cacertdir, ld_cert, ld_key ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: could not extract from the NSS DB.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ if ( NULL == ( readme_path = PR_smprintf( "%s/" TLSMC_README_FILE_NAME, pem_dir ) ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: could not allocate memory.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ if ( 0 == tlsmc_write_file( readme_path, data, S_IRUSR ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: ERROR: could not create README file.\n",
+ 0, 0, 0 );
+ }
+
+pem_dir_exists:
+ if (*ld_cacertdir) free(*ld_cacertdir);
+ *ld_cacertdir = PR_smprintf( "%s/" TLSMC_CACERTS_DIR_NAME, dir );
+ *ld_cacertdir = PR_smprintf( "%s/" TLSMC_CACERTS_DIR_NAME, pem_dir );
+ if ( ! ( ( 0 == stat( *ld_cacertdir, &stat_buf ) )
+ && S_ISDIR(stat_buf.st_mode) ) ) {
+ Debug( LDAP_DEBUG_ANY,
@ -1514,7 +1364,7 @@ index 000000000..8383cb4ec
+ }
+
+ if (*ld_cert) free(*ld_cert);
+ *ld_cert = PR_smprintf( "%s/" TLSMC_CERT_FILE_NAME, dir );
+ *ld_cert = PR_smprintf( "%s/" TLSMC_CERT_FILE_NAME, pem_dir );
+ if ( ! ( ( 0 == stat( *ld_cert, &stat_buf ) )
+ && S_ISREG(stat_buf.st_mode) ) ) {
+ Debug( LDAP_DEBUG_ANY,
@ -1524,7 +1374,7 @@ index 000000000..8383cb4ec
+ }
+
+ if (*ld_key) free(*ld_key);
+ *ld_key = PR_smprintf( "%s/" TLSMC_KEY_FILE_NAME, dir );
+ *ld_key = PR_smprintf( "%s/" TLSMC_KEY_FILE_NAME, pem_dir );
+ if ( ! ( ( 0 == stat( *ld_key, &stat_buf ) )
+ && S_ISREG(stat_buf.st_mode) ) ) {
+ Debug( LDAP_DEBUG_ANY,
@ -1536,8 +1386,8 @@ index 000000000..8383cb4ec
+ rv = 1;
+
+bail:
+ if ( pem_dirs[0] ) PR_smprintf_free( pem_dirs[0] );
+ if ( pem_dirs[1] ) PR_smprintf_free( pem_dirs[1] );
+ if ( pem_dir ) PR_smprintf_free( pem_dir );
+ if ( data ) free( data );
+ if ( nssdb_prefix ) free( nssdb_prefix );
+ if ( nssdb_dir_path ) free( nssdb_dir_path );
+ if ( nss_ctx ) tlsmc_close_nssdb( &nss_ctx );
@ -1550,8 +1400,6 @@ index 000000000..8383cb4ec
+}
+
+
+
+
+// returns 0 when successful
+int
+tlsmc_intercept_initialization( struct ldapoptions *lo, int is_server )
@ -1606,6 +1454,7 @@ index 000000000..8383cb4ec
+ return rv;
+}
+
+
+#endif /* HAVE_MOZNSS_COMPATIBILITY */
+/*
+ emacs settings
@ -1616,7 +1465,6 @@ index 000000000..8383cb4ec
+*/
diff --git a/libraries/libldap/tls_mc.h b/libraries/libldap/tls_mc.h
new file mode 100644
index 000000000..2e6e567dc
--- /dev/null
+++ b/libraries/libldap/tls_mc.h
@@ -0,0 +1,18 @@
@ -1640,10 +1488,9 @@ index 000000000..2e6e567dc
+#endif /* _LDAP_TLSMC_H */
diff --git a/libraries/libldap/tls_mc_ossl.c b/libraries/libldap/tls_mc_ossl.c
new file mode 100644
index 000000000..d61ec207c
--- /dev/null
+++ b/libraries/libldap/tls_mc_ossl.c
@@ -0,0 +1,90 @@
@@ -0,0 +1,95 @@
+#include "portable.h"
+
+/* This file contains functions that require OpenSSL headers due to some
@ -1695,12 +1542,17 @@ index 000000000..d61ec207c
+ last_slash_p = strrchr( cert_path, '/' );
+ cert_filename_p = last_slash_p ? last_slash_p + 1 : cert_path;
+ for ( cnt = 0; cnt < 10; cnt++ ) {
+ symlink_path = PR_smprintf( "%s/%08lx.%d", cacerts_dir, hash, cnt );
+ if ( NULL == ( symlink_path = PR_smprintf( "%s/%08lx.%d", cacerts_dir, hash, cnt ) ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_cert_create_hash_symlink: ERROR: memory allocation error.\n",
+ 0, 0, 0 );
+ continue;
+ }
+ if ( 0 != symlink( cert_filename_p, symlink_path ) ) {
+ if ( errno == EEXIST ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_cert_create_hash_symlink: INFO: symlink `%s' already exists.\n",
+ 0, 0, 0 );
+ symlink_path, 0, 0 );
+ if ( symlink_path ) PR_smprintf( symlink_path );
+ continue;
+ }
@ -1736,7 +1588,6 @@ index 000000000..d61ec207c
+*/
diff --git a/libraries/libldap/tls_mc_ossl.h b/libraries/libldap/tls_mc_ossl.h
new file mode 100644
index 000000000..1b4284576
--- /dev/null
+++ b/libraries/libldap/tls_mc_ossl.h
@@ -0,0 +1,12 @@
@ -1753,7 +1604,6 @@ index 000000000..1b4284576
+#endif
+#endif
diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in
index cdf4070dd..c7a86c95f 100644
--- a/libraries/libldap_r/Makefile.in
+++ b/libraries/libldap_r/Makefile.in
@@ -28,7 +28,7 @@ XXSRCS = apitest.c test.c \

View File

@ -5,7 +5,7 @@
Name: openldap
Version: 2.4.45
Release: 4%{?dist}
Release: 5%{?dist}
Summary: LDAP support libraries
Group: System Environment/Daemons
License: OpenLDAP
@ -516,6 +516,14 @@ exit 0
%{_mandir}/man3/*
%changelog
* Wed Dec 6 2017 Matus Honek <mhonek@redhat.com> - 2.4.45-5
- Fix issues in MozNSS compatibility layer (#1400570)
+ Force write file with fsync to avoid race conditions
+ Always filestamp both sql and dbm NSS DB variants to not rely on default DB type prefix
+ Allow missing cert and key which is a valid usecase
+ Create extraction folder only in /tmp to simplify selinux rules
+ Fix Covscan issues
* Fri Nov 3 2017 Matus Honek <mhonek@redhat.com> - 2.4.45-4
- Build with OpenSSL with MozNSS compatibility layer (#1400570)