1 # Copyright 2014, 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 from . import exception 20 from . import qpol 21 from . import role 22 from . import mls 23 from . import symbol 24 25 26 def user_factory(qpol_policy, name): 27 """Factory function for creating User objects.""" 28 29 if isinstance(name, User): 30 assert name.policy == qpol_policy 31 return name 32 elif isinstance(name, qpol.qpol_user_t): 33 return User(qpol_policy, name) 34 35 try: 36 return User(qpol_policy, qpol.qpol_user_t(qpol_policy, str(name))) 37 except ValueError: 38 raise exception.InvalidUser("{0} is not a valid user".format(name)) 39 40 41 class User(symbol.PolicySymbol): 42 43 """A user.""" 44 45 @property 46 def roles(self): 47 """The user's set of roles.""" 48 49 roleset = set() 50 51 for role_ in self.qpol_symbol.role_iter(self.policy): 52 item = role.role_factory(self.policy, role_) 53 54 # object_r is implicitly added to all roles by the compiler. 55 # technically it is incorrect to skip it, but policy writers 56 # and analysts don't expect to see it in results, and it 57 # will confuse, especially for role set equality user queries. 58 if item != "object_r": 59 roleset.add(item) 60 61 return roleset 62 63 @property 64 def mls_level(self): 65 """The user's default MLS level.""" 66 return mls.level_factory(self.policy, self.qpol_symbol.dfltlevel(self.policy)) 67 68 @property 69 def mls_range(self): 70 """The user's MLS range.""" 71 return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy)) 72 73 def statement(self): 74 roles = list(str(r) for r in self.roles) 75 stmt = "user {0} roles ".format(self) 76 if len(roles) > 1: 77 stmt += "{{ {0} }}".format(' '.join(roles)) 78 else: 79 stmt += roles[0] 80 81 try: 82 stmt += " level {0.mls_level} range {0.mls_range};".format(self) 83 except exception.MLSDisabled: 84 stmt += ";" 85 86 return stmt 87