#!/usr/bin/python # -*- coding: utf-8 -*- # (c) 2012, Derek Carter<goozbach@friocorte.com> # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see <http://www.gnu.org/licenses/>. # selinux module - change policy and state of SELinux # usage: # # selinux policy=<SELINUX_POLICY> state=[enforcing|permissive|disabled] configfile=[SELINUX_CONFIG_FILE] # # configfile defaults to /etc/selinux/config # policy files should be installed via the yum/apt modules # # bugs: # # Not tested on any debian based system import os import re try: import selinux HAVE_SELINUX=True except ImportError: HAVE_SELINUX=False # getter subroutines def get_config_state(configfile): myfile = open(configfile, "r") lines = myfile.readlines() myfile.close() for line in lines: stateline = re.match('^SELINUX=.*$', line) if (stateline): return(line.split('=')[1].strip()) def get_config_policy(configfile): myfile = open(configfile, "r") lines = myfile.readlines() myfile.close() for line in lines: stateline = re.match('^SELINUXTYPE=.*$', line) if (stateline): return(line.split('=')[1].strip()) # setter subroutines def set_config_state(state, configfile): #SELINUX=permissive # edit config file with state value stateline='SELINUX=%s' % state myfile = open(configfile, "r") lines = myfile.readlines() myfile.close() myfile = open(configfile, "w") for line in lines: myfile.write(re.sub(r'^SELINUX=.*', stateline, line)) myfile.close() def set_state(state): if (state == 'enforcing'): selinux.security_setenforce(1) elif (state == 'permissive'): selinux.security_setenforce(0) elif (state == 'disabled'): pass else: msg = 'trying to set invalid runtime state %s' % state fail_json(msg=msg) def set_config_policy(policy, configfile): # edit config file with state value #SELINUXTYPE=targeted policyline='SELINUXTYPE=%s' % policy myfile = open(configfile, "r") lines = myfile.readlines() myfile.close() myfile = open(configfile, "w") for line in lines: myfile.write(re.sub(r'^SELINUXTYPE=.*', policyline, line)) myfile.close() def main(): if (not HAVE_SELINUX): fail_json(msg='python-selinux required for this module') module = AnsibleModule( argument_spec = dict( policy=dict(required=True), state=dict(choices=['enforcing', 'permissive', 'disabled'], required=True), configfile=dict(aliases=['conf','file'], default='/etc/selinux/config') ) ) # global vars changed=False msgs = [] configfile = module.params['configfile'] policy = module.params['policy'] state = module.params['state'] runtime_enabled = selinux.is_selinux_enabled() runtime_policy = selinux.selinux_getpolicytype()[1] runtime_state = 'disabled' if (runtime_enabled): # enabled means 'enforcing' or 'permissive' if (selinux.security_getenforce()): runtime_state = 'enforcing' else: runtime_state = 'permissive' config_policy = get_config_policy(configfile) config_state = get_config_state(configfile) # check changed values and run changes if (policy != runtime_policy): # cannot change runtime policy msgs.append('reboot to change the loaded policy') changed=True if (policy != config_policy): msgs.append('config policy changed from \'%s\' to \'%s\'' % (config_policy, policy)) set_config_policy(policy, configfile) changed=True if (state != runtime_state): if (state == 'disabled'): msgs.append('disabled state will take effect next reboot') else: msgs.append('runtime state changed from \'%s\' to \'%s\'' % (runtime_state, state)) set_state(state) changed=True if (state != config_state): msgs.append('config state changed from \'%s\' to \'%s\'' % (config_state, state)) set_config_state(state, configfile) changed=True module.exit_json(changed=changed, msg=', '.join(msgs), configfile=configfile, policy=policy, state=state) ################################################# # include magic from lib/ansible/module_common.py #<<INCLUDE_ANSIBLE_MODULE_COMMON>> main()