1# Copyright 2014-2015, Tresys Technology, LLC 2# 3# This file is part of SETools. 4# 5# SETools is free software: you can redistribute it and/or modify 6# it under the terms of the GNU Lesser General Public License as 7# published by the Free Software Foundation, either version 2.1 of 8# the License, or (at your option) any later version. 9# 10# SETools is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public 16# License along with SETools. If not, see 17# <http://www.gnu.org/licenses/>. 18# 19import logging 20import re 21 22from . import mixins, query 23from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor 24from .policyrep.exception import InvalidType, RuleUseError 25 26 27class RBACRuleQuery(mixins.MatchObjClass, query.PolicyQuery): 28 29 """ 30 Query the RBAC rules. 31 32 Parameter: 33 policy The policy to query. 34 35 Keyword Parameters/Class attributes: 36 ruletype The list of rule type(s) to match. 37 source The name of the source role/attribute to match. 38 source_indirect If true, members of an attribute will be 39 matched rather than the attribute itself. 40 source_regex If true, regular expression matching will 41 be used on the source role/attribute. 42 Obeys the source_indirect option. 43 target The name of the target role/attribute to match. 44 target_indirect If true, members of an attribute will be 45 matched rather than the attribute itself. 46 target_regex If true, regular expression matching will 47 be used on the target role/attribute. 48 Obeys target_indirect option. 49 tclass The object class(es) to match. 50 tclass_regex If true, use a regular expression for 51 matching the rule's object class. 52 default The name of the default role to match. 53 default_regex If true, regular expression matching will 54 be used on the default role. 55 """ 56 57 ruletype = RuletypeDescriptor("validate_rbac_ruletype") 58 source = CriteriaDescriptor("source_regex", "lookup_role") 59 source_regex = False 60 source_indirect = True 61 _target = None 62 target_regex = False 63 target_indirect = True 64 tclass = CriteriaSetDescriptor("tclass_regex", "lookup_class") 65 tclass_regex = False 66 default = CriteriaDescriptor("default_regex", "lookup_role") 67 default_regex = False 68 69 @property 70 def target(self): 71 return self._target 72 73 @target.setter 74 def target(self, value): 75 if not value: 76 self._target = None 77 elif self.target_regex: 78 self._target = re.compile(value) 79 else: 80 try: 81 self._target = self.policy.lookup_type_or_attr(value) 82 except InvalidType: 83 self._target = self.policy.lookup_role(value) 84 85 def results(self): 86 """Generator which yields all matching RBAC rules.""" 87 self.log.info("Generating results from {0.policy}".format(self)) 88 self.log.debug("Ruletypes: {0.ruletype}".format(self)) 89 self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, " 90 "regex: {0.source_regex}".format(self)) 91 self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, " 92 "regex: {0.target_regex}".format(self)) 93 self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self)) 94 self.log.debug("Default: {0.default!r}, regex: {0.default_regex}".format(self)) 95 96 for rule in self.policy.rbacrules(): 97 # 98 # Matching on rule type 99 # 100 if self.ruletype: 101 if rule.ruletype not in self.ruletype: 102 continue 103 104 # 105 # Matching on source role 106 # 107 if self.source and not self._match_indirect_regex( 108 rule.source, 109 self.source, 110 self.source_indirect, 111 self.source_regex): 112 continue 113 114 # 115 # Matching on target type (role_transition)/role(allow) 116 # 117 if self.target and not self._match_indirect_regex( 118 rule.target, 119 self.target, 120 self.target_indirect, 121 self.target_regex): 122 continue 123 124 # 125 # Matching on object class 126 # 127 try: 128 if not self._match_object_class(rule): 129 continue 130 except RuleUseError: 131 continue 132 133 # 134 # Matching on default role 135 # 136 if self.default: 137 try: 138 if not self._match_regex( 139 rule.default, 140 self.default, 141 self.default_regex): 142 continue 143 except RuleUseError: 144 continue 145 146 # if we get here, we have matched all available criteria 147 yield rule 148