diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/plugins/xmlclient.py | 29 | ||||
-rw-r--r-- | ipalib/rpc.py | 53 |
2 files changed, 81 insertions, 1 deletions
diff --git a/ipalib/plugins/xmlclient.py b/ipalib/plugins/xmlclient.py new file mode 100644 index 000000000..fa5afb553 --- /dev/null +++ b/ipalib/plugins/xmlclient.py @@ -0,0 +1,29 @@ +# Authors: +# Jason Gerard DeRose <jderose@redhat.com> +# Rob Crittenden <rcritten@redhat.com> +# +# Copyright (C) 2008 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 only +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +XML-RPC client plugin. +""" + +from ipalib import api + +if 'in_server' in api.env and api.env.in_server is False: + from ipalib.rpc import xmlclient + api.register(xmlclient) diff --git a/ipalib/rpc.py b/ipalib/rpc.py index e7823ef95..e845b8939 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -1,5 +1,6 @@ # Authors: # Jason Gerard DeRose <jderose@redhat.com> +# Rob Crittenden <rcritten@redhat.com> # # Copyright (C) 2008 Red Hat # see file 'COPYING' for use and warranty information @@ -31,7 +32,8 @@ Also see the `ipaserver.rpcserver` module. from types import NoneType import threading -from xmlrpclib import Binary, Fault, dumps, loads +from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy, SafeTransport +import kerberos from ipalib.backend import Backend from ipalib.errors2 import public_errors, PublicError, UnknownError from ipalib.request import context @@ -161,15 +163,62 @@ def xml_loads(data): return (xml_unwrap(params), method) +class KerbTransport(SafeTransport): + """ + Handles Kerberos Negotiation authentication to an XML-RPC server. + """ + + def get_host_info(self, host): + + (host, extra_headers, x509) = SafeTransport.get_host_info(self, host) + + # Set the remote host principal + service = "HTTP@" + host.split(':')[0] + + try: + (rc, vc) = kerberos.authGSSClientInit(service) + except kerberos.GSSError, e: + raise e # FIXME: raise a PublicError + + try: + kerberos.authGSSClientStep(vc, "") + except kerberos.GSSError, e: + raise e # FIXME: raise a PublicError + + extra_headers += [ + ('Authorization', 'negotiate %s' % kerberos.authGSSClientResponse(vc)) + ] + + return (host, extra_headers, x509) + + class xmlclient(Backend): """ Forwarding backend for XML-RPC client. """ + connection_name = 'xmlconn' + def __init__(self): super(xmlclient, self).__init__() self.__errors = dict((e.errno, e) for e in public_errors) + def connect(self, ccache=None, user=None, password=None): + if hasattr(context, self.connection_name): + raise StandardError( + '%s.connect(): context.%s already exists in thread %r' % ( + self.name, self.connection_name, threading.currentThread().getName() + ) + ) + conn = ServerProxy(self.env.xmlrpc_uri, + transport=KerbTransport(), + allow_none=True, + ) + setattr(context, self.connection_name, conn) + + def get_connection(self): + return getattr(context, self.connection_name) + def forward(self, name, *args, **kw): """ Forward call to command named ``name`` over XML-RPC. @@ -197,6 +246,8 @@ class xmlclient(Backend): response = command(xml_wrap(params)) return xml_unwrap(response) except Fault, e: + self.debug('Caught fault %d from server %s: %s', e.faultCode, + self.env.xmlrpc_uri, e.faultString) if e.faultCode in self.__errors: error = self.__errors[e.faultCode] raise error(message=e.faultString) |