1 # Copyright 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 .descriptors import CriteriaDescriptor, CriteriaSetDescriptor 23 from .mixins import MatchObjClass, MatchPermission 24 from .policyrep.exception import ConstraintUseError 25 from .query import PolicyQuery 26 from .util import match_in_set 27 28 29 class ConstraintQuery(MatchObjClass, MatchPermission, PolicyQuery): 30 31 """ 32 Query constraint rules, (mls)constrain/(mls)validatetrans. 33 34 Parameter: 35 policy The policy to query. 36 37 Keyword Parameters/Class attributes: 38 ruletype The list of rule type(s) to match. 39 tclass The object class(es) to match. 40 tclass_regex If true, use a regular expression for 41 matching the rule's object class. 42 perms The permission(s) to match. 43 perms_equal If true, the permission set of the rule 44 must exactly match the permissions 45 criteria. If false, any set intersection 46 will match. 47 perms_regex If true, regular expression matching will be used 48 on the permission names instead of set logic. 49 role The name of the role to match in the 50 constraint expression. 51 role_indirect If true, members of an attribute will be 52 matched rather than the attribute itself. 53 role_regex If true, regular expression matching will 54 be used on the role. 55 type_ The name of the type/attribute to match in the 56 constraint expression. 57 type_indirect If true, members of an attribute will be 58 matched rather than the attribute itself. 59 type_regex If true, regular expression matching will 60 be used on the type/attribute. 61 user The name of the user to match in the 62 constraint expression. 63 user_regex If true, regular expression matching will 64 be used on the user. 65 """ 66 67 ruletype = CriteriaSetDescriptor(lookup_function="validate_constraint_ruletype") 68 user = CriteriaDescriptor("user_regex", "lookup_user") 69 user_regex = False 70 role = CriteriaDescriptor("role_regex", "lookup_role") 71 role_regex = False 72 role_indirect = True 73 type_ = CriteriaDescriptor("type_regex", "lookup_type_or_attr") 74 type_regex = False 75 type_indirect = True 76 77 def __init__(self, policy, **kwargs): 78 super(ConstraintQuery, self).__init__(policy, **kwargs) 79 self.log = logging.getLogger(__name__) 80 81 def _match_expr(self, expr, criteria, indirect, regex): 82 """ 83 Match roles/types/users in a constraint expression, 84 optionally by expanding the contents of attributes. 85 86 Parameters: 87 expr The expression to match. 88 criteria The criteria to match. 89 indirect If attributes in the expression should be expanded. 90 regex If regular expression matching should be used. 91 """ 92 93 if indirect: 94 obj = set() 95 for item in expr: 96 obj.update(item.expand()) 97 else: 98 obj = expr 99 100 return match_in_set(obj, criteria, regex) 101 102 def results(self): 103 """Generator which yields all matching constraints rules.""" 104 self.log.info("Generating constraint results from {0.policy}".format(self)) 105 self.log.debug("Ruletypes: {0.ruletype}".format(self)) 106 self._match_object_class_debug(self.log) 107 self._match_perms_debug(self.log) 108 self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self)) 109 self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self)) 110 self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self)) 111 112 for c in self.policy.constraints(): 113 if self.ruletype: 114 if c.ruletype not in self.ruletype: 115 continue 116 117 if not self._match_object_class(c): 118 continue 119 120 try: 121 if not self._match_perms(c): 122 continue 123 except ConstraintUseError: 124 continue 125 126 if self.role and not self._match_expr( 127 c.roles, 128 self.role, 129 self.role_indirect, 130 self.role_regex): 131 continue 132 133 if self.type_ and not self._match_expr( 134 c.types, 135 self.type_, 136 self.type_indirect, 137 self.type_regex): 138 continue 139 140 if self.user and not self._match_expr( 141 c.users, 142 self.user, 143 False, 144 self.user_regex): 145 continue 146 147 yield c 148