Merge pull request #29155 from shpsec-david/selinux-modules

Adding basic control for selinux modules
This commit is contained in:
Mike Place 2015-11-30 13:50:21 -07:00
commit 1e8fae820a
2 changed files with 142 additions and 7 deletions

View File

@ -3,12 +3,12 @@
Execute calls on selinux
.. note::
This module requires the ``semanage`` and ``setsebool`` commands to be
available on the minion. On RHEL-based distros, this means that the
``policycoreutils`` and ``policycoreutils-python`` packages must be
installed. If not on a RHEL-based distribution, consult the selinux
documentation for your distro to ensure that the proper packages are
installed.
This module requires the ``semanage``, ``setsebool`` and ``semodule``
commands to be available on the minion. On RHEL-based distros, this
means that the ``policycoreutils`` and ``policycoreutils-python``
packages must be installed. If not on a RHEL-based distribution,
consult the selinux documentation for your distro to ensure that the
proper packages are installed.
'''
# Import python libs
@ -29,7 +29,7 @@ def __virtual__():
Check if the os is Linux, and then if selinux is running in permissive or
enforcing mode.
'''
required_cmds = ('semanage', 'setsebool')
required_cmds = ('semanage', 'setsebool', 'semodule')
# Iterate over all of the commands this module uses and make sure
# each of them are available in the standard PATH to prevent breakage
@ -191,3 +191,65 @@ def list_sebool():
'Default': comps[3][:-1],
'Description': ' '.join(comps[4:])}
return ret
def getsemod(module):
'''
Return the information on a specific selinux module
CLI Example:
.. code-block:: bash
salt '*' selinux.getsemod mysql
.. versionadded:: Boron
'''
return list_semod().get(module, {})
def setsemod(module, state):
'''
Enable or disable an SELinux module.
CLI Example:
.. code-block:: bash
salt '*' selinux.setsemod nagios Enabled
.. versionadded:: Boron
'''
if state.lower() == 'enabled':
cmd = 'semodule -e {0}'.format(module)
elif state.lower() == 'disabled':
cmd = 'semodule -d {0}'.format(module)
return not __salt__['cmd.retcode'](cmd)
def list_semod():
'''
Return a structure listing all of the selinux modules on the system and
what state they are in
CLI Example:
.. code-block:: bash
salt '*' selinux.list_semod
.. versionadded:: Boron
'''
mdata = __salt__['cmd.run']('semodule -l').splitlines()
ret = {}
for line in mdata[1:]:
if not line.strip():
continue
comps = line.split()
if len(comps) == 3:
ret[comps[0]] = {'Enabled': False,
'Version': comps[1]}
else:
ret[comps[0]] = {'Enabled': True,
'Version': comps[1]}
return ret

View File

@ -16,6 +16,10 @@ booleans can be set.
- value: True
- persist: True
nginx:
selinux.module:
- enabled: False
.. note::
Use of these states require that the :mod:`selinux <salt.modules.selinux>`
execution module is available.
@ -57,6 +61,19 @@ def _refine_value(value):
return None
def _refine_module_state(module_state):
'''
Return a predictable value, or allow us to error out
.. versionadded:: Boron
'''
module_state = str(module_state).lower()
if module_state in ('1', 'on', 'yes', 'true', 'enabled'):
return 'enabled'
if module_state in ('0', 'off', 'no', 'false', 'disabled'):
return 'disabled'
return 'unknown'
def mode(name):
'''
Verifies the mode SELinux is running in, can be set to enforcing or
@ -144,3 +161,59 @@ def boolean(name, value, persist=False):
return ret
ret['comment'] = 'Failed to set the boolean {0} to {1}'.format(name, rvalue)
return ret
def module(name, module_state='Enabled', version='any'):
'''
Enable/Disable and optionally force a specific version for an SELinux module
name
The name of the module to control
module_state
Should the module be enabled or disabled?
version
Defaults to no preference, set to a specified value if required.
Currently can only alert if the version is incorrect.
.. versionadded:: Boron
'''
ret = {'name': name,
'result': True,
'comment': '',
'changes': {}}
modules = __salt__['selinux.list_semod']()
if name not in modules:
ret['comment'] = 'Module {0} is not available'.format(name)
ret['result'] = False
return ret
rmodule_state = _refine_module_state(module_state)
if rmodule_state == 'unknown':
ret['comment'] = '{0} is not a valid state for the ' \
'{1} module.'.format(module_state, module)
ret['result'] = False
return ret
if not version == 'any':
installed_version = modules[name]['Version']
if not installed_version == version:
ret['comment'] = 'Module version is {0} and does not match ' \
'the desired version of {1}'.format(installed_version, version)
ret['result'] = False
return ret
current_module_state = _refine_module_state(modules[name]['Enabled'])
if rmodule_state == current_module_state:
ret['comment'] = 'Module {0} is in the desired state'.format(name)
return ret
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'Module {0} is set to be togggled to {1}'.format(
name, module_state)
return ret
if __salt__['selinux.setsemod'](name, rmodule_state):
ret['comment'] = 'Module {0} has been set to {1}'.format(name, module_state)
return ret
ret['result'] = False
ret['comment'] = 'Failed to set the Module {0} to {1}'.format(name, module_state)
return ret