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)
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)
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))
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)
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)
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)
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)
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)