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 # 19 import logging 20 import re 21 22 from . import mixins, query 23 from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor 24 from .policyrep.exception import InvalidType, RuleUseError 25 26 27 class 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