* [pve-devel] [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator
@ 2023-06-05 14:21 Fabian Grünbichler
2023-06-05 14:21 ` [pve-devel] [PATCH access-control 2/2] acls: restrict less-privileged ACL modifications Fabian Grünbichler
2023-06-07 9:18 ` [pve-devel] applied-series: [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator Thomas Lamprecht
0 siblings, 2 replies; 3+ messages in thread
From: Fabian Grünbichler @ 2023-06-05 14:21 UTC (permalink / raw)
To: pve-devel
to reduce the chances of accidentally handing out privilege modification
privileges. the old default setup of having Permissions.Modify in PVESysAdmin
and PVEAdmin weakened the distinction between those roles and Administrator.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
---
Notes:
this is obviously a breaking change
can be detected in pve7to8 if any ACLs with PVESysAdmin or PVEAdmin are
configured, with a hint about adding a custom role if desired.
src/PVE/AccessControl.pm | 5 +++--
src/test/perm-test1.pl | 4 ++++
src/test/perm-test8.pl | 4 ++--
src/test/test1.cfg | 2 ++
src/test/test8.cfg | 2 +-
5 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/PVE/AccessControl.pm b/src/PVE/AccessControl.pm
index eee0869..9107653 100644
--- a/src/PVE/AccessControl.pm
+++ b/src/PVE/AccessControl.pm
@@ -1066,7 +1066,6 @@ my $privgroups = {
'Sys.Incoming', # incoming storage/guest migrations
],
admin => [
- 'Permissions.Modify',
'Sys.Console',
'Sys.Syslog',
],
@@ -1124,7 +1123,9 @@ my $privgroups = {
},
};
-my $valid_privs = {};
+my $valid_privs = {
+ 'Permissions.Modify' => 1, # not contained in a group
+};
my $special_roles = {
'NoAccess' => {}, # no privileges
diff --git a/src/test/perm-test1.pl b/src/test/perm-test1.pl
index d8527e7..d7cab3d 100755
--- a/src/test/perm-test1.pl
+++ b/src/test/perm-test1.pl
@@ -58,6 +58,10 @@ check_permission('max@pve', '/vms/100', 'VM.Audit,VM.PowerMgmt');
check_permission('alex@pve', '/vms', '');
check_permission('alex@pve', '/vms/100', 'VM.Audit,VM.PowerMgmt');
+# PVEVMAdmin -> no Permissions.Modify!
+check_permission('alex@pve', '/vms/300', 'VM.Allocate,VM.Audit,VM.Backup,VM.Clone,VM.Config.CDROM,VM.Config.CPU,VM.Config.Cloudinit,VM.Config.Disk,VM.Config.HWType,VM.Config.Memory,VM.Config.Network,VM.Config.Options,VM.Console,VM.Migrate,VM.Monitor,VM.PowerMgmt,VM.Snapshot,VM.Snapshot.Rollback');
+# Administrator -> Permissions.Modify!
+check_permission('alex@pve', '/vms/400', 'Datastore.Allocate,Datastore.AllocateSpace,Datastore.AllocateTemplate,Datastore.Audit,Group.Allocate,Permissions.Modify,Pool.Allocate,Pool.Audit,Realm.Allocate,Realm.AllocateUser,SDN.Allocate,SDN.Audit,Sys.Audit,Sys.Console,Sys.Incoming,Sys.Modify,Sys.PowerMgmt,Sys.Syslog,User.Modify,VM.Allocate,VM.Audit,VM.Backup,VM.Clone,VM.Config.CDROM,VM.Config.CPU,VM.Config.Cloudinit,VM.Config.Disk,VM.Config.HWType,VM.Config.Memory,VM.Config.Network,VM.Config.Options,VM.Console,VM.Migrate,VM.Monitor,VM.PowerMgmt,VM.Snapshot,VM.Snapshot.Rollback');
check_roles('max@pve', '/vms/200', 'storage_manager');
check_roles('joe@pve', '/vms/200', 'vm_admin');
diff --git a/src/test/perm-test8.pl b/src/test/perm-test8.pl
index 980a990..21bf1d3 100644
--- a/src/test/perm-test8.pl
+++ b/src/test/perm-test8.pl
@@ -50,7 +50,7 @@ check_roles('max@pve', '/vms/100', 'customer');
check_roles('max@pve', '/vms/101', 'vm_admin');
check_permission('max@pve', '/', '');
-check_permission('max@pve', '/vms', 'Permissions.Modify,VM.Allocate,VM.Audit,VM.Console');
+check_permission('max@pve', '/vms', 'VM.Allocate,VM.Audit,VM.Console');
check_permission('max@pve', '/vms/100', 'VM.Audit,VM.PowerMgmt');
check_permission('alex@pve', '/vms', '');
@@ -66,7 +66,7 @@ check_roles('max@pve!token', '/vms/200', 'storage_manager');
check_roles('max@pve!token2', '/vms/200', 'customer');
# check intersection -> token has Administrator, but user only vm_admin
-check_permission('max@pve!token2', '/vms/300', 'Permissions.Modify,VM.Allocate,VM.Audit,VM.Console,VM.PowerMgmt');
+check_permission('max@pve!token2', '/vms/300', 'VM.Allocate,VM.Audit,VM.Console,VM.PowerMgmt');
print "all tests passed\n";
diff --git a/src/test/test1.cfg b/src/test/test1.cfg
index d27c5d6..0b1b587 100644
--- a/src/test/test1.cfg
+++ b/src/test/test1.cfg
@@ -19,4 +19,6 @@ acl:1:/users:max@pve:Administrator:
acl:1:/vms/200:@testgroup3:storage_manager:
acl:1:/vms/200:@testgroup2:NoAccess:
+acl:1:/vms/300:alex@pve:PVEVMAdmin:
+acl:1:/vms/400:alex@pve:Administrator:
diff --git a/src/test/test8.cfg b/src/test/test8.cfg
index d5c7e86..ce704ef 100644
--- a/src/test/test8.cfg
+++ b/src/test/test8.cfg
@@ -13,7 +13,7 @@ group:testgroup3:max@pve:
role:storage_manager:Datastore.AllocateSpace,Datastore.Audit:
role:customer:VM.Audit,VM.PowerMgmt:
-role:vm_admin:VM.Audit,VM.Allocate,Permissions.Modify,VM.Console:
+role:vm_admin:VM.Audit,VM.Allocate,VM.Console:
acl:1:/vms:@testgroup1:vm_admin:
acl:0:/vms/300:max@pve:customer:
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [pve-devel] [PATCH access-control 2/2] acls: restrict less-privileged ACL modifications
2023-06-05 14:21 [pve-devel] [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator Fabian Grünbichler
@ 2023-06-05 14:21 ` Fabian Grünbichler
2023-06-07 9:18 ` [pve-devel] applied-series: [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator Thomas Lamprecht
1 sibling, 0 replies; 3+ messages in thread
From: Fabian Grünbichler @ 2023-06-05 14:21 UTC (permalink / raw)
To: pve-devel
there are currently three possibilities to modify ACLs without the
'Permissions.Modify' privilege in PVE::RPCEnvironment::check_perm_modify:
if ($path =~ m|^/storage/.+$|) {
push @$testperms, 'Datastore.Allocate';
} elsif ($path =~ m|^/vms/.+$|) {
push @$testperms, 'VM.Allocate';
} elsif ($path =~ m|^/pool/.+$|) {
push @$testperms, 'Pool.Allocate';
}
lock those down by only allowing the currently authenticated user to hand out a
subset of their own privileges, never more.
for example, this still allows a PVEVMAdmin to create ACLs for other
users/tokens with PVEVMUser (on '/vm/XXX'), but not with Administrator or
PVEPermAdmin.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
---
Notes:
this one is also a breaking change, but a bit more niche -> IMHO a callout in the release notes is sufficient.
src/PVE/API2/ACL.pm | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/PVE/API2/ACL.pm b/src/PVE/API2/ACL.pm
index f0c9efb..93adb78 100644
--- a/src/PVE/API2/ACL.pm
+++ b/src/PVE/API2/ACL.pm
@@ -148,9 +148,12 @@ __PACKAGE__->register_method ({
PVE::AccessControl::lock_user_config(
sub {
-
my $cfg = cfs_read_file("user.cfg");
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $authuser = $rpcenv->get_user();
+ my $auth_user_privs = $rpcenv->permissions($authuser, $path);
+
my $propagate = 1;
if (defined($param->{propagate})) {
@@ -163,6 +166,25 @@ __PACKAGE__->register_method ({
die "role '$role' does not exist\n"
if !$cfg->{roles}->{$role};
+ if (!$auth_user_privs->{'Permissions.Modify'}) {
+ # 'perm-modify' allows /vms/* with VM.Allocate and similar restricted use cases
+ # filter those to only allow handing out a subset of currently active privs
+ my $role_privs = $cfg->{roles}->{$role};
+ my $verb = $param->{delete} ? 'remove' : 'add';
+ foreach my $priv (keys $role_privs->%*) {
+ raise_param_exc({ role => "Cannot $verb role '$role' - requires 'Permissions.Modify' or superset of privileges." })
+ if !defined($auth_user_privs->{$priv});
+
+ # propagation is only potentially problematic for adding ACLs, not removing..
+ raise_param_exc({ role => "Cannot $verb role '$role' with propagation - requires 'Permissions.Modify' or propagated superset of privileges." })
+ if $propagate && $auth_user_privs->{$priv} != $propagate && !$param->{delete};
+ }
+
+ # NoAccess has no privs, needs an explicit check
+ raise_param_exc({ role => "Cannot $verb role '$role' - requires 'Permissions.Modify'"})
+ if $role eq 'NoAccess';
+ }
+
foreach my $group (split_list($param->{groups})) {
die "group '$group' does not exist\n"
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [pve-devel] applied-series: [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator
2023-06-05 14:21 [pve-devel] [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator Fabian Grünbichler
2023-06-05 14:21 ` [pve-devel] [PATCH access-control 2/2] acls: restrict less-privileged ACL modifications Fabian Grünbichler
@ 2023-06-07 9:18 ` Thomas Lamprecht
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Lamprecht @ 2023-06-07 9:18 UTC (permalink / raw)
To: Proxmox VE development discussion, Fabian Grünbichler
Am 05/06/2023 um 16:21 schrieb Fabian Grünbichler:
> to reduce the chances of accidentally handing out privilege modification
> privileges. the old default setup of having Permissions.Modify in PVESysAdmin
> and PVEAdmin weakened the distinction between those roles and Administrator.
>
> Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
> ---
>
> Notes:
> this is obviously a breaking change
>
> can be detected in pve7to8 if any ACLs with PVESysAdmin or PVEAdmin are
> configured, with a hint about adding a custom role if desired.
>
> src/PVE/AccessControl.pm | 5 +++--
> src/test/perm-test1.pl | 4 ++++
> src/test/perm-test8.pl | 4 ++--
> src/test/test1.cfg | 2 ++
> src/test/test8.cfg | 2 +-
> 5 files changed, 12 insertions(+), 5 deletions(-)
>
>
applied both patches, thanks!
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-06-07 9:18 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-05 14:21 [pve-devel] [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator Fabian Grünbichler
2023-06-05 14:21 ` [pve-devel] [PATCH access-control 2/2] acls: restrict less-privileged ACL modifications Fabian Grünbichler
2023-06-07 9:18 ` [pve-devel] applied-series: [PATCH access-control 1/2] roles: restrict Permissions.Modify to Administrator Thomas Lamprecht
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox