Skip to content

Commit f155903

Browse files
committed
[S-RBAC] Fix policies for CUD subnets APIs
In new, secure RBAC policies for create subnet there was rule "ADMIN_OR_PROJECT_MEMBER" used and that was wrong as this rule is basically allows any member (PROJECT_MEMBER) create subnet in networks visible to them, not necessarily this project needs to be owner of that network. So it allowed users to create new subnets in the shared or provider networks as well. Now policy for create subnet is ADMIN OR NET_OWNER_MEMBER to avoid that. Additionally this patch also fixes policies for update and delete subnet APIs where there was rule NET_OWNER used and that effectively allowed to update or delete subnet to the network owner who has READER role only. Now this is also fixed by using NET_OWNER_MEMBER rule instead. Conflicts: neutron/conf/policies/subnet.py Closes-Bug: #2023679 Change-Id: Ia494872b58f368581fb29fa40b7da17e1071db22 (cherry picked from commit 6e35251)
1 parent 64e3752 commit f155903

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

neutron/conf/policies/subnet.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,18 @@
3535
{'method': 'GET', 'path': RESOURCE_PATH},
3636
]
3737

38+
# TODO(slaweq): remove it once network will be added to the
39+
# EXT_PARENT_RESOURCE_MAPPING in neutron_lib and rule base.PARENT_OWNER_MEMBER
40+
# will be possible to use instead of RULE_NET_OWNER_MEMBER
41+
RULE_NET_OWNER_MEMBER = 'role:member and ' + base.RULE_NET_OWNER
42+
3843

3944
rules = [
4045
policy.DocumentedRuleDefault(
4146
name='create_subnet',
4247
check_str=base.policy_or(
43-
base.ADMIN_OR_PROJECT_MEMBER,
44-
base.RULE_NET_OWNER),
48+
base.ADMIN,
49+
RULE_NET_OWNER_MEMBER),
4550
scope_types=['project'],
4651
description='Create a subnet',
4752
operations=ACTION_POST,
@@ -111,7 +116,7 @@
111116
name='update_subnet',
112117
check_str=base.policy_or(
113118
base.ADMIN_OR_PROJECT_MEMBER,
114-
base.RULE_NET_OWNER),
119+
RULE_NET_OWNER_MEMBER),
115120
scope_types=['project'],
116121
description='Update a subnet',
117122
operations=ACTION_PUT,
@@ -149,7 +154,7 @@
149154
name='delete_subnet',
150155
check_str=base.policy_or(
151156
base.ADMIN_OR_PROJECT_MEMBER,
152-
base.RULE_NET_OWNER),
157+
RULE_NET_OWNER_MEMBER),
153158
scope_types=['project'],
154159
description='Delete a subnet',
155160
operations=ACTION_DELETE,

neutron/tests/unit/conf/policies/test_subnet.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,33 @@ def setUp(self):
2929

3030
self.network = {
3131
'id': uuidutils.generate_uuid(),
32+
'tenant_id': self.project_id,
3233
'project_id': self.project_id}
34+
self.alt_network = {
35+
'id': uuidutils.generate_uuid(),
36+
'tenant_id': self.alt_project_id,
37+
'project_id': self.alt_project_id}
38+
39+
networks = {
40+
self.network['id']: self.network,
41+
self.alt_network['id']: self.alt_network}
3342

3443
self.target = {
3544
'project_id': self.project_id,
45+
'tenant_id': self.project_id,
3646
'network_id': self.network['id'],
3747
'ext_parent_network_id': self.network['id']}
3848
self.alt_target = {
3949
'project_id': self.alt_project_id,
40-
'network_id': self.network['id'],
41-
'ext_parent_network_id': self.network['id']}
50+
'tenant_id': self.alt_project_id,
51+
'network_id': self.alt_network['id'],
52+
'ext_parent_network_id': self.alt_network['id']}
53+
54+
def get_network(context, id, fields=None):
55+
return networks.get(id)
4256

4357
self.plugin_mock = mock.Mock()
44-
self.plugin_mock.get_network.return_value = self.network
58+
self.plugin_mock.get_network.side_effect = get_network
4559
mock.patch(
4660
'neutron_lib.plugins.directory.get_plugin',
4761
return_value=self.plugin_mock).start()

0 commit comments

Comments
 (0)