def filter_command(command, rootwrap_config):
    # Load rootwrap configuration
    try:
        rawconfig = ConfigParser.RawConfigParser()
        rawconfig.read(rootwrap_config)
        rw_config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        LOG.error(_LE('Incorrect value in %(config)s: %(exc)s'),
                  {'config': rootwrap_config, 'exc': exc.message})
        sys.exit(errno.EINVAL)
    except ConfigParser.Error:
        LOG.error(_LE('Incorrect configuration file: %(config)s'),
                  {'config': rootwrap_config})
        sys.exit(errno.EINVAL)

    # Check if command matches any of the loaded filters
    filters = wrapper.load_filters(rw_config.filters_path)
    try:
        wrapper.match_filter(filters, command, exec_dirs=rw_config.exec_dirs)
    except wrapper.FilterMatchNotExecutable as exc:
        LOG.error(_LE('Command %(command)s is not executable: '
                      '%(path)s (filter match = %(name)s)'),
                  {'command': command,
                   'path': exc.match.exec_path,
                   'name': exc.match.name})
        sys.exit(errno.EINVAL)
    except wrapper.NoFilterMatched:
        LOG.error(_LE('Unauthorized command: %(cmd)s (no filter matched)'),
                  {'cmd': command})
        sys.exit(errno.EPERM)
def filter_command(command, rootwrap_config):
    # Load rootwrap configuration
    try:
        rawconfig = ConfigParser.RawConfigParser()
        rawconfig.read(rootwrap_config)
        rw_config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        LOG.error('Incorrect value in %(config)s: %(exc)s', {
            'config': rootwrap_config,
            'exc': exc
        })
        sys.exit(errno.EINVAL)
    except ConfigParser.Error:
        LOG.error('Incorrect configuration file: %(config)s',
                  {'config': rootwrap_config})
        sys.exit(errno.EINVAL)

    # Check if command matches any of the loaded filters
    filters = wrapper.load_filters(rw_config.filters_path)
    try:
        wrapper.match_filter(filters, command, exec_dirs=rw_config.exec_dirs)
    except wrapper.FilterMatchNotExecutable as exc:
        LOG.error(
            'Command %(command)s is not executable: '
            '%(path)s (filter match = %(name)s)', {
                'command': command,
                'path': exc.match.exec_path,
                'name': exc.match.name
            })
        sys.exit(errno.EINVAL)
    except wrapper.NoFilterMatched:
        LOG.error('Unauthorized command: %(cmd)s (no filter matched)',
                  {'cmd': command})
        sys.exit(errno.EPERM)
Exemple #3
0
    def test_strict_switched_off_in_configparser(self):
        temp_dir = self.useFixture(fixtures.TempDir()).path
        temp_file = os.path.join(temp_dir, 'test.conf')
        f = open(temp_file, 'w')
        f.write("""[Filters]
privsep: PathFilter, privsep-helper, root
privsep: PathFilter, privsep-helper, root
""")
        f.close()
        filterlist = wrapper.load_filters([temp_dir])
        self.assertIsNotNone(filterlist)
Exemple #4
0
    def test_privsep_in_loader(self):
        privsep = ["privsep-helper", "--context", "foo"]
        filterlist = wrapper.load_filters([])

        # mock out get_exec because
        with mock.patch.object(filters.CommandFilter, 'get_exec') as ge:
            ge.return_value = "/fake/privsep-helper"
            filtermatch = wrapper.match_filter(filterlist, privsep)

            self.assertIsNotNone(filtermatch)
            self.assertEqual(["/fake/privsep-helper", "--context", "foo"],
                             filtermatch.get_command(privsep))
Exemple #5
0
def main(run_daemon=False):
    # Split arguments, require at least a command
    execname = sys.argv.pop(0)
    if run_daemon:
        if len(sys.argv) != 1:
            _exit_error(execname,
                        "Extra arguments to daemon",
                        RC_NOCOMMAND,
                        log=False)
    else:
        if len(sys.argv) < 2:
            _exit_error(execname,
                        "No command specified",
                        RC_NOCOMMAND,
                        log=False)

    configfile = sys.argv.pop(0)

    # Load configuration
    try:
        rawconfig = moves.configparser.RawConfigParser()
        rawconfig.read(configfile)
        config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        msg = "Incorrect value in %s: %s" % (configfile, exc.message)
        _exit_error(execname, msg, RC_BADCONFIG, log=False)
    except moves.configparser.Error:
        _exit_error(execname,
                    "Incorrect configuration file: %s" % configfile,
                    RC_BADCONFIG,
                    log=False)

    if config.use_syslog:
        wrapper.setup_syslog(execname, config.syslog_log_facility,
                             config.syslog_log_level)

    filters = wrapper.load_filters(config.filters_path)

    if run_daemon:
        daemon_mod.daemon_start(config, filters)
    else:
        run_one_command(execname, config, filters, sys.argv)
Exemple #6
0
def main(run_daemon=False):
    # Split arguments, require at least a command
    execname = sys.argv.pop(0)
    if run_daemon:
        if len(sys.argv) != 1:
            _exit_error(execname, "Extra arguments to daemon", RC_NOCOMMAND,
                        log=False)
    else:
        if len(sys.argv) < 2:
            _exit_error(execname, "No command specified", RC_NOCOMMAND,
                        log=False)

    configfile = sys.argv.pop(0)

    # Load configuration
    try:
        rawconfig = moves.configparser.RawConfigParser()
        rawconfig.read(configfile)
        config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        msg = "Incorrect value in %s: %s" % (configfile, exc.message)
        _exit_error(execname, msg, RC_BADCONFIG, log=False)
    except moves.configparser.Error:
        _exit_error(execname, "Incorrect configuration file: %s" % configfile,
                    RC_BADCONFIG, log=False)

    if config.use_syslog:
        wrapper.setup_syslog(execname,
                             config.syslog_log_facility,
                             config.syslog_log_level)

    filters = wrapper.load_filters(config.filters_path)

    if run_daemon:
        # NOTE(dims): When not running as daemon, this import
        # slows us down just a bit. So moving it here so we have
        # it only when we need it.
        from oslo_rootwrap import daemon as daemon_mod
        daemon_mod.daemon_start(config, filters)
    else:
        run_one_command(execname, config, filters, sys.argv)
Exemple #7
0
def main(run_daemon=False):
    # Split arguments, require at least a command
    execname = sys.argv.pop(0)
    if run_daemon:
        if len(sys.argv) != 1:
            _exit_error(execname, "Extra arguments to daemon", RC_NOCOMMAND,
                        log=False)
    else:
        if len(sys.argv) < 2:
            _exit_error(execname, "No command specified", RC_NOCOMMAND,
                        log=False)

    configfile = sys.argv.pop(0)

    # Load configuration
    try:
        rawconfig = moves.configparser.RawConfigParser()
        rawconfig.read(configfile)
        config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        msg = "Incorrect value in %s: %s" % (configfile, exc.args[0])
        _exit_error(execname, msg, RC_BADCONFIG, log=False)
    except moves.configparser.Error:
        _exit_error(execname, "Incorrect configuration file: %s" % configfile,
                    RC_BADCONFIG, log=False)

    if config.use_syslog:
        wrapper.setup_syslog(execname,
                             config.syslog_log_facility,
                             config.syslog_log_level)

    filters = wrapper.load_filters(config.filters_path)

    if run_daemon:
        # NOTE(dims): When not running as daemon, this import
        # slows us down just a bit. So moving it here so we have
        # it only when we need it.
        from oslo_rootwrap import daemon as daemon_mod
        daemon_mod.daemon_start(config, filters)
    else:
        run_one_command(execname, config, filters, sys.argv)
Exemple #8
0
def main(run_daemon=False):
    # Split arguments, require at least a command
    execname = sys.argv.pop(0)
    if run_daemon:
        if len(sys.argv) != 1:
            _exit_error(execname, "Extra arguments to daemon", RC_NOCOMMAND,
                        log=False)
    else:
        if len(sys.argv) < 2:
            _exit_error(execname, "No command specified", RC_NOCOMMAND,
                        log=False)

    configfile = sys.argv.pop(0)

    # Load configuration
    try:
        rawconfig = moves.configparser.RawConfigParser()
        rawconfig.read(configfile)
        config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        msg = "Incorrect value in %s: %s" % (configfile, exc.message)
        _exit_error(execname, msg, RC_BADCONFIG, log=False)
    except moves.configparser.Error:
        _exit_error(execname, "Incorrect configuration file: %s" % configfile,
                    RC_BADCONFIG, log=False)

    if config.use_syslog:
        wrapper.setup_syslog(execname,
                             config.syslog_log_facility,
                             config.syslog_log_level)

    filters = wrapper.load_filters(config.filters_path)

    if run_daemon:
        daemon_mod.daemon_start(config, filters)
    else:
        run_one_command(execname, config, filters, sys.argv)
Exemple #9
0
def main(run_daemon=False):
    # Split arguments, require at least a command
    execname = sys.argv.pop(0)
    if run_daemon:
        if len(sys.argv) != 1:
            _exit_error(execname,
                        "Extra arguments to daemon",
                        RC_NOCOMMAND,
                        log=False)
    else:
        if len(sys.argv) < 2:
            _exit_error(execname,
                        "No command specified",
                        RC_NOCOMMAND,
                        log=False)

    configfile = sys.argv.pop(0)

    # Load configuration
    try:
        rawconfig = moves.configparser.RawConfigParser()
        rawconfig.read(configfile)
        config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        msg = "Incorrect value in %s: %s" % (configfile, exc.args[0])
        _exit_error(execname, msg, RC_BADCONFIG, log=False)
    except moves.configparser.Error:
        _exit_error(execname,
                    "Incorrect configuration file: %s" % configfile,
                    RC_BADCONFIG,
                    log=False)

    if resource:
        # When use close_fds=True on Python 2.x, calling subprocess with
        # close_fds=True (which we do by default) can be inefficient when
        # the current fd ulimits are large, because it blindly closes
        # all fds in the range(1, $verylargenumber)

        # Lower our ulimit to a reasonable value to regain performance.
        fd_limits = resource.getrlimit(resource.RLIMIT_NOFILE)
        sensible_fd_limit = min(config.rlimit_nofile, fd_limits[0])
        if (fd_limits[0] > sensible_fd_limit):
            # Close any fd beyond sensible_fd_limit prior adjusting our
            # rlimit to ensure all fds are closed
            for fd_entry in os.listdir('/proc/self/fd'):
                # NOTE(dmllr): In a previous patch revision non-numeric
                # dir entries were silently ignored which reviewers
                # didn't like. Readd exception handling when it occurs.
                fd = int(fd_entry)
                if fd >= sensible_fd_limit:
                    os.close(fd)
            # Unfortunately this inherits to our children, so allow them to
            # re-raise by passing through the hard limit unmodified
            resource.setrlimit(resource.RLIMIT_NOFILE,
                               (sensible_fd_limit, fd_limits[1]))
            # This is set on import to the hard ulimit. if its defined we
            # already have imported it, so we need to update it to the new
            # limit.
            if (hasattr(subprocess, 'MAXFD')
                    and subprocess.MAXFD > sensible_fd_limit):
                subprocess.MAXFD = sensible_fd_limit

    if config.use_syslog:
        wrapper.setup_syslog(execname, config.syslog_log_facility,
                             config.syslog_log_level)

    filters = wrapper.load_filters(config.filters_path)

    if run_daemon:
        # NOTE(dims): When not running as daemon, this import
        # slows us down just a bit. So moving it here so we have
        # it only when we need it.
        from oslo_rootwrap import daemon as daemon_mod
        daemon_mod.daemon_start(config, filters)
    else:
        run_one_command(execname, config, filters, sys.argv)
Exemple #10
0
def main(run_daemon=False):
    # Split arguments, require at least a command
    execname = sys.argv.pop(0)
    if run_daemon:
        if len(sys.argv) != 1:
            _exit_error(execname, "Extra arguments to daemon", RC_NOCOMMAND,
                        log=False)
    else:
        if len(sys.argv) < 2:
            _exit_error(execname, "No command specified", RC_NOCOMMAND,
                        log=False)

    configfile = sys.argv.pop(0)

    # Load configuration
    try:
        rawconfig = moves.configparser.RawConfigParser()
        rawconfig.read(configfile)
        config = wrapper.RootwrapConfig(rawconfig)
    except ValueError as exc:
        msg = "Incorrect value in %s: %s" % (configfile, exc.args[0])
        _exit_error(execname, msg, RC_BADCONFIG, log=False)
    except moves.configparser.Error:
        _exit_error(execname, "Incorrect configuration file: %s" % configfile,
                    RC_BADCONFIG, log=False)

    if resource:
        # When use close_fds=True on Python 2.x, calling subprocess with
        # close_fds=True (which we do by default) can be inefficient when
        # the current fd ulimits are large, because it blindly closes
        # all fds in the range(1, $verylargenumber)

        # Lower our ulimit to a reasonable value to regain performance.
        fd_limits = resource.getrlimit(resource.RLIMIT_NOFILE)
        sensible_fd_limit = min(config.rlimit_nofile, fd_limits[0])
        if (fd_limits[0] > sensible_fd_limit):
            # Close any fd beyond sensible_fd_limit prior adjusting our
            # rlimit to ensure all fds are closed
            for fd_entry in os.listdir('/proc/self/fd'):
                # NOTE(dmllr): In a previous patch revision non-numeric
                # dir entries were silently ignored which reviewers
                # didn't like. Readd exception handling when it occurs.
                fd = int(fd_entry)
                if fd >= sensible_fd_limit:
                    os.close(fd)
            # Unfortunately this inherits to our children, so allow them to
            # re-raise by passing through the hard limit unmodified
            resource.setrlimit(
                resource.RLIMIT_NOFILE, (sensible_fd_limit, fd_limits[1]))
            # This is set on import to the hard ulimit. if its defined we
            # already have imported it, so we need to update it to the new
            # limit.
            if (hasattr(subprocess, 'MAXFD') and
                    subprocess.MAXFD > sensible_fd_limit):
                subprocess.MAXFD = sensible_fd_limit

    if config.use_syslog:
        wrapper.setup_syslog(execname,
                             config.syslog_log_facility,
                             config.syslog_log_level)

    filters = wrapper.load_filters(config.filters_path)

    if run_daemon:
        # NOTE(dims): When not running as daemon, this import
        # slows us down just a bit. So moving it here so we have
        # it only when we need it.
        from oslo_rootwrap import daemon as daemon_mod
        daemon_mod.daemon_start(config, filters)
    else:
        run_one_command(execname, config, filters, sys.argv)