def testHbacResultString(self): results = [ pyhbac.HBAC_EVAL_ALLOW, pyhbac.HBAC_EVAL_DENY, pyhbac.HBAC_EVAL_ERROR ] for r in results: s = pyhbac.hbac_result_string(r) self.assertIsInstance(s, unicode) assert len(s) > 0
def execute(self, *args, **options): # First receive all needed information: # 1. HBAC rules (whether enabled or disabled) # 2. Required options are (user, target host, service) # 3. Options: rules to test (--rules, --enabled, --disabled), request for detail output rules = [] # Use all enabled IPA rules by default all_enabled = True all_disabled = False # We need a local copy of test rules in order find incorrect ones testrules = {} if 'rules' in options: testrules = list(options['rules']) # When explicit rules are provided, disable assumptions all_enabled = False all_disabled = False sizelimit = None if 'sizelimit' in options: sizelimit = int(options['sizelimit']) # Check if --disabled is specified, include all disabled IPA rules if options['disabled']: all_disabled = True all_enabled = False # Finally, if enabled is specified implicitly, override above decisions if options['enabled']: all_enabled = True hbacset = [] if len(testrules) == 0: hbacset = self.api.Command.hbacrule_find( sizelimit=sizelimit, no_members=False)['result'] else: for rule in testrules: try: hbacset.append(self.api.Command.hbacrule_show(rule)['result']) except Exception: pass # We have some rules, import them # --enabled will import all enabled rules (default) # --disabled will import all disabled rules # --rules will implicitly add the rules from a rule list for rule in hbacset: ipa_rule = _convert_to_ipa_rule(rule) if ipa_rule.name in testrules: ipa_rule.enabled = True rules.append(ipa_rule) testrules.remove(ipa_rule.name) elif all_enabled and ipa_rule.enabled: # Option --enabled forces to include all enabled IPA rules into test rules.append(ipa_rule) elif all_disabled and not ipa_rule.enabled: # Option --disabled forces to include all disabled IPA rules into test ipa_rule.enabled = True rules.append(ipa_rule) # Check if there are unresolved rules left if len(testrules) > 0: # Error, unresolved rules are left in --rules return {'summary' : unicode(_(u'Unresolved rules in --rules')), 'error': testrules, 'matched': None, 'notmatched': None, 'warning' : None, 'value' : False} # Rules are converted to pyhbac format, build request and then test it request = pyhbac.HbacRequest() if options['user'] != u'all': # check first if this is not a trusted domain user if _dcerpc_bindings_installed: is_valid_sid = ipaserver.dcerpc.is_sid_valid(options['user']) else: is_valid_sid = False components = util.normalize_name(options['user']) if is_valid_sid or 'domain' in components or 'flatname' in components: # this is a trusted domain user if not _dcerpc_bindings_installed: raise errors.NotFound(reason=_( 'Cannot perform external member validation without ' 'Samba 4 support installed. Make sure you have installed ' 'server-trust-ad sub-package of IPA on the server')) domain_validator = ipaserver.dcerpc.DomainValidator(self.api) if not domain_validator.is_configured(): raise errors.NotFound(reason=_( 'Cannot search in trusted domains without own domain configured. ' 'Make sure you have run ipa-adtrust-install on the IPA server first')) user_sid, group_sids = domain_validator.get_trusted_domain_user_and_groups(options['user']) request.user.name = user_sid # Now search for all external groups that have this user or # any of its groups in its external members. Found entires # memberOf links will be then used to gather all groups where # this group is assigned, including the nested ones filter_sids = "(&(objectclass=ipaexternalgroup)(|(ipaExternalMember=%s)))" \ % ")(ipaExternalMember=".join(group_sids + [user_sid]) ldap = self.api.Backend.ldap2 group_container = DN(api.env.container_group, api.env.basedn) try: entries, _truncated = ldap.find_entries( filter_sids, ['memberof'], group_container) except errors.NotFound: request.user.groups = [] else: groups = [] for entry in entries: memberof_dns = entry.get('memberof', []) for memberof_dn in memberof_dns: if memberof_dn.endswith(group_container): groups.append(memberof_dn[0][0].value) request.user.groups = sorted(set(groups)) else: # try searching for a local user try: request.user.name = options['user'] search_result = self.api.Command.user_show(request.user.name)['result'] groups = search_result['memberof_group'] if 'memberofindirect_group' in search_result: groups += search_result['memberofindirect_group'] request.user.groups = sorted(set(groups)) except Exception: pass if options['service'] != u'all': try: request.service.name = options['service'] service_result = self.api.Command.hbacsvc_show(request.service.name)['result'] if 'memberof_hbacsvcgroup' in service_result: request.service.groups = service_result['memberof_hbacsvcgroup'] except Exception: pass if options['targethost'] != u'all': try: request.targethost.name = self.canonicalize(options['targethost']) tgthost_result = self.api.Command.host_show(request.targethost.name)['result'] groups = tgthost_result['memberof_hostgroup'] if 'memberofindirect_hostgroup' in tgthost_result: groups += tgthost_result['memberofindirect_hostgroup'] request.targethost.groups = sorted(set(groups)) except Exception: pass matched_rules = [] notmatched_rules = [] error_rules = [] warning_rules = [] result = {'warning':None, 'matched':None, 'notmatched':None, 'error':None} if not options['nodetail']: # Validate runs rules one-by-one and reports failed ones for ipa_rule in rules: try: res = request.evaluate([ipa_rule]) if res == pyhbac.HBAC_EVAL_ALLOW: matched_rules.append(ipa_rule.name) if res == pyhbac.HBAC_EVAL_DENY: notmatched_rules.append(ipa_rule.name) except pyhbac.HbacError as e: code, rule_name = e.args if code == pyhbac.HBAC_EVAL_ERROR: error_rules.append(rule_name) self.log.info('Native IPA HBAC rule "%s" parsing error: %s' % \ (rule_name, pyhbac.hbac_result_string(code))) except (TypeError, IOError) as info: self.log.error('Native IPA HBAC module error: %s' % info) access_granted = len(matched_rules) > 0 else: res = request.evaluate(rules) access_granted = (res == pyhbac.HBAC_EVAL_ALLOW) result['summary'] = _('Access granted: %s') % (access_granted) if len(matched_rules) > 0: result['matched'] = matched_rules if len(notmatched_rules) > 0: result['notmatched'] = notmatched_rules if len(error_rules) > 0: result['error'] = error_rules if len(warning_rules) > 0: result['warning'] = warning_rules result['value'] = access_granted return result
def _load_user_allowed_hosts(self): self._all_ssh_hosts = self._load_all_hosts(self.api) hbacset = [] rules = [] sizelimit = None hbacset = api.Command.hbacrule_find(sizelimit=sizelimit)['result'] for rule in hbacset: ipa_rule = self.convert_to_ipa_rule(rule) if ipa_rule.enabled: rules.append(ipa_rule) for ipa_rule in rules: for host in self._all_ssh_hosts: request = pyhbac.HbacRequest() #Build request user/usergroups try: request.user.name = self.user search_result = api.Command.user_show( request.user.name)['result'] groups = search_result['memberof_group'] if 'memberofindirect_group' in search_result: groups += search_result['memberofindirect_group'] request.user.groups = sorted(set(groups)) except: pass # Add sshd service + service groups it belongs to try: request.service.name = "sshd" service_result = api.Command.hbacsvc_show( request.service.name)['result'] if 'memberof_hbacsvcgroup' in service_result: request.service.groups = service_result[ 'memberof_hbacsvcgroup'] except: pass # Build request host/hostgroups try: request.targethost.name = host tgthost_result = api.Command.host_show( request.targethost.name)['result'] groups = tgthost_result['memberof_hostgroup'] if 'memberofindirect_hostgroup' in tgthost_result: groups += tgthost_result['memberofindirect_hostgroup'] request.targethost.groups = sorted(set(groups)) except: pass try: logging.debug("Core: Checking %s", host) res = request.evaluate([ipa_rule]) if res == pyhbac.HBAC_EVAL_ALLOW: logging.debug("Core: ALLOWED_HOSTS %s", host) self._allowed_ssh_hosts.append(host) except pyhbac.HbacError as (code, rule_name): if code == pyhbac.HBAC_EVAL_ERROR: #TODO log error print('Native IPA HBAC rule "%s" parsing error: %s' % \ (rule_name, pyhbac.hbac_result_string(code))) except (TypeError, IOError) as (info): print('Native IPA HBAC module error: %s' % (info))
def execute(self, *args, **options): # First receive all needed information: # 1. HBAC rules (whether enabled or disabled) # 2. Required options are (user, target host, service) # 3. Options: rules to test (--rules, --enabled, --disabled), request for detail output rules = [] # Use all enabled IPA rules by default all_enabled = True all_disabled = False # We need a local copy of test rules in order find incorrect ones testrules = {} if 'rules' in options: testrules = list(options['rules']) # When explicit rules are provided, disable assumptions all_enabled = False all_disabled = False sizelimit = None if 'sizelimit' in options: sizelimit = int(options['sizelimit']) # Check if --disabled is specified, include all disabled IPA rules if options['disabled']: all_disabled = True all_enabled = False # Finally, if enabled is specified implicitly, override above decisions if options['enabled']: all_enabled = True hbacset = [] if len(testrules) == 0: hbacset = self.api.Command.hbacrule_find( sizelimit=sizelimit, no_members=False)['result'] else: for rule in testrules: try: hbacset.append(self.api.Command.hbacrule_show(rule)['result']) except Exception: pass # We have some rules, import them # --enabled will import all enabled rules (default) # --disabled will import all disabled rules # --rules will implicitly add the rules from a rule list for rule in hbacset: ipa_rule = convert_to_ipa_rule(rule) if ipa_rule.name in testrules: ipa_rule.enabled = True rules.append(ipa_rule) testrules.remove(ipa_rule.name) elif all_enabled and ipa_rule.enabled: # Option --enabled forces to include all enabled IPA rules into test rules.append(ipa_rule) elif all_disabled and not ipa_rule.enabled: # Option --disabled forces to include all disabled IPA rules into test ipa_rule.enabled = True rules.append(ipa_rule) # Check if there are unresolved rules left if len(testrules) > 0: # Error, unresolved rules are left in --rules return {'summary' : unicode(_(u'Unresolved rules in --rules')), 'error': testrules, 'matched': None, 'notmatched': None, 'warning' : None, 'value' : False} # Rules are converted to pyhbac format, build request and then test it request = pyhbac.HbacRequest() if options['user'] != u'all': # check first if this is not a trusted domain user if _dcerpc_bindings_installed: is_valid_sid = ipaserver.dcerpc.is_sid_valid(options['user']) else: is_valid_sid = False components = util.normalize_name(options['user']) if is_valid_sid or 'domain' in components or 'flatname' in components: # this is a trusted domain user if not _dcerpc_bindings_installed: raise errors.NotFound(reason=_( 'Cannot perform external member validation without ' 'Samba 4 support installed. Make sure you have installed ' 'server-trust-ad sub-package of IPA on the server')) domain_validator = ipaserver.dcerpc.DomainValidator(self.api) if not domain_validator.is_configured(): raise errors.NotFound(reason=_( 'Cannot search in trusted domains without own domain configured. ' 'Make sure you have run ipa-adtrust-install on the IPA server first')) user_sid, group_sids = domain_validator.get_trusted_domain_user_and_groups(options['user']) request.user.name = user_sid # Now search for all external groups that have this user or # any of its groups in its external members. Found entires # memberOf links will be then used to gather all groups where # this group is assigned, including the nested ones filter_sids = "(&(objectclass=ipaexternalgroup)(|(ipaExternalMember=%s)))" \ % ")(ipaExternalMember=".join(group_sids + [user_sid]) ldap = self.api.Backend.ldap2 group_container = DN(api.env.container_group, api.env.basedn) try: entries, _truncated = ldap.find_entries( filter_sids, ['memberof'], group_container) except errors.NotFound: request.user.groups = [] else: groups = [] for entry in entries: memberof_dns = entry.get('memberof', []) for memberof_dn in memberof_dns: if memberof_dn.endswith(group_container): groups.append(memberof_dn[0][0].value) request.user.groups = sorted(set(groups)) else: # try searching for a local user try: request.user.name = options['user'] search_result = self.api.Command.user_show(request.user.name)['result'] groups = search_result['memberof_group'] if 'memberofindirect_group' in search_result: groups += search_result['memberofindirect_group'] request.user.groups = sorted(set(groups)) except Exception: pass if options['service'] != u'all': try: request.service.name = options['service'] service_result = self.api.Command.hbacsvc_show(request.service.name)['result'] if 'memberof_hbacsvcgroup' in service_result: request.service.groups = service_result['memberof_hbacsvcgroup'] except Exception: pass if options['targethost'] != u'all': try: request.targethost.name = self.canonicalize(options['targethost']) tgthost_result = self.api.Command.host_show(request.targethost.name)['result'] groups = tgthost_result['memberof_hostgroup'] if 'memberofindirect_hostgroup' in tgthost_result: groups += tgthost_result['memberofindirect_hostgroup'] request.targethost.groups = sorted(set(groups)) except Exception: pass matched_rules = [] notmatched_rules = [] error_rules = [] warning_rules = [] result = {'warning':None, 'matched':None, 'notmatched':None, 'error':None} if not options['nodetail']: # Validate runs rules one-by-one and reports failed ones for ipa_rule in rules: try: res = request.evaluate([ipa_rule]) if res == pyhbac.HBAC_EVAL_ALLOW: matched_rules.append(ipa_rule.name) if res == pyhbac.HBAC_EVAL_DENY: notmatched_rules.append(ipa_rule.name) except pyhbac.HbacError as e: code, rule_name = e.args if code == pyhbac.HBAC_EVAL_ERROR: error_rules.append(rule_name) self.log.info('Native IPA HBAC rule "%s" parsing error: %s' % \ (rule_name, pyhbac.hbac_result_string(code))) except (TypeError, IOError) as info: self.log.error('Native IPA HBAC module error: %s' % info) access_granted = len(matched_rules) > 0 else: res = request.evaluate(rules) access_granted = (res == pyhbac.HBAC_EVAL_ALLOW) result['summary'] = _('Access granted: %s') % (access_granted) if len(matched_rules) > 0: result['matched'] = matched_rules if len(notmatched_rules) > 0: result['notmatched'] = notmatched_rules if len(error_rules) > 0: result['error'] = error_rules if len(warning_rules) > 0: result['warning'] = warning_rules result['value'] = access_granted return result
def execute(self, *args, **options): # First receive all needed information: # 1. HBAC rules (whether enabled or disabled) # 2. Required options are (user, target host, service) # 3. Options: rules to test (--rules, --enabled, --disabled), request for detail output rules = [] # Use all enabled IPA rules by default all_enabled = True all_disabled = False # We need a local copy of test rules in order find incorrect ones testrules = {} if 'rules' in options: testrules = list(options['rules']) # When explicit rules are provided, disable assumptions all_enabled = False all_disabled = False sizelimit = None if 'sizelimit' in options: sizelimit = int(options['sizelimit']) # Check if --disabled is specified, include all disabled IPA rules if options['disabled']: all_disabled = True all_enabled = False # Finally, if enabled is specified implicitly, override above decisions if options['enabled']: all_enabled = True hbacset = [] if len(testrules) == 0: hbacset = self.api.Command.hbacrule_find(sizelimit=sizelimit)['result'] else: for rule in testrules: try: hbacset.append(self.api.Command.hbacrule_show(rule)['result']) except: pass # We have some rules, import them # --enabled will import all enabled rules (default) # --disabled will import all disabled rules # --rules will implicitly add the rules from a rule list for rule in hbacset: ipa_rule = convert_to_ipa_rule(rule) if ipa_rule.name in testrules: ipa_rule.enabled = True rules.append(ipa_rule) testrules.remove(ipa_rule.name) elif all_enabled and ipa_rule.enabled: # Option --enabled forces to include all enabled IPA rules into test rules.append(ipa_rule) elif all_disabled and not ipa_rule.enabled: # Option --disabled forces to include all disabled IPA rules into test ipa_rule.enabled = True rules.append(ipa_rule) # Check if there are unresolved rules left if len(testrules) > 0: # Error, unresolved rules are left in --rules return {'summary' : unicode(_(u'Unresolved rules in --rules')), 'error': testrules, 'matched': None, 'notmatched': None, 'warning' : None, 'value' : False} # Rules are converted to pyhbac format, build request and then test it request = pyhbac.HbacRequest() if options['user'] != u'all': try: request.user.name = options['user'] search_result = self.api.Command.user_show(request.user.name)['result'] groups = search_result['memberof_group'] if 'memberofindirect_group' in search_result: groups += search_result['memberofindirect_group'] request.user.groups = sorted(set(groups)) except: pass if options['service'] != u'all': try: request.service.name = options['service'] service_result = self.api.Command.hbacsvc_show(request.service.name)['result'] if 'memberof_hbacsvcgroup' in service_result: request.service.groups = service_result['memberof_hbacsvcgroup'] except: pass if options['targethost'] != u'all': try: request.targethost.name = self.canonicalize(options['targethost']) tgthost_result = self.api.Command.host_show(request.targethost.name)['result'] groups = tgthost_result['memberof_hostgroup'] if 'memberofindirect_hostgroup' in tgthost_result: groups += tgthost_result['memberofindirect_hostgroup'] request.targethost.groups = sorted(set(groups)) except: pass matched_rules = [] notmatched_rules = [] error_rules = [] warning_rules = [] result = {'warning':None, 'matched':None, 'notmatched':None, 'error':None} if not options['nodetail']: # Validate runs rules one-by-one and reports failed ones for ipa_rule in rules: try: res = request.evaluate([ipa_rule]) if res == pyhbac.HBAC_EVAL_ALLOW: matched_rules.append(ipa_rule.name) if res == pyhbac.HBAC_EVAL_DENY: notmatched_rules.append(ipa_rule.name) except pyhbac.HbacError as (code, rule_name): if code == pyhbac.HBAC_EVAL_ERROR: error_rules.append(rule_name) self.log.info('Native IPA HBAC rule "%s" parsing error: %s' % \ (rule_name, pyhbac.hbac_result_string(code))) except (TypeError, IOError) as (info): self.log.error('Native IPA HBAC module error: %s' % (info))