Martin Kosek wrote:
On 10/02/2012 08:23 PM, Rob Crittenden wrote:
Clear the host session key when enrolling a client.

Make sure dbdir is preserved when a new connection is created.

rob


I tested repeatedly installing, uninstalling client and unlike previously, I
did not receive any NSS initialization error. Other test were also OK for me,
so generally I agree with the patch.

I just see one potential issue in this section:


+                if (current_conn is not None and
+                  hasattr(current_conn.conn._ServerProxy__transport, 'dbdir')):
+                    dbdir = current_conn.conn._ServerProxy__transport.dbdir
+                    self.debug('Using dbdir %s' % dbdir)

If I understand that correctly, dbdir attribute in
current_conn.conn._ServerProxy__transport may be changed by other thread, i.e.
I would rather do something like that:

if current_conn is not None:
     dbdir = getattr(current_conn.conn._ServerProxy__transport, 'dbdir', None)
     if dbdir is not None:
         self.debug('Using dbdir %s' % dbdir)

I did not reproduce that, but I'd be afraid that some other thread may remove
'dbdir' right after our hasattr check, so the next statement would fail.

Martin

Good idea, can't be too safe.

rob


>From ea5cfb68005d276f00d4c575a976a3f874164368 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Mon, 1 Oct 2012 13:05:11 -0400
Subject: [PATCH] Clear kernel keyring in client installer, save dbdir on new
 connections

This patch addresses two issues:

1. If a client is previously enrolled in an IPA server and the server
   gets re-installed then the client machine may still have a keyring
   entry for the old server. This can cause a redirect from the
   session URI to the negotiate one. As a rule, always clear the keyring
   when enrolling a new client.

2. We save the NSS dbdir in the connection so that when creating a new
   session we can determine if we need to re-initialize NSS or not. Most
   of the time we do not. The dbdir was not always being preserved between
   connections which could cause an NSS_Shutdown() to happen which would
   fail because of existing usage. This preserves the dbdir information when
   a new connection is created as part of the session mechanism.

https://fedorahosted.org/freeipa/ticket/3108
---
 ipa-client/ipa-install/ipa-client-install | 11 ++++++++++-
 ipalib/rpc.py                             | 15 +++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index ee8e5831866e1f5d960cbbca290606a944b0f357..7b057a9878c566343d606ea7399cc9e4509e65b6 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -42,6 +42,8 @@ try:
     from ipalib import api, errors
     from ipapython.dn import DN
     from ipapython.ssh import SSHPublicKey
+    from ipapython import kernel_keyring
+    from ipalib.rpc import COOKIE_NAME
     import SSSDConfig
     from ConfigParser import RawConfigParser
     from optparse import SUPPRESS_HELP, OptionGroup
@@ -1666,13 +1668,14 @@ def install(options, env, fstore, statestore):
         root_logger.info("Failed to add CA to the default NSS database.")
         return CLIENT_INSTALL_ERROR
 
+    host_principal = 'host/%s@%s' % (hostname, cli_realm)
     if options.on_master:
         # If on master assume kerberos is already configured properly.
         # Get the host TGT.
         os.environ['KRB5CCNAME'] = CCACHE_FILE
         try:
             run(['/usr/bin/kinit', '-k', '-t', '/etc/krb5.keytab',
-                    'host/%s@%s' % (hostname, cli_realm)])
+                    host_principal])
         except CalledProcessError, e:
             root_logger.error("Failed to obtain host TGT.")
             return CLIENT_INSTALL_ERROR
@@ -1693,6 +1696,12 @@ def install(options, env, fstore, statestore):
         root_logger.info(
             "Configured /etc/krb5.conf for IPA realm %s", cli_realm)
 
+    # Clear out any current session keyring information
+    try:
+        kernel_keyring.del_key(COOKIE_NAME % host_principal)
+    except ValueError:
+        pass
+
     # Now, let's try to connect to the server's XML-RPC interface
     try:
         api.Backend.xmlclient.connect()
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index fc135f4f6a1bc4e98e3c4c3bbf6857b98fdc94db..e97536d9de5c455d3ff58c081fca37f16d087370 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -546,8 +546,23 @@ class xmlclient(Connectible):
                     # This shouldn't happen if we have a session but
                     # it isn't fatal.
                     pass
+
+                # Create a new serverproxy with the non-session URI. If there
+                # is an existing connection we need to save the NSS dbdir so
+                # we can skip an unnecessary NSS_Initialize() and avoid
+                # NSS_Shutdown issues.
                 serverproxy = self.create_connection(os.environ.get('KRB5CCNAME'), self.env.verbose, self.env.fallback, self.env.delegate)
+
+                dbdir = None
+                current_conn = getattr(context, self.id, None)
+                if current_conn is not None:
+                    dbdir = getattr(current_conn.conn._ServerProxy__transport, 'dbdir', None)
+                    if dbdir is not None:
+                        self.debug('Using dbdir %s' % dbdir)
                 setattr(context, self.id, Connection(serverproxy, self.disconnect))
+                if dbdir is not None:
+                    current_conn = getattr(context, self.id, None)
+                    current_conn.conn._ServerProxy__transport.dbdir = dbdir
                 return self.forward(name, *args, **kw)
             raise NetworkError(uri=server, error=e.errmsg)
         except socket.error, e:
-- 
1.7.11.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to