From 23f20588aa69a1ed4b68de24ec294092f99683ff Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Thu, 21 Sep 2023 14:56:06 +0200 Subject: [PATCH] seboolean: make it work with disabled SELinux Sometimes it's necessary to configure SELinux before it's enabled on the system. There's `ignore_selinux_state` which should allow it. Before this change `seboolean` module failed on SELinux disabled system even with `ignore_selinux_state: true` and SELinux policy installed while `semanage boolean` worked as expected: $ ansible -i 192.168.121.153, -m seboolean -a "name=ssh_sysadm_login state=on ignore_selinux_state=true" all 192.168.121.153 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "msg": "Failed to get list of boolean names" } $ ssh root@192.168.121.153 semanage boolean -l | grep ssh_sysadm_login ssh_sysadm_login (off , off) Allow ssh to sysadm login It's caused by `selinux.security_get_boolean_names()` and `selinux.security_get_boolean_active(name)` which required SELinux enabled system. This change adds a fallback to semanage API which works in SELinux disabled system when SELinux targeted policy is installed: ANSIBLE_LIBRARY=plugins/modules ansible -i 192.168.121.153, -m seboolean -a "name=ssh_sysadm_login state=on persistent=true ignore_selinux_state=true" all 192.168.121.153 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "name": "ssh_sysadm_login", "persistent": true, "state": true } $ ssh root@192.168.121.153 semanage boolean -l | grep ssh_sysadm_login ssh_sysadm_login (on , on) Allow ssh to sysadm login Note that without `persistent=true` this module is effectively NO-OP now. Signed-off-by: Petr Lautrbach --- ...ean-make-it-wrk-with-SELinux-disabled.yaml | 3 ++ plugins/modules/seboolean.py | 30 ++++--------------- 2 files changed, 9 insertions(+), 24 deletions(-) create mode 100644 changelogs/fragments/496_seboolean-make-it-wrk-with-SELinux-disabled.yaml diff --git a/changelogs/fragments/496_seboolean-make-it-wrk-with-SELinux-disabled.yaml b/changelogs/fragments/496_seboolean-make-it-wrk-with-SELinux-disabled.yaml new file mode 100644 index 0000000..e14cfa6 --- /dev/null +++ b/changelogs/fragments/496_seboolean-make-it-wrk-with-SELinux-disabled.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - seboolean - make it work with disabled SELinux diff --git a/plugins/modules/seboolean.py b/plugins/modules/seboolean.py index 0d23073..1e73aef 100644 --- a/plugins/modules/seboolean.py +++ b/plugins/modules/seboolean.py @@ -73,8 +73,7 @@ except ImportError: HAVE_SEMANAGE = False from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from ansible.module_utils.six import binary_type -from ansible.module_utils._text import to_bytes, to_text +from ansible.module_utils._text import to_text from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL @@ -82,23 +81,6 @@ def get_runtime_status(ignore_selinux_state=False): return True if ignore_selinux_state is True else selinux.is_selinux_enabled() -def has_boolean_value(module, name): - bools = [] - try: - rc, bools = selinux.security_get_boolean_names() - except OSError: - module.fail_json(msg="Failed to get list of boolean names") - # work around for selinux who changed its API, see - # https://github.com/ansible/ansible/issues/25651 - if len(bools) > 0: - if isinstance(bools[0], binary_type): - name = to_bytes(name) - if name in bools: - return True - else: - return False - - def get_boolean_value(module, name): state = 0 try: @@ -174,7 +156,10 @@ def semanage_set_boolean_value(module, handle, name, value): semanage.semanage_handle_destroy(handle) module.fail_json(msg="Failed to modify boolean key with semanage") - if semanage.semanage_bool_set_active(handle, boolkey, sebool) < 0: + if ( + selinux.is_selinux_enabled() + and semanage.semanage_bool_set_active(handle, boolkey, sebool) < 0 + ): semanage.semanage_handle_destroy(handle) module.fail_json(msg="Failed to set boolean key active with semanage") @@ -315,12 +300,9 @@ def main(): # Feature only available in selinux library since 2012. name = selinux.selinux_boolean_sub(name) - if not has_boolean_value(module, name): - module.fail_json(msg="SELinux boolean %s does not exist." % name) - if persistent: changed = semanage_boolean_value(module, name, state) - else: + elif selinux.is_selinux_enabled(): cur_value = get_boolean_value(module, name) if cur_value != state: changed = True