From 814b7ecc9e245171a9abfcc17be8b9aa1f3fd047 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Jun 29 2011 18:04:29 +0000 Subject: Bug 710372 - Not able to open the Manage Certificate from DS-console https://bugzilla.redhat.com/show_bug.cgi?id=710372 Resolves: bug 710372 Bug Description: Not able to open the Manage Certificate from DS-console Reviewed by: nkinder (Thanks!) Branch: master Fix Description: NSS_Initialize fails to open the cert db for the specified directory server because NSS_Shutdown failed. That failed because of a memory leak in openldap using moznss: http://www.openldap.org/its/index.cgi?findid=6980 and https://bugzilla.redhat.com/show_bug.cgi?id=717730 The workaround is to use a new NSS InitContext to open the key/cert db. Platforms tested: RHEL6 x86_64 Flag Day: no Doc impact: no --- diff --git a/admserv/cgi-src40/security.c b/admserv/cgi-src40/security.c index ce84a81..093655c 100644 --- a/admserv/cgi-src40/security.c +++ b/admserv/cgi-src40/security.c @@ -115,6 +115,7 @@ extern "C" { int expired = 0; CERTCertDBHandle *certdb = NULL; char line[BIG_LINE]; +static NSSInitContext *secctx = NULL; static char *securitydir; /* based on the sie - security dir for ds or as */ @@ -233,10 +234,18 @@ static char * getParameter(char *key, char *keyName) { return get_cgi_var(key, getResourceString(DBT_PARAMETERMISSING), line); } -static void closeAllSecurityDB() { +static void closeAllSecurityDB(int global) { /* close all db */ - SSL_ClearSessionCache(); - NSS_Shutdown(); + if (NSS_IsInitialized()) { + SSL_ClearSessionCache(); + } + if (secctx) { + NSS_ShutdownContext(secctx); + secctx = NULL; + } + if (global) { + NSS_Shutdown(); + } } static void errorAllocateMem() { @@ -247,7 +256,7 @@ static void errorAllocateMem() { } static void errorRpt(int type, char* detailInfo) { - closeAllSecurityDB(); + closeAllSecurityDB(1); rpt_err(type, getResourceString(DBT_ERROR_OCCURED), detailInfo, @@ -255,7 +264,7 @@ static void errorRpt(int type, char* detailInfo) { } static void errorRptExtended(int type, char* detail, char* extra) { - closeAllSecurityDB(); + closeAllSecurityDB(1); rpt_err(type, getResourceString(DBT_ERROR_OCCURED), detail, @@ -455,8 +464,20 @@ getSecurityDir(AdmldapInfo info, const char *sie) return PL_strdup(util_get_security_dir()); /* same as admin server security dir */ } +#ifdef DUMP_CACHE_INFO + if (NSS_IsInitialized()) { + printf("nss_DumpCertificateCacheInfo 6\n"); + nss_DumpCertificateCacheInfo(); + } +#endif /* create pset with this dn */ pset = psetCreateSSL((char *)sie, configdir, NULL, NULL, &rval); +#ifdef DUMP_CACHE_INFO + if (NSS_IsInitialized()) { + printf("nss_DumpCertificateCacheInfo 7\n"); + nss_DumpCertificateCacheInfo(); + } +#endif if (pset && ((rval == PSET_OP_OK) || (rval == PSET_LOCAL_OPEN_FAIL))) { /* only admin-serv uses local file */ securitydir = psetGetAttrSingleValue(pset, "configuration.encryption.certdir", &rval); if (!securitydir && util_psetHasObjectClass(pset, DSOBJECTCLASS)) { @@ -496,8 +517,20 @@ getSecurityDir(AdmldapInfo info, const char *sie) } psetDelete(pset); +#ifdef DUMP_CACHE_INFO + if (NSS_IsInitialized()) { + printf("nss_DumpCertificateCacheInfo 8\n"); + nss_DumpCertificateCacheInfo(); + } +#endif pset = psetRealCreateSSL(info, host, port, security, DSCONFIGENTRY, binddn, bindpw, NULL, &rval); +#ifdef DUMP_CACHE_INFO + if (NSS_IsInitialized()) { + printf("nss_DumpCertificateCacheInfo 9\n"); + nss_DumpCertificateCacheInfo(); + } +#endif securitydir = psetGetAttrSingleValue(pset, DSSECURITYDIR, &rval); PL_strfree(host); PL_strfree(sport); @@ -511,7 +544,12 @@ getSecurityDir(AdmldapInfo info, const char *sie) } } psetDelete(pset); - +#ifdef DUMP_CACHE_INFO + if (NSS_IsInitialized()) { + printf("nss_DumpCertificateCacheInfo 10\n"); + nss_DumpCertificateCacheInfo(); + } +#endif return securitydir; } @@ -980,17 +1018,18 @@ static void setTrust(char *certFingerprint, int trust) { static void securityInitialization(char* securitydir) { PRUint32 flags = 0; - char *db_name; int const minPwdLen = 8; int const pwdRequired = 1; + NSSInitParameters initParams; - /* PKSC11 module must be configured before NSS is initialized */ - db_name = strdup("internal (software) "); - PK11_ConfigurePKCS11(NULL,NULL,NULL,db_name,NULL,NULL,NULL,NULL, - minPwdLen, pwdRequired); + memset(&initParams, 0, sizeof(initParams)); + initParams.length = sizeof(initParams); + initParams.dbTokenDescription = strdup("internal (software) "); + initParams.minPWLen = minPwdLen; + initParams.passwordRequired = pwdRequired; /* init NSS */ - if (NSS_Initialize(securitydir, NULL, NULL, SECMOD_DB, flags)) { + if (!(secctx = NSS_InitContext(securitydir, NULL, NULL, SECMOD_DB, &initParams, flags))) { rpt_err(GENERAL_FAILURE, getResourceString(DBT_INTERNAL_ERROR), getResourceString(DBT_OPEN_CERTDB_FAIL), @@ -1454,7 +1493,7 @@ installCACert(char *tokenName, char *certname) getResourceString(DBT_INSTALL_FAIL), line); } - if(NULL == PK11_FindCertInSlot(slot, cert, NULL)) { + if(CK_INVALID_HANDLE == PK11_FindCertInSlot(slot, cert, NULL)) { errorRpt(GENERAL_FAILURE, getResourceString(DBT_INSTALL_FAIL)); } @@ -2042,6 +2081,13 @@ int main(int argc, char *argv[]) errorRpt(FILE_ERROR, line); } +#ifdef DUMP_CACHE_INFO + if (NSS_IsInitialized()) { + printf("nss_DumpCertificateCacheInfo 1\n"); + nss_DumpCertificateCacheInfo(); + } +#endif + if(ADMSSL_InitSimple((char *)configdir, (char *)secdir, 1)) { errorRpt(SYSTEM_ERROR, getResourceString(CMN_SSL_INIT_ERROR)); } @@ -2070,7 +2116,7 @@ int main(int argc, char *argv[]) /* we got here, we think sie is a valid prefix */ /* close all db - we may have had to open the admin server key/cert db in order to use LDAPS before - now have to shut down NSS and reinit */ - closeAllSecurityDB(); + closeAllSecurityDB(0); securityInitialization(securitydir); if (!PORT_Strcmp(operation, "LIST_CERTIFICATE")) { @@ -2192,7 +2238,7 @@ int main(int argc, char *argv[]) errorRpt(INCORRECT_USAGE, line); } /* close all db */ - closeAllSecurityDB(); + closeAllSecurityDB(1); } }