|
|
403b09 |
From 96bb5ecac07255fd4b6149c617c5ef23b7e7c84f Mon Sep 17 00:00:00 2001
|
|
|
403b09 |
From: Jan Cholasta <jcholast@redhat.com>
|
|
|
403b09 |
Date: Mon, 29 Aug 2016 14:49:44 +0200
|
|
|
403b09 |
Subject: [PATCH] rpcserver: assume version 1 for unversioned command calls
|
|
|
403b09 |
|
|
|
403b09 |
When a command is called on the server over RPC without its version
|
|
|
403b09 |
specified, assume version 1 instead of the highest known version.
|
|
|
403b09 |
|
|
|
403b09 |
This ensures backward compatibility with old clients, which do not support
|
|
|
403b09 |
versioned commands and understand only the first version of any given
|
|
|
403b09 |
command.
|
|
|
403b09 |
|
|
|
403b09 |
https://fedorahosted.org/freeipa/ticket/6217
|
|
|
403b09 |
|
|
|
403b09 |
Reviewed-By: David Kupka <dkupka@redhat.com>
|
|
|
403b09 |
---
|
|
|
403b09 |
ipaserver/rpcserver.py | 43 +++++++++++++++++++++++++++----------------
|
|
|
403b09 |
1 file changed, 27 insertions(+), 16 deletions(-)
|
|
|
403b09 |
|
|
|
403b09 |
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
|
|
|
403b09 |
index e48dc3498d6ed8feb6ea44a9a678a8b8c50e8d9b..dd446ae849076d350c97ce9cd6c5a704783f39c0 100644
|
|
|
403b09 |
--- a/ipaserver/rpcserver.py
|
|
|
403b09 |
+++ b/ipaserver/rpcserver.py
|
|
|
403b09 |
@@ -42,7 +42,7 @@ from ipalib import plugable, errors
|
|
|
403b09 |
from ipalib.capabilities import VERSION_WITHOUT_CAPABILITIES
|
|
|
403b09 |
from ipalib.frontend import Local
|
|
|
403b09 |
from ipalib.backend import Executioner
|
|
|
403b09 |
-from ipalib.errors import (PublicError, InternalError, CommandError, JSONError,
|
|
|
403b09 |
+from ipalib.errors import (PublicError, InternalError, JSONError,
|
|
|
403b09 |
CCacheError, RefererError, InvalidSessionPassword, NotFound, ACIError,
|
|
|
403b09 |
ExecutionError, PasswordExpired, KrbPrincipalExpired, UserLocked)
|
|
|
403b09 |
from ipalib.request import context, destroy_context
|
|
|
403b09 |
@@ -311,6 +311,21 @@ class WSGIExecutioner(Executioner):
|
|
|
403b09 |
if 'wsgi_dispatch' in self.api.Backend:
|
|
|
403b09 |
self.api.Backend.wsgi_dispatch.mount(self, self.key)
|
|
|
403b09 |
|
|
|
403b09 |
+ def __get_command(self, name):
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ # assume version 1 for unversioned command calls
|
|
|
403b09 |
+ command = self.api.Command[name, '1']
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ command = self.api.Command[name]
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ command = None
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if command is None or isinstance(command, Local):
|
|
|
403b09 |
+ raise errors.CommandError(name=name)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ return command
|
|
|
403b09 |
+
|
|
|
403b09 |
def wsgi_execute(self, environ):
|
|
|
403b09 |
result = None
|
|
|
403b09 |
error = None
|
|
|
403b09 |
@@ -319,6 +334,7 @@ class WSGIExecutioner(Executioner):
|
|
|
403b09 |
name = None
|
|
|
403b09 |
args = ()
|
|
|
403b09 |
options = {}
|
|
|
403b09 |
+ command = None
|
|
|
403b09 |
|
|
|
403b09 |
e = None
|
|
|
403b09 |
if not 'HTTP_REFERER' in environ:
|
|
|
403b09 |
@@ -345,11 +361,9 @@ class WSGIExecutioner(Executioner):
|
|
|
403b09 |
(name, args, options, _id) = self.simple_unmarshal(environ)
|
|
|
403b09 |
if name in self._system_commands:
|
|
|
403b09 |
result = self._system_commands[name](self, *args, **options)
|
|
|
403b09 |
- elif (name not in self.api.Command or
|
|
|
403b09 |
- isinstance(self.api.Command[name], Local)):
|
|
|
403b09 |
- raise CommandError(name=name)
|
|
|
403b09 |
else:
|
|
|
403b09 |
- result = self.Command[name](*args, **options)
|
|
|
403b09 |
+ command = self.__get_command(name)
|
|
|
403b09 |
+ result = command(*args, **options)
|
|
|
403b09 |
except PublicError as e:
|
|
|
403b09 |
if self.api.env.debug:
|
|
|
403b09 |
self.debug('WSGI wsgi_execute PublicError: %s', traceback.format_exc())
|
|
|
403b09 |
@@ -363,9 +377,9 @@ class WSGIExecutioner(Executioner):
|
|
|
403b09 |
os.environ['LANG'] = lang
|
|
|
403b09 |
|
|
|
403b09 |
principal = getattr(context, 'principal', 'UNKNOWN')
|
|
|
403b09 |
- if name and name in self.Command:
|
|
|
403b09 |
+ if command is not None:
|
|
|
403b09 |
try:
|
|
|
403b09 |
- params = self.Command[name].args_options_2_params(*args, **options)
|
|
|
403b09 |
+ params = command.args_options_2_params(*args, **options)
|
|
|
403b09 |
except Exception as e:
|
|
|
403b09 |
self.info(
|
|
|
403b09 |
'exception %s caught when converting options: %s', e.__class__.__name__, str(e)
|
|
|
403b09 |
@@ -380,7 +394,7 @@ class WSGIExecutioner(Executioner):
|
|
|
403b09 |
type(self).__name__,
|
|
|
403b09 |
principal,
|
|
|
403b09 |
name,
|
|
|
403b09 |
- ', '.join(self.Command[name]._repr_iter(**params)),
|
|
|
403b09 |
+ ', '.join(command._repr_iter(**params)),
|
|
|
403b09 |
result_string)
|
|
|
403b09 |
else:
|
|
|
403b09 |
self.info('[%s] %s: %s: %s',
|
|
|
403b09 |
@@ -698,24 +712,21 @@ class xmlserver(KerberosWSGIExecutioner):
|
|
|
403b09 |
# TODO
|
|
|
403b09 |
# for now let's not go out of our way to document standard XML-RPC
|
|
|
403b09 |
return u'undef'
|
|
|
403b09 |
- elif (method_name in self.api.Command and
|
|
|
403b09 |
- not isinstance(self.api.Command[method_name], Local)):
|
|
|
403b09 |
+ else:
|
|
|
403b09 |
+ self.__get_command(method_name)
|
|
|
403b09 |
+
|
|
|
403b09 |
# All IPA commands return a dict (struct),
|
|
|
403b09 |
# and take a params, options - list and dict (array, struct)
|
|
|
403b09 |
return [[u'struct', u'array', u'struct']]
|
|
|
403b09 |
- else:
|
|
|
403b09 |
- raise errors.CommandError(name=method_name)
|
|
|
403b09 |
|
|
|
403b09 |
def methodHelp(self, *params):
|
|
|
403b09 |
"""get method docstring for XML-RPC introspection"""
|
|
|
403b09 |
method_name = self._get_method_name('system.methodHelp', *params)
|
|
|
403b09 |
if method_name in self._system_commands:
|
|
|
403b09 |
return u''
|
|
|
403b09 |
- elif (method_name in self.api.Command and
|
|
|
403b09 |
- not isinstance(self.api.Command[method_name], Local)):
|
|
|
403b09 |
- return unicode(self.Command[method_name].doc or '')
|
|
|
403b09 |
else:
|
|
|
403b09 |
- raise errors.CommandError(name=method_name)
|
|
|
403b09 |
+ command = self.__get_command(method_name)
|
|
|
403b09 |
+ return unicode(command.doc or '')
|
|
|
403b09 |
|
|
|
403b09 |
_system_commands = {
|
|
|
403b09 |
'system.listMethods': listMethods,
|
|
|
403b09 |
--
|
|
|
403b09 |
2.7.4
|
|
|
403b09 |
|