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))
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)