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)
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)
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)
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 ) )
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)
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
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)
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)
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
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
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)
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)
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)
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]
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
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())
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
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() )
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))
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)
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)
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)
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)
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', })
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
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
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
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)
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
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)
def result(): #print 'uid, gid = %d, %d; %s' % (os.getuid(), os.getgid(), 'starting reincarnation') os.setgid(user_gid) os.setuid(user_uid)
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
def set_ids(): os.setgid(gid) os.setuid(uid)
def drop_root_privilege() -> None: if os.getuid() == 0: pw = pwd.getpwnam('nobody') os.setgid(pw.pw_gid) os.setuid(pw.pw_uid)
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, '..'))
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:
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)))
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']):
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)
def prepare(): cgclassify(job.job_id,os.getpid()) #os.setpgrp() if os.getuid() == 0: os.setgid(job.owner_gid) os.setuid(job.owner_uid)
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"
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")
#!/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)
def preexec(): os.setgid(self._get_gid_of_uid(self.vdus.user.uid)) os.setuid(self.vdus.user.uid)
def wrapper(): if user is not None: os.setuid(user) if group is not None: os.setgid(group)
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)
def switch_uid_gid(): if gid is not None: os.setgid(gid) if uid is not None: os.setuid(uid)
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()))
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)
def preexec(): if resource.group: gid = _coerce_gid(resource.group) os.setgid(gid) os.setegid(gid)
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)
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()
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()
def result(): os.setgid(grp.getgrnam(user).gr_gid) os.setuid(pwd.getpwnam(user).pw_uid)
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',
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)
# 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.
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)