Merge pull request #974 from goozbach/add_selinux_module
add selinux module
This commit is contained in:
commit
4da4c31dfb
1 changed files with 159 additions and 0 deletions
159
library/selinux
Normal file
159
library/selinux
Normal file
|
@ -0,0 +1,159 @@
|
|||
#!/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'], default='enforcing'),
|
||||
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()
|
Loading…
Reference in a new issue