rpc: avoid possible recursion in create_connection

There was a recursion in RPCClient.create_connection() which under rare
circumstances would not have an ending condition. This commit removes
it and cleans up the code a bit as well.

https://pagure.io/freeipa/issue/6796

Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
Stanislav Laznicka authored and Martin Basti committed 2017-06-02 16:43:02 +02:00
1 parent 79d1752577
commit e1f8684e85
1 file changed
+25 -17
+25 -17
View File
@@ -999,13 +999,18 @@ class RPCClient(Connectible):
# No session key, do full Kerberos auth
pass
urls = self.get_url_list(rpc_uri)
serverproxy = None
for url in urls:
kw = {
proxy_kw = {
'allow_none': True,
'encoding': 'UTF-8',
'verbose': verbose
}
for url in urls:
# should we get ProtocolError (=> error in HTTP response) and
# 401 (=> Unauthorized), we'll be re-trying with new session
# cookies several times
for _try_num in range(0, 5):
if url.startswith('https://'):
if delegate:
transport_class = DelegatedKerbTransport
@@ -1013,11 +1018,11 @@ class RPCClient(Connectible):
transport_class = KerbTransport
else:
transport_class = LanguageAwareTransport
kw['transport'] = transport_class(protocol=self.protocol,
service='HTTP', ccache=ccache)
proxy_kw['transport'] = transport_class(
protocol=self.protocol, service='HTTP', ccache=ccache)
self.log.info('trying %s' % url)
setattr(context, 'request_url', url)
serverproxy = self.server_proxy_class(url, **kw)
serverproxy = self.server_proxy_class(url, **proxy_kw)
if len(urls) == 1:
# if we have only 1 server and then let the
# main requester handle any errors. This also means it
@@ -1039,7 +1044,7 @@ class RPCClient(Connectible):
server=url,
)
# We don't care about the response, just that we got one
break
return serverproxy
except errors.KerberosError:
# kerberos error on one server is likely on all
raise
@@ -1050,26 +1055,29 @@ class RPCClient(Connectible):
try:
delete_persistent_client_session_data(principal)
except Exception:
# This shouldn't happen if we have a session but it isn't fatal.
# This shouldn't happen if we have a session but
# it isn't fatal.
pass
return self.create_connection(
ccache, verbose, fallback, delegate)
# try the same url once more with a new session cookie
continue
if not fallback:
raise
else:
self.log.info('Connection to %s failed with %s', url, e)
serverproxy = None
self.log.info(
'Connection to %s failed with %s', url, e)
# try the next url
break
except Exception as e:
if not fallback:
raise
else:
self.log.info('Connection to %s failed with %s', url, e)
serverproxy = None
if serverproxy is None:
self.log.info(
'Connection to %s failed with %s', url, e)
# try the next url
break
# finished all tries but no serverproxy was found
raise NetworkError(uri=_('any of the configured servers'),
error=', '.join(urls))
return serverproxy
def destroy_connection(self):
conn = getattr(context, self.id, None)