# Copyright 2014, Tresys Technology, LLC # # This file is part of SETools. # # SETools is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation, either version 2.1 of # the License, or (at your option) any later version. # # SETools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with SETools. If not, see # <http://www.gnu.org/licenses/>. # from . import exception from . import qpol from . import role from . import mls from . import symbol def user_factory(qpol_policy, name): """Factory function for creating User objects.""" if isinstance(name, User): assert name.policy == qpol_policy return name elif isinstance(name, qpol.qpol_user_t): return User(qpol_policy, name) try: return User(qpol_policy, qpol.qpol_user_t(qpol_policy, str(name))) except ValueError: raise exception.InvalidUser("{0} is not a valid user".format(name)) class User(symbol.PolicySymbol): """A user.""" @property def roles(self): """The user's set of roles.""" roleset = set() for role_ in self.qpol_symbol.role_iter(self.policy): item = role.role_factory(self.policy, role_) # object_r is implicitly added to all roles by the compiler. # technically it is incorrect to skip it, but policy writers # and analysts don't expect to see it in results, and it # will confuse, especially for role set equality user queries. if item != "object_r": roleset.add(item) return roleset @property def mls_level(self): """The user's default MLS level.""" return mls.level_factory(self.policy, self.qpol_symbol.dfltlevel(self.policy)) @property def mls_range(self): """The user's MLS range.""" return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy)) def statement(self): roles = list(str(r) for r in self.roles) stmt = "user {0} roles ".format(self) if len(roles) > 1: stmt += "{{ {0} }}".format(' '.join(roles)) else: stmt += roles[0] try: stmt += " level {0.mls_level} range {0.mls_range};".format(self) except exception.MLSDisabled: stmt += ";" return stmt