Exemple #1
0
def main():
    """
    The entry point of daemon_factory process
    """
    parser = argparse.ArgumentParser(
        description='Factory process to manage storlet daemons')
    parser.add_argument('sbus_path', help='the path to unix domain socket')
    parser.add_argument('log_level', help='log level')
    parser.add_argument('container_id', help='container id')
    opts = parser.parse_args()

    # Initialize logger
    logger = get_logger("daemon-factory", opts.log_level, opts.container_id)
    logger.debug("Daemon factory started")

    try:
        SBus.start_logger("DEBUG", container_id=opts.container_id)

        # Impersonate the swift user
        pw = pwd.getpwnam('swift')
        os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
        os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

        # create an instance of daemon_factory
        factory = StorletDaemonFactory(opts.sbus_path, logger,
                                       opts.container_id)

        # Start the main loop
        sys.exit(factory.main_loop())

    except Exception:
        logger.eception('Unhandled exception')
        sys.exit(EXIT_FAILURE)
Exemple #2
0
 def __init__(self, user, visitor, token):
     self.user = user
     self.visitor = visitor
     self.token = token
     if os.geteuid() is 0:
         os.setresgid(61015, 61015, 61015)
         os.setresuid(61020, 61020, 61020)
Exemple #3
0
def prepare(suid, slave):
    if suid is not None:
        try:
            if not type(suid) in (int, long):
                userinfo = pwd.getpwnam(suid)
                suid = userinfo.pw_uid
                sgid = userinfo.pw_gid
            else:
                userinfo = pwd.getpwuid(suid)
                sgid = userinfo.pw_gid
        except:
            pass

        try:
            if slave:
                path = os.getttyname(slave)
                os.chown(path, suid)
        except:
            pass

        try:
            os.initgroups(userinfo.pw_name, sgid)
            os.chdir(userinfo.pw_dir)
        except:
            pass

        try:
            os.setresgid(suid, suid, sgid)
            os.setresuid(suid, suid, sgid)
        except:
            pass

    os.setsid()
    fcntl.ioctl(sys.stdin, termios.TIOCSCTTY, 0)
Exemple #4
0
 def _drop_privs(self):
     # First get the list of groups to assign.
     # This *should* generate a list *exactly* like as if that user ran os.getgroups(),
     # with the addition of self.cfg['build_user']['gid'] (if it isn't included already).
     newgroups = list(
         sorted([
             g.gr_gid for g in grp.getgrall()
             if pwd.getpwuid(self.cfg['build_user']['uid']) in g.gr_mem
         ]))
     if self.cfg['build_user']['gid'] not in newgroups:
         newgroups.append(self.cfg['build_user']['gid'])
         newgroups.sort()
     # This is the user's "primary group"
     user_gid = pwd.getpwuid(self.cfg['build_user']['uid']).pw_gid
     if user_gid not in newgroups:
         newgroups.append(user_gid)
     os.setgroups(newgroups)
     # If we used os.setgid and os.setuid, we would PERMANENTLY/IRREVOCABLY drop privs.
     # Being that that doesn't suit the meta of the rest of the script (chmodding, etc.) - probably not a good idea.
     os.setresgid(self.cfg['build_user']['gid'],
                  self.cfg['build_user']['gid'], -1)
     os.setresuid(self.cfg['build_user']['uid'],
                  self.cfg['build_user']['uid'], -1)
     # Default on most linux systems. reasonable enough for building? (equal to chmod 755/644)
     os.umask(0o0022)
     # TODO: we need a full env construction here, I think, as well. PATH, HOME, GNUPGHOME at the very least?
     return ()
Exemple #5
0
def EnterSandbox(user: str, group: str) -> None:
    """Enters the sandbox.

  Drops root privileges, by changing the user and group.

  Args:
    user: New UNIX user name to run as. If empty then the user is not changed.
    group: New UNIX group name to run as. If empty then the group is not
      changed.
  """
    if group:
        gid = grp.getgrnam(group).gr_gid
        os.setgroups([gid])
        if getattr(os, "setresgid", False):
            # We prefer setresgid if available, which is the case on Linux.
            # The reason is that it's the most explicit of the various set*id
            # variants.
            os.setresgid(gid, gid, gid)
        else:
            # This is the same as the above if called by the superuser.
            os.setgid(gid)

    if user:
        uid = pwd.getpwnam(user).pw_uid
        if getattr(os, "setresuid", False):
            # We prefer setresuid if available, which is the case on Linux.
            # The reason is that it's the most explicit of the various set*id
            # variants.
            os.setresuid(uid, uid, uid)
        else:
            # This is the same as the above if called by the superuser.
            os.setuid(uid)
Exemple #6
0
def main(argv):
    """
    The entry point of daemon_factory process

    :param argv: parameters given from command line
    """
    if (len(argv) != 5):
        usage()
        return EXIT_FAILURE

    storlet_name = argv[0]
    sbus_path = argv[1]
    log_level = argv[2]
    pool_size = argv[3]
    container_id = argv[4]

    # Initialize logger
    logger = start_logger("storlets-daemon", log_level, container_id)
    logger.debug("Storlet Daemon started")
    SBus.start_logger("DEBUG", container_id=container_id)

    # Impersonate the swift user
    pw = pwd.getpwnam('swift')
    os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
    os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

    # create an instance of storlet daemon
    try:
        daemon = Daemon(storlet_name, sbus_path, logger, pool_size)
    except Exception as e:
        logger.error(e.message)
        return EXIT_FAILURE

    # Start the main loop
    return daemon.main_loop()
Exemple #7
0
 def start(self):
     serversockets = []
     for port in self.ports:
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         try:
             s.bind(("", port))
         except socket.error as e:
             self.print_error("Could not bind port %s: %s." % (port, e))
             sys.exit(1)
         s.listen(5)
         serversockets.append(s)
         del s
         self.print_info("Listening on port %d." % port)
     if self.chroot:
         os.chdir(self.chroot)
         os.chroot(self.chroot)
         self.print_info("Changed root directory to %s" % self.chroot)
     if self.setuid:
         os.setresgid(self.setuid[1], self.setuid[1], self.setuid[1])
         os.setresuid(self.setuid[0], self.setuid[0], self.setuid[0])
         self.print_info("Setting uid:gid to %s:%s"
                         % (self.setuid[0], self.setuid[1]))
     last_aliveness_check = time.time()
     while True:
         (iwtd, owtd, ewtd) = select.select(
             serversockets + [x.socket for x in self.clients.values()],
             [x.socket for x in self.clients.values()
                       if x.write_queue_size() > 0],
             [],
             10)
         for x in iwtd:
             if x in self.clients:
                 self.clients[x].socket_readable_notification()
             else:
                 (conn, addr) = x.accept()
                 if self.ssl_pem_file:
                     import ssl
                     try:
                         conn = ssl.wrap_socket(
                             conn,
                             server_side=True,
                             certfile=self.ssl_pem_file,
                             keyfile=self.ssl_pem_file)
                     except ssl.SSLError as e:
                         self.print_error(
                             "SSL error for connection from %s:%s: %s" % (
                                 addr[0], addr[1], e))
                         continue
                 self.clients[conn] = self.client_factory(conn)
                 self.print_info("Accepted connection from %s:%s." % (
                     addr[0], addr[1]))
         for x in owtd:
             if x in self.clients: # client may have been disconnected
                 self.clients[x].socket_writable_notification()
         now = time.time()
         if last_aliveness_check + 10 < now:
             for client in self.clients.values():
                 client.check_aliveness()
             last_aliveness_check = now
Exemple #8
0
 def inner(*args, **kwargs):
     # Get sudoer's UID
     try:
         sudo_uid = int(os.environ['SUDO_UID'])
     except (KeyError, ValueError):
         print("Could not get UID for sudoer", file=sys.stderr)
         return
     # Get sudoer's GID
     try:
         sudo_gid = int(os.environ['SUDO_GID'])
     except (KeyError, ValueError):
         print("Could not get GID for sudoer", file=sys.stderr)
         return
     # Make sure groups are reset
     try:
         os.setgroups([])
     except PermissionError:
         pass
     # Drop root
     os.setresgid(sudo_gid, sudo_gid, -1)
     os.setresuid(sudo_uid, sudo_uid, -1)
     # Execute function
     ret = function(*args, **kwargs)
     # Get root back
     os.setresgid(0, 0, -1)
     os.setresuid(0, 0, -1)
     return ret
Exemple #9
0
    def _unmount_as_user_fstab_fail(self, pipe, uid, gid, device):
        """ Try to unmount @device as user with given @uid and @gid.
            @device shouldn't be listed in /etc/fstab when running this, so
            this is expected to fail.
        """
        os.setresgid(gid, gid, gid)
        os.setresuid(uid, uid, uid)

        # try to mount the device -- it should fail
        try:
            safe_dbus.call_sync(self.iface_prefix,
                                self.path_prefix + '/block_devices/' + os.path.basename(device),
                                self.iface_prefix + '.Filesystem',
                                'Unmount',
                                GLib.Variant('(a{sv})', ({},)))
        except Exception as e:
            msg = 'GDBus.Error:org.freedesktop.UDisks2.Error.NotAuthorizedCanObtain: Not authorized to perform operation'
            if msg in str(e):
                pipe.send([True, ''])
                pipe.close()
                return
            else:
                pipe.send([False, 'Unmount DBus call failed with unexpected exception: %s' % str(e)])
                pipe.close()
                return

        ret, _out = self.run_command('grep \"%s\" /proc/mounts' % device)
        if ret == 0:
            pipe.send([False, 'Unmount DBus call didn\'t fail but %s seems to be still mounted.' % device])
            pipe.close()
            return
        else:
            pipe.send([False, '%s was unmounted for UID %d without proper record in fstab' % (device, uid)])
            pipe.close()
            return
Exemple #10
0
def demote_subprocess():
    """
    Lower the privileges of the spawned subprocess by setting limits on its resource use and
    by switching it to be run as another user.

    NOTE: The resource limits were set by using ulimit and shell=True before. This was changed
          in order to address security questions raised by using the shell and to make passing
          arguments easier.
    """
    #info("Demoting subprocess.")
    # Set resource limits
    resource.setrlimit(resource.RLIMIT_NPROC, (10, 10))  # Prevent fork bombs
    resource.setrlimit(resource.RLIMIT_NOFILE, (50, 50)) # Limit number of files
    resource.setrlimit(resource.RLIMIT_FSIZE, (500*1024, 500*1024))  # Limit space used by a file
    resource.setrlimit(resource.RLIMIT_CPU, (2, 2))      # Limit CPU time
    
    # Change the group and user IDs to lower privileged ones
    user_gid = Privileges.get_low_gid()
    user_uid = Privileges.get_low_uid()
    try:
        os.setresgid(user_gid, user_gid, user_gid)
        os.setresuid(user_uid, user_uid, user_uid)
    except OSError:
        #error("Unable to demote the subprocess to uid: %d, gid: %d!" % (user_uid, user_gid))
        pass
    else:
        #info("Successfully demoted the subprocess to uid: %d, gid: %d." % (user_uid, user_gid))
        pass
Exemple #11
0
def main(argv):
    """
    The entry point of daemon_factory process

    :param argv: parameters given from command line
    """
    if (len(argv) != 3):
        usage()
        # TODO(takashi): returning non-zero value is better?
        return

    pipe_path = argv[0]
    log_level = argv[1]
    container_id = argv[2]

    # Initialize logger
    logger = start_logger("daemon_factory", log_level, container_id)
    logger.debug("Daemon factory started")
    SBus.start_logger("DEBUG", container_id=container_id)

    # Impersonate the swift user
    pw = pwd.getpwnam('swift')
    os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
    os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

    # create an instance of daemon_factory
    factory = daemon_factory(pipe_path, logger)

    # Start the main loop
    factory.main_loop(container_id)
def root_privileges_drop():
    if (os.geteuid() == 0 and 'SUDO_GID' in os.environ
            and 'SUDO_UID' in os.environ):
        sudo_gid = int(os.environ['SUDO_GID'])
        sudo_uid = int(os.environ['SUDO_UID'])
        os.setresgid(sudo_gid, sudo_gid, -1)
        os.setresuid(sudo_uid, sudo_uid, -1)
Exemple #13
0
def runfastcgi(argset=[], **kwargs):
    options = FASTCGI_OPTIONS.copy()
    options.update(kwargs)
    for x in argset:
        if '=' in x:
            k, v = x.split('=', 1)
        else:
            k, v = x, True
        options[k.lower()] = v

    if 'help' in options:
        return fastcgi_help()

    if 'run_as' in options:
        from pwd import getpwnam
        try:
            pw = getpwnam(options['run_as'])
        except KeyError:
            pw = None
        if pw:
            os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
            os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

    try:
        import flup
    except ImportError, e:
        print >> sys.stderr, 'ERROR: %s' % e
        print >> sys.stderr, '  Unable to load the flup package.  In order to run pyzzle'
        print >> sys.stderr, '  as a FastCGI application, you will need to get flup from'
        print >> sys.stderr, "  http://www.saddi.com/software/flup/   If you've already"
        print >> sys.stderr, '  installed flup, then make sure you have it in your PYTHONPATH.'
        return False
Exemple #14
0
def drop_privileges(user, group):
    if user is None:
        uid = os.getuid()
    elif user.lstrip("-").isdigit():
        uid = int(user)
    else:
        uid = pwd.getpwnam(user).pw_uid

    if group is None:
        gid = os.getgid()
    elif group.lstrip("-").isdigit():
        gid = int(group)
    else:
        gid = grp.getgrnam(group).gr_gid

    username = pwd.getpwuid(uid).pw_name
    # groupname = grp.getgrgid(gid).gr_name
    groups = [g for g in grp.getgrall() if username in g.gr_mem]

    os.setgroups(groups)
    if hasattr(os, 'setresgid'):
        os.setresgid(gid, gid, gid)
    else:
        os.setregid(gid, gid)
    if hasattr(os, 'setresuid'):
        os.setresuid(uid, uid, uid)
    else:
        os.setreuid(uid, uid)
Exemple #15
0
    def _mount_as_user_fstab(self, pipe, uid, gid, device):
        """ Try to mount and then unmount @device as user with given @uid and
            @gid.
            @device should be listed in /etc/fstab with proper options so user
            is able to run these operations and this shouldn't fail.
        """
        os.setresgid(gid, gid, gid)
        os.setresuid(uid, uid, uid)

        # try to mount the device
        try:
            safe_dbus.call_sync(self.iface_prefix,
                                self.path_prefix + '/block_devices/' + os.path.basename(device),
                                self.iface_prefix + '.Filesystem',
                                'Mount',
                                GLib.Variant('(a{sv})', ({},)))
        except Exception as e:
            pipe.send([False, 'Mount DBus call failed: %s' % str(e)])
            pipe.close()
            return

        ret, out = self.run_command('grep \"%s\" /proc/mounts' % device)
        if ret != 0:
            pipe.send([False, '%s not mounted' % device])
            pipe.close()
            return

        if 'uid=%s,gid=%s' % (uid, gid) not in out:
            pipe.send([False, '%s not mounted with given uid/gid.\nMount info: %s' % (device, out)])
            pipe.close()
            return

        pipe.send([True, ''])
        pipe.close()
        return
Exemple #16
0
def prepare(suid, slave):
    if suid is not None:
        try:
            if not type(suid) in (int, long):
                userinfo = pwd.getpwnam(suid)
                suid = userinfo.pw_uid
                sgid = userinfo.pw_gid
            else:
                userinfo = pwd.getpwuid(suid)
                sgid = userinfo.pw_gid
        except:
            pass

        try:
            if slave:
                path = os.getttyname(slave)
                os.chown(path, suid)
        except:
            pass

        try:
            os.initgroups(userinfo.pw_name, sgid)
            os.chdir(userinfo.pw_dir)
        except:
            pass

        try:
            os.setresgid(suid, suid, sgid)
            os.setresuid(suid, suid, sgid)
        except:
            pass

    os.setsid()
    fcntl.ioctl(sys.stdin, termios.TIOCSCTTY, 0)
  def debug_server(self, shared_queue):
    self.read_configuration()

    uid = int(self.server_uid)
    if os.getuid() != uid:
      os.setresuid(uid, uid, uid)

    gid = int(self.server_gid)
    if os.getgid() != gid:
      os.setresgid(gid, gid, gid)

    for key in self.env:
      debug("Setting environment variable %s=%s" % (key, self.env[key]))
      os.putenv(key, self.env[key])

    if self.pre_command is not None:
      os.system(self.pre_command)

    crash = None
    for i in range(0,3):
      try:
        crash = self.launch_debugger(self.timeout, self.command, "")
        break
      except:
        log("Exception: %s" % sys.exc_info()[1])
        continue

    if self.post_command is not None:
      os.system(self.post_command)

    if crash is not None:
      self.crash_info = crash
      shared_queue.put(crash)
      return True
    return False
Exemple #18
0
def main():
    os.open('/bin/bash', os.O_RDONLY)
    fd = os.open('./flag', os.O_RDONLY)
    os.dup2(fd, 9)

    path = os.path.join('/tmp', secrets.token_hex(16))

    data = os.read(0, 0x10)
    os.close(0)
    check_input(data)

    fd = os.open(path, os.O_CREAT | os.O_RDWR, 0o777)
    os.write(fd, b'#!/d' + data)
    os.close(fd)

    pid = os.fork()
    if pid == 0:
        os.setresgid(NOGROUP, NOGROUP, NOGROUP)
        os.setresuid(NOBODY, NOBODY, NOBODY)
        try:
            os.execv(path, [path])
        except:
            os._exit(-1)
    else:
        os.waitpid(pid, 0)
        os.unlink(path)
Exemple #19
0
    def _unmount_as_user_fstab(self, pipe, uid, gid, device):
        """ Try to unmount @device as user with given @uid and @gid.
            @device should be listed in /etc/fstab with "users" option when running this, so
            this is expected to succeed.
        """
        os.setresgid(gid, gid, gid)
        os.setresuid(uid, uid, uid)

        # try to unmount the device
        try:
            safe_dbus.call_sync(self.iface_prefix,
                                self.path_prefix + '/block_devices/' + os.path.basename(device),
                                self.iface_prefix + '.Filesystem',
                                'Unmount',
                                GLib.Variant('(a{sv})', ({},)))
        except Exception as e:
            pipe.send([False, 'Unmount DBus call failed: %s' % str(e)])
            pipe.close()
            return

        ret, _out = self.run_command('grep \"%s\" /proc/mounts' % device)
        if ret == 0:
            pipe.send([False, 'Unmount DBus call didn\'t fail but %s seems to be still mounted.' % device])
            pipe.close()
            return
        else:
            pipe.send([True, ''])
            pipe.close()
            return
def main(argv):
    '''
    @summary: main
              The entry point. 
              - Initialize logger, 
              - impersonate to swift user,
              - create an instance of daemon_factory, 
              - start the main loop. 
    '''
    if (len(argv) != 2):
        usage()
        return
    
    pipe_path = argv[0]
    log_level = argv[1]
    logger = start_logger("daemon_factory", log_level)
    logger.debug("Daemon factory started")
    SBus.start_logger("DEBUG")
        
    # Impersonate the swift user
    pw = pwd.getpwnam('swift')
    os.setresgid(pw.pw_gid,pw.pw_gid,pw.pw_gid)
    os.setresuid(pw.pw_uid,pw.pw_uid,pw.pw_uid)

    
    factory = daemon_factory(pipe_path, logger)
    factory.main_loop()      
Exemple #21
0
def runfastcgi(app, argset=[], **kwargs):
    options = FASTCGI_OPTIONS.copy()
    options.update(kwargs)
    for x in argset:
        if '=' in x:
            k, v = x.split('=', 1)
        else:
            k, v = x, True
        options[k.lower()] = v

    if 'help' in options:
        return fastcgi_help()

    if 'run_as' in options:
        from pwd import getpwnam
        try:
            pw = getpwnam(options['run_as'])
        except KeyError:
            pw = None
        if pw:
            os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
            os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)
        

    try:
        import flup
    except ImportError, e:
        print >> sys.stderr, 'ERROR: %s' % e
        print >> sys.stderr, '  Unable to load the flup package.  In order to run rsted'
        print >> sys.stderr, '  as a FastCGI application, you will need to get flup from'
        print >> sys.stderr, "  http://www.saddi.com/software/flup/   If you've already"
        print >> sys.stderr, '  installed flup, then make sure you have it in your PYTHONPATH.'
        return False
    def _unmount_as_user_fstab_fail(self, pipe, uid, gid, device):
        """ Try to unmount @device as user with given @uid and @gid.
            @device shouldn't be listed in /etc/fstab when running this, so
            this is expected to fail.
        """
        os.setresgid(gid, gid, gid)
        os.setresuid(uid, uid, uid)

        # try to mount the device -- it should fail
        try:
            safe_dbus.call_sync(self.iface_prefix,
                                self.path_prefix + '/block_devices/' + os.path.basename(device),
                                self.iface_prefix + '.Filesystem',
                                'Unmount',
                                GLib.Variant('(a{sv})', ({},)))
        except Exception as e:
            msg = 'GDBus.Error:org.freedesktop.UDisks2.Error.NotAuthorizedCanObtain: Not authorized to perform operation'
            if msg in str(e):
                pipe.send([True, ''])
                pipe.close()
                return
            else:
                pipe.send([False, 'Unmount DBus call failed with unexpected exception: %s' % str(e)])
                pipe.close()
                return

        ret, _out = self.run_command('grep \"%s\" /proc/mounts' % device)
        if ret == 0:
            pipe.send([False, 'Unmount DBus call didn\'t fail but %s seems to be still mounted.' % device])
            pipe.close()
            return
        else:
            pipe.send([False, '%s was unmounted for UID %d without proper record in fstab' % (device, uid)])
            pipe.close()
            return
Exemple #23
0
def drop_privileges(user, group):
    if user is None:
        uid = os.getuid()
    elif user.lstrip("-").isdigit():
        uid = int(user)
    else:
        uid = pwd.getpwnam(user).pw_uid

    if group is None:
        gid = os.getgid()
    elif group.lstrip("-").isdigit():
        gid = int(group)
    else:
        gid = grp.getgrnam(group).gr_gid

    username = pwd.getpwuid(uid).pw_name
    # groupname = grp.getgrgid(gid).gr_name
    groups = [g for g in grp.getgrall() if username in g.gr_mem]

    os.setgroups(groups)
    if hasattr(os, 'setresgid'):
        os.setresgid(gid, gid, gid)
    else:
        os.setregid(gid, gid)
    if hasattr(os, 'setresuid'):
        os.setresuid(uid, uid, uid)
    else:
        os.setreuid(uid, uid)
def _demoted_child_call(uid, gid, ret_data_q, func):
    """Call a function/method with different uid/gid"""
    # Set UID and GID
    if gid and gid > 0:
        try:
            os.setresgid(gid, gid, gid)
        except OSError as err:
            ret_data_q.put(GbpServiceError("Setting GID (%s) failed: %s" %
                                           (gid, err)))
            sys.exit(_RET_FORK_ERR)
    if uid and uid > 0:
        try:
            os.setresuid(uid, uid, uid)
        except OSError as err:
            ret_data_q.put(GbpServiceError("Setting UID (%s) failed: %s" %
                                           (uid, err)))
            sys.exit(_RET_FORK_ERR)
        try:
            # Set environment
            os.environ['HOME'] = pwd.getpwuid(uid).pw_dir
        except KeyError:
            pass
    # Call the function
    try:
        # Func must be a callable without arguments
        ret = func()
    # pylint: disable=broad-except
    except Exception as err:
        ret_data_q.put(GbpChildBTError())
        sys.exit(_RET_FORK_ERR)
    # pylint: enable=broad-except
    else:
        ret_data_q.put(ret)
    sys.exit(_RET_FORK_OK)
Exemple #25
0
def set_user_context(user_details: dict) -> None:
    os.setgroups(user_details['grouplist'])
    os.setresgid(user_details['pw_gid'], user_details['pw_gid'],
                 user_details['pw_gid'])
    os.setresuid(user_details['pw_uid'], user_details['pw_uid'],
                 user_details['pw_uid'])

    if any(c() != v for c, v in (
        (os.getuid, user_details['pw_uid']),
        (os.geteuid, user_details['pw_uid']),
        (os.getgid, user_details['pw_gid']),
        (os.getegid, user_details['pw_gid']),
    )):
        raise Exception(
            f'Unable to set user context to {user_details["pw_name"]!r} user')

    try:
        os.chdir(user_details['pw_dir'])
    except Exception:
        os.chdir('/var/empty')

    os.environ.update({
        'HOME':
        user_details['pw_dir'],
        'PATH':
        '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/bin',
    })
Exemple #26
0
    def debug_server(self, shared_queue):
        self.read_configuration()

        uid = int(self.server_uid)
        if os.getuid() != uid:
            os.setresuid(uid, uid, uid)

        gid = int(self.server_gid)
        if os.getgid() != gid:
            os.setresgid(gid, gid, gid)

        for key in self.env:
            debug("Setting environment variable %s=%s" % (key, self.env[key]))
            os.putenv(key, self.env[key])

        if self.pre_command is not None:
            os.system(self.pre_command)

        crash = None
        for i in range(0, 3):
            try:
                crash = self.launch_debugger(self.timeout, self.command, "")
                break
            except:
                log("Exception: %s" % sys.exc_info()[1])
                continue

        if self.post_command is not None:
            os.system(self.post_command)

        if crash is not None:
            self.crash_info = crash
            shared_queue.put(crash)
            return True
        return False
Exemple #27
0
def _drop_priv(username):
    pw = pwd.getpwnam(username)
    groups = list(set([ g.gr_gid for g in grp.getgrall()
                        if pw.pw_name in g.gr_mem ] + [ pw.pw_gid]))
    os.setgroups(groups)
    os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
    os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)
Exemple #28
0
def drop_privileges():
	try:
		uid = os.getuid()
		gid = os.getgid()
		os.setresgid(gid, gid, gid)
		os.setresuid(uid, uid, uid)
	except:
		die('Unable to drop privileges')
Exemple #29
0
 def preexec():
     try:
         os.setresgid(1000, 1000, 1000)
         os.setresuid(1000, 1000, 1000)
         os.makedirs(home, 0o755, exist_ok=True)
         os.chdir(home)
     except e:
         print(e)
Exemple #30
0
 def __exit__(self, exc_type: Optional[Type[BaseException]],
              exc_value: Optional[BaseException],
              traceback: Optional[TracebackType]) -> None:
     os.umask(self.current_mask)
     unprivileged_uid = os.getresuid()[2]  # retrieve saved-set-UID
     unprivileged_gid = os.getresgid()[2]  # retrieve saved-set-GID
     os.setresuid(unprivileged_uid, unprivileged_uid, 0)
     os.setresgid(unprivileged_gid, unprivileged_gid, 0)
 def __init__(self, user, visitor):
     uid = 61060
     gid = 60000  # To access person and transfer db
     self.user = user
     self.visitor = visitor
     self.token = get_token(user)
     os.setresgid(gid, gid, gid)
     os.setresuid(uid, uid, uid)
def drop_privileges(uid_spec=None, uid=None, gid=None):
	if uid_spec:
		assert not (uid or gid), [uid_spec, uid, gid]
		uid, gid = parse_uid_spec(uid_spec)
	assert uid is not None and gid is not None, [uid_spec, uid, gid]
	os.setresgid(gid, gid, gid)
	os.setresuid(uid, uid, uid)
	log.debug('Switched uid/gid to %s:%s', uid, gid)
Exemple #33
0
 def __init__(self, user, visitor):
     self.user = user
     self.visitor = visitor
     credDb = zoodb.cred_setup() 
     cred = credDb.query(zoodb.Cred).get(self.user)
     self.token = cred.token
     os.setresgid(61013, 61013, 61013)            
     os.setresuid(61014, 61014, 61014)
Exemple #34
0
    def __set_unprivileged_user():
        """
        Set the real and effective user and group to an unprivileged user.
        """
        _, _, uid, gid, _, _, _ = pwd.getpwnam('enarksh')

        os.setresgid(gid, gid, 0)
        os.setresuid(uid, uid, 0)
Exemple #35
0
def setresgid(space, rgid, egid, sgid):
    """ setresgid(rgid, egid, sgid)
    
    Set the current process's real, effective, and saved group ids.
    """
    try:
        os.setresgid(rgid, egid, sgid)
    except OSError as e:
        raise wrap_oserror(space, e)
Exemple #36
0
def _change_privileges(root):
    gid = 0 if root else int(os.getenv('SUDO_GID'))
    uid = 0 if root else int(os.getenv('SUDO_UID'))

    if not root and uid == 0:
        raise Exception('Rights weren\'t changed!')

    os.setresgid(gid, gid, -1)
    os.setresuid(uid, uid, -1)
Exemple #37
0
 def __enter__(self) -> Tuple[int, int]:
     current_uid = os.geteuid()
     current_gid = os.getegid()
     if current_uid == 0 or current_gid == 0:
         raise CosmkError("nested privileges elevations do not work")
     os.setresgid(0, 0, current_gid)  # GID before UID otherwise this fails
     os.setresuid(0, 0, current_uid)
     self.current_mask = os.umask(0o022)
     return (current_uid, current_gid)
Exemple #38
0
 def restore_user_group(self):
     try:
         (ruid, euid, suid) = os.getresuid()
         (rgid, egid, sgid) = os.getresgid()
         os.setresuid(suid, suid, suid)
         os.setresgid(sgid, sgid, sgid)
     except Exception, e:
         log.error("Error: %s" % e)
         exit(1)
Exemple #39
0
def setresgid(space, rgid, egid, sgid):
    """ setresgid(rgid, egid, sgid)
    
    Set the current process's real, effective, and saved group ids.
    """
    try:
        os.setresgid(rgid, egid, sgid)
    except OSError as e:
        raise wrap_oserror(space, e)
Exemple #40
0
 def down_permissions(self):
     """ Drop our current permissions """
     try:
         os.setresgid(self.down_gid, self.down_gid, 0)
         os.setresuid(self.down_uid, self.down_uid, 0)
         os.environ['HOME'] = self.home_dir
     except Exception as e:
         print("Failed to drop permissions: {}".format(e))
         return False
     return True
Exemple #41
0
 def up_permissions(self):
     """ Elevate our current permissions """
     try:
         os.setresuid(0, 0, 0)
         os.setresgid(0, 0, 0)
         os.environ['HOME'] = '/root'
     except Exception as e:
         print("Failed to raise permissions: {}".format(e))
         return False
     return True
Exemple #42
0
 def down_permissions(self):
     """ Drop our current permissions """
     try:
         os.setresgid(self.down_gid, self.down_gid, 0)
         os.setresuid(self.down_uid, self.down_uid, 0)
         os.environ['HOME'] = self.home_dir
     except Exception as e:
         print("Failed to drop permissions: {}".format(e))
         return False
     return True
Exemple #43
0
 def up_permissions(self):
     """ Elevate our current permissions """
     try:
         os.setresuid(0, 0, 0)
         os.setresgid(0, 0, 0)
         os.environ['HOME'] = '/root'
     except Exception as e:
         print("Failed to raise permissions: {}".format(e))
         return False
     return True
Exemple #44
0
Fichier : sh.py Projet : mk-fg/fgc
def drop_privileges(uid_spec=None, uid=None, gid=None, log=None):
	if log is False: log = lambda *a,**k: None
	elif log is None: log = logging.getLogger('fgc.sh.drop_privileges')
	if uid_spec:
		assert not (uid or gid), [uid_spec, uid, gid]
		uid, gid = parse_uid_spec(uid_spec)
	assert uid is not None and gid is not None, [uid_spec, uid, gid]
	os.setresgid(gid, gid, gid)
	os.setresuid(uid, uid, uid)
	log.debug('Switched uid/gid to %s:%s', uid, gid)
    def _injectBackup(self):
        try:
            destination = self._get_volume_path()
        except RuntimeError as e:
            return (1, str(e))
        # NFS mounts using root_squash will fail if accessed with root user.
        # Dropping root privileges and moving to vdsm user.
        prev_xdg_runtime_dir = os.getenv('XDG_RUNTIME_DIR', None)
        try:
            os.setresgid(self._parent.environment[ohostedcons.VDSMEnv.KVM_GID],
                         self._parent.environment[ohostedcons.VDSMEnv.KVM_GID],
                         -1)
            os.setresuid(
                self._parent.environment[ohostedcons.VDSMEnv.VDSM_UID],
                self._parent.environment[ohostedcons.VDSMEnv.VDSM_UID], -1)
            # $XDG_RUNTIME_DIR is not set if the current user is not the
            # original user of the session
            os.unsetenv('XDG_RUNTIME_DIR')
        except OSError as os_err:
            self._parent.logger.error('Unable to drop root privileges')
            self._parent.logger.debug('exception', exc_info=True)
            raise os_err

        try:
            g = guestfs.GuestFS(python_return_dict=True)
            g.set_backend('direct')
            g.add_drive_opts(filename=destination, format='raw', readonly=0)
            self.logger.debug(
                'disk added from {path}'.format(path=destination))
            try:
                g.launch()
                self._parent.logger.debug('guestfs launched')
                g.mount('/dev/sda1', '/')
                self._parent.logger.debug('disk mounted')
                g.upload(
                    self._backup_src, self._parent.environment[
                        ohostedcons.Upgrade.DST_BACKUP_FILE])
                self._parent.logger.debug('backup file uploaded')
                g.umount('/')
                self._parent.logger.debug('disk unmounted')
            finally:
                g.shutdown()
        finally:
            g.close()
        try:
            # regain root privileges
            os.setresgid(0, 0, -1)
            os.setresuid(0, 0, -1)
            if prev_xdg_runtime_dir:
                os.environ['XDG_RUNTIME_DIR'] = prev_xdg_runtime_dir
        except OSError as os_err:
            self._parent.logger.error('Unable to regain root privileges')
            self._parent.logger.debug('exception', exc_info=True)
            raise os_err
        return (0, 'OK')
Exemple #46
0
 def _restore_privs(self):
     os.setresuid(self.cfg['orig_user']['uid'],
                  self.cfg['orig_user']['uid'],
                  self.cfg['orig_user']['uid'])
     os.setresgid(self.cfg['orig_user']['gid'],
                  self.cfg['orig_user']['gid'],
                  self.cfg['orig_user']['gid'])
     os.setgroups(self.cfg['orig_user']['groups'])
     os.umask(self.cfg['orig_user']['umask'])
     # TODO: if we change the env, we need to change it back here. I capture it in self.cfg['orig_user']['env'].
     return ()
Exemple #47
0
def _setuid():
    """
    Drop root: switch to UID 1000.

    Why call this? Because Linux gives special capabilities to root (even after
    we drop privileges).

    ref: man setresuid(2)
    """
    os.setresuid(1000, 1000, 1000)
    os.setresgid(1000, 1000, 1000)
Exemple #48
0
    def start_job(self):
        self.__log_job_start()

        # Create pipes for stdout and stderr.
        pipe_stdout = os.pipe()
        pipe_stderr = os.pipe()

        self.__child_pid = os.fork()
        if self.__child_pid == 0:
            # Child process.
            try:
                # Close the read ends from the pipes.
                os.close(pipe_stdout[0])
                os.close(pipe_stderr[0])

                # Duplicate stdout and stderr on the pipes.
                sys.stdout.flush()
                sys.stderr.flush()
                os.dup2(pipe_stdout[1], sys.stdout.fileno())
                os.dup2(pipe_stderr[1], sys.stderr.fileno())

                # Set the effective user and group.
                if self.__user_name in self.__allowed_users:
                    _, _, uid, gid, _, _, _ = pwd.getpwnam(self.__user_name)
                    os.setuid(0)
                    os.setresgid(gid, gid, gid)
                    os.setresuid(uid, uid, uid)
                else:
                    raise RuntimeError("Spanner is not allowed to start processes under user '%s'." % self.__user_name)

                # Set variable for subprocess.
                os.putenv('ENK_RND_ID', str(self.__rnd_id))
                os.putenv('ENK_SCH_ID', str(self.__sch_id))

                # Replace this child process with the actual job.
                os.execv(self.__args[0], self.__args)

            except Exception as e:
                self.__log.error('Unable to start job')
                self.__log.error('Reason: {}'.format(str(e)))
                self.__log.exception('Error')

                # Exit immediately without running the exit handlers (e.g. from daemon) from the parent process.
                os._exit(-1)
        else:
            # Parent process.
            # Close the write ends from the pipes.
            os.close(pipe_stdout[1])
            os.close(pipe_stderr[1])

            # Remember the fds for reading the stdout and stderr from the child process.
            self.__stdout = pipe_stdout[0]
            self.__stderr = pipe_stderr[0]
    def _mount_as_user_fstab(self, pipe, uid, gid, device):
        """ Try to mount and then unmount @device as user with given @uid and
            @gid.
            @device should be listed in /etc/fstab with proper options so user
            is able to run these operations and this shouldn't fail.
        """
        os.setresgid(gid, gid, gid)
        os.setresuid(uid, uid, uid)

        # try to mount the device
        try:
            safe_dbus.call_sync(self.iface_prefix,
                                self.path_prefix + '/block_devices/' + os.path.basename(device),
                                self.iface_prefix + '.Filesystem',
                                'Mount',
                                GLib.Variant('(a{sv})', ({},)))
        except Exception as e:
            pipe.send([False, 'Mount DBus call failed: %s' % str(e)])
            pipe.close()
            return

        ret, out = self.run_command('grep \"%s\" /proc/mounts' % device)
        if ret != 0:
            pipe.send([False, '%s not mounted' % device])
            pipe.close()
            return

        if 'uid=%s,gid=%s' % (uid, gid) not in out:
            pipe.send([False, '%s not mounted with given uid/gid.\nMount info: %s' % (device, out)])
            pipe.close()
            return

        # and now try to unmount it
        try:
            safe_dbus.call_sync(self.iface_prefix,
                                self.path_prefix + '/block_devices/' + os.path.basename(device),
                                self.iface_prefix + '.Filesystem',
                                'Unmount',
                                GLib.Variant('(a{sv})', ({},)))
        except Exception as e:
            pipe.send([False, 'Unmount DBus call failed: %s' % str(e)])
            pipe.close()
            return

        ret, _out = self.run_command('grep \"%s\" /proc/mounts' % device)
        if ret == 0:
            pipe.send([False, '%s mounted after unmount called' % device])
            pipe.close()
            return

        pipe.send([True, ''])
        pipe.close()
        return
Exemple #50
0
def drop_privileges_save():
    """Drop the real UID/GID as well, and hide them in saved IDs."""
    # At the moment, we only know how to handle this when effective
    # privileges were already dropped.
    assert _dropped_privileges is not None and _dropped_privileges > 0
    uid = os.environ.get('SUDO_UID')
    gid = os.environ.get('SUDO_GID')
    if uid is not None:
        uid = int(uid)
        set_groups_for_uid(uid)
    if gid is not None:
        gid = int(gid)
        os.setresgid(gid, gid, 0)
    if uid is not None:
        os.setresuid(uid, uid, 0)
Exemple #51
0
def launch_sequence():
	print "Creating resource directories."
	for resource in resources.values():
		if not os.path.exists(resource.path):
			print "Creating: %s" % resource.path
			os.mkdir(resource.path)
	print "Setting permissions on resources."
	for resource in resources.values():
		uid, gid = resource.uid, resource.gid
		for leaf in os.listdir(resource.path) + ["."]:
			path = resource.path + "/" + leaf
			# Set the owner bits.
			os.chown(path, uid, gid)
			# Set the permission bits.
			if os.path.isdir(path):
				# Justification:
				os.chmod(path, 0750) # rwxr-x---
			else:
				os.chmod(path, 0640) # rw-r-----
	wait_list = []
	for process in processes.values():
		print "Spawning", process.name
		# Delete the RPC resource socket, if there happens to be an old one sitting around.
		# XXX: This code knows about the convention of rpc/Service/sock!
		if process.rpc_resource != None:
			if os.path.exists(process.rpc_resource.path + "/sock"):
				os.unlink(process.rpc_resource.path + "/sock")
		pid = os.fork()
		if pid == 0:
			# Change into the dryer21 directory.
			os.chdir("/dryer21")
			# Drop permissions.
			os.setresgid(NO_PRIVS, NO_PRIVS, NO_PRIVS)
			os.setgroups(process.groups)
			os.setresuid(process.uid, process.uid, process.uid)
			# Now launch python on the given script.
			os.execve("/usr/bin/python", ["python", process.binary_path] + process.arguments, {"HOME": "/nonexistant", "PYTHONPATH": "/dryer21/code"})
		else:
			# Wait for the child to finish setting up, if it has an rpc_resource.
			# This is necessary to prevent race conditions where future processes try to connect before this one is done setting up.
			if process.rpc_resource != None:
				# Currently I just use a little spin loop, which is good enough -- I'm not going to use inotify.
				while not os.path.exists(process.rpc_resource.path + "/sock"):
					time.sleep(0.1)
			wait_list.append(pid)
	for pid in wait_list:
		os.waitpid(pid, 0)
	print "Exiting."
Exemple #52
0
def act(act_as):
    srv_uid = Privileges.get_high_uid()
    srv_gid = Privileges.get_high_gid()
    sp_uid = Privileges.get_low_uid()
    sp_gid = Privileges.get_low_gid()
    try:
        if act_as == "server":
            os.setresgid(srv_gid, sp_gid, srv_gid)
            os.setresuid(srv_uid, sp_uid, srv_uid)
        elif act_as == "subprocess":
            os.setresgid(srv_gid, sp_gid, sp_gid)
            os.setresuid(srv_uid, sp_uid, sp_uid)
    except OSError:
        error("Unable to set effective user rights as %s!" % (act_as))
    else:
        info("Effective user: %s." % (act_as))
Exemple #53
0
def demote_server():
    srv_uid = Privileges.get_high_uid()
    srv_gid = Privileges.get_high_gid()
    srv_name = Privileges.get_high_name()
    sp_uid = Privileges.get_low_uid()
    sp_gid = Privileges.get_low_gid()

    # Demote the server to server_uid, but allow further demotion to sp_uid
    try:
        # http://stackoverflow.com/a/6037494
        os.setresgid(srv_gid, sp_gid, sp_gid)
        os.setresuid(srv_uid, sp_uid, sp_uid)
    except OSError:
        error("Losing privileges not permitted.")
    else:
        info("Demoted the server process to user %s (%d) and group %d." % (srv_name, srv_uid, srv_gid))
Exemple #54
0
def _ReExecuteIfNeeded(argv, network):
  """Re-execute as root so we can unshare resources."""
  if os.geteuid() != 0:
    cmd = ['sudo', '-E', 'HOME=%s' % os.environ['HOME'],
           'PATH=%s' % os.environ['PATH'], '--'] + argv
    os.execvp(cmd[0], cmd)
  else:
    cgroups.Cgroup.InitSystem()
    namespaces.SimpleUnshare(net=not network, pid=True)
    # We got our namespaces, so switch back to the user to run the tests.
    gid = int(os.environ.pop('SUDO_GID'))
    uid = int(os.environ.pop('SUDO_UID'))
    user = os.environ.pop('SUDO_USER')
    os.initgroups(user, gid)
    os.setresgid(gid, gid, gid)
    os.setresuid(uid, uid, uid)
    os.environ['USER'] = user
Exemple #55
0
def drop_privileges():
    """
    Drop all the privileges that can be reasonably dropped. This is to prevent
    the forked process from harming its creator and from accessing any data
    belonging to the evaluation server process exclusively.

    For more information, review:
    - http://man7.org/linux/man-pages/man2/setresuid.2.html
    - https://docs.python.org/3/library/os.html#os.setresuid
    """

    # Drop the real, effective and saved group and user ids
    try:
        os.setresgid(student_gid, student_gid, student_gid)
        os.setresuid(student_uid, student_uid, student_uid)
    except OSError:
        print("Unable to drop privileges to GID: (r:{s_gid}, e:{s_gid}, s:{s_gid}), UID: (r:{s_uid}, e:{s_uid}, s:{s_uid})".
              format(s_gid=student_gid, s_uid=student_uid))
Exemple #56
0
def drop_privileges(user, group):
    """Drop privileges to specified user and group"""
    if group is not None:
        import grp
        gid = grp.getgrnam(group).gr_gid
        logger.debug("Dropping privileges to group {0}/{1}".format(group, gid))
        try:
            os.setresgid(gid, gid, gid)
        except AttributeError:
            os.setregid(gid, gid)
    if user is not None:
        import pwd
        uid = pwd.getpwnam(user).pw_uid
        logger.debug("Dropping privileges to user {0}/{1}".format(user, uid))
        try:
            os.setresuid(uid, uid, uid)
        except AttributeError:
            os.setreuid(uid, uid)
Exemple #57
0
def _do_callable( runnable ):
    "changes the user and group id of the process"
    ret = None
    exc = None
    exc_traceback = None
    stdout = ''
    try:
        # catch streams:
        with capture.StreamCapture() as output:
            os.setresuid( runnable.uid,runnable.uid,runnable.uid )
            os.setresgid( runnable.gid,runnable.gid,runnable.gid )
            ret = runnable.callable( *(runnable.args), **(runnable.kwargs) )        

        stdout = '\n'.join( output.getvalue() )
    except:
        exc_type, exc, exc_traceback = sys.exc_info()
        ret = None

    return RunResult( ret, exc, stdout ) # must be pickle-able, as it will travel between processes