diff options
-rwxr-xr-x | ipa-client/ipa-install/ipa-client-install | 5 | ||||
-rw-r--r-- | ipalib/rpc.py | 31 | ||||
-rw-r--r-- | ipapython/nsslib.py | 13 |
3 files changed, 42 insertions, 7 deletions
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install index 99b5137f..22c6a925 100755 --- a/ipa-client/ipa-install/ipa-client-install +++ b/ipa-client/ipa-install/ipa-client-install @@ -179,6 +179,7 @@ def nssldap_exists(): def emit_quiet(quiet, message): if not quiet: print message + root_logger.debug(message) def uninstall(options, env, quiet=False): @@ -1033,6 +1034,7 @@ def update_ssh_keys(server, hostname, ssh_dir, create_sshfp): except StandardError, e: root_logger.warning("host_mod: %s" % str(e)) print >>sys.stderr, "Failed to upload host SSH public keys." + root_logger.debug('Failed to upload host SSH public keys.') return if create_sshfp: @@ -1326,7 +1328,6 @@ def install(options, env, fstore, statestore): if 'config_loaded' not in api.env: print >>sys.stderr, "Failed to initialize IPA API." return CLIENT_INSTALL_ERROR - api.Backend.xmlclient.connect() # Always back up sssd.conf. It gets updated by authconfig --enablekrb5. fstore.backup_file("/etc/sssd/sssd.conf") @@ -1350,6 +1351,7 @@ def install(options, env, fstore, statestore): os.environ['KRB5CCNAME'] = CCACHE_FILE try: ipautil.run(['/usr/bin/kinit', '-k', '-t', '/etc/krb5.keytab', 'host/%s' % hostname]) + api.Backend.xmlclient.connect() except CalledProcessError, e: print >>sys.stderr, "Failed to obtain host TGT." @@ -1480,6 +1482,7 @@ def install(options, env, fstore, statestore): configure_ssh(fstore, ipaservices.knownservices.sshd.get_config_dir(), options) print "Client configuration complete." + root_logger.debug('Client configuration complete.') return 0 diff --git a/ipalib/rpc.py b/ipalib/rpc.py index d8fee563..16c095cb 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -42,7 +42,7 @@ import kerberos from ipalib.backend import Connectible from ipalib.errors import public_errors, PublicError, UnknownError, NetworkError, KerberosError, XMLRPCMarshallError from ipalib import errors -from ipalib.request import context +from ipalib.request import context, Connection from ipapython import ipautil, dnsclient import httplib import socket @@ -215,16 +215,39 @@ class LanguageAwareTransport(Transport): class SSLTransport(LanguageAwareTransport): """Handles an HTTPS transaction to an XML-RPC server.""" + def __nss_initialized(self, dbdir): + """ + 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. + """ + for value in context.__dict__.values(): + if not isinstance(value, Connection): + continue + if not isinstance(value.conn._ServerProxy__transport, SSLTransport): + continue + if value.conn._ServerProxy__transport.dbdir == dbdir: + return True + return False + def make_connection(self, host): host, self._extra_headers, x509 = self.get_host_info(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. + self.dbdir='/etc/pki/nssdb' + no_init = self.__nss_initialized(self.dbdir) (major, minor, micro, releaselevel, serial) = sys.version_info if major == 2 and minor < 7: - conn = NSSHTTPS(host, 443, dbdir="/etc/pki/nssdb") + conn = NSSHTTPS(host, 443, dbdir=self.dbdir, no_init=no_init) else: - conn = NSSConnection(host, 443, dbdir="/etc/pki/nssdb") + conn = NSSConnection(host, 443, dbdir=self.dbdir, no_init=no_init) conn.connect() return conn diff --git a/ipapython/nsslib.py b/ipapython/nsslib.py index 22555193..cc6ab1de 100644 --- a/ipapython/nsslib.py +++ b/ipapython/nsslib.py @@ -190,7 +190,16 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback): default_port = httplib.HTTPSConnection.default_port def __init__(self, host, port=None, strict=None, - dbdir=None, family=socket.AF_UNSPEC): + dbdir=None, family=socket.AF_UNSPEC, no_init=False): + """ + :param host: the server to connect to + :param port: the port to use (default is set in HTTPConnection) + :param dbdir: the NSS database directory + :param family: network family to use (default AF_UNSPEC) + :param no_init: do not initialize the NSS database. This requires + that the database has already been initialized or + the request will fail. + """ httplib.HTTPConnection.__init__(self, host, port, strict) NSSAddressFamilyFallback.__init__(self, family) @@ -198,7 +207,7 @@ class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback): raise RuntimeError("dbdir is required") root_logger.debug('%s init %s', self.__class__.__name__, host) - if nss.nss_is_initialized(): + if not no_init and nss.nss_is_initialized(): # close any open NSS database and use the new one ssl.clear_session_cache() try: |