From d181b0472d2d1e3a5204a91a199229a03ca9b413 Mon Sep 17 00:00:00 2001 From: Matúš Honěk Date: Dec 06 2017 14:13:49 +0000 Subject: 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 --- diff --git a/openldap-tlsmc.patch b/openldap-tlsmc.patch index 2bc514f..d781817 100644 --- a/openldap-tlsmc.patch +++ b/openldap-tlsmc.patch @@ -1,5 +1,8 @@ +MozNSS Interception Code + +Author: Matus Honek +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 ( -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", ++ 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: could not allocate memory.\n", + 0, 0, 0 ); -+ if ( 0 == tlsmc_prepare_dir( dir ) ) { ++ 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: WARN: cannot prepare the PEM dir, will try another one.\n", ++ "tlsmc_convert: INFO: using the existing PEM dir.\n", + 0, 0, 0 ); -+ continue; -+ } -+ if ( 0 == tlsmc_extract_nssdb( dir, ld_cacertdir, ld_cert, ld_key ) ) { ++ goto pem_dir_exists; ++ } else { + Debug( LDAP_DEBUG_ANY, -+ "tlsmc_convert: FATAL: could not extract from the NSS DB.\n", ++ "tlsmc_convert: FATAL: tried to stat the PEM dir but it is not a directory.\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 ) { ++ 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: no usable PEM dir.\n", ++ "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 \ diff --git a/openldap.spec b/openldap.spec index 0a065dc..d4cddc5 100644 --- a/openldap.spec +++ b/openldap.spec @@ -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 - 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 - 2.4.45-4 - Build with OpenSSL with MozNSS compatibility layer (#1400570)