diff options
author | Alexander Bokovoy <abokovoy@redhat.com> | 2011-07-22 16:14:44 +0300 |
---|---|---|
committer | Alexander Bokovoy <abokovoy@redhat.com> | 2011-07-22 16:16:21 +0300 |
commit | 80dfc5751d26171fc565bad2f1bc51fa909a987f (patch) | |
tree | 0b2d89c4ecb4b60d4c43315ad5c3c90a1ed0481d | |
parent | df7ee2ccf5ff12ab43b1a97385b4f28bc64ef083 (diff) | |
download | freeipa-80dfc5751d26171fc565bad2f1bc51fa909a987f.tar.gz freeipa-80dfc5751d26171fc565bad2f1bc51fa909a987f.tar.xz freeipa-80dfc5751d26171fc565bad2f1bc51fa909a987f.zip |
Add hbactest command
-rw-r--r-- | ipalib/plugins/hbactest.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/ipalib/plugins/hbactest.py b/ipalib/plugins/hbactest.py new file mode 100644 index 000000000..94c6464a5 --- /dev/null +++ b/ipalib/plugins/hbactest.py @@ -0,0 +1,172 @@ +# Authors: +# Alexander Bokovoy <abokovoy@redhat.com> +# +# Copyright (C) 2011 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +""" +Simulate use of Host-based access controls + +HBAC rules control who can access what services on what hosts and from where. +You can use HBAC to control which users or groups on a source host can +access a service, or group of services, on a target host. + +Since applying HBAC rules implies use of a production environment, +this plugin aims to provide simulation of HBAC rules evaluation without +having access to the production environment. + +EXAMPLES: + + Test user coming from source host to a service on a named host against existing + enabled rules. If --rules specified (whether enabled or disabled, does not matter). + simulate enabling of the specified rules in addition to already enabled ones and test + the login of the user. If --validate is specified, provide detailed per-rule result + of simulation. If both --rules and --validate are specified, apply simulation to --rules + only. + + ipa hbactest --user= --srchost= --host= --service= [--rules=rules-list] [--validate] +""" + +from ipalib import api, errors, output +from ipalib import Command, List, Str, Flag +from ipalib.cli import to_cli +from ipalib import _, ngettext +import pyhbac + +class hbactest(Command): + + has_output_params = ( + List('passed', + label=_('Passed rules'), + ), + List('denied', + label=_('Denied rules'), + ), + List('error', + label=_('Incorrect rules'), + ), + ) + + has_output = output.standard_entry + + takes_options = ( + Str('user', + cli_name='user', + label=_('User name'), + primary_key=True, + required=True, + ), + Str('sourcehost', + cli_name='srchost', + label=_('Source host'), + required=True, + ), + Str('targethost', + cli_name='host', + label=_('Target host'), + required=True, + ), + Str('service', + cli_name='service', + label=_('Service'), + required=True, + ), + List('testrules?', + cli_name='rules', + label=_('Rules to test'), + ), + Flag('validate?', + cli_name='validate', + label=_('Validate rules'), + ), + ) + + def __convert_to_ipa_rule(self, rule): + # convert a dict with a rule to an pyhbac rule + ipa_rule = pyhbac.HbacRule(rule['cn'][0]) + ipa_rule.enabled = rule['ipaenabledflag'][0] + # Following code attempts to process rule systematically + structure = (('user', 'memberuser', 'user', 'group', ipa_rule.users), + ('host', 'memberhost', 'host', 'hostgroup', ipa_rule.targethosts), + ('sourcehost', 'sourcehost', 'host', 'hostgroup', ipa_rule.srchosts), + ('service', 'memberservice', 'hbacsvc', 'hbacsvcgroup', ipa_rule.services), + ) + for element in structure: + category = '%scategory' % (element[0]) + if category in rule and rule[category][0] == u'all': + # rule applies to all elements + element[4].category = set([pyhbac.HBAC_CATEGORY_ALL]) + else: + # rule is about specific entities + # Check if there are explicitly listed entities + attr_name = '%s_%s' % (element[1], element[2]) + if attr_name in rule: + element[4].names = rule[attr_name] + # Now add groups of entities if they are there + attr_name = '%s_%s' % (element[1], element[3]) + if attr_name in rule: + element[4].groups = rule[attr_name] + return ipa_rule + + def execute(self, *args, **options): + # First receive all needed information: + # 1. HBAC rules (whether enabled or disabled) + # 2. Required options are (user, source host, target host, service) + # 3. Options: rules to test, validation request + rules = [] + hbacset = self.api.Command.hbacrule_find()['result'] + # We have some rules, import them + for rule in hbacset: + ipa_rule = self.__convert_to_ipa_rule(rule) + if options['validate'] and 'testrules' in options: + if ipa_rule.name in options['testrules']: + ipa_rule.enabled = True + rules.append(ipa_rule) + else: + if 'testrules' in options and ipa_rule.name in options['testrules']: + # Explicitly add any rule that was specified in testrules + ipa_rule.enabled = True + if ipa_rule.enabled: + rules.append(ipa_rule) + # Rules are converted to pyhbac format, we can test them + request = pyhbac.HbacRequest() + request.user.name = options['user'] + request.service.name = options['service'] + request.srchost.name = options['sourcehost'] + request.targethost.name = options['targethost'] + passed_rules = [] + denied_rules = [] + error_rules = [] + if options['validate']: + # Validate runs rules one-by-one and reports failed ones + for ipa_rule in rules: + res = request.evaluate([ipa_rule]) + self.log.info("Evaluated rule %s, result: %d" % (ipa_rule.name, res)) + if res == pyhbac.HBAC_EVAL_ALLOW: + passed_rules.append(ipa_rule.name) + if res == pyhbac.HBAC_EVAL_DENY: + denied_rules.append(ipa_rule.name) + if res == pyhbac.HBAC_EVAL_ERROR: + error_rules.append(ipa_rule.name) + access_granted = len(passed_rules) > 0 + else: + res = request.evaluate(rules) + access_granted = (res == pyhbac.HBAC_EVAL_ALLOW) + return dict(summary=_(u'Access granted: %s') % (access_granted), + result=dict(passed=passed_rules, denied=denied_rules, errors=error_rules), + value=unicode(access_granted)) + +api.register(hbactest) + |