Home | History | Annotate | Download | only in policyrep
      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