示例#1
0
    def forward(self, name, *args, **kw):
        """
        Forward call to command named ``name`` over XML-RPC.

        This method will encode and forward an XML-RPC request, and will then
        decode and return the corresponding XML-RPC response.

        :param command: The name of the command being forwarded.
        :param args: Positional arguments to pass to remote command.
        :param kw: Keyword arguments to pass to remote command.
        """
        server = getattr(context, 'request_url', None)
        self.log.info("Forwarding '%s' to %s server '%s'", name, self.protocol,
                      server)
        command = getattr(self.conn, name)
        params = [args, kw]
        try:
            return self._call_command(command, params)
        except Fault as e:
            e = decode_fault(e)
            self.debug('Caught fault %d from server %s: %s', e.faultCode,
                       server, e.faultString)
            if e.faultCode in errors_by_code:
                error = errors_by_code[e.faultCode]
                raise error(message=e.faultString)
            raise UnknownError(
                code=e.faultCode,
                error=e.faultString,
                server=server,
            )
        except SSLError as e:
            raise NetworkError(uri=server, error=str(e))
        except ProtocolError as e:
            # By catching a 401 here we can detect the case where we have
            # a single IPA server and the session is invalid. Otherwise
            # we always have to do a ping().
            session_cookie = getattr(context, 'session_cookie', None)
            if session_cookie and e.errcode == 401:
                # Unauthorized. Remove the session and try again.
                delattr(context, 'session_cookie')
                try:
                    principal = getattr(context, 'principal', None)
                    delete_persistent_client_session_data(principal)
                except Exception as e:
                    # This shouldn't happen if we have a session but it isn't fatal.
                    pass

                # Create a new serverproxy with the non-session URI
                serverproxy = self.create_connection(
                    os.environ.get('KRB5CCNAME'), self.env.verbose,
                    self.env.fallback, self.env.delegate)
                setattr(context, self.id,
                        Connection(serverproxy, self.disconnect))
                return self.forward(name, *args, **kw)
            raise NetworkError(uri=server, error=e.errmsg)
        except socket.error as e:
            raise NetworkError(uri=server, error=str(e))
        except (OverflowError, TypeError) as e:
            raise XMLRPCMarshallError(error=str(e))
示例#2
0
                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:
            raise NetworkError(uri=server, error=str(e))
        except (OverflowError, TypeError), e:
            raise XMLRPCMarshallError(error=str(e))


class xmlclient(RPCClient):
    session_path = '/ipa/session/xml'
    server_proxy_class = ServerProxy
    protocol = 'xml'
    env_rpc_uri_key = 'xmlrpc_uri'

    def _call_command(self, command, params):
        version = params[1].get('version', VERSION_WITHOUT_CAPABILITIES)
        params = xml_wrap(params, version)
        result = command(*params)
        return xml_unwrap(result)