mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
134 lines
3.9 KiB
Plaintext
134 lines
3.9 KiB
Plaintext
|
#!/usr/bin/env python
|
||
|
|
||
|
import sys
|
||
|
sys.path.insert(0, "..")
|
||
|
sys.path.insert(0, ".")
|
||
|
import SimpleXMLRPCServer
|
||
|
import logging
|
||
|
import xmlrpclib
|
||
|
import re
|
||
|
import threading
|
||
|
import commands
|
||
|
from ipalib import api, conn
|
||
|
from ipalib.conn import context
|
||
|
import ipalib.load_plugins
|
||
|
|
||
|
PORT=8888
|
||
|
|
||
|
class StoppableXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
|
||
|
"""Override of TIME_WAIT"""
|
||
|
allow_reuse_address = True
|
||
|
|
||
|
def serve_forever(self):
|
||
|
self.stop = False
|
||
|
while not self.stop:
|
||
|
self.handle_request()
|
||
|
|
||
|
class LoggingSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
|
||
|
"""Overides the default SimpleXMLRPCRequestHander to support logging.
|
||
|
Logs client IP and the XML request and response.
|
||
|
"""
|
||
|
|
||
|
def parse(self, given):
|
||
|
"""Convert the incoming arguments into the format IPA expects"""
|
||
|
args = []
|
||
|
kw = {}
|
||
|
for g in given:
|
||
|
kw[g] = unicode(given[g])
|
||
|
return (args, kw)
|
||
|
|
||
|
def _dispatch(self, method, params):
|
||
|
"""Dispatches the XML-RPC method.
|
||
|
|
||
|
Methods beginning with an '_' are considered private and will
|
||
|
not be called.
|
||
|
"""
|
||
|
if (params):
|
||
|
(args, kw) = self.parse(*params)
|
||
|
else:
|
||
|
args = []
|
||
|
kw = {}
|
||
|
|
||
|
# this is fine for our test server
|
||
|
uid = commands.getoutput('/usr/bin/id -u')
|
||
|
krbccache = "FILE:/tmp/krb5cc_" + uid
|
||
|
|
||
|
func = None
|
||
|
try:
|
||
|
# FIXME: don't hardcode host and port
|
||
|
context.conn = conn.IPAConn("localhost", 389, krbccache)
|
||
|
try:
|
||
|
# check to see if a matching function has been registered
|
||
|
func = funcs[method]
|
||
|
except KeyError:
|
||
|
raise Exception('method "%s" is not supported' % method)
|
||
|
return func(**kw)
|
||
|
finally:
|
||
|
# Clean up any per-request data and connections
|
||
|
for k in context.__dict__.keys():
|
||
|
del context.__dict__[k]
|
||
|
|
||
|
def do_POST(self):
|
||
|
clientIP, port = self.client_address
|
||
|
# Log client IP and Port
|
||
|
logger.info('Client IP: %s - Port: %s' % (clientIP, port))
|
||
|
try:
|
||
|
# get arguments
|
||
|
data = self.rfile.read(int(self.headers["content-length"]))
|
||
|
|
||
|
# unmarshal the XML data
|
||
|
params, method = xmlrpclib.loads(data)
|
||
|
|
||
|
# Log client request
|
||
|
logger.info('Client request: \n%s\n' % data)
|
||
|
|
||
|
response = self.server._marshaled_dispatch(
|
||
|
data, getattr(self, '_dispatch', None))
|
||
|
|
||
|
# Log server response
|
||
|
logger.info('Server response: \n%s\n' % response)
|
||
|
except:
|
||
|
# This should only happen if the module is buggy
|
||
|
# internal error, report as HTTP server error
|
||
|
self.send_response(500)
|
||
|
self.end_headers()
|
||
|
else:
|
||
|
# got a valid XML-RPC response
|
||
|
self.send_response(200)
|
||
|
self.send_header("Content-type", "text/xml")
|
||
|
self.send_header("Content-length", str(len(response)))
|
||
|
self.end_headers()
|
||
|
self.wfile.write(response)
|
||
|
|
||
|
# shut down the connection
|
||
|
self.wfile.flush()
|
||
|
self.connection.shutdown(1)
|
||
|
|
||
|
# Set up our logger
|
||
|
logger = logging.getLogger('xmlrpcserver')
|
||
|
hdlr = logging.FileHandler('xmlrpcserver.log')
|
||
|
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
|
||
|
hdlr.setFormatter(formatter)
|
||
|
logger.addHandler(hdlr)
|
||
|
logger.setLevel(logging.INFO)
|
||
|
|
||
|
# Set up the server
|
||
|
XMLRPCServer = StoppableXMLRPCServer(("",PORT), LoggingSimpleXMLRPCRequestHandler)
|
||
|
|
||
|
XMLRPCServer.register_introspection_functions()
|
||
|
|
||
|
# Get and register all the methods
|
||
|
api.finalize()
|
||
|
for cmd in api.Method:
|
||
|
logger.info("registering %s" % cmd)
|
||
|
XMLRPCServer.register_function(api.Method[cmd], cmd)
|
||
|
|
||
|
funcs = XMLRPCServer.funcs
|
||
|
|
||
|
print "Listening on port %d" % PORT
|
||
|
try:
|
||
|
XMLRPCServer.serve_forever()
|
||
|
except KeyboardInterrupt:
|
||
|
XMLRPCServer.server_close()
|
||
|
print "Server shutdown."
|