#!/usr/bin/env python import sys, os import getopt, syslog import pwd, grp import Backend, Pivot, Config SCRIPT = "slapd-pivot" USER = None GROUP = None PIDFILE = None class Log: def __init__(self): syslog.openlog('slapd-pivot') def write(self, string): string = string.encode("utf-8", "replace").strip("\n\r") if string: syslog.syslog(syslog.LOG_WARNING | syslog.LOG_DAEMON, string) def flush(self): pass def failure(msg, details = None): if details: msg += ": " + details print >> sys.stderr, "%s: %s" % (SCRIPT, msg) sys.exit(1) def usage(): print >> sys.stderr, "usage: %s -f config [-d level] [-g group] [-p pidfile] [-u user]" % SCRIPT sys.exit(2) def run_server(): server = Backend.Server("/tmp/pivot-slapd.sock", Pivot.Database) try: print >> sys.stderr, "%s starting up..." % SCRIPT server.serve_forever() except KeyboardInterrupt: sys.exit(0) def drop_privileges(): global GROUP, USER if GROUP: try: GROUP = int(GROUP) except ValueError: try: GROUP = grp.getgrgid(GROUP)[2] except KeyError: failure("invalid group: %s" % GROUP) os.setegid(GROUP) if USER: try: USER = int(USER) except ValueError: try: USER = pwd.getpwnam(USER)[2] except KeyError: failure("invalid user: %s" % USER) os.seteuid(USER) def daemon(): # do the UNIX double-fork magic, see Stevens' "Advanced # Programming in the UNIX Environment" for details (ISBN 0201563177) try: pid = os.fork() if pid > 0: # exit first parent sys.exit(0) except OSError, e: failure("couldn't fork to daemon", e.strerror) # decouple from parent environment os.setsid() os.umask(0) # do second fork try: pid = os.fork() if pid > 0: # exit from second parent, print eventual PID before if PIDFILE: open(PIDFILE,'w').write("%d" % pid) sys.exit(0) except OSError, e: failure("couldn't fork to daemon", e.strerror) os.chdir("/") sys.stderr = Log() if __name__ == '__main__': daemonize = True config = "/usr/local/etc/slapd-pivot.conf" try: opts, args = getopt.getopt(sys.argv[1:], 'd:f:g:p:u:') except getopt.GetoptError: usage() for (opt, oarg) in opts: if opt == "-d": try: daemonize = False level = int(oarg) if level >= 4: Backend.debug = True except: failure("invalid debug level", oarg) elif opt == '-f': config = oarg elif opt == '-g': GROUP = oarg elif opt == '-p': PIDFILE = oarg elif opt == '-u': USER = oarg # No extra arguments if args: usage() try: # Load up our config file Config.load(config) except Config.Error, ex: failure(str(ex)) # Change to a user that was specified drop_privileges() # Become a daemon if requested if daemonize: daemon() # And off we go run_server()