mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
Merge pull request #29155 from shpsec-david/selinux-modules
Adding basic control for selinux modules
This commit is contained in:
commit
1e8fae820a
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user