summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2011-07-22 16:14:44 +0300
committerAlexander Bokovoy <abokovoy@redhat.com>2011-07-22 16:16:21 +0300
commit80dfc5751d26171fc565bad2f1bc51fa909a987f (patch)
tree0b2d89c4ecb4b60d4c43315ad5c3c90a1ed0481d
parentdf7ee2ccf5ff12ab43b1a97385b4f28bc64ef083 (diff)
downloadfreeipa-80dfc5751d26171fc565bad2f1bc51fa909a987f.tar.gz
freeipa-80dfc5751d26171fc565bad2f1bc51fa909a987f.tar.xz
freeipa-80dfc5751d26171fc565bad2f1bc51fa909a987f.zip
Add hbactest command
-rw-r--r--ipalib/plugins/hbactest.py172
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)
+