Ejemplo n.º 1
0
 def copyUIDs(self):
     """Copy EUID/EGID to UID/GID"""
     uid, gid = os.geteuid(), os.getegid()
     if uid != 0 and os.getuid() == 0:
         os.seteuid(0)
         os.setgid(gid)
         os.setuid(uid)
Ejemplo n.º 2
0
 def SetIDs_callback():
     if gid is not -1:
         os.setgroups([gid])
         os.setgid(gid)
     if uid is not -1:
         os.setuid(uid)
         os.environ["HOME"] = os.path.expanduser("~" + User)
Ejemplo n.º 3
0
        def preexec_fn():
            streams = [sys.stdin]

            if self.close_child_stdout:
                streams.append(sys.stdout)

            if self.close_child_stderr:
                streams.append(sys.stderr)

            self._null_streams(streams)
            os.setsid()

            for limit, value in self.rlimits.items():
                res = getattr(resource, 'RLIMIT_%s' % limit.upper(), None)
                if res is None:
                    raise ValueError('unknown rlimit "%s"' % limit)
                # TODO(petef): support hard/soft limits
                resource.setrlimit(res, (value, value))

            if self.gid:
                try:
                    os.setgid(self.gid)
                except OverflowError:
                    if not ctypes:
                        raise
                    # versions of python < 2.6.2 don't manage unsigned int for
                    # groups like on osx or fedora
                    os.setgid(-ctypes.c_int(-self.gid).value)

            if self.uid:
                os.setuid(self.uid)
Ejemplo n.º 4
0
def _chugid(runas):
    uinfo = pwd.getpwnam(runas)

    if os.getuid() == uinfo.pw_uid and os.getgid() == uinfo.pw_gid:
        # No need to change user or group
        return

    # No logging can happen on this function
    #
    # 08:46:32,161 [salt.loaded.int.module.cmdmod:276 ][DEBUG   ] stderr: Traceback (most recent call last):
    #   File "/usr/lib/python2.7/logging/__init__.py", line 870, in emit
    #     self.flush()
    #   File "/usr/lib/python2.7/logging/__init__.py", line 832, in flush
    #     self.stream.flush()
    # IOError: [Errno 9] Bad file descriptor
    # Logged from file cmdmod.py, line 59
    # 08:46:17,481 [salt.loaded.int.module.cmdmod:59  ][DEBUG   ] Switching user 0 -> 1008 and group 0 -> 1012 if needed
    #
    # apparently because we closed fd's on Popen, though if not closed, output
    # would also go to it's stderr

    if os.getgid() != uinfo.pw_gid:
        try:
            os.setgid(uinfo.pw_gid)
        except OSError, err:
            raise CommandExecutionError(
                'Failed to change from gid {0} to {1}. Error: {2}'.format(
                    os.getgid(), uinfo.pw_gid, err
                )
            )
Ejemplo n.º 5
0
    def drop_privileges(self, uid_name=None, gid_name=None):
        """ Drop privileges
        
        Found in https://github.com/zedshaw/python-lust/blob/master/lust/unix.py
        """
        if os.getuid() != 0:
            self.logger.warning("Must be root to drop privileges!")
            return
    
        # Get the uid/gid from the name. If no group given, then derive group from uid_name
        if uid_name is None:
            uid_name = "nobody"  # builtin default is nobody
        running_uid = pwd.getpwnam(uid_name).pw_uid
        if gid_name is None:
            running_gid = pwd.getpwnam(uid_name).pw_gid
        else:
            running_gid = grp.getgrnam(gid_name).gr_gid

        self.logger.debug("Running as %r.%r" % (running_uid, running_gid))
    
        # Remove group privileges
        os.setgroups([])
    
        # Try setting the new uid/gid
        os.setgid(running_gid)
        os.setuid(running_uid)
    
        # Ensure a very conservative umask
        os.umask(077)
Ejemplo n.º 6
0
    def lookup(self, params):
        if self.gid >= 0:
            os.setgid(self.gid)
        if self.uid >= 0:
            os.setuid(self.uid)

        try:
            user, domain = params['username'].split('@', 1)
        except ValueError:
            user, domain = params['username'], self.defaultdomain

        def repl(m):
            l = m.group(2)
            r = m.group(3)
            c = m.group(4)
            if c == '%':
                return '%'
            elif c == 'u':
                s = user
            elif c == 'd':
                s = domain
            if l:
                l = int(l)
                if r:
                    r = int(r[1:])
                    return s[l:l+r]
                else:
                    return s[:l]
            else:
                return s
        username = path_re.sub(repl, self.path)
        return username
Ejemplo n.º 7
0
    def shell(self):
        self.callee = utils.User(name='nobody')

        assert self.callee is not None

        try:
            os.chdir(self.path or self.callee.dir)
        except:
            pass

        env = os.environ
        # User has been auth with ssl or is the same user as server
        # or login is explicitly turned off
        if (
                not tornado.options.options.unsecure and
                tornado.options.options.login and not (
                    self.socket.local and
                    self.caller == self.callee and
                    server == self.callee
                )):
            # User is authed by ssl, setting groups
            try:
                os.initgroups(self.callee.name, self.callee.gid)
                os.setgid(self.callee.gid)
                os.setuid(self.callee.uid)
            except:
                print('The server must be run as root '
                      'if you want to log as different user\n')
                sys.exit(1)

        args = [tornado.options.options.shell or self.callee.shell]
        args.append('-q')
        args.append('--lf')
        args.append('/dev/pts/2')
        os.execvpe(args[0], args, env)
Ejemplo n.º 8
0
def drop_privileges():
  """Drop root privileges down to the specified SETUID_USER.

  N.B. DO NOT USE THE logging MODULE FROM WITHIN THIS FUNCTION.
  This function is run in forked processes right before it calls
  exec, but the fork may have occured while a different thread
  had locked the log. Since it's a forked process, the log will
  be locked forever in the subprocess and thus a logging.X may
  block forever.
  """
  we_are_root = os.getuid() == 0
  if not we_are_root:
    print >>sys.stdout, "[INFO] Not running as root, skipping privilege drop"
    return

  try:
    pw = pwd.getpwnam(SETUID_USER)
  except:
    print >>sys.stderr, "[ERROR] Couldn't get user information for user " + SETUID_USER
    raise

  try:
    gr = grp.getgrnam(SETGID_GROUP)
  except:
    print >>sys.stderr, "[ERROR] Couldn't get group information for group " + SETGID_GROUP
    raise

  # gid has to be set first
  os.setgid(gr.gr_gid)
  os.setuid(pw.pw_uid)
Ejemplo n.º 9
0
def check_user(user, log):
    '''
    Check user and assign process uid/gid.
    '''
    if 'os' in os.environ:
        if os.environ['os'].startswith('Windows'):
            return True
    if user == getpass.getuser():
        return True
    import pwd  # after confirming not running Windows
    try:
        p = pwd.getpwnam(user)
        try:
            os.setgid(p.pw_gid)
            os.setuid(p.pw_uid)
        except OSError:
            if user == 'root':
                msg = 'Sorry, the salt must run as root.  http://xkcd.com/838'
            else:
                msg = 'Salt must be run from root or user "{0}"'.format(user)
            log.critical(msg)
            return False
    except KeyError:
        msg = 'User not found: "{0}"'.format(user)
        log.critical(msg)
        return False
    return True
Ejemplo n.º 10
0
	def drop_privileges (self):
		"""returns true if we are left with insecure privileges"""
		# os.name can be ['posix', 'nt', 'os2', 'ce', 'java', 'riscos']
		if os.name not in ['posix',]:
			return False

		uid = os.getuid()
		gid = os.getgid()

		if uid and gid:
			return False

		try:
			user = pwd.getpwnam(self.user)
			nuid = int(user.pw_uid)
			ngid = int(user.pw_uid)
		except KeyError:
			return True

		# not sure you can change your gid if you do not have a pid of zero
		try:
			if not gid:
				os.setgid(ngid)
			if not uid:
				os.setuid(nuid)
			return False
		except OSError:
			return True
Ejemplo n.º 11
0
    def change_uid(self):
        c_user =  self.config.uid
        c_group = self.config.gid

        if os.getuid() == 0:
            cpw = pwd.getpwnam(c_user)
            c_uid = cpw.pw_uid
            if c_group:
                cgr = grp.getgrnam(c_group)
                c_gid = cgr.gr_gid
            else:
                c_gid = cpw.pw_gid

            c_groups = []
            for item in grp.getgrall():
                if c_user in item.gr_mem:
                    c_groups.append(item.gr_gid)
                if c_gid not in c_groups:
                    c_groups.append(c_gid)

            os.chown(self.config.datadir, c_uid, c_gid)
            os.chown(self.config.rundir, c_uid, c_gid)
            os.chown(self.config.pidfile, c_uid, c_gid)

            for root, _, filenames in os.walk(self.config.datadir):
                for filename in filenames:
                    os.chown(os.path.join(root, filename), c_uid, c_gid)

            for root, _, filenames in os.walk(self.config.rundir):
                for filename in filenames:
                    os.chown(os.path.join(root, filename), c_uid, c_gid)

            os.setgid(c_gid)
            os.setgroups(c_groups)
            os.setuid(c_uid)
Ejemplo n.º 12
0
def setgid(group):
    if group is None:
        return
    if not hasattr(os, 'setgid'):
        return

    # if root, setgid to the running user
    if os.getuid():
        print _('WARNING: ignoring "-g" argument, not root')
        return

    try:
        import grp
    except ImportError:
        raise ValueError, _("Can't change groups - no grp module")
    try:
        try:
            gid = int(group)
        except ValueError:
            gid = grp.getgrnam(group)[2]
        else:
            grp.getgrgid(gid)
    except KeyError:
        raise ValueError,_("Group %(group)s doesn't exist")%locals()
    os.setgid(gid)
Ejemplo n.º 13
0
def change_user(uid, gid, euid=False):
    # TODO: validate uid/gid, do root checks, etc.
    os.setgid(gid)
    if not euid:
        os.setuid(uid)
    else:
        os.seteuid(uid)
Ejemplo n.º 14
0
 def __init__(self, config, config_files=None, config_dirs=None,
         managed=None):
     config = clcommon.config.update(DEFAULT_CONFIG, config)
     self.config, _args = clcommon.config.load(config, config_files,
         config_dirs, False)
     config = self.config['clcommon']['server']
     if config['daemonize']:
         if os.fork() > 0:
             exit(0)
         os.setsid()
         null = open('/dev/null')
         os.dup2(null.fileno(), 0)
         os.dup2(null.fileno(), 1)
         os.dup2(null.fileno(), 2)
     clcommon.log.setup(self.config)
     self._parent = os.getpid()
     if config['pid_file'] is not None:
         pid_file = open(config['pid_file'], 'w')
         pid_file.write('%d' % self._parent)
     if config['group'] is not None:
         os.setgid(grp.getgrnam(config['group']).gr_gid)
     if config['user'] is not None:
         os.setuid(pwd.getpwnam(config['user']).pw_uid)
     self.log = clcommon.log.get_log('clcommon_server', config['log_level'])
     self._children = {}
     self._stopping = False
     if managed is None:
         self.managed = []
     else:
         self.managed = [method(self.config) for method in managed]
Ejemplo n.º 15
0
def change_process_owner(uid, gid, initgroups=False):
    """ Change the owning UID, GID, and groups of this process.
        :param uid: The target UID for the daemon process.
        :param gid: The target GID for the daemon process.
        :param initgroups: If true, initialise the supplementary
            groups of the process.
        :return: ``None``.
        Sets the owning GID and UID of the process (in that order, to
        avoid permission errors) to the specified `gid` and `uid`
        values.
        If `initgroups` is true, the supplementary groups of the
        process are also initialised, with those corresponding to the
        username for the target UID.
        All these operations require appropriate OS privileges. If
        permission is denied, a ``DaemonOSEnvironmentError`` is
        raised.
        """
    try:
        username = get_username_for_uid(uid)
    except KeyError:
        # We don't have a username to pass to ‘os.initgroups’.
        initgroups = False
    try:
        if initgroups:
            os.initgroups(username, gid)
        else:
            os.setgid(gid)
        os.setuid(uid)
    except Exception as exc:
        error = DaemonOSEnvironmentError(
                "Unable to change process owner ({exc})".format(exc=exc))
        raise error
Ejemplo n.º 16
0
    def daemonize(keepfd=None, chdir='/'):
        os.umask(0)
        if chdir:
            os.chdir(chdir)
        else:
            os.chdir('/')
        os.setgid(os.getgid())  # relinquish elevations
        os.setuid(os.getuid())  # relinquish elevations

        # Double fork to daemonize
        if os.fork() > 0: os._exit(0)  # Parent exits
        os.setsid()                    # Obtain new process group
        if os.fork() > 0: os._exit(0)  # Parent exits

        # Signal handling
        signal.signal(signal.SIGTERM, signal.SIG_IGN)
        signal.signal(signal.SIGINT, signal.SIG_IGN)

        # Close open files
        maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
        if maxfd == resource.RLIM_INFINITY: maxfd = 256
        for fd in reversed(range(maxfd)):
            try:
                if fd != keepfd:
                    os.close(fd)
            except OSError:
                _, exc, _ = sys.exc_info()
                if exc.errno != errno.EBADF: raise

        # Redirect I/O to /dev/null
        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdin.fileno())
        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdout.fileno())
        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stderr.fileno())
Ejemplo n.º 17
0
def main(argv):
    parser = argparse.ArgumentParser(description='osdial_remote_agents - Simulates presence of both remote and virtual agents.')
    parser.add_argument('-v', '--verbose', action='count', default=0, help='Increases verbosity.', dest='verbose')
    parser.add_argument('--version', action='version', version='%(prog)s %(ver)s' % {'prog':PROGNAME,'ver':VERSION})
    parser.add_argument('--debug', action='store_true', help='Run in debug mode.',dest='debug')
    parser.add_argument('-t', '--test', action='store_true', help='Run in test mode.',dest='test')
    parser.add_argument('-d', '--daemon', action='store_true', help='Puts process in daemon mode.',dest='daemon')
    parser.add_argument('-l', '--logLevel', action='store', default='INFO', choices=['CRITICAL','ERROR','WARNING','INFO','DEBUG'], help='Sets the level of output verbosity.', dest='loglevel')
    parser.add_argument('--delay', action='store', default=2, help='delay per loop, in seconds (default 2)', dest='delay')
    opts = parser.parse_args(args=argv)
    newargs = vars(opts)
    for arg in newargs:
        opt[arg] = newargs[arg]

    if not opt['delay']:
        opt['delay'] = 2
    opt['delay'] = int(opt['delay']) * 1000

    try:
        if os.getuid() == 0:
            astpwd = pwd.getpwnam('asterisk');
            os.setgid(astpwd.pw_gid)
            os.setuid(astpwd.pw_uid)
    except KeyError, e:
        pass
Ejemplo n.º 18
0
    def demote(self, uid):
        try:
            username = pwd.getpwuid(uid).pw_name
            gid = pwd.getpwuid(uid).pw_gid
        except KeyError:
            username = None
            gid = uid

        if os.getuid() == uid:
            return
        else:
            if os.getuid() != 0:
                logging.warn('Running as a limited user, setuid() unavailable!')
                return

        logging.info(
            'Worker %s is demoting to UID %s / GID %s...',
            os.getpid(),
            uid,
            gid
        )

        groups = [
            g.gr_gid
            for g in grp.getgrall()
            if username in g.gr_mem or g.gr_gid == gid
        ]
        os.setgroups(groups)
        os.setgid(gid)
        os.setuid(uid)
        logging.info(
            '...done, new EUID %s EGID %s',
            os.geteuid(),
            os.getegid()
        )
Ejemplo n.º 19
0
def drop_privileges(user: pwd.struct_passwd, group: grp.struct_group, permanent: bool = True):
    """
    Drop root privileges and change to something more safe.

    :param user: The tuple with user info
    :param group: The tuple with group info
    :param permanent: Whether we want to drop just the euid (temporary), or all uids (permanent)
    """
    # Restore euid=0 if we have previously changed it
    if os.geteuid() != 0 and os.getuid() == 0:
        restore_privileges()

    if os.geteuid() != 0:
        raise RuntimeError("Not running as root: cannot change uid/gid to {}/{}".format(user.pw_name, group.gr_name))

    # Remove group privileges
    os.setgroups([])

    if permanent:
        os.setgid(group.gr_gid)
        os.setuid(user.pw_uid)
    else:
        os.setegid(group.gr_gid)
        os.seteuid(user.pw_uid)

    # Ensure a very conservative umask
    os.umask(0o077)

    if permanent:
        logger.debug("Permanently dropped privileges to {}/{}".format(user.pw_name, group.gr_name))
    else:
        logger.debug("Dropped privileges to {}/{}".format(user.pw_name, group.gr_name))
Ejemplo n.º 20
0
def drop_privs(username, groupname, umask=None):
    """Drop process privileges to specified user and group.

    Privileges will only be dropped if current uid is root.
    
    Args:
        username: drop user privileges to username
        groupname: drop group privilegs to groupname
        umask: if provided, process umask will be changed accordingly.
    """

    #If not root, nothing to drop.
    if os.getuid() != 0:
        return

    uid = pwd.getpwnam(username).pw_uid
    gid = grp.getgrnam(groupname).gr_gid

    #Remove groups
    os.setgroups([])

    #Set gid and uid
    os.setgid(gid)
    os.setuid(uid)
    
    #Set umask if provided
    if umask is not None:
        os.umask(umask)
Ejemplo n.º 21
0
def dropPrivileges():
    nobody = pwd.getpwnam('nobody')
    adm    = grp.getgrnam('adm')

    os.setgroups([adm.gr_gid])
    os.setgid(adm.gr_gid)
    os.setuid(nobody.pw_uid)
Ejemplo n.º 22
0
def setuser(username):
    if not username:
        return

    import pwd
    import grp

    try:
        pwrec = pwd.getpwnam(username)
    except KeyError:
        sys.stderr.write('user not found: %s\n' % username)
        raise
    user = pwrec[0]
    uid = pwrec[2]
    gid = pwrec[3]

    cur_uid = os.getuid()
    if uid == cur_uid:
        return
    if cur_uid != 0:
        sys.stderr.write('can not set user as nonroot user\n')
        # will raise later

    # inspired by supervisor
    if hasattr(os, 'setgroups'):
        groups = [grprec[2] for grprec in grp.getgrall() if user in grprec[3]]
        groups.insert(0, gid)
        os.setgroups(groups)
    os.setgid(gid)
    os.setuid(uid)
Ejemplo n.º 23
0
def drop(new_uid='nobody', new_gid='nogroup'):
    starting_uid = os.getuid()
    starting_gid = os.getgid()

    if os.getuid() != 0:
        return
    if starting_uid == 0:
        run_uid = pwd.getpwnam(new_uid)[2]
        run_gid = grp.getgrnam(new_gid)[2]
        try:
            os.chown("files", run_uid, run_gid)
            os.chown("db", run_uid, run_gid)
            os.chown("log", run_uid, run_gid)
            recursive_chown("files", run_uid, run_gid)
            recursive_chown("db", run_uid, run_gid)
            recursive_chown("log", run_uid, run_gid)
            os.chown("modules/handlers/emulators/dork_list/pages",
                     run_uid, run_gid)
            os.chown("modules/handlers/emulators/dork_list/comments.txt",
                     run_uid, run_gid)
        except OSError, e:
            print "Could not change file owner: %s" % (e)
        try:
            os.setgid(run_gid)
        except OSError, e:
            print "Could not set new group: %s" % (e)
Ejemplo n.º 24
0
def tor_new_process():
    """
    Drops privileges to TOR_USER user and start a new Tor process
    """
    debian_tor_uid = getpwnam(TOR_USER).pw_uid
    debian_tor_gid = getpwnam(TOR_USER).pw_gid
    os.setgid(debian_tor_gid)
    os.setuid(debian_tor_uid)
    os.setegid(debian_tor_gid)
    os.seteuid(debian_tor_uid)
    os.environ['HOME'] = "/var/lib/tor"

    tor_process = stem.process.launch_tor_with_config(
      config = {
        'SocksPort': '6666',
        'ControlPort': '6969',
        'DNSPort': '9053',
        'DNSListenAddress': '127.0.0.1',
        'AutomapHostsOnResolve': '1',
        'AutomapHostsSuffixes': '.exit,.onion',
        'VirtualAddrNetwork': '10.192.0.0/10',
        'TransPort': '9040',
        'TransListenAddress': '127.0.0.1',
        'AvoidDiskWrites': '1',
        'WarnUnsafeSocks': '1',
      })
Ejemplo n.º 25
0
def release_privileges( uid_name, gid_name ):
   
   if os.getuid() != 0:
      # not root, so nothing to do
      return 0
   
   # get desired uid/gid 
   try:
      running_pwd = pwd.getpwnam( uid_name )
      running_uid = running_pwd.pw_uid 
   except KeyError:
      log.error("No such user '%s'" % uid_name)
      return -errno.EINVAL
   
   try:
      running_grp = grp.getgrnam( gid_name )
      running_gid = running_grp.gr_gid
   except KeyError:
      log.error("No such group '%s'" % gid_name)
      return -errno.EINVAL 
   
   # unset groups 
   os.setgroups( [] )
   
   # set new uid/gid 
   os.setgid( running_gid )
   os.setuid( running_uid )
   
   return 0 
Ejemplo n.º 26
0
    def drop_privileges(self):
        """drop privileges, and terminate the parent process"""
        if self.DAEMONIZED:
            #Child kills parent ... hmm sounds like a greek tragedy.
            os.kill(self.parentPid, signal.SIGTERM)
            self.parentPid = 0 #just in case

        if os.getuid() != 0:
            # We're not root so, like, whatever dude
            return

        import config
        import grp
        import pwd
        # Get the uid/gid from the name
        running_uid = pwd.getpwnam(config.DRONED_USER).pw_uid
        running_gid = grp.getgrnam(config.DRONED_GROUP).gr_gid
        self.log('set uid/gid %d/%d\n' % (running_uid,running_gid))
  
        # Remove group privileges
        os.setgroups([])
  
        # Try setting the new uid/gid
        os.setgid(running_gid)
        os.setuid(running_uid)
        # let services know it is ok to start
        self.reactor.fireSystemEvent('priviledges')
        #prevent this from being called ever again
        self.drop_privileges = lambda: None
Ejemplo n.º 27
0
def check_user(user):
    '''
    Check user and assign process uid/gid.
    '''
    if 'os' in os.environ:
        if os.environ['os'].startswith('Windows'):
            return True
    if user == getpass.getuser():
        return True
    import pwd  # after confirming not running Windows
    try:
        p = pwd.getpwnam(user)
        try:
            os.setgid(p.pw_gid)
            os.setuid(p.pw_uid)
        except OSError:
            msg = 'Salt configured to run as user "{0}" but unable to switch.'
            msg = msg.format(user)
            if is_console_configured():
                log.critical(msg)
            else:
                sys.stderr.write("CRITICAL: {0}\n".format(msg))
            return False
    except KeyError:
        msg = 'User not found: "{0}"'.format(user)
        if is_console_configured():
            log.critical(msg)
        else:
            sys.stderr.write("CRITICAL: {0}\n".format(msg))
        return False
    return True
Ejemplo n.º 28
0
def setgid():
    """
    Change group.

    Change to a less privileged group. Unless you're using it incorrectly --
    in which case, don't use it.

    :raises SystemExit: Exit code :py:obj:`os.EX_USAGE` when a configuration
                        error occurs or :py:obj:`os.EX_NOPERM` when a
                        permission error occurs.

    .. note::

       MUST be called BEFORE setuid, not after.
    """
    config = Config()
    try:
        gid = grp.getgrnam(config.group).gr_gid
        os.setgid(gid)
    except KeyError:
        logger.error("Group '%s' does not exist.", config.group)
        raise SystemExit(os.EX_USAGE)
    except PermissionError:
        logger.error(
            "You do not have permission to switch to group '%s'.", config.group
        )
        raise SystemExit(os.EX_NOPERM)
Ejemplo n.º 29
0
    def setuid(self):
        """
        Set user and group ID of the process

        If ``self.group`` is not defined, then this method uses the group ID of
        the ``self.user``.

        Returns a tuple containing the active user and group IDs.
        """
        if not has_user:
            logging.warn('User switching is disabled on this OS')
            return
        logging.debug('Setting process UID and GID')
        pwinfo = pwd.getpwnam(self.user)
        uid = pwinfo.pw_uid
        os.setuid(uid)
        os.seteuid(uid)
        if self.group:
            logging.debug('Using specified group for GID')
            gid = grp.getgrpnam(self.group).grp_gid
        else:
            logging.debug('Using specified user for GID')
            gid = pwinfo.pw_gid
        os.setgid(gid)
        os.setegid(gid)
        logging.debug('Process UID=%s and GID=%s', uid, gid)
        return uid, gid
Ejemplo n.º 30
0
def main():
    
    if args.group and len(args.group) > 0:
        gid = grp.getgrnam(args.group[0])
        os.setgid(gid[2])
    
    if args.user and len(args.user) > 0:
        print("Switching to user %s" % args.user[0])
        uid = pwd.getpwnam(args.user[0])[2]
        os.setuid(uid)
    
    global pending
    pubsub = PubSubClient()
    pubsub.url = config.get("Servers", "pubsub")
    pubsub.start()
    
    logging.warn("Service restarted, checking for updates in all tracked repos")
    for option in config.options("Tracking"):
        repo = config.get("Tracking", option)
        path = option
        pending[repo] = path
    
    while True:
        updatePending()
        time.sleep(3)
Ejemplo n.º 31
0
 def result():
     #print 'uid, gid = %d, %d; %s' % (os.getuid(), os.getgid(), 'starting reincarnation')
     os.setgid(user_gid)
     os.setuid(user_uid)
Ejemplo n.º 32
0
def main(config_file="config.json"):
    """ Usage: python3 calendar_manager.py [path/to/config_file.json]
    """

    stream = logging.StreamHandler()
    stream.setFormatter(
        logging.Formatter("%(asctime)-15s [%(levelname)s] %(message)s"))
    logger = logging.getLogger('calmgr')
    logger.addHandler(stream)

    # load configuration
    config = deepcopy(DEFAULT_CONFIG)
    try:
        with open(config_file, 'r') as fh:
            config.update(json.load(fh))
    except Exception as e:
        logger.error('Could not load configuration file, terminating.')
        logger.exception(e)
        return 1

    # start logging
    logger.setLevel(level=getattr(logging, config['logLevel']))

    # create synchronization structures
    flag = Event()
    queue = Queue()

    # instantiate http listener
    try:
        httpd = socketserver.TCPServer(("", config['listenPort']),
                                       get_http_handler(queue, config))
        if config['ssl']['enable']:
            httpd.socket = ssl.wrap_socket(
                httpd.socket,
                server_side=True,
                keyfile=config['ssl']['keyfile'],
                certfile=config['ssl']['certfile'],
            )
        httpd.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    except Exception as e:
        logger.error("Failed to initialize HTTP server. Terminating.")
        logger.exception(e)
        return 1

    # load google api credentials
    logger.info("Loading API credentials...")
    creds = ServiceAccountCredentials.from_json_keyfile_name(
        config['googleSecretFile'], 'https://www.googleapis.com/auth/calendar')

    # drop root privileges
    if os.geteuid() == 0 and config['dropPrivileges']['enable']:
        logger.info("Dropping root privileges...")
        uid = pwd.getpwnam(config['dropPrivileges']['user']).pw_uid
        gid = grp.getgrnam(config['dropPrivileges']['group']).gr_gid
        os.setgroups([])
        os.setgid(gid)
        os.setegid(gid)
        os.setuid(uid)
        os.seteuid(uid)
        os.umask(0o077)

    # make child thread ignore sigint
    signal.signal(signal.SIGINT, signal.SIG_IGN)

    # instantiate event processing thread
    thread = Thread(target=event_processor_thread,
                    args=[config, creds, flag, queue])
    thread.start()
    flag.wait()

    # check for successful initialization
    if not thread.successful_init:
        logger.error(
            "Event processing thread failed to initialize. Terminating.")
        thread.join()
        queue.join()
        return 1

    logger.info("Event processing thread successfully initialized.")
    logger.info("Starting HTTP listener...")

    # re-enable sigint and register a handler to translate it to KeyboardInterrupt
    def sig_hdl(sig, frame):
        raise KeyboardInterrupt()

    signal.signal(signal.SIGINT, sig_hdl)

    # start listening
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass

    logger.info("Received interrupt, closing threads...")

    # terminate event thread
    stop_thread(thread, queue)

    logger.info("Goodbye.")

    return 0
Ejemplo n.º 33
0
 def set_ids():
     os.setgid(gid)
     os.setuid(uid)
Ejemplo n.º 34
0
def drop_root_privilege() -> None:
    if os.getuid() == 0:
        pw = pwd.getpwnam('nobody')
        os.setgid(pw.pw_gid)
        os.setuid(pw.pw_uid)
Ejemplo n.º 35
0
def su_to_zulip():
    # type: () -> None
    pwent = pwd.getpwnam("zulip")
    os.setgid(pwent.pw_gid)
    os.setuid(pwent.pw_uid)
    os.environ['HOME'] = os.path.abspath(os.path.join(DEPLOYMENTS_DIR, '..'))
Ejemplo n.º 36
0
    if args.daemonise:
        os.chdir("/")

    # Open pidfile
    if args.daemonise:
        try:
            pidfile = open(args.pidfile, "w")
        except Exception, ex:
            logging.error("Could not open %s for writing: %s" %
                          (args.pidfile, ex))
            raise SystemExit(1)

    # Drop privs
    if args.daemonise and config.getboolean('main', 'drop_privs'):
        try:
            os.setgid(grp.getgrnam(config.get('main', 'group')).gr_gid)
            os.setuid(pwd.getpwnam(config.get('main', 'user')).pw_uid)
        except OSError, ex:
            logging.error(
                "Could not drop privs to %s.%s: %s" %
                (config.get('main', 'user'), config.get('main', 'group'), ex))

    # Double fork to detach from controlling terminal and ensure we can't ever reclaim one.
    if args.daemonise:
        if os.fork() != 0:
            raise SystemExit(0)
        if os.fork() != 0:
            raise SystemExit(0)

    # Close FDs
    if args.daemonise:
Ejemplo n.º 37
0
def main():
    # Set umask.
    os.umask(0o077)

    # Establish SQL database connections.
    db_conns = utils.get_required_db_conns()

    # Initialize policy daemon.
    logger.info("Starting iRedAPD (version: {0}, backend: {1}), "
                "listening on {2}:{3}.".format(__version__, settings.backend,
                                               settings.listen_address,
                                               settings.listen_port))
    local_addr = (settings.listen_address, int(settings.listen_port))
    DaemonSocket(local_addr=local_addr,
                 db_conns=db_conns,
                 policy_channel='policy',
                 plugins=settings.plugins)

    if (settings.srs_secrets and settings.srs_domain):
        logger.info("Starting SRS sender rewriting channel, listening on "
                    "{0}:{1}".format(settings.listen_address,
                                     settings.srs_forward_port))
        local_addr = (settings.listen_address, int(settings.srs_forward_port))
        DaemonSocket(local_addr=local_addr,
                     db_conns=db_conns,
                     policy_channel='srs_sender')

        logger.info("Starting SRS recipient rewriting channel, listening on "
                    "{0}:{1}".format(settings.listen_address,
                                     settings.srs_reverse_port))
        local_addr = (settings.listen_address, int(settings.srs_reverse_port))
        DaemonSocket(local_addr=local_addr,
                     db_conns=db_conns,
                     policy_channel='srs_recipient')
    else:
        logger.info(
            "No SRS domain and/or secret strings in settings.py, not loaded.")

    # Run this program as daemon.
    if '--foreground' not in sys.argv:
        try:
            daemon.daemonize(no_close=True)
        except Exception as e:
            logger.error("Error in daemon.daemonize: {0}".format(repr(e)))

    # Write pid number into pid file.
    f = open(settings.pid_file, 'w')
    f.write(str(os.getpid()))
    f.close()

    # Get uid/gid of daemon user.
    p = pwd.getpwnam(settings.run_as_user)
    uid = p.pw_uid
    gid = p.pw_gid

    # Run as daemon user
    os.setgid(gid)
    os.setuid(uid)

    # Create a global dict used to track smtp session data.
    #   - gather data at RCPT state
    #   - used in END-OF-MESSAGE state
    #   - clean up after applied all enabled plugins
    settings.GLOBAL_SESSION_TRACKING = {}

    # Starting loop.
    try:
        if sys.version_info >= (3, 4):
            # workaround for the "Bad file descriptor" issue on Python 2.7, gh-161
            asyncore.loop(use_poll=True)
        else:
            # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0
            asyncore.loop(use_poll=False)

    except KeyboardInterrupt:
        pass
    except Exception as e:
        logger.error("Error in asyncore.loop: {0}".format(repr(e)))
Ejemplo n.º 38
0
from datetime import datetime

OUT_DIR = '/tmp'
WORKDIR = os.path.join(OUT_DIR, 'apache_config_{0}/'.format(os.getpid()))
OUT_FILE = os.path.join(
    OUT_DIR,
    'apache_config_{1}'.format(OUT_DIR,
                               datetime.now().strftime('%Y-%m-%d_%H:%M:%S')))
LOGS_DIR = '/var/log/httpd/'
VAR_DIR = '/var/www/html/'
USR = '******'
UID = pwd.getpwnam(USR).pw_uid
GID = pwd.getpwnam(USR).pw_gid
NOEXIST = 'No such file or directory'

os.setgid(GID)
os.setuid(UID)


def usage():
    print('''
    Copy file(s) from {0} and/or {1}
    to {2}. If multiple files, a .zip archive will be created.

    Usage: ./{3} arg1 [arg2 ...]
    
        arg1, arg2, ...:  File(s) or Dir(s) path(s)
    '''.format(LOGS_DIR, VAR_DIR, OUT_DIR, sys.argv[0]))


if (len(sys.argv) < 2) or (sys.argv[1] in ['-h', '--help']):
Ejemplo n.º 39
0
def init_user(user, keys, environ):
    logger.info('init user %s', user)
    p = pwd.getpwnam(user)
    uid, gid = p.pw_uid, p.pw_gid
    homedir = p.pw_dir

    # os
    os.initgroups(user, gid)
    os.setgid(gid)
    os.setuid(uid)
    os.umask(0o027)
    os.chdir(homedir)

    # env
    os.environ["USER"] = user
    os.environ["HOME"] = homedir
    os.environ["UID"] = str(uid)
    os.environ["GEM_HOME"] = "{}/{}".format(homedir, environ["GEM_HOME"])
    os.environ["BUNDLE_PATH"] = os.environ["GEM_HOME"]
    os.environ["PATH"] = "{}:{}/bin".format(os.environ["PATH"],
                                            os.environ["GEM_HOME"])

    environ["HOME"] = homedir
    environ["PATH"] = os.environ["PATH"]
    environ["GEM_HOME"] = os.environ["GEM_HOME"]
    environ["BUNDLE_PATH"] = os.environ["BUNDLE_PATH"]

    # update .profile and env directory (for chpst)
    os.mkdir('.env')
    for key in ('GEM_HOME', 'SECRET_KEY_BASE', 'PASSWORD', 'GROUPNAME',
                'POSTGRES_HOST', 'POSTGRES_PORT', 'HOME', 'PATH',
                'BUNDLE_PATH'):
        # Bash
        with open('.profile', 'a', encoding='utf-8') as f:
            f.write('''\
export {key}="{value}"
'''.format(key=key, value=environ[key]))

        if SYSTEMD:
            with open('.envfile', 'a', encoding='utf-8') as f:
                f.write('''\
    {key}="{value}"
    '''.format(key=key, value=environ[key]))

        if RUNIT:
            with open('.env/{}'.format(key), 'w', encoding='utf-8') as f:
                f.write(environ[key])

    with open('.profile', 'a', encoding="utf-8") as f:
        f.write('''
# Added by configure.py
export GEM_PATH="$GEM_HOME:/usr/lib/ruby/gems/2.4.0"
export GEM_CACHE="$GEM_HOME/cache"
'''.format(**environ))

    # create .gitconfig
    with open('.gitconfig', 'w', encoding="utf-8") as f:
        f.write('''
[credentials "https://github.com"]
    helper = store
[push]
    default = simple
[color]
    status = auto
    branch = auto
    interactive = auto
    diff = auto
[alias]
    lol = log --graph --decorate --pretty=oneline --abbrev-commit
    lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
''')

    # Ruby gem config
    with open('.gemrc', 'w', encoding="utf-8") as f:
        f.write('gem: --user-install\n')
    subprocess.check_call(['gem', 'install', 'bundler'],
                          env=os.environ,
                          stdin=subprocess.PIPE,
                          stdout=sys.stdout,
                          stderr=sys.stderr)

    # Postgresql config
    with open('.pgpass', 'w', encoding="utf-8") as f:
        f.write('{POSTGRES_HOST}:{POSTGRES_PORT}:'
                '{GROUPNAME}:{GROUPNAME}:{PASSWORD}\n'.format(**environ))
    os.chmod(".pgpass", mode=0o0600)

    # Create .ssh/authorized_keys
    os.mkdir(".ssh")
    os.chmod(".ssh", mode=0o0700)
    with open('.ssh/authorized_keys', 'w') as f:
        f.write('\n'.join(keys))
    os.chmod(".ssh/authorized_keys", mode=0o0600)

    os.mkdir("config")
    with open('config/nginx.conf', 'w') as f:
        f.write('''
upstream puma-{GROUPNAME} {{
    server unix:/tmp/puma-{GROUPNAME}.sock fail_timeout=0;
}}

server {{
    listen 80;
    server_name {GROUPNAME}.{HOSTNAME};

    client_max_body_size 4G;

    root /home/{GROUPNAME}/www/app/public;
    index index.html index.htm;

    access_log /home/{GROUPNAME}/logs/access.log;
    error_log /home/{GROUPNAME}/logs/error.log;

    location / {{
        try_files $uri/index.html $uri @rack;
    }}

    location @rack {{
        proxy_pass http://puma-{GROUPNAME};
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }}

    # Nice Ruby on Rails error messages instead of Nginx'
    error_page 500 501 502 503 504 505 /500.html;
    keepalive_timeout 10;
}}
'''.format(**environ))

    with open('config/puma.rb', 'w') as f:
        f.write('''\
#!/usr/bin/env puma

environment ENV['RACK_ENV'] || "production"

threads 0, 16
workers 1

directory "/home/{GROUPNAME}/www/app"
bind "unix:///tmp/puma-{GROUPNAME}.sock"

plugin :tmp_restart

stdout_redirect "/home/{GROUPNAME}/logs/puma.out", "/home/{GROUPNAME}/logs/puma.err", true
'''.format(**environ))

    os.mkdir("logs")

    # www
    os.makedirs("www/app/public")
    with open('www/app/config.ru', 'w', encoding='utf-8') as f:
        f.write('''\
run Proc.new {{ |env|
    ['200',
     {{'Content-Type' => 'text/plain; charset=utf-8'}},
     ["Hello {GROUPNAME}!\\n\\n",
      env .merge(ENV)
          .select {{ |k,v| k !~ /^(PASSWORD|SECRET_KEY_BASE)$/ }}
          .collect {{ |k,v| "#{{k}}:\\t#{{v}}" }}
          .flatten
          .join("\\n")]]
}}
'''.format(**environ))
    with open('www/app/Gemfile', 'w', encoding='utf-8') as f:
        f.write('''\
# frozen_string_literal: true
source 'https://rubygems.org'

gem 'puma'
gem 'rack'
''')

    os.chdir('www/app')
    subprocess.check_call(['bundler', 'install'],
                          env=os.environ,
                          stdin=subprocess.PIPE,
                          stdout=sys.stdout,
                          stderr=sys.stderr)

    return 0
 def result():
     os.setgid(user_gid)
     os.setuid(user_uid)
Ejemplo n.º 41
0
 def prepare():
     cgclassify(job.job_id,os.getpid())
     #os.setpgrp()
     if os.getuid() == 0:
         os.setgid(job.owner_gid)
         os.setuid(job.owner_uid)
Ejemplo n.º 42
0
        stncdf = stnfiles[filename]
        stncdf.addobs(obs,'0')
        #stnfiles[filename]=stncdf


def callback(ch, method, properties, body):
    # queue call back function on event
    t = time.time()
    obs = pickle.loads(body) # expand our object back
    ch.basic_ack(delivery_tag = method.delivery_tag)
    recordobs(obs)
    print "{0:10.10f}".format(time.time()-t)
    time.sleep(0.001)

if __name__=="__main__":
    # we can assume this is the general execution case
 
    connection = pika.BlockingConnection(pika.ConnectionParameters(
            host=rabbitmq_server))
    channel = connection.channel()
    channel.queue_declare(queue='Final', durable=True)
    os.umask(003)
    os.setgid(1004)
    os.seteuid(1004)
    # now that our initials are set lets move forward to some packets
    channel.basic_consume(callback,
                      queue='Final')
    channel.start_consuming()
    print "goodbye"

Ejemplo n.º 43
0
 def run(self):
     # First, initialise the process
     self.load()
     self.running = True
     # Try to ensure the state file is readable
     state_dir = os.path.dirname(self.state_file)
     if not os.path.isdir(state_dir):
         os.makedirs(state_dir)
     if self.uid is not None:
         try:
             os.chown(state_dir, self.uid, -1)
         except OSError:
             pass
         try:
             os.chown(self.state_file, self.uid, -1)
         except OSError:
             pass
     # Then, launch the socket loops
     pool = GreenBody(
         len(self.external_addresses) + len(self.internal_addresses) +
         len(self.management_addresses) + 1)
     pool.spawn(self.save_loop)
     for address, family in self.external_addresses:
         pool.spawn(self.listen_loop, address, family, internal=False)
     for address, family in self.internal_addresses:
         pool.spawn(self.listen_loop, address, family, internal=True)
     for address, family in self.management_addresses:
         pool.spawn(self.management_loop, address, family)
     # Give the other threads a chance to open their listening sockets
     eventlet.sleep(0.5)
     # Drop to the lesser UID/GIDs, if supplied
     if self.gid:
         try:
             os.setegid(self.gid)
             os.setgid(self.gid)
         except OSError:
             logging.error(
                 "Cannot change to GID %i (probably not running as root)" %
                 self.gid)
         else:
             logging.info("Dropped to GID %i" % self.gid)
     if self.uid:
         try:
             os.seteuid(0)
             os.setuid(self.uid)
             os.seteuid(self.uid)
         except OSError:
             logging.error(
                 "Cannot change to UID %i (probably not running as root)" %
                 self.uid)
         else:
             logging.info("Dropped to UID %i" % self.uid)
     # Ensure we can save to the state file, or die hard.
     try:
         open(self.state_file, "a").close()
     except (OSError, IOError):
         logging.critical("Cannot write to state file %s" % self.state_file)
         sys.exit(1)
     # Wait for one to exit, or for a clean/forced shutdown
     try:
         pool.wait()
     except (KeyboardInterrupt, StopIteration, SystemExit):
         pass
     except:
         logging.error(traceback.format_exc())
     # We're done
     self.running = False
     logging.info("Exiting")
Ejemplo n.º 44
0
#!/usr/bin/env python
import os
import sys
import pwd

production_user = "******"

if production_user:
    (uid, gid, gecos, homedir) = pwd.getpwnam(production_user)[2:6]
    try:
        os.setgid(gid)
        os.setuid(uid)
    except OSError as e:
        sys.stderr.write("%s\nThis program needs to be run as the " % e)
        sys.stderr.write("%s user, or root.\n" % production_user)
        sys.exit(1)
    else:
        os.environ["HOME"] = homedir

if __name__ == "__main__":
    if production_user:
        # prepare the settings module for the django app
        from ccg_django_utils.conf import setup_prod_env
        setup_prod_env("yabi")
    else:
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "yabi.settings")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)
Ejemplo n.º 45
0
 def preexec():
     os.setgid(self._get_gid_of_uid(self.vdus.user.uid))
     os.setuid(self.vdus.user.uid)
Ejemplo n.º 46
0
 def wrapper():
     if user is not None:
         os.setuid(user)
     if group is not None:
         os.setgid(group)
Ejemplo n.º 47
0
        def preexec():
            streams = [sys.stdin]

            if self.close_child_stdout:
                streams.append(sys.stdout)

            if self.close_child_stderr:
                streams.append(sys.stderr)

            self._null_streams(streams)
            os.setsid()

            if resource:
                for limit, value in self.rlimits.items():
                    res = getattr(resource, 'RLIMIT_%s' % limit.upper(), None)
                    if res is None:
                        raise ValueError('unknown rlimit "%s"' % limit)

                    # TODO(petef): support hard/soft limits

                    # for the NOFILE limit, if we fail to set an unlimited
                    # value then check the existing hard limit because we
                    # probably can't bypass it due to a kernel limit - so just
                    # assume that the caller means they want to use the kernel
                    # limit when they pass the unlimited value. This is better
                    # than failing to start the process and forcing the caller
                    # to always be aware of what the kernel configuration is.
                    # If they do pass in a real limit value, then we'll just
                    # raise the failure as they should know that their
                    # expectations couldn't be met.
                    # TODO - we can't log here as this occurs in the child
                    # process after the fork but it would be very good to
                    # notify the admin of the situation somehow.
                    retry = False
                    try:
                        resource.setrlimit(res, (value, value))
                    except ValueError:
                        if res == resource.RLIMIT_NOFILE and \
                                value == resource.RLIM_INFINITY:
                            _soft, value = resource.getrlimit(res)
                            retry = True
                        else:
                            raise
                    if retry:
                        resource.setrlimit(res, (value, value))

            if self.gid:
                try:
                    os.setgid(self.gid)
                except OverflowError:
                    if not ctypes:
                        raise
                    # versions of python < 2.6.2 don't manage unsigned int for
                    # groups like on osx or fedora
                    os.setgid(-ctypes.c_int(-self.gid).value)

                if self.username is not None:
                    try:
                        os.initgroups(self.username, self.gid)
                    except (OSError, AttributeError):
                        # not support on Mac or 2.6
                        pass

            if self.uid:
                os.setuid(self.uid)
 def set_ids():
     os.setgid(user_gid)
     os.setuid(user_uid)
Ejemplo n.º 49
0
 def switch_uid_gid():
     if gid is not None:
         os.setgid(gid)
     if uid is not None:
         os.setuid(uid)
Ejemplo n.º 50
0
    def daemonize(self):
        """Detach a process from the controlling terminal and run it in the
		background as a daemon.
		"""

        self.testpid()

        try:
            pid = os.fork()
        except OSError as e:
            raise Exception("%s [%d]" % (e.strerror, e.errno))

        if (pid == 0):  # The first child
            os.setsid()
            try:
                pid = os.fork()  # Fork a second child.
            except OSError as e:
                raise Exception("%s [%d]" % (e.strerror, e.errno))

            if (pid == 0):  # The second child.
                if self.pidfile:
                    open(self.pidfile, 'w').write(str(os.getpid()))
                self.pid = int(os.getpid())
                os.chdir(self.workdir)
                os.umask(self.umask)
            else:
                os._exit(
                    0)  # Exit parent (the first child) of the second child.
        else:
            os._exit(0)  # Exit parent of the first child.

        # at this point the process is daemonised
        # we close any open files except our logger
        maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
        if (maxfd == resource.RLIM_INFINITY):
            maxfd = self.MAXFD
        for fd in range(0, maxfd):
            try:
                if fd != self.logfileno and fd not in self.keepfilenos:
                    os.close(fd)
            except OSError:  # ERROR, fd wasn't open to begin with (ignored)
                pass

        # all fds are closed, this way we open 0,1,2 while directing
        # stin and stdout to /dev/null and stderr to the daemon log for
        # easier debugging
        os.open(os.devnull, os.O_RDWR)
        os.dup2(0, 1)
        os.dup2(self.logfileno, 2)

        if self.user:  # must get user before we chroot and cannot access /etc/passwd anymore
            user = pwd.getpwnam(self.user)
        self.log(logging.INFO, "Daemonisation finalized")
        if self.user:
            uid, gid = user[2], user[3]
            os.chown(self.pidfile, uid, gid)
        if self.rootdir:
            os.chroot(self.rootdir)
            os.chdir('/')
            self.log(logging.INFO, "Chroot executed to " + self.rootdir)
        if self.user:
            os.setgid(gid)
            os.setuid(uid)
            self.log(logging.INFO,
                     "Credentials set to those of user " + self.user)

        def terminate(signalnum, stack):
            self.log(logging.INFO, "Terminating daemon...")
            self.rm_pid()  # only has effect if not chrooted
            os._exit(0)

        # end the daemon. Sent by stop() but can also come from outside
        signal.signal(signal.SIGTERM, terminate)

        self.log(
            logging.INFO,
            "pid = %s, ppid = %s, pgid = %s, sid = %s, uid = %s, euid = %s, gid = %s, egid = %s"
            % (os.getpid(), os.getppid(), os.getpgrp(), os.getsid(0),
               os.getuid(), os.geteuid(), os.getgid(), os.getegid()))
Ejemplo n.º 51
0
def start(foreground, root, config_file):
    """Run the Wazuh API.

    If another Wazuh API is running, this function fails.
    This function exits with 0 if successful or 1 if failed because the API was already running.

    Arguments
    ---------
    foreground : bool
        If the API must be daemonized or not
    root : bool
        If true, the daemon is run as root. Normally not recommended for security reasons
    config_file : str
        Path to the API config file
    """
    import asyncio
    import logging
    import os
    import ssl

    import connexion
    import uvloop
    from aiohttp_cache import setup_cache
    from api import alogging, configuration

    import wazuh.security
    from api import __path__ as api_path
    # noinspection PyUnresolvedReferences
    from api import validator
    from api.api_exception import APIError
    from api.constants import CONFIG_FILE_PATH
    from api.middlewares import set_user_name, security_middleware, response_postprocessing, request_logging, \
        set_secure_headers
    from api.signals import modify_response_headers
    from api.uri_parser import APIUriParser
    from api.util import to_relative_path
    from wazuh.core import pyDaemonModule

    def set_logging(log_path='logs/api.log',
                    foreground_mode=False,
                    debug_mode='info'):
        for logger_name in ('connexion.aiohttp_app',
                            'connexion.apis.aiohttp_api', 'wazuh-api'):
            api_logger = alogging.APILogger(
                log_path=log_path,
                foreground_mode=foreground_mode,
                logger_name=logger_name,
                debug_level='info' if logger_name != 'wazuh-api'
                and debug_mode != 'debug2' else debug_mode)
            api_logger.setup_logger()

    configuration.api_conf.update(
        configuration.read_yaml_config(config_file=config_file))
    api_conf = configuration.api_conf
    security_conf = configuration.security_conf
    log_path = api_conf['logs']['path']

    # Set up logger
    set_logging(log_path=log_path,
                debug_mode=api_conf['logs']['level'],
                foreground_mode=foreground)
    logger = logging.getLogger('wazuh-api')

    # Set correct permissions on api.log file
    if os.path.exists(os.path.join(common.wazuh_path, log_path)):
        os.chown(os.path.join(common.wazuh_path, log_path), common.wazuh_uid(),
                 common.wazuh_gid())
        os.chmod(os.path.join(common.wazuh_path, log_path), 0o660)

    # Configure https
    ssl_context = None
    if api_conf['https']['enabled']:
        try:
            # Generate SSL if it does not exist and HTTPS is enabled
            if not os.path.exists(
                    api_conf['https']['key']) or not os.path.exists(
                        api_conf['https']['cert']):
                logger.info(
                    'HTTPS is enabled but cannot find the private key and/or certificate. '
                    'Attempting to generate them')
                private_key = configuration.generate_private_key(
                    api_conf['https']['key'])
                logger.info(
                    f"Generated private key file in WAZUH_PATH/{to_relative_path(api_conf['https']['key'])}"
                )
                configuration.generate_self_signed_certificate(
                    private_key, api_conf['https']['cert'])
                logger.info(
                    f"Generated certificate file in WAZUH_PATH/{to_relative_path(api_conf['https']['cert'])}"
                )

            allowed_ssl_protocols = {
                'tls': ssl.PROTOCOL_TLS,
                'tlsv1': ssl.PROTOCOL_TLSv1,
                'tlsv1.1': ssl.PROTOCOL_TLSv1_1,
                'tlsv1.2': ssl.PROTOCOL_TLSv1_2
            }

            ssl_protocol = allowed_ssl_protocols[api_conf['https']
                                                 ['ssl_protocol'].lower()]

            ssl_context = ssl.SSLContext(protocol=ssl_protocol)

            if api_conf['https']['use_ca']:
                ssl_context.verify_mode = ssl.CERT_REQUIRED
                ssl_context.load_verify_locations(api_conf['https']['ca'])

            ssl_context.load_cert_chain(certfile=api_conf['https']['cert'],
                                        keyfile=api_conf['https']['key'])

            # Loads SSL ciphers if any have been specified
            if api_conf['https']['ssl_ciphers']:
                ssl_ciphers = api_conf['https']['ssl_ciphers'].upper()
                try:
                    ssl_context.set_ciphers(ssl_ciphers)
                except ssl.SSLError:
                    logger.error(
                        str(
                            APIError(
                                2003,
                                details='SSL ciphers can not be selected')))
                    sys.exit(1)

        except ssl.SSLError:
            logger.error(
                str(
                    APIError(
                        2003,
                        details=
                        'Private key does not match with the certificate')))
            sys.exit(1)
        except IOError as e:
            if e.errno == 22:
                logger.error(
                    str(APIError(2003, details='PEM phrase is not correct')))
            elif e.errno == 13:
                logger.error(
                    str(
                        APIError(
                            2003,
                            details=
                            'Ensure the certificates have the correct permissions'
                        )))
            else:
                print(
                    'Wazuh API SSL ERROR. Please, ensure if path to certificates is correct in the configuration '
                    f'file WAZUH_PATH/{to_relative_path(CONFIG_FILE_PATH)}')
            sys.exit(1)

    # Drop privileges to wazuh
    if not root:
        if api_conf['drop_privileges']:
            os.setgid(common.wazuh_gid())
            os.setuid(common.wazuh_uid())
    else:
        print(f"Starting API as root")

    # Foreground/Daemon
    utils.check_pid('wazuh-apid')
    if not foreground:
        pyDaemonModule.pyDaemon()
    pid = os.getpid()
    pyDaemonModule.create_pid('wazuh-apid', pid) or register(
        pyDaemonModule.delete_pid, 'wazuh-apid', pid)
    if foreground:
        print(f"Starting API in foreground (pid: {pid})")

    # Load the SPEC file into memory to use as a reference for future calls
    wazuh.security.load_spec()

    # Set up API
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    app = connexion.AioHttpApp(__name__,
                               host=api_conf['host'],
                               port=api_conf['port'],
                               specification_dir=os.path.join(
                                   api_path[0], 'spec'),
                               options={
                                   "swagger_ui": False,
                                   'uri_parser_class': APIUriParser
                               },
                               only_one_api=True)
    app.add_api('spec.yaml',
                arguments={
                    'title': 'Wazuh API',
                    'protocol':
                    'https' if api_conf['https']['enabled'] else 'http',
                    'host': api_conf['host'],
                    'port': api_conf['port']
                },
                strict_validation=True,
                validate_responses=False,
                pass_context_arg_name='request',
                options={
                    "middlewares": [
                        response_postprocessing, set_user_name,
                        security_middleware, request_logging,
                        set_secure_headers
                    ]
                })

    # Maximum body size that the API can accept (bytes)
    app.app._client_max_size = configuration.api_conf['max_upload_size']

    # Enable CORS
    if api_conf['cors']['enabled']:
        import aiohttp_cors
        cors = aiohttp_cors.setup(
            app.app,
            defaults={
                api_conf['cors']['source_route']:
                aiohttp_cors.ResourceOptions(
                    expose_headers=api_conf['cors']['expose_headers'],
                    allow_headers=api_conf['cors']['allow_headers'],
                    allow_credentials=api_conf['cors']['allow_credentials'])
            })
        # Configure CORS on all endpoints.
        for route in list(app.app.router.routes()):
            cors.add(route)

    # Enable cache plugin
    if api_conf['cache']['enabled']:
        setup_cache(app.app)

    # Add application signals
    app.app.on_response_prepare.append(modify_response_headers)

    # API configuration logging
    logger.debug(f'Loaded API configuration: {api_conf}')
    logger.debug(f'Loaded security API configuration: {security_conf}')

    # Start API
    app.run(port=api_conf['port'],
            host=api_conf['host'],
            ssl_context=ssl_context,
            access_log_class=alogging.AccessLogger,
            use_default_access_log=True)
Ejemplo n.º 52
0
 def preexec():
     if resource.group:
         gid = _coerce_gid(resource.group)
         os.setgid(gid)
         os.setegid(gid)
Ejemplo n.º 53
0
def server(pidfile,
           *,
           stdin='/dev/null',
           stdout='/dev/null',
           stderr='/dev/null'):
    logzero.logfile("/tmp/Server.log",
                    maxBytes=1e6,
                    backupCount=3,
                    disableStderrLogger=True)
    # Check if a pidfile already exists, if it does, throw error, if it doesnt, continue
    if os.path.exists(pidfile):
        logger.error('Already Running')

    # start a socket and listen to the socket
    listenSocket = socket(AF_INET6, SOCK_STREAM)
    listenSocket.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
    listenSocket.bind(SERVER_ADDRESS)
    listenSocket.listen(QUEUE_SIZE)
    # Kill zombie children process
    signal.signal(signal.SIGCHLD, grim_reaper)
    signal.signal(SIGPIPE, SIG_DFL)
    # Fork once
    try:
        if os.fork() > 0:
            raise SystemExit(0)
    except OSError as e:
        logger.error("Fork #1 failed:" + e)

    # change current directory. session id and file permissions
    os.chdir("/tmp")
    os.setsid()
    os.umask(0)
    # try setuid and setgid
    try:
        os.setuid(os.getuid())
        os.setgid(os.getgid())
    except Exception as err:
        logger.info("Error: " + err)
    #Fork a second time
    try:
        if os.fork() > 0:
            raise SystemExit(0)
    except OSError as e:
        raise RuntimeError('fork #1 failed:' + e)
    #Write the pid of the process to a file
    f = open(pidfile, "w+")
    f.write(str(os.getpid()))
    f.close()
    # Flush out I/O buffers
    sys.stdout.flush()
    sys.stderr.flush()
    # Replace file descriptors for stdin, stdout and stderr
    with open(stdin, 'rb', 0) as f:
        os.dup2(f.fileno(), sys.stdin.fileno())
    with open(stdout, 'ab', 0) as f:
        os.dup2(f.fileno(), sys.stdout.fileno())
    with open(stderr, 'ab', 0) as f:
        os.dup2(f.fileno(), sys.stderr.fileno())
    # Remove Pid File once the daemon stops
    def removePidFile(signum, frame):
        os.remove(pidfile)

    try:
        signal.signal(signal.SIGTERM, removePidFile)
    except Exception:
        raise RuntimeError("ERROR")
    # Accept connections and fork off children to handle connection requests
    while True:
        try:
            clientConnection, clientAddress = listenSocket.accept()
        except IOError as e:
            code, msg = e.args
            if code == errno.EINTR:
                continue
            else:
                raise
        childPid = os.fork()
        if childPid == 0:
            listenSocket.close()
            handle_client(clientConnection)
            clientConnection.close()
            os._exit(0)

        else:
            clientConnection.close()

    def sigterm_handler(signo, frame):
        raise SystemExit(1)

    signal.signal(signal.SIGTERM, sigterm_handler)
Ejemplo n.º 54
0
        t.daemon = True
        t.start()
        self.ts[task.task_id.value] = t

    def killTask(self, driver, task_id):
        try:
            if task_id.value in self.ps:
                self.ps[task_id.value].kill()
                reply_status(driver, task_id, 'TASK_KILLED')
        except:
            pass

    def shutdown(self, driver):
        for p in self.ps.values():
            try:
                p.kill()
            except:
                pass
        for t in self.ts.values():
            t.join()


if __name__ == "__main__":
    if os.getuid() == 0:
        gid = os.environ['GID']
        uid = os.environ['UID']
        os.setgid(int(gid))
        os.setuid(int(uid))
    executor = MyExecutor()
    MesosExecutorDriver(executor, use_addict=True).run()
Ejemplo n.º 55
0
    def start(self):
        """ start method
        Main daemonization process.
        """
        # If pidfile already exists, we should read pid from there; to overwrite it, if locking
        # will fail, because locking attempt somehow purges the file contents.
        if os.path.isfile(self.pid):
            with open(self.pid, "r") as old_pidfile:
                old_pid = old_pidfile.read()
        # Create a lockfile so that only one instance of this daemon is running at any time.
        try:
            lockfile = open(self.pid, "w")
        except IOError:
            print("Unable to create the pidfile.")
            sys.exit(1)
        try:
            # Try to get an exclusive lock on the file. This will fail if another process has the file
            # locked.
            fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except IOError:
            print("Unable to lock on the pidfile.")
            # We need to overwrite the pidfile if we got here.
            with open(self.pid, "w") as pidfile:
                pidfile.write(old_pid)
            sys.exit(1)

        # Fork, creating a new process for the child.
        process_id = os.fork()
        if process_id < 0:
            # Fork error. Exit badly.
            sys.exit(1)
        elif process_id != 0:
            # This is the parent process. Exit.
            sys.exit(0)
        # This is the child process. Continue.

        # Stop listening for signals that the parent process receives.
        # This is done by getting a new process id.
        # setpgrp() is an alternative to setsid().
        # setsid puts the process in a new parent group and detaches its controlling terminal.
        process_id = os.setsid()
        if process_id == -1:
            # Uh oh, there was a problem.
            sys.exit(1)

        # Add lockfile to self.keep_fds.
        self.keep_fds.append(lockfile.fileno())

        # Close all file descriptors, except the ones mentioned in self.keep_fds.
        devnull = "/dev/null"
        if hasattr(os, "devnull"):
            # Python has set os.devnull on this system, use it instead as it might be different
            # than /dev/null.
            devnull = os.devnull

        if self.auto_close_fds:
            for fd in range(3, resource.getrlimit(resource.RLIMIT_NOFILE)[0]):
                if fd not in self.keep_fds:
                    try:
                        os.close(fd)
                    except OSError:
                        pass

        devnull_fd = os.open(devnull, os.O_RDWR)
        os.dup2(devnull_fd, 0)
        os.dup2(devnull_fd, 1)
        os.dup2(devnull_fd, 2)

        if self.logger is None:
            # Initialize logging.
            self.logger = logging.getLogger(self.app)
            self.logger.setLevel(logging.DEBUG)
            # Display log messages only on defined handlers.
            self.logger.propagate = False

            # Initialize syslog.
            # It will correctly work on OS X, Linux and FreeBSD.
            if sys.platform == "darwin":
                syslog_address = "/var/run/syslog"
            else:
                syslog_address = "/dev/log"

            # We will continue with syslog initialization only if actually have such capabilities
            # on the machine we are running this.
            if os.path.isfile(syslog_address):
                syslog = handlers.SysLogHandler(syslog_address)
                if self.verbose:
                    syslog.setLevel(logging.DEBUG)
                else:
                    syslog.setLevel(logging.INFO)
                # Try to mimic to normal syslog messages.
                formatter = logging.Formatter("%(asctime)s %(name)s: %(message)s",
                                              "%b %e %H:%M:%S")
                syslog.setFormatter(formatter)

                self.logger.addHandler(syslog)

        # Set umask to default to safe file permissions when running as a root daemon. 027 is an
        # octal number which we are typing as 0o27 for Python3 compatibility.
        os.umask(0o27)

        # Change to a known directory. If this isn't done, starting a daemon in a subdirectory that
        # needs to be deleted results in "directory busy" errors.
        os.chdir("/")

        # Execute privileged action
        privileged_action_result = self.privileged_action()
        if not privileged_action_result:
            privileged_action_result = []

        # Change gid
        if self.group:
            try:
                gid = grp.getgrnam(self.group).gr_gid
            except KeyError:
                self.logger.error("Group {0} not found".format(self.group))
                sys.exit(1)
            try:
                os.setgid(gid)
            except OSError:
                self.logger.error("Unable to change gid.")
                sys.exit(1)

        # Change uid
        if self.user:
            try:
                uid = pwd.getpwnam(self.user).pw_uid
            except KeyError:
                self.logger.error("User {0} not found.".format(self.user))
                sys.exit(1)
            try:
                os.setuid(uid)
            except OSError:
                self.logger.error("Unable to change uid.")
                sys.exit(1)

        try:
            lockfile.write("%s" % (os.getpid()))
            lockfile.flush()
        except IOError:
            self.logger.error("Unable to write pid to the pidfile.")
            print("Unable to write pid to the pidfile.")
            sys.exit(1)

        # Set custom action on SIGTERM.
        signal.signal(signal.SIGTERM, self.sigterm)
        atexit.register(self.exit)

        self.logger.warn("Starting daemon.")
        #self.action(*privileged_action_result)
        self.run()
Ejemplo n.º 56
0
 def result():
     os.setgid(grp.getgrnam(user).gr_gid)
     os.setuid(pwd.getpwnam(user).pw_uid)
Ejemplo n.º 57
0
        except:
            dict["type"] = None

        return dict


if __name__ == "__main__":

    timer = Timer()
    #first let's drop privileges, shall we?
    if os.getuid() == 0:
        try:
            running_uid = pwd.getpwnam('named').pw_uid
            running_gid = grp.getgrnam('named').gr_gid
            os.setgroups([])
            os.setgid(running_gid)
            os.setuid(running_uid)
        except Exception, e:
            print "[!] %s %s Error dropping privileges! %s : %s" % (
                timer.getToday(), timer.getNow(), Exception, e)

    p = optparse.OptionParser(
        description='Monitor DNS server logs for queries to malicious domains.',
        prog='dns_watch',
        version='0.1',
        usage='%prog -c config_file [-v --verbose]')
    p.add_option('--verbose',
                 '-v',
                 action="store_true",
                 help="print extra info")
    p.add_option('--config',
Ejemplo n.º 58
0
def run():
    options.parse_command_line()

    if options.config:
        options.parse_config_file(options.config)

    options.storage = os.path.abspath(options.storage)

    if os.getuid() == 0 and options.user:
        pw = pwd.getpwnam(options.user)
        uid, gid = pw.pw_uid, pw.pw_gid
        log.info("Changind user to %s [%s:%s]", options.user, uid, gid)
        os.setgid(uid)
        os.setuid(uid)

    try:
        if not all(
                f(options.storage) for f in (os.path.exists, os.path.isdir)):
            log.info('Creating new package storage directory: "%s"',
                     options.storage)
            os.makedirs(options.storage)

        def on_interrupt(*args):
            log.warning(
                "Receiving interrupt signal. Application will be stopped.")
            exit(errno.EINTR)

        log.debug("Preparing signal handling")
        for sig in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT):
            signal.signal(sig, on_interrupt)

        def handle_pdb(sig, frame):
            import pdb
            pdb.Pdb().set_trace(frame)

        if options.debug:
            signal.signal(signal.SIGUSR2, handle_pdb)

        log.debug("Creating application instance")
        app = create_app(
            options.debug,
            options.secret,
            options.gzip,
        )

        log.debug("Creating IOLoop instance.")
        io_loop = IOLoop.current()

        io_loop.run_sync(lambda: init_db(options.database))

        if not (os.path.exists(options.cache_dir)
                and os.path.isdir(options.cache_dir)):
            os.makedirs(options.cache_dir)

        Cache.CACHE_DIR = options.cache_dir

        log.info("Init thread pool with %d threads", options.pool_size)
        handlers.base.BaseHandler.THREAD_POOL = futures.ThreadPoolExecutor(
            options.pool_size)

        AsyncHTTPClient.configure(None, max_clients=options.max_http_clients)

        PYPIClient.configure(options.pypi_server,
                             handlers.base.BaseHandler.THREAD_POOL)

        pypi_updater = PeriodicCallback(PYPIClient.packages, HOUR * 1000,
                                        io_loop)

        io_loop.add_callback(PYPIClient.packages)
        io_loop.add_callback(pypi_updater.start)

        log.info("Starting server http://%s:%d/", options.address,
                 options.port)
        http_server = HTTPServer(app, xheaders=options.proxy_mode)
        http_server.listen(options.port, address=options.address)

        log.debug('Setting "%s" as storage', options.storage)
        PackageFile.set_storage(options.storage)

        log.debug("Starting main loop")
        io_loop.start()
    except Exception as e:
        log.fatal("Exception on main loop:")
        log.exception(e)
        exit(1)
    else:
        exit(0)
Ejemplo n.º 59
0
        # Is user a valid system user?
        try:
            user_info = user.get_user_by_username(g.username)
        except user.NoSuchUser, e:
            log.error('User %s is not a valid user' % g.username)
            abort(400)

    if app.config["PROCESS_SWITCHING"]:
        # If required, set uid and gid of handler process
        if os.getuid() != user_info.uid:
            if os.getuid() != 0:
                log.error("Pegasus service must run as root to enable process switching")
                return make_response("Pegasus service must run as root to enable process switching", 500)

        os.setgid(user_info.gid)
        os.setuid(user_info.uid)

    # Does the user have a Pegasus home directory?
    user_pegasus_dir = user_info.get_pegasus_dir()

    if not os.path.isdir(user_pegasus_dir):
        log.info("User's pegasus directory does not exist. Creating one...")
        try:
            os.makedirs(user_pegasus_dir, mode=0744)
        except OSError:
            log.info("Invalid Permissions: Could not create user's pegasus directory.")
            return make_response("Could not find user's Pegasus directory", 404)

    # Set master DB URL for the dashboard
    # For testing master_db_url would be pre-populated, so let's not overwrite it here.
Ejemplo n.º 60
0
    def start(self):
        """ start method
        Main daemonization process.
        """
        # Fork, creating a new process for the child.
        process_id = os.fork()
        if process_id < 0:
            # Fork error. Exit badly.
            sys.exit(1)
        elif process_id != 0:
            # This is the parent process. Exit.
            sys.exit(0)
        # This is the child process. Continue.

        # Stop listening for signals that the parent process receives.
        # This is done by getting a new process id.
        # setpgrp() is an alternative to setsid().
        # setsid puts the process in a new parent group and detaches its controlling terminal.
        process_id = os.setsid()
        if process_id == -1:
            # Uh oh, there was a problem.
            sys.exit(1)

        # Close all file descriptors, except the ones mentioned in self.keep_fds.
        devnull = "/dev/null"
        if hasattr(os, "devnull"):
            # Python has set os.devnull on this system, use it instead as it might be different
            # than /dev/null.
            devnull = os.devnull

        for fd in range(resource.getrlimit(resource.RLIMIT_NOFILE)[0]):
            if fd not in self.keep_fds:
                try:
                    os.close(fd)
                except OSError:
                    pass

        os.open(devnull, os.O_RDWR)
        os.dup(0)
        os.dup(0)

        # Initialize syslog.
        # It will work on OS X and Linux. No FreeBSD support, guys, I don't want to import re here
        # to parse your peculiar platform string.
        if sys.platform == "darwin":
            syslog_address = "/var/run/syslog"
        else:
            syslog_address = "/dev/log"
        syslog = handlers.SysLogHandler(syslog_address)
        if self.verbose:
            syslog.setLevel(logging.DEBUG)
        else:
            syslog.setLevel(logging.INFO)
        # Try to mimic to normal syslog messages.
        formatter = logging.Formatter("%(asctime)s %(name)s: %(message)s",
                                      "%b %e %H:%M:%S")
        syslog.setFormatter(formatter)

        self.logger.addHandler(syslog)

        # Set umask to default to safe file permissions when running as a root daemon. 027 is an
        # octal number which we are typing as 0o27 for Python3 compatibility.
        os.umask(0o27)

        # Change to a known directory. If this isn't done, starting a daemon in a subdirectory that
        # needs to be deleted results in "directory busy" errors.
        os.chdir("/")

        # Execute privileged action
        priviled_action_result = self.privileged_action()

        # Change gid
        if self.group:
            try:
                gid = grp.getgrnam(self.group).gr_gid
            except KeyError:
                self.logger.error("Group {0} not found".format(self.group))
                sys.exit(1)
            try:
                os.setgid(gid)
            except OSError:
                self.logger.error("Unable to change gid.")
                sys.exit(1)

        # Change uid
        if self.user:
            try:
                uid = pwd.getpwnam(self.user).pw_uid
            except KeyError:
                self.logger.error("User {0} not found.".format(self.user))
                sys.exit(1)
            try:
                os.setuid(uid)
            except OSError:
                self.logger.error("Unable to change uid.")
                sys.exit(1)

        try:
            # Create a lockfile so that only one instance of this daemon is running at any time.
            lockfile = open(self.pid, "w")
        except IOError:
            self.logger.error("Unable to create a pidfile.")
            sys.exit(1)
        try:
            # Try to get an exclusive lock on the file. This will fail if another process has the file
            # locked.
            fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
            # Record the process id to the lockfile. This is standard practice for daemons.
            lockfile.write("%s" % (os.getpid()))
            lockfile.flush()
        except IOError:
            self.logger.error("Unable to lock on the pidfile.")
            os.remove(self.pid)
            sys.exit(1)

        # Set custom action on SIGTERM.
        signal.signal(signal.SIGTERM, self.sigterm)
        atexit.register(self.exit)

        self.logger.warn("Starting daemon.")

        self.action(*priviled_action_result)