diff --git a/meson.build b/meson.build index f7956689..02b59c83 100644 --- a/meson.build +++ b/meson.build @@ -28,7 +28,8 @@ config_data = configuration_data({ 'SBINDIR': get_option('prefix') / get_option('sbindir'), 'SYSCONFDIR': '/' / get_option('sysconfdir'), 'sysconfdir': '/' / get_option('sysconfdir'), - 'top_srcdir': meson.source_root() + 'top_srcdir': meson.source_root(), + 'CORE_SELINUX_POLICY': get_option('core_selinux_policy'), }) run_target('update-egg', command: 'scripts/01-upgrade-egg.sh') @@ -49,4 +50,9 @@ if get_option('auto_registration').enabled() else configuration += '\tauto_registration\t: ' + 'disabled' + '\n' endif +if get_option('core_selinux_policy') != '' + configuration += '\tSELinux policy for insights-core\t: ' + get_option('core_selinux_policy') + '\n' +else + configuration += '\tSELinux policy for insights-core\t: ' + 'disabled' + '\n' +endif message(configuration) diff --git a/meson_options.txt b/meson_options.txt index 8b4a3a00..3bd68a20 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,3 +2,4 @@ option('python', type: 'string', value: 'python3', description: 'python interpre option('auto_registration', type: 'feature', value: 'disabled', description: 'enable automatic registration') option('checkin', type: 'feature', value: 'disabled', description: 'enable hourly check-in') option('redhat_access_insights', type: 'boolean', value: false, description: 'enable deprecated redhat-access-insights executable') +option('core_selinux_policy', type: 'string', value: '', description: 'SELinux policy for insights-core (empty: none used)') diff --git a/src/insights_client/__init__.py b/src/insights_client/__init__.py index 400d1d9f..a6290744 100644 --- a/src/insights_client/__init__.py +++ b/src/insights_client/__init__.py @@ -17,12 +17,25 @@ try: from .constants import InsightsConstants + from .constants import CORE_SELINUX_POLICY + + # if there is a policy for insights-core, unconditionally try to interface + # with SELinux: insights-client was built with a policy for insights-core, + # so not being able to apply that is an hard failure + if CORE_SELINUX_POLICY != "": + import selinux + + SWITCH_CORE_SELINUX_POLICY = selinux.is_selinux_enabled() + else: + SWITCH_CORE_SELINUX_POLICY = False except ImportError: # The source file is build from 'constants.py.in' and is not # available during development class InsightsConstants(object): version = "development" + CORE_SELINUX_POLICY = "" + SWITCH_CORE_SELINUX_POLICY = False LOG_FORMAT = "%(asctime)s %(levelname)8s %(name)s:%(lineno)s %(message)s" NO_COLOR = os.environ.get("NO_COLOR") is not None @@ -306,8 +319,25 @@ def run_phase(phase, client, validated_eggs): env = os.environ env.update(insights_env) + if SWITCH_CORE_SELINUX_POLICY: + # in case we can switch to a different SELinux policy for + # insights-core, get the current context and switch the type + context = selinux.context_new(selinux.getcon()[1]) + # additional check: in case the current type is a certain one + # (e.g. unconfined_t when insights-client is run from a shell), + # then the switch will not work + if selinux.context_type_get(context) not in ["unconfined_t", "sysadm_t"]: + selinux.context_type_set(context, CORE_SELINUX_POLICY) + new_core_context = selinux.context_str(context) + selinux.setexeccon(new_core_context) + selinux.context_free(context) process = subprocess.Popen(insights_command, env=env) process.communicate() + if SWITCH_CORE_SELINUX_POLICY: + # setexeccon() in theory ought to reset the context for the next + # execv*() after that execution; it does not seem to happen though, + # so for now manually reset it + selinux.setexeccon(None) if process.returncode == 0: # phase successful, don't try another egg logger.debug("phase '%s' successful", phase["name"]) diff --git a/src/insights_client/constants.py.in b/src/insights_client/constants.py.in index e93fa4ed..5b63acbe 100644 --- a/src/insights_client/constants.py.in +++ b/src/insights_client/constants.py.in @@ -13,6 +13,7 @@ DATADIR = "@DATADIR@" SYSCONFDIR = "@SYSCONFDIR@" LOCALSTATEDIR = "@LOCALSTATEDIR@" DOCDIR = "@DOCDIR@" +CORE_SELINUX_POLICY = "@CORE_SELINUX_POLICY@" class InsightsConstants(object):