summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/rpc.py34
-rw-r--r--ipapython/nsslib.py35
2 files changed, 42 insertions, 27 deletions
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index 5934f0c26..001b7f1ca 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -63,6 +63,7 @@ from ipaplatform.paths import paths
from ipapython.cookie import Cookie
from ipapython.dnsutil import DNSName
from ipalib.text import _
+import ipapython.nsslib
from ipapython.nsslib import NSSHTTPS, NSSConnection
from ipalib.krb_utils import KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, KRB5KRB_AP_ERR_TKT_EXPIRED, \
KRB5_FCC_PERM, KRB5_FCC_NOFILE, KRB5_CC_FORMAT, KRB5_REALM_CANT_RESOLVE
@@ -450,14 +451,10 @@ class LanguageAwareTransport(MultiProtocolTransport):
class SSLTransport(LanguageAwareTransport):
"""Handles an HTTPS transaction to an XML-RPC server."""
- def __nss_initialized(self, dbdir):
+ def get_connection_dbdir(self):
"""
- If there is another connections open it may have already
- initialized NSS. This is likely to lead to an NSS shutdown
- failure. One way to mitigate this is to tell NSS to not
- initialize if it has already been done in another open connection.
-
- Returns True if another connection is using the same db.
+ If there is a connections open it may have already initialized
+ NSS database. Return the database location used by the connection.
"""
for value in context.__dict__.values():
if not isinstance(value, Connection):
@@ -466,25 +463,32 @@ class SSLTransport(LanguageAwareTransport):
getattr(value.conn, '_ServerProxy__transport', None),
SSLTransport):
continue
- if hasattr(value.conn._ServerProxy__transport, 'dbdir') and \
- value.conn._ServerProxy__transport.dbdir == dbdir:
- return True
- return False
+ if hasattr(value.conn._ServerProxy__transport, 'dbdir'):
+ return value.conn._ServerProxy__transport.dbdir
+ return None
def make_connection(self, host):
host, self._extra_headers, x509 = self.get_host_info(host)
# Python 2.7 changed the internal class used in xmlrpclib from
# HTTP to HTTPConnection. We need to use the proper subclass
- # If we an existing connection exists using the same NSS database
- # there is no need to re-initialize. Pass thsi into the NSS
- # connection creator.
if sys.version_info >= (2, 7):
if self._connection and host == self._connection[0]:
return self._connection[1]
dbdir = getattr(context, 'nss_dir', paths.IPA_NSSDB_DIR)
- no_init = self.__nss_initialized(dbdir)
+ connection_dbdir = self.get_connection_dbdir()
+
+ if connection_dbdir:
+ # If an existing connection is already using the same NSS
+ # database there is no need to re-initialize.
+ no_init = dbdir == connection_dbdir
+
+ else:
+ # If the NSS database is already being used there is no
+ # need to re-initialize.
+ no_init = dbdir == ipapython.nsslib.current_dbdir
+
if sys.version_info < (2, 7):
conn = NSSHTTPS(host, 443, dbdir=dbdir, no_init=no_init)
else:
diff --git a/ipapython/nsslib.py b/ipapython/nsslib.py
index 93b0c56fc..1452a2a58 100644
--- a/ipapython/nsslib.py
+++ b/ipapython/nsslib.py
@@ -31,6 +31,9 @@ import nss.ssl as ssl
import nss.error as error
from ipaplatform.paths import paths
+# NSS database currently open
+current_dbdir = None
+
def auth_certificate_callback(sock, check_sig, is_server, certdb):
cert_is_valid = False
@@ -184,19 +187,27 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback):
httplib.HTTPConnection.__init__(self, host, port, strict)
NSSAddressFamilyFallback.__init__(self, family)
- if not dbdir:
- raise RuntimeError("dbdir is required")
-
root_logger.debug('%s init %s', self.__class__.__name__, host)
- if not no_init and nss.nss_is_initialized():
- # close any open NSS database and use the new one
- ssl.clear_session_cache()
- try:
- nss.nss_shutdown()
- except NSPRError, e:
- if e.errno != error.SEC_ERROR_NOT_INITIALIZED:
- raise e
- nss.nss_init(dbdir)
+
+ # If initialization is requested, initialize the new database.
+ if not no_init:
+
+ if nss.nss_is_initialized():
+ ssl.clear_session_cache()
+ try:
+ nss.nss_shutdown()
+ except NSPRError, e:
+ if e.errno != error.SEC_ERROR_NOT_INITIALIZED:
+ raise e
+
+ if not dbdir:
+ raise RuntimeError("dbdir is required")
+
+ nss.nss_init(dbdir)
+
+ global current_dbdir
+ current_dbdir = dbdir
+
ssl.set_domestic_policy()
nss.set_password_callback(self.password_callback)