summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/setools/policyrep/fscontext.py
blob: 215dcd7ebc757827904ac85e532dee1ff5d8b35a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# 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/>.
#
import stat

from . import exception
from . import qpol
from . import symbol
from . import context


def validate_ruletype(types):
    """Validate fs_use_* rule types."""
    for t in types:
        if t not in ["fs_use_xattr", "fs_use_trans", "fs_use_task"]:
            raise exception.InvalidConstraintType("{0} is not a valid fs_use_* type.".format(t))


def fs_use_factory(policy, name):
    """Factory function for creating fs_use_* objects."""

    if not isinstance(name, qpol.qpol_fs_use_t):
        raise TypeError("fs_use_* cannot be looked-up.")

    return FSUse(policy, name)


def genfscon_factory(policy, name):
    """Factory function for creating genfscon objects."""

    if not isinstance(name, qpol.qpol_genfscon_t):
        raise TypeError("Genfscons cannot be looked-up.")

    return Genfscon(policy, name)


class FSContext(symbol.PolicySymbol):

    """Base class for in-policy labeling rules."""

    def __str__(self):
        raise NotImplementedError

    @property
    def fs(self):
        """The filesystem type for this statement."""
        return self.qpol_symbol.name(self.policy)

    @property
    def context(self):
        """The context for this statement."""
        return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))

    def statement(self):
        return str(self)


class Genfscon(FSContext):

    """A genfscon statement."""

    _filetype_to_text = {
        0: "",
        stat.S_IFBLK: "-b",
        stat.S_IFCHR: "-c",
        stat.S_IFDIR: "-d",
        stat.S_IFIFO: "-p",
        stat.S_IFREG: "--",
        stat.S_IFLNK: "-l",
        stat.S_IFSOCK: "-s"}

    def __str__(self):
        return "genfscon {0.fs} {0.path} {1} {0.context}".format(
            self, self._filetype_to_text[self.filetype])

    def __eq__(self, other):
        # Libqpol allocates new C objects in the
        # genfscons iterator, so pointer comparison
        # in the PolicySymbol object doesn't work.
        try:
            return (self.fs == other.fs and
                    self.path == other.path and
                    self.filetype == other.filetype and
                    self.context == other.context)
        except AttributeError:
            return str(self) == str(other)

    @property
    def filetype(self):
        """The file type (e.g. stat.S_IFBLK) for this genfscon statement."""
        return self.qpol_symbol.object_class(self.policy)

    @property
    def path(self):
        """The path for this genfscon statement."""
        return self.qpol_symbol.path(self.policy)


class FSUse(FSContext):

    """A fs_use_* statement."""

    # there are more rule types, but modern SELinux
    # only supports these three.
    _ruletype_to_text = {
        qpol.QPOL_FS_USE_XATTR: 'fs_use_xattr',
        qpol.QPOL_FS_USE_TRANS: 'fs_use_trans',
        qpol.QPOL_FS_USE_TASK: 'fs_use_task'}

    def __str__(self):
        return "{0.ruletype} {0.fs} {0.context};".format(self)

    @property
    def ruletype(self):
        """The rule type for this fs_use_* statement."""
        return self._ruletype_to_text[self.qpol_symbol.behavior(self.policy)]