Skip to content

Commit d31e634

Browse files
authored
Merge pull request #145 from cgzones/role_types
Add option to see roles allowed for single type
2 parents 69a22ed + 349dcff commit d31e634

File tree

5 files changed

+227
-0
lines changed

5 files changed

+227
-0
lines changed

seinfo

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ queries.add_argument("--polcap", help="Print policy capabilities.", dest="polcap
7676
nargs='?', const=True, metavar="NAME")
7777
queries.add_argument("--portcon", help="Print portcon statements.", dest="portconquery",
7878
nargs='?', const=True, metavar="PORTNUM[-PORTNUM]")
79+
queries.add_argument("--role_types", help="Print all roles associated with the given type.",
80+
dest="roletypesquery", nargs=1, metavar="TYPE")
7981
queries.add_argument("--sensitivity", help="Print MLS sensitivities.", dest="mlssensquery",
8082
nargs='?', const=True, metavar="SENS")
8183
queries.add_argument("--typebounds", help="Print typebounds statements.", dest="typeboundsquery",
@@ -263,6 +265,12 @@ try:
263265

264266
components.append(("Roles", rq, lambda x: x.statement()))
265267

268+
if args.roletypesquery:
269+
q = setools.RoleTypesQuery(p)
270+
q.name = args.roletypesquery[0]
271+
272+
components.append(("Roles", q, lambda x: x.statement()))
273+
266274
if args.mlssensquery or args.all:
267275
msq = setools.SensitivityQuery(p, alias_deref=True)
268276
if isinstance(args.mlssensquery, str):

setools/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from .objclassquery import ObjClassQuery
4545
from .polcapquery import PolCapQuery
4646
from .rolequery import RoleQuery
47+
from .roletypesquery import RoleTypesQuery
4748
from .sensitivityquery import SensitivityQuery
4849
from .typequery import TypeQuery
4950
from .typeattrquery import TypeAttributeQuery

setools/roletypesquery.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright 2025, Christian Göttsche
2+
#
3+
# SPDX-License-Identifier: LGPL-2.1-only
4+
#
5+
from collections.abc import Iterable
6+
import typing
7+
8+
from . import mixins, policyrep, query
9+
10+
__all__: typing.Final[tuple[str, ...]] = ("RoleTypesQuery",)
11+
12+
13+
class RoleTypesQuery(mixins.MatchName, query.PolicyQuery):
14+
15+
"""
16+
Query SELinux policy roles.
17+
18+
Parameter:
19+
policy The policy to query.
20+
21+
Keyword Parameters/Class attributes:
22+
name The type name to match.
23+
name_regex If true, regular expression matching
24+
will be used on the type names.
25+
"""
26+
27+
def results(self) -> Iterable[policyrep.Role]:
28+
"""Generator which yields all matching roles."""
29+
self.log.info(f"Generating role-types results from {self.policy}")
30+
self._match_name_debug(self.log)
31+
32+
for r in self.policy.roles():
33+
for t in r.types():
34+
if self._match_name(t):
35+
yield r
36+
break

tests/library/roletypesquery.conf

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
class infoflow
2+
class infoflow2
3+
class infoflow3
4+
class infoflow4
5+
class infoflow5
6+
class infoflow6
7+
class infoflow7
8+
9+
sid kernel
10+
sid security
11+
12+
common infoflow
13+
{
14+
low_w
15+
med_w
16+
hi_w
17+
low_r
18+
med_r
19+
hi_r
20+
}
21+
22+
class infoflow
23+
inherits infoflow
24+
25+
class infoflow2
26+
inherits infoflow
27+
{
28+
super_w
29+
super_r
30+
}
31+
32+
class infoflow3
33+
{
34+
null
35+
}
36+
37+
class infoflow4
38+
inherits infoflow
39+
40+
class infoflow5
41+
inherits infoflow
42+
43+
class infoflow6
44+
inherits infoflow
45+
46+
class infoflow7
47+
inherits infoflow
48+
{
49+
super_w
50+
super_r
51+
super_none
52+
super_both
53+
super_unmapped
54+
}
55+
56+
sensitivity low_s;
57+
sensitivity medium_s alias med;
58+
sensitivity high_s;
59+
60+
dominance { low_s med high_s }
61+
62+
category here;
63+
category there;
64+
category elsewhere alias lost;
65+
66+
#level decl
67+
level low_s:here.there;
68+
level med:here, elsewhere;
69+
level high_s:here.lost;
70+
71+
#some constraints
72+
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
73+
74+
attribute mls_exempt;
75+
76+
type system;
77+
role system;
78+
role system types system;
79+
80+
################################################################################
81+
# Type enforcement declarations and rules
82+
83+
allow system system:infoflow3 null;
84+
85+
########################################
86+
#
87+
# Role Query
88+
#
89+
90+
# test 1
91+
type test1;
92+
93+
# test 2
94+
role test2ra;
95+
role test2rb;
96+
type test2a;
97+
type test2b;
98+
role test2ra types { test2a test2b };
99+
role test2rb types test2b;
100+
101+
# test 3
102+
103+
role test3ra;
104+
role test3rb;
105+
role test3rc;
106+
role test3rd;
107+
type test3a;
108+
type test3b;
109+
type test3c;
110+
type test3d;
111+
role test3ra types { test3b test3c test3d };
112+
role test3rb types { test3a test3c test3d };
113+
role test3rc types { test3a test3b test3d };
114+
role test3rd types { test3a test3b test3c };
115+
116+
################################################################################
117+
118+
#users
119+
user system roles system level med range low_s - high_s:here.lost;
120+
121+
#normal constraints
122+
constrain infoflow hi_w (u1 == u2);
123+
124+
#isids
125+
sid kernel system:system:system:medium_s:here
126+
sid security system:system:system:high_s:lost
127+
128+
#fs_use
129+
fs_use_trans devpts system:object_r:system:low_s;
130+
fs_use_xattr ext3 system:object_r:system:low_s;
131+
fs_use_task pipefs system:object_r:system:low_s;
132+
133+
#genfscon
134+
genfscon proc / system:object_r:system:med
135+
genfscon proc /sys system:object_r:system:low_s
136+
genfscon selinuxfs / system:object_r:system:high_s:here.there
137+
138+
portcon tcp 80 system:object_r:system:low_s
139+
140+
netifcon eth0 system:object_r:system:low_s system:object_r:system:low_s
141+
142+
nodecon 127.0.0.1 255.255.255.255 system:object_r:system:low_s:here
143+
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:low_s:here
144+

tests/library/test_roletypesquery.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright 2025, Christian Göttsche
2+
#
3+
# SPDX-License-Identifier: GPL-2.0-only
4+
#
5+
import pytest
6+
import setools
7+
8+
9+
@pytest.mark.obj_args("tests/library/roletypesquery.conf")
10+
class TestRoleTypesQuery:
11+
12+
def test_name_nomatch(self, compiled_policy: setools.SELinuxPolicy) -> None:
13+
"""Type with no associated role."""
14+
q = setools.RoleTypesQuery(compiled_policy, name="test1")
15+
16+
roles = sorted(str(r) for r in q.results())
17+
assert [] == roles
18+
19+
def test_name_onematch(self, compiled_policy: setools.SELinuxPolicy) -> None:
20+
"""Type with one associated role."""
21+
q = setools.RoleTypesQuery(compiled_policy, name="test2a")
22+
23+
roles = sorted(str(r) for r in q.results())
24+
assert ["test2ra"] == roles
25+
26+
def test_name_multiplematches(self, compiled_policy: setools.SELinuxPolicy) -> None:
27+
"""Type with multiple associated roles."""
28+
q = setools.RoleTypesQuery(compiled_policy, name="test3a")
29+
30+
roles = sorted(str(r) for r in q.results())
31+
assert ["test3rb", "test3rc", "test3rd"] == roles
32+
33+
def test_name_multiplematches_regex(self, compiled_policy: setools.SELinuxPolicy) -> None:
34+
"""Multiple types with multiple associated roles."""
35+
q = setools.RoleTypesQuery(compiled_policy, name="test3", name_regex=True)
36+
37+
roles = sorted(str(r) for r in q.results())
38+
assert ["test3ra", "test3rb", "test3rc", "test3rd"] == roles

0 commit comments

Comments
 (0)