* [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege @ 2022-02-08 13:10 Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 1/5] add default "SuperAdministrator" role with the new "SuperUser" privilege Oguz Bektas ` (5 more replies) 0 siblings, 6 replies; 13+ messages in thread From: Oguz Bektas @ 2022-02-08 13:10 UTC (permalink / raw) To: pve-devel "SuperUser" (henceforth referred as SU) privilege allows to give root-only permissions to API users, enabling them to perform privileged actions on behalf of root@pam. this privilege is enabled by default for "root@pam", and also mapped inside "SuperAdministrator" (referred as SA) changes from RFC (thanks for the review fabian g.!): * manager: allow SAs to see/edit certain things on GUI * qemu-server: also check the required non-root VM privileges along with the SU priv * pve-container: adapted error messages, changed variable name to "is_superuser" for better clarity (in comparison to prev. "is_root" which is a bit confusing) * access-control: TFA permissions adaptation for SAs access-control: Oguz Bektas (2): add "SuperAdministrator" role with the new "SuperUser" privilege tfa: allow superusers to edit root@pam tfa src/PVE/API2/TFA.pm | 7 +++++-- src/PVE/AccessControl.pm | 9 ++++++--- src/PVE/RPCEnvironment.pm | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) container: Oguz Bektas (1): fix #2582: api: add checks for 'SuperUser' privilege for root-only options src/PVE/API2/LXC.pm | 13 ++++++------- src/PVE/API2/LXC/Status.pm | 8 ++++++-- src/PVE/LXC.pm | 9 ++++++--- 3 files changed, 18 insertions(+), 12 deletions(-) manager: Oguz Bektas (1): change 'root@pam' checks with 'SuperUser' capability check www/manager6/Utils.js | 3 ++- www/manager6/dc/Config.js | 2 +- www/manager6/dc/UserView.js | 2 +- www/manager6/lxc/Options.js | 2 +- www/manager6/lxc/Resources.js | 2 +- www/manager6/node/Config.js | 2 +- www/manager6/window/Migrate.js | 4 ++-- 7 files changed, 9 insertions(+), 8 deletions(-) qemu-server: Oguz Bektas (1): add SuperUser privilege checks for root-only options PVE/API2/Qemu.pm | 119 +++++++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 46 deletions(-) -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [pve-devel] [PATCH v1 access-control 1/5] add default "SuperAdministrator" role with the new "SuperUser" privilege 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas @ 2022-02-08 13:10 ` Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 2/5] tfa: allow superusers to edit root@pam tfa Oguz Bektas ` (4 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Oguz Bektas @ 2022-02-08 13:10 UTC (permalink / raw) To: pve-devel we map all valid privileges to the "Administrator" role except "SuperUser". "SuperAdministrator"/SA gets all valid privileges (including the new "SuperUser"/SU priv), and 'root@pam' is assigned as an SA by default. Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> --- src/PVE/AccessControl.pm | 9 ++++++--- src/PVE/RPCEnvironment.pm | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/PVE/AccessControl.pm b/src/PVE/AccessControl.pm index 1306576..1137756 100644 --- a/src/PVE/AccessControl.pm +++ b/src/PVE/AccessControl.pm @@ -1008,6 +1008,7 @@ my $privgroups = { }, Sys => { root => [ + 'SuperUser', 'Sys.PowerMgmt', 'Sys.Modify', # edit/change node settings ], @@ -1074,7 +1075,8 @@ my $valid_privs = {}; my $special_roles = { 'NoAccess' => {}, # no privileges - 'Administrator' => $valid_privs, # all privileges + 'Administrator' => {}, # populated with all privs except superuser + 'SuperAdministrator' => $valid_privs, # can do everything }; sub create_roles { @@ -1101,6 +1103,7 @@ sub create_roles { } $special_roles->{"PVETemplateUser"} = { 'VM.Clone' => 1, 'VM.Audit' => 1 }; + $special_roles->{"Administrator"} = { map { $_ => 1 } grep { $_ ne 'SuperUser' } keys %$valid_privs }; }; create_roles(); @@ -1581,7 +1584,7 @@ sub write_user_config { $collect_rolelist_members->($d->{'groups'}, $rolelist_members, '@'); - # no need to save 'root@pam', it is always 'Administrator' + # no need to save 'root@pam', it is always 'SuperAdministrator' $collect_rolelist_members->($d->{'users'}, $rolelist_members, '', 'root@pam'); $collect_rolelist_members->($d->{'tokens'}, $rolelist_members, ''); @@ -1635,7 +1638,7 @@ sub roles { # corresponding user has. # Use $rpcenv->permission() for any actual permission checks! - return 'Administrator' if $user eq 'root@pam'; # root can do anything + return 'SuperAdministrator' if $user eq 'root@pam'; # root can do anything if (pve_verify_tokenid($user, 1)) { my $tokenid = $user; diff --git a/src/PVE/RPCEnvironment.pm b/src/PVE/RPCEnvironment.pm index b1348fa..3afb311 100644 --- a/src/PVE/RPCEnvironment.pm +++ b/src/PVE/RPCEnvironment.pm @@ -101,7 +101,7 @@ sub permissions { if ($user eq 'root@pam') { # root can do anything my $cfg = $self->{user_cfg}; - return { map { $_ => 1 } keys %{$cfg->{roles}->{'Administrator'}} }; + return { map { $_ => 1 } keys %{$cfg->{roles}->{'SuperAdministrator'}} }; } if (PVE::AccessControl::pve_verify_tokenid($user, 1)) { -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [pve-devel] [PATCH v1 access-control 2/5] tfa: allow superusers to edit root@pam tfa 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 1/5] add default "SuperAdministrator" role with the new "SuperUser" privilege Oguz Bektas @ 2022-02-08 13:10 ` Oguz Bektas [not found] ` <<20220208131011.752134-3-o.bektas@proxmox.com> 2022-02-08 13:10 ` [pve-devel] [PATCH v1 container 3/5] fix #2582: api: add checks for 'SuperUser' privilege for root-only options Oguz Bektas ` (3 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Oguz Bektas @ 2022-02-08 13:10 UTC (permalink / raw) To: pve-devel users with the SU privilege are able to override the existing check for 'root@pam' when calling tfa-related endpoints of the API. Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> --- src/PVE/API2/TFA.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PVE/API2/TFA.pm b/src/PVE/API2/TFA.pm index bee4dee..70555cc 100644 --- a/src/PVE/API2/TFA.pm +++ b/src/PVE/API2/TFA.pm @@ -102,13 +102,16 @@ my $TFA_UPDATE_INFO_SCHEMA = { my sub root_permission_check : prototype($$$$) { my ($rpcenv, $authuser, $userid, $password) = @_; + # authuser = the user making the change + # userid = the user to be changed ($userid, undef, my $realm) = PVE::AccessControl::verify_username($userid); $rpcenv->check_user_exist($userid); - raise_perm_exc() if $userid eq 'root@pam' && $authuser ne 'root@pam'; + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/access/groups", ['SuperUser'], 1); + raise_perm_exc() if $userid eq 'root@pam' && !$is_superuser; # root@pam can be only edited by himself or a SuperUser # Regular users need to confirm their password to change TFA settings. - if ($authuser ne 'root@pam') { + if ($authuser ne 'root@pam') { # we still do password confirmation for superusers like the other users raise_param_exc({ 'password' => 'password is required to modify TFA data' }) if !defined($password); -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <<20220208131011.752134-3-o.bektas@proxmox.com>]
* Re: [pve-devel] [PATCH v1 access-control 2/5] tfa: allow superusers to edit root@pam tfa [not found] ` <<20220208131011.752134-3-o.bektas@proxmox.com> @ 2022-02-10 15:30 ` Fabian Grünbichler 0 siblings, 0 replies; 13+ messages in thread From: Fabian Grünbichler @ 2022-02-10 15:30 UTC (permalink / raw) To: Proxmox VE development discussion On February 8, 2022 2:10 pm, Oguz Bektas wrote: > users with the SU privilege are able to override the existing check for > 'root@pam' when calling tfa-related endpoints of the API. > > Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> > --- > src/PVE/API2/TFA.pm | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/src/PVE/API2/TFA.pm b/src/PVE/API2/TFA.pm > index bee4dee..70555cc 100644 > --- a/src/PVE/API2/TFA.pm > +++ b/src/PVE/API2/TFA.pm > @@ -102,13 +102,16 @@ my $TFA_UPDATE_INFO_SCHEMA = { > my sub root_permission_check : prototype($$$$) { > my ($rpcenv, $authuser, $userid, $password) = @_; > > + # authuser = the user making the change > + # userid = the user to be changed > ($userid, undef, my $realm) = PVE::AccessControl::verify_username($userid); > $rpcenv->check_user_exist($userid); > > - raise_perm_exc() if $userid eq 'root@pam' && $authuser ne 'root@pam'; > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/access/groups", ['SuperUser'], 1); > + raise_perm_exc() if $userid eq 'root@pam' && !$is_superuser; # root@pam can be only edited by himself or a SuperUser can be shorted (root@pam is by definition a SuperUser), but IMHO, the whole comment can be dropped - the variables have meaningful names anyway? some rationale why this was changed, but the very similar code in PVE:API2::AccessControl->change_password is not adapted is also missing. also, a similar mechanism exists in the other direction as well: root@pam can create tickets for other users - should SuperUser also be allowed to do that? if not, the reason for that exception should be added to the relevant part as comment (or if it should, then the relevant changes should be part of the series ;)) one more point - check_api2_permissions has the general 'no permission specified in schema => only root@pam allowed' rule. obviously with the semantics of 'superuser does not entail all privileges' that can't be switched to superuser - but it means all the existing API calls without specific permissions need to be checked and either adapted (e.g., with an appropriate ACL with regular privilege + SuperUser), or marked as root only with a reason. one way to do this would be to analyze the API dump, or even forbid endpoints without a permission in the schema (e.g. in the api verification code we run at build time), and switch the remaining root-only endpoints to just have an explicit permission in the schema that encodes that. obviously in any case the check in check_api2_permissions needs to remain to catch anything that slipped through. > > # Regular users need to confirm their password to change TFA settings. > - if ($authuser ne 'root@pam') { > + if ($authuser ne 'root@pam') { # we still do password confirmation for superusers like the other users > raise_param_exc({ 'password' => 'password is required to modify TFA data' }) > if !defined($password); > > -- > 2.30.2 > > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [pve-devel] [PATCH v1 container 3/5] fix #2582: api: add checks for 'SuperUser' privilege for root-only options 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 1/5] add default "SuperAdministrator" role with the new "SuperUser" privilege Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 2/5] tfa: allow superusers to edit root@pam tfa Oguz Bektas @ 2022-02-08 13:10 ` Oguz Bektas [not found] ` <<20220208131011.752134-4-o.bektas@proxmox.com> 2022-02-08 13:10 ` [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check Oguz Bektas ` (2 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Oguz Bektas @ 2022-02-08 13:10 UTC (permalink / raw) To: pve-devel this way we can allow non-root users to act as a SU on specific root-only API paths by giving them the built-in SA role or a custom role with the SU privilege included. Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> --- src/PVE/API2/LXC.pm | 13 ++++++------- src/PVE/API2/LXC/Status.pm | 8 ++++++-- src/PVE/LXC.pm | 9 ++++++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm index 7573814..b24e405 100644 --- a/src/PVE/API2/LXC.pm +++ b/src/PVE/API2/LXC.pm @@ -295,7 +295,7 @@ __PACKAGE__->register_method({ my $conf = {}; - my $is_root = $authuser eq 'root@pam'; + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); my $no_disk_param = {}; my $mp_param = {}; @@ -330,8 +330,8 @@ __PACKAGE__->register_method({ my $mp = $mountpoint->{mp}; if ($mountpoint->{type} ne 'volume') { # bind or device - die "Only root can pass arbitrary filesystem paths.\n" - if !$is_root; + die "Only superusers can pass arbitrary filesystem paths.\n" + if !$is_superuser; } else { my ($sid, $volname) = PVE::Storage::parse_volume_id($volid); &$check_and_activate_storage($sid); @@ -371,7 +371,7 @@ __PACKAGE__->register_method({ # causing it to restore the raw lxc entries, among which there may be # 'lxc.idmap' entries. We need to make sure that the extracted contents # of the container match up with the restored configuration afterwards: - $conf->{lxc} = $orig_conf->{lxc} if $is_root; + $conf->{lxc} = $orig_conf->{lxc} if $is_superuser; $conf->{unprivileged} = $orig_conf->{unprivileged} if !defined($unprivileged) && defined($orig_conf->{unprivileged}); @@ -405,8 +405,7 @@ __PACKAGE__->register_method({ my $type = $mountpoint->{type}; die "restoring rootfs to $type mount is only possible by specifying -rootfs manually!\n" if ($ms eq 'rootfs'); - die "restoring '$ms' to $type mount is only possible for root\n" - if !$is_root; + die "restoring '$ms' to $type mount is only possible for root\n" if !$is_superuser; if ($mountpoint->{backup}) { warn "WARNING - unsupported configuration!\n"; @@ -447,7 +446,7 @@ __PACKAGE__->register_method({ if ($restore) { print "merging backed-up and given configuration..\n"; - PVE::LXC::Create::restore_configuration($vmid, $storage_cfg, $archive, $rootdir, $conf, !$is_root, $unique, $skip_fw_config_restore); + PVE::LXC::Create::restore_configuration($vmid, $storage_cfg, $archive, $rootdir, $conf, !$is_superuser, $unique, $skip_fw_config_restore); my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir); $lxc_setup->template_fixup($conf); } else { diff --git a/src/PVE/API2/LXC/Status.pm b/src/PVE/API2/LXC/Status.pm index f7e3128..791cdc6 100644 --- a/src/PVE/API2/LXC/Status.pm +++ b/src/PVE/API2/LXC/Status.pm @@ -150,9 +150,11 @@ __PACKAGE__->register_method({ my $node = extract_param($param, 'node'); my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + if $skiplock && !$is_superuser; die "CT $vmid already running\n" if PVE::LXC::check_running($vmid); @@ -234,9 +236,11 @@ __PACKAGE__->register_method({ my $node = extract_param($param, 'node'); my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + if $skiplock && !$is_superuser; die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid); diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm index b07d986..6b5125c 100644 --- a/src/PVE/LXC.pm +++ b/src/PVE/LXC.pm @@ -1254,7 +1254,9 @@ sub template_create { sub check_ct_modify_config_perm { my ($rpcenv, $authuser, $vmid, $pool, $oldconf, $newconf, $delete, $unprivileged) = @_; - return 1 if $authuser eq 'root@pam'; + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser']); + return 1 if $is_superuser; + my $storage_cfg = PVE::Storage::config(); my $check = sub { @@ -1320,12 +1322,13 @@ sub check_ct_modify_config_perm { } } raise_perm_exc("changing feature flags (except nesting) is only allowed for root\@pam") - if $other_changed; + if $other_changed && !$is_superuser; $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Allocate']) if $nesting_changed; } elsif ($opt eq 'hookscript') { # For now this is restricted to root@pam - raise_perm_exc("changing the hookscript is only allowed for root\@pam"); + raise_perm_exc("changing the hookscript is only allowed for root\@pam") + if !$is_superuser; } else { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Options']); } -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <<20220208131011.752134-4-o.bektas@proxmox.com>]
* Re: [pve-devel] [PATCH v1 container 3/5] fix #2582: api: add checks for 'SuperUser' privilege for root-only options [not found] ` <<20220208131011.752134-4-o.bektas@proxmox.com> @ 2022-02-10 15:30 ` Fabian Grünbichler 0 siblings, 0 replies; 13+ messages in thread From: Fabian Grünbichler @ 2022-02-10 15:30 UTC (permalink / raw) To: Proxmox VE development discussion On February 8, 2022 2:10 pm, Oguz Bektas wrote: > this way we can allow non-root users to act as a SU on specific > root-only API paths by giving them the built-in SA role or a custom role > with the SU privilege included. > > Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> > --- > src/PVE/API2/LXC.pm | 13 ++++++------- > src/PVE/API2/LXC/Status.pm | 8 ++++++-- > src/PVE/LXC.pm | 9 ++++++--- > 3 files changed, 18 insertions(+), 12 deletions(-) > > diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm > index 7573814..b24e405 100644 > --- a/src/PVE/API2/LXC.pm > +++ b/src/PVE/API2/LXC.pm > @@ -295,7 +295,7 @@ __PACKAGE__->register_method({ > > my $conf = {}; > > - my $is_root = $authuser eq 'root@pam'; > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > > my $no_disk_param = {}; > my $mp_param = {}; > @@ -330,8 +330,8 @@ __PACKAGE__->register_method({ > my $mp = $mountpoint->{mp}; > > if ($mountpoint->{type} ne 'volume') { # bind or device > - die "Only root can pass arbitrary filesystem paths.\n" > - if !$is_root; > + die "Only superusers can pass arbitrary filesystem paths.\n" > + if !$is_superuser; schema still has root-only in the description, both here and in the update path.. > } else { > my ($sid, $volname) = PVE::Storage::parse_volume_id($volid); > &$check_and_activate_storage($sid); > @@ -371,7 +371,7 @@ __PACKAGE__->register_method({ > # causing it to restore the raw lxc entries, among which there may be > # 'lxc.idmap' entries. We need to make sure that the extracted contents > # of the container match up with the restored configuration afterwards: > - $conf->{lxc} = $orig_conf->{lxc} if $is_root; > + $conf->{lxc} = $orig_conf->{lxc} if $is_superuser; > > $conf->{unprivileged} = $orig_conf->{unprivileged} > if !defined($unprivileged) && defined($orig_conf->{unprivileged}); > @@ -405,8 +405,7 @@ __PACKAGE__->register_method({ > my $type = $mountpoint->{type}; > die "restoring rootfs to $type mount is only possible by specifying -rootfs manually!\n" > if ($ms eq 'rootfs'); > - die "restoring '$ms' to $type mount is only possible for root\n" > - if !$is_root; > + die "restoring '$ms' to $type mount is only possible for root\n" if !$is_superuser; still references root > > if ($mountpoint->{backup}) { > warn "WARNING - unsupported configuration!\n"; > @@ -447,7 +446,7 @@ __PACKAGE__->register_method({ > > if ($restore) { > print "merging backed-up and given configuration..\n"; > - PVE::LXC::Create::restore_configuration($vmid, $storage_cfg, $archive, $rootdir, $conf, !$is_root, $unique, $skip_fw_config_restore); > + PVE::LXC::Create::restore_configuration($vmid, $storage_cfg, $archive, $rootdir, $conf, !$is_superuser, $unique, $skip_fw_config_restore); > my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir); > $lxc_setup->template_fixup($conf); > } else { > diff --git a/src/PVE/API2/LXC/Status.pm b/src/PVE/API2/LXC/Status.pm > index f7e3128..791cdc6 100644 > --- a/src/PVE/API2/LXC/Status.pm > +++ b/src/PVE/API2/LXC/Status.pm > @@ -150,9 +150,11 @@ __PACKAGE__->register_method({ > my $node = extract_param($param, 'node'); > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > raise_param_exc({ skiplock => "Only root may use this option." }) nit: message needs updating (repeated a few times below) > - if $skiplock && $authuser ne 'root@pam'; > + if $skiplock && !$is_superuser; > > die "CT $vmid already running\n" if PVE::LXC::check_running($vmid); > > @@ -234,9 +236,11 @@ __PACKAGE__->register_method({ > my $node = extract_param($param, 'node'); > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + if $skiplock && !$is_superuser; > > die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid); > > diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm > index b07d986..6b5125c 100644 > --- a/src/PVE/LXC.pm > +++ b/src/PVE/LXC.pm > @@ -1254,7 +1254,9 @@ sub template_create { > sub check_ct_modify_config_perm { > my ($rpcenv, $authuser, $vmid, $pool, $oldconf, $newconf, $delete, $unprivileged) = @_; > > - return 1 if $authuser eq 'root@pam'; > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser']); > + return 1 if $is_superuser; so.. 'SuperUser' on its own should only skip those parts where root@pam was previously a requirement on top of other checks, but instead 'SuperUser' can now modify the config however even with no other privs? > + > my $storage_cfg = PVE::Storage::config(); > > my $check = sub { > @@ -1320,12 +1322,13 @@ sub check_ct_modify_config_perm { here there is the non-volume part that is still root-only, with no comment about why that one is not switched to 'SuperUser'? also, features for privileged containers is still root-only (should probably require VM.Allocate + SuperUser, when looking at the create/restore path). > } > } > raise_perm_exc("changing feature flags (except nesting) is only allowed for root\@pam") wrong message now > - if $other_changed; > + if $other_changed && !$is_superuser; > $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Allocate']) > if $nesting_changed; > } elsif ($opt eq 'hookscript') { > # For now this is restricted to root@pam > - raise_perm_exc("changing the hookscript is only allowed for root\@pam"); > + raise_perm_exc("changing the hookscript is only allowed for root\@pam") > + if !$is_superuser; comment, message and code don't agree > } else { > $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Options']); > } > -- > 2.30.2 > > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas ` (2 preceding siblings ...) 2022-02-08 13:10 ` [pve-devel] [PATCH v1 container 3/5] fix #2582: api: add checks for 'SuperUser' privilege for root-only options Oguz Bektas @ 2022-02-08 13:10 ` Oguz Bektas [not found] ` <<20220208131011.752134-5-o.bektas@proxmox.com> 2022-02-08 13:10 ` [pve-devel] [PATCH v1 qemu-server 5/5] add SuperUser privilege checks for root-only options Oguz Bektas 2022-02-10 15:28 ` [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Fabian Grünbichler 5 siblings, 1 reply; 13+ messages in thread From: Oguz Bektas @ 2022-02-08 13:10 UTC (permalink / raw) To: pve-devel 'root@pam' has the privilege by default (since it's an SA), so we can drop the string comparisons all around and check that privilege instead when deciding to enable/disable buttons or views Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> --- www/manager6/Utils.js | 3 ++- www/manager6/dc/Config.js | 2 +- www/manager6/dc/UserView.js | 2 +- www/manager6/lxc/Options.js | 2 +- www/manager6/lxc/Resources.js | 2 +- www/manager6/node/Config.js | 2 +- www/manager6/window/Migrate.js | 4 ++-- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index aafe359a..31ab94e8 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -1656,7 +1656,8 @@ Ext.define('PVE.Utils', { showCephInstallOrMask: function(container, msg, nodename, callback) { if (msg.match(/not (installed|initialized)/i)) { - if (Proxmox.UserName === 'root@pam') { + let caps = Ext.state.Manager.get('GuiCap'); + if (caps.node.SuperUser) { container.el.mask(); if (!container.down('pveCephInstallWindow')) { var isInstalled = !!msg.match(/not initialized/i); diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js index 9c54b19d..917c426f 100644 --- a/www/manager6/dc/Config.js +++ b/www/manager6/dc/Config.js @@ -197,7 +197,7 @@ Ext.define('PVE.dc.Config', { }); } - if (Proxmox.UserName === 'root@pam') { + if (caps.dc.SuperUser) { me.items.push({ xtype: 'pveACMEClusterView', title: 'ACME', diff --git a/www/manager6/dc/UserView.js b/www/manager6/dc/UserView.js index bbfc4f7c..fe0c0149 100644 --- a/www/manager6/dc/UserView.js +++ b/www/manager6/dc/UserView.js @@ -29,7 +29,7 @@ Ext.define('PVE.dc.UserView', { selModel: sm, baseurl: '/access/users/', dangerous: true, - enableFn: rec => caps.access['User.Modify'] && rec.data.userid !== 'root@pam', + enableFn: rec => caps.access['User.Modify'] && !caps.access.SuperUser, callback: () => reload(), }); let run_editor = function() { diff --git a/www/manager6/lxc/Options.js b/www/manager6/lxc/Options.js index f2661dfc..f8eb8a5c 100644 --- a/www/manager6/lxc/Options.js +++ b/www/manager6/lxc/Options.js @@ -136,7 +136,7 @@ Ext.define('PVE.lxc.Options', { features: { header: gettext('Features'), defaultValue: Proxmox.Utils.noneText, - editor: Proxmox.UserName === 'root@pam' || caps.vms['VM.Allocate'] + editor: caps.vms.SuperUser || caps.vms['VM.Allocate'] ? 'PVE.lxc.FeaturesEdit' : undefined, }, hookscript: { diff --git a/www/manager6/lxc/Resources.js b/www/manager6/lxc/Resources.js index 15ee3c67..2081b4a2 100644 --- a/www/manager6/lxc/Resources.js +++ b/www/manager6/lxc/Resources.js @@ -257,7 +257,7 @@ Ext.define('PVE.lxc.RessourceView', { var isUsedDisk = isDisk && !isUnusedDisk; var noedit = rec.data.delete || !rowdef.editor; - if (!noedit && Proxmox.UserName !== 'root@pam' && key.match(/^mp\d+$/)) { + if (!noedit && !caps.vms.SuperUser && key.match(/^mp\d+$/)) { var mp = PVE.Parser.parseLxcMountPoint(value); if (mp.type !== 'volume') { noedit = true; diff --git a/www/manager6/node/Config.js b/www/manager6/node/Config.js index 68f80391..9f49f0dd 100644 --- a/www/manager6/node/Config.js +++ b/www/manager6/node/Config.js @@ -236,7 +236,7 @@ Ext.define('PVE.node.Config', { itemId: 'apt', upgradeBtn: { xtype: 'pveConsoleButton', - disabled: Proxmox.UserName !== 'root@pam', + disabled: !caps.nodes.SuperUser, text: gettext('Upgrade'), consoleType: 'upgrade', nodename: nodename, diff --git a/www/manager6/window/Migrate.js b/www/manager6/window/Migrate.js index 1c23abb3..20fcf81d 100644 --- a/www/manager6/window/Migrate.js +++ b/www/manager6/window/Migrate.js @@ -52,8 +52,8 @@ Ext.define('PVE.window.Migrate', { } }, setLocalResourceCheckboxHidden: function(get) { - if (get('running') || !get('migration.hasLocalResources') || - Proxmox.UserName !== 'root@pam') { + let caps = Ext.state.Manager.get('GuiCap'); + if (get('running') || !get('migration.hasLocalResources') || caps.vms.SuperUser) { return true; } else { return false; -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <<20220208131011.752134-5-o.bektas@proxmox.com>]
* Re: [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check [not found] ` <<20220208131011.752134-5-o.bektas@proxmox.com> @ 2022-02-10 15:29 ` Fabian Grünbichler 2022-02-25 10:13 ` Dominik Csapak 0 siblings, 1 reply; 13+ messages in thread From: Fabian Grünbichler @ 2022-02-10 15:29 UTC (permalink / raw) To: Proxmox VE development discussion On February 8, 2022 2:10 pm, Oguz Bektas wrote: > 'root@pam' has the privilege by default (since it's an SA), so we can > drop the string comparisons all around and check that privilege instead > when deciding to enable/disable buttons or views > > Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> > --- > www/manager6/Utils.js | 3 ++- > www/manager6/dc/Config.js | 2 +- > www/manager6/dc/UserView.js | 2 +- > www/manager6/lxc/Options.js | 2 +- > www/manager6/lxc/Resources.js | 2 +- > www/manager6/node/Config.js | 2 +- > www/manager6/window/Migrate.js | 4 ++-- > 7 files changed, 9 insertions(+), 8 deletions(-) > > diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js > index aafe359a..31ab94e8 100644 > --- a/www/manager6/Utils.js > +++ b/www/manager6/Utils.js > @@ -1656,7 +1656,8 @@ Ext.define('PVE.Utils', { > > showCephInstallOrMask: function(container, msg, nodename, callback) { > if (msg.match(/not (installed|initialized)/i)) { > - if (Proxmox.UserName === 'root@pam') { > + let caps = Ext.state.Manager.get('GuiCap'); > + if (caps.node.SuperUser) { but if you change this here, you also need to change the backend - as this is currently root-only (the API path called by the Ceph install wizard requires Sys.Console which is not a given just because you have SuperUser, and the ceph_install handling itself requires root@pam - the user is then presented with a login shell). so either this remains root-only for now (like the upgrade thing - both have the same problem after all!), but then please add a comment why or mention that in the commit message - or you find a good safe solution, then please argue why it is safe ;) > container.el.mask(); > if (!container.down('pveCephInstallWindow')) { > var isInstalled = !!msg.match(/not initialized/i); > diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js > index 9c54b19d..917c426f 100644 > --- a/www/manager6/dc/Config.js > +++ b/www/manager6/dc/Config.js > @@ -197,7 +197,7 @@ Ext.define('PVE.dc.Config', { > }); > } > > - if (Proxmox.UserName === 'root@pam') { > + if (caps.dc.SuperUser) { the plugins actually require 'Sys.Modify', and the account endpoints are unqualified (root-only) or open to everyone (those returning schema/static stuff for front-end re-use) at the moment but that can probably be re-evaluated. in any case, switching this just in the front-end cannot work.. > me.items.push({ > xtype: 'pveACMEClusterView', > title: 'ACME', > diff --git a/www/manager6/dc/UserView.js b/www/manager6/dc/UserView.js > index bbfc4f7c..fe0c0149 100644 > --- a/www/manager6/dc/UserView.js > +++ b/www/manager6/dc/UserView.js > @@ -29,7 +29,7 @@ Ext.define('PVE.dc.UserView', { > selModel: sm, > baseurl: '/access/users/', > dangerous: true, > - enableFn: rec => caps.access['User.Modify'] && rec.data.userid !== 'root@pam', > + enableFn: rec => caps.access['User.Modify'] && !caps.access.SuperUser, no rationale given for the different way of accessing - I'll leave it to more JS affine reviewers to decide whether this is sensible or not, but please provide the reason WHY this doesn't use `caps.access['SuperUser']` also, it's wrong - a SuperUser still requires User.Modify to modify users, so this either needs to stay as it is or simply drop the root@pam shortcut. > callback: () => reload(), > }); > let run_editor = function() { > diff --git a/www/manager6/lxc/Options.js b/www/manager6/lxc/Options.js > index f2661dfc..f8eb8a5c 100644 > --- a/www/manager6/lxc/Options.js > +++ b/www/manager6/lxc/Options.js > @@ -136,7 +136,7 @@ Ext.define('PVE.lxc.Options', { > features: { > header: gettext('Features'), > defaultValue: Proxmox.Utils.noneText, > - editor: Proxmox.UserName === 'root@pam' || caps.vms['VM.Allocate'] > + editor: caps.vms.SuperUser || caps.vms['VM.Allocate'] > ? 'PVE.lxc.FeaturesEdit' : undefined, > }, > hookscript: { > diff --git a/www/manager6/lxc/Resources.js b/www/manager6/lxc/Resources.js > index 15ee3c67..2081b4a2 100644 > --- a/www/manager6/lxc/Resources.js > +++ b/www/manager6/lxc/Resources.js > @@ -257,7 +257,7 @@ Ext.define('PVE.lxc.RessourceView', { > var isUsedDisk = isDisk && !isUnusedDisk; > > var noedit = rec.data.delete || !rowdef.editor; > - if (!noedit && Proxmox.UserName !== 'root@pam' && key.match(/^mp\d+$/)) { > + if (!noedit && !caps.vms.SuperUser && key.match(/^mp\d+$/)) { > var mp = PVE.Parser.parseLxcMountPoint(value); > if (mp.type !== 'volume') { > noedit = true; > diff --git a/www/manager6/node/Config.js b/www/manager6/node/Config.js > index 68f80391..9f49f0dd 100644 > --- a/www/manager6/node/Config.js > +++ b/www/manager6/node/Config.js > @@ -236,7 +236,7 @@ Ext.define('PVE.node.Config', { > itemId: 'apt', > upgradeBtn: { > xtype: 'pveConsoleButton', > - disabled: Proxmox.UserName !== 'root@pam', > + disabled: !caps.nodes.SuperUser, we discussed this in depth and said we'll keep the upgrade console root only for now.. also, the backend isn't change to allow this for SuperUser so it's moot anyway? > text: gettext('Upgrade'), > consoleType: 'upgrade', > nodename: nodename, > diff --git a/www/manager6/window/Migrate.js b/www/manager6/window/Migrate.js > index 1c23abb3..20fcf81d 100644 > --- a/www/manager6/window/Migrate.js > +++ b/www/manager6/window/Migrate.js > @@ -52,8 +52,8 @@ Ext.define('PVE.window.Migrate', { > } > }, > setLocalResourceCheckboxHidden: function(get) { > - if (get('running') || !get('migration.hasLocalResources') || > - Proxmox.UserName !== 'root@pam') { > + let caps = Ext.state.Manager.get('GuiCap'); > + if (get('running') || !get('migration.hasLocalResources') || caps.vms.SuperUser) { > return true; > } else { > return false; > -- > 2.30.2 > > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check 2022-02-10 15:29 ` Fabian Grünbichler @ 2022-02-25 10:13 ` Dominik Csapak 2022-02-25 12:24 ` Thomas Lamprecht 0 siblings, 1 reply; 13+ messages in thread From: Dominik Csapak @ 2022-02-25 10:13 UTC (permalink / raw) To: Proxmox VE development discussion, Fabian Grünbichler On 2/10/22 16:29, Fabian Grünbichler wrote: >> me.items.push({ >> xtype: 'pveACMEClusterView', >> title: 'ACME', >> diff --git a/www/manager6/dc/UserView.js b/www/manager6/dc/UserView.js >> index bbfc4f7c..fe0c0149 100644 >> --- a/www/manager6/dc/UserView.js >> +++ b/www/manager6/dc/UserView.js >> @@ -29,7 +29,7 @@ Ext.define('PVE.dc.UserView', { >> selModel: sm, >> baseurl: '/access/users/', >> dangerous: true, >> - enableFn: rec => caps.access['User.Modify'] && rec.data.userid !== 'root@pam', >> + enableFn: rec => caps.access['User.Modify'] && !caps.access.SuperUser, > no rationale given for the different way of accessing - I'll leave it to > more JS affine reviewers to decide whether this is sensible or not, but > please provide the reason WHY this doesn't use `caps.access['SuperUser']` just to give the reason: eslint complains if we use foo['bar'] when we could use foo.bar we prefer 'dot-notation' (so foo.bar.baz) for objects, but in all other cases of the caps object that does not work because the keys themselves contain a '.' > > also, it's wrong - a SuperUser still requires User.Modify to modify > users, so this either needs to stay as it is or simply drop the root@pam > shortcut. > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check 2022-02-25 10:13 ` Dominik Csapak @ 2022-02-25 12:24 ` Thomas Lamprecht 0 siblings, 0 replies; 13+ messages in thread From: Thomas Lamprecht @ 2022-02-25 12:24 UTC (permalink / raw) To: Proxmox VE development discussion, Dominik Csapak, Fabian Grünbichler On 25/02/2022 11:13, Dominik Csapak wrote: >>> - enableFn: rec => caps.access['User.Modify'] && rec.data.userid !== 'root@pam', >>> + enableFn: rec => caps.access['User.Modify'] && !caps.access.SuperUser, >> no rationale given for the different way of accessing - I'll leave it to >> more JS affine reviewers to decide whether this is sensible or not, but >> please provide the reason WHY this doesn't use `caps.access['SuperUser']` > > just to give the reason: > > eslint complains if we use foo['bar'] when we could use foo.bar > > we prefer 'dot-notation' (so foo.bar.baz) for objects, but in > all other cases of the caps object that does not work because > the keys themselves contain a '.' one just add a comment to tell eslint to ignore that one in that case though, else this may always look a bit weird to people reading over the code by accident. ^ permalink raw reply [flat|nested] 13+ messages in thread
* [pve-devel] [PATCH v1 qemu-server 5/5] add SuperUser privilege checks for root-only options 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas ` (3 preceding siblings ...) 2022-02-08 13:10 ` [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check Oguz Bektas @ 2022-02-08 13:10 ` Oguz Bektas [not found] ` <<20220208131011.752134-6-o.bektas@proxmox.com> 2022-02-10 15:28 ` [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Fabian Grünbichler 5 siblings, 1 reply; 13+ messages in thread From: Oguz Bektas @ 2022-02-08 13:10 UTC (permalink / raw) To: pve-devel analogous to the changes in container. we now allow users with SU privilege to edit real device configurations, provided that they also have the necessary VM privileges. note that root@pam is still able to do everything as usual --- PVE/API2/Qemu.pm | 119 +++++++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 46 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 6992f6f..9d403b4 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -352,7 +352,7 @@ my $cloudinitoptions = { my $check_vm_create_serial_perm = sub { my ($rpcenv, $authuser, $vmid, $pool, $param) = @_; - return 1 if $authuser eq 'root@pam'; + return 1 if $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); foreach my $opt (keys %{$param}) { next if $opt !~ m/^serial\d+$/; @@ -370,7 +370,7 @@ my $check_vm_create_serial_perm = sub { my $check_vm_create_usb_perm = sub { my ($rpcenv, $authuser, $vmid, $pool, $param) = @_; - return 1 if $authuser eq 'root@pam'; + return 1 if $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); foreach my $opt (keys %{$param}) { next if $opt !~ m/^usb\d+$/; @@ -388,7 +388,7 @@ my $check_vm_create_usb_perm = sub { my $check_vm_modify_config_perm = sub { my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_; - return 1 if $authuser eq 'root@pam'; + return 1 if $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); foreach my $opt (@$key_list) { # some checks (e.g., disk, serial port, usb) need to be done somewhere @@ -1117,9 +1117,10 @@ my $update_vm_api = sub { push @paramarr, "-$key", $value; } + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; my $delete_str = extract_param($param, 'delete'); @@ -1340,16 +1341,18 @@ my $update_vm_api = sub { } elsif ($opt =~ m/^serial\d+$/) { if ($val eq 'socket') { $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); - } elsif ($authuser ne 'root@pam') { - die "only root can delete '$opt' config for real devices\n"; + } elsif (!$is_superuser) { + die "only superusers can delete '$opt' config for real devices\n" + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); } PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force); PVE::QemuConfig->write_config($vmid, $conf); } elsif ($opt =~ m/^usb\d+$/) { if ($val =~ m/spice/) { $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); - } elsif ($authuser ne 'root@pam') { - die "only root can delete '$opt' config for real devices\n"; + } elsif (!$is_superuser) { + die "only superusers can delete '$opt' config for real devices\n" + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); } PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force); PVE::QemuConfig->write_config($vmid, $conf); @@ -1392,15 +1395,17 @@ my $update_vm_api = sub { } elsif ($opt =~ m/^serial\d+/) { if ((!defined($conf->{$opt}) || $conf->{$opt} eq 'socket') && $param->{$opt} eq 'socket') { $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); - } elsif ($authuser ne 'root@pam') { - die "only root can modify '$opt' config for real devices\n"; + } elsif (!$is_superuser) { + die "only superuser can modify '$opt' config for real devices\n" + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); } $conf->{pending}->{$opt} = $param->{$opt}; } elsif ($opt =~ m/^usb\d+/) { if ((!defined($conf->{$opt}) || $conf->{$opt} =~ m/spice/) && $param->{$opt} =~ m/spice/) { $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); - } elsif ($authuser ne 'root@pam') { - die "only root can modify '$opt' config for real devices\n"; + } elsif (!$is_superuser) { + die "only superuser can modify '$opt' config for real devices\n" + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); } $conf->{pending}->{$opt} = $param->{$opt}; } else { @@ -1644,9 +1649,11 @@ __PACKAGE__->register_method({ my $authuser = $rpcenv->get_user(); my $vmid = $param->{vmid}; + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = $param->{skiplock}; - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; my $early_checks = sub { # test if VM exists @@ -2291,10 +2298,12 @@ __PACKAGE__->register_method({ my $machine = extract_param($param, 'machine'); my $force_cpu = extract_param($param, 'force-cpu'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $get_root_param = sub { my $value = extract_param($param, $_[0]); - raise_param_exc({ "$_[0]" => "Only root may use this option." }) - if $value && $authuser ne 'root@pam'; + raise_param_exc({ "$_[0]" => "Only superusers may use this option." }) + if $value && !$is_superuser; return $value; }; @@ -2436,17 +2445,19 @@ __PACKAGE__->register_method({ my $node = extract_param($param, 'node'); my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; my $keepActive = extract_param($param, 'keepActive'); - raise_param_exc({ keepActive => "Only root may use this option." }) - if $keepActive && $authuser ne 'root@pam'; + raise_param_exc({ keepActive => "Only superusers may use this option." }) + if $keepActive && !$is_superuser; my $migratedfrom = extract_param($param, 'migratedfrom'); - raise_param_exc({ migratedfrom => "Only root may use this option." }) - if $migratedfrom && $authuser ne 'root@pam'; + raise_param_exc({ migratedfrom => "Only superusers may use this option." }) + if $migratedfrom && !$is_superuser; my $storecfg = PVE::Storage::config(); @@ -2513,9 +2524,11 @@ __PACKAGE__->register_method({ my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid); @@ -2580,13 +2593,15 @@ __PACKAGE__->register_method({ my $node = extract_param($param, 'node'); my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; my $keepActive = extract_param($param, 'keepActive'); - raise_param_exc({ keepActive => "Only root may use this option." }) - if $keepActive && $authuser ne 'root@pam'; + raise_param_exc({ keepActive => "Only superusers may use this option." }) + if $keepActive && !$is_superuser; my $storecfg = PVE::Storage::config(); @@ -2739,9 +2754,11 @@ __PACKAGE__->register_method({ my $statestorage = extract_param($param, 'statestorage'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid); @@ -2811,13 +2828,15 @@ __PACKAGE__->register_method({ my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; my $nocheck = extract_param($param, 'nocheck'); - raise_param_exc({ nocheck => "Only root may use this option." }) - if $nocheck && $authuser ne 'root@pam'; + raise_param_exc({ nocheck => "Only superusers may use this option." }) + if $nocheck && !$is_superuser; my $to_disk_suspended; eval { @@ -2883,9 +2902,11 @@ __PACKAGE__->register_method({ my $vmid = extract_param($param, 'vmid'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; PVE::QemuServer::vm_sendkey($vmid, $skiplock, $param->{key}); @@ -3392,6 +3413,8 @@ __PACKAGE__->register_method({ my $storecfg = PVE::Storage::config(); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $move_updatefn = sub { my $conf = PVE::QemuConfig->load_config($vmid); PVE::QemuConfig->check_lock($conf); @@ -3856,7 +3879,7 @@ __PACKAGE__->register_method({ }, force => { type => 'boolean', - description => "Allow to migrate VMs which use local devices. Only root may use this option.", + description => "Allow to migrate VMs which use local devices. Only superusers may use this option.", optional => 1, }, migration_type => { @@ -3910,15 +3933,17 @@ __PACKAGE__->register_method({ my $vmid = extract_param($param, 'vmid'); - raise_param_exc({ force => "Only root may use this option." }) - if $param->{force} && $authuser ne 'root@pam'; + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); - raise_param_exc({ migration_type => "Only root may use this option." }) - if $param->{migration_type} && $authuser ne 'root@pam'; + raise_param_exc({ force => "Only superusers may use this option." }) + if $param->{force} && !$is_superuser; + + raise_param_exc({ migration_type => "Only superusers may use this option." }) + if $param->{migration_type} && !$is_superuser; # allow root only until better network permissions are available - raise_param_exc({ migration_network => "Only root may use this option." }) - if $param->{migration_network} && $authuser ne 'root@pam'; + raise_param_exc({ migration_network => "Only superusers may use this option." }) + if $param->{migration_network} && !$is_superuser; # test if VM exists my $conf = PVE::QemuConfig->load_config($vmid); @@ -4098,9 +4123,11 @@ __PACKAGE__->register_method({ my $sizestr = extract_param($param, 'size'); + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); + my $skiplock = extract_param($param, 'skiplock'); - raise_param_exc({ skiplock => "Only root may use this option." }) - if $skiplock && $authuser ne 'root@pam'; + raise_param_exc({ skiplock => "Only superusers may use this option." }) + if $skiplock && !$is_superuser; my $storecfg = PVE::Storage::config(); -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <<20220208131011.752134-6-o.bektas@proxmox.com>]
* Re: [pve-devel] [PATCH v1 qemu-server 5/5] add SuperUser privilege checks for root-only options [not found] ` <<20220208131011.752134-6-o.bektas@proxmox.com> @ 2022-02-10 15:29 ` Fabian Grünbichler 0 siblings, 0 replies; 13+ messages in thread From: Fabian Grünbichler @ 2022-02-10 15:29 UTC (permalink / raw) To: Proxmox VE development discussion this needs a rebase anyhow, I reviewed it on HEAD~3 where it still applies ;) there's one check for 'root@pam' that looks okay same for the one in the move disk API endpoint it might be worth it to mention that you checked those and not switched them to superuser since they are only a shortcut for skipping the permission check for root, and not limiting access to some root-only action (or maybe even add a comment so that future people looking at it don't have to remember that). On February 8, 2022 2:10 pm, Oguz Bektas wrote: > analogous to the changes in container. > > we now allow users with SU privilege to edit real device configurations, > provided that they also have the necessary VM privileges. > > note that root@pam is still able to do everything as usual > > --- > PVE/API2/Qemu.pm | 119 +++++++++++++++++++++++++++++------------------ > 1 file changed, 73 insertions(+), 46 deletions(-) > > diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm > index 6992f6f..9d403b4 100644 > --- a/PVE/API2/Qemu.pm > +++ b/PVE/API2/Qemu.pm > @@ -352,7 +352,7 @@ my $cloudinitoptions = { > my $check_vm_create_serial_perm = sub { > my ($rpcenv, $authuser, $vmid, $pool, $param) = @_; > > - return 1 if $authuser eq 'root@pam'; > + return 1 if $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); nope - this still needs to check VM.Config.HWType in the SuperUser case.. e.g., should look like this: my $check_vm_create_serial_perm = sub { my ($rpcenv, $authuser, $vmid, $pool, $param) = @_; return 1 if $authuser eq 'root@pam'; my $is_superuser = $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); foreach my $opt (keys %{$param}) { next if $opt !~ m/^serial\d+$/; $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.HWType']); die "only superusers can set '$opt' config for real devices\n" if !($param->{$opt} eq 'socket' || $is_superuser); } return 1; }; > > foreach my $opt (keys %{$param}) { > next if $opt !~ m/^serial\d+$/; > @@ -370,7 +370,7 @@ my $check_vm_create_serial_perm = sub { > my $check_vm_create_usb_perm = sub { > my ($rpcenv, $authuser, $vmid, $pool, $param) = @_; > > - return 1 if $authuser eq 'root@pam'; > + return 1 if $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); same here, but with spice instead of socket > > foreach my $opt (keys %{$param}) { > next if $opt !~ m/^usb\d+$/; > @@ -388,7 +388,7 @@ my $check_vm_create_usb_perm = sub { > my $check_vm_modify_config_perm = sub { > my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_; > > - return 1 if $authuser eq 'root@pam'; > + return 1 if $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); completely wrong, like in pve-container! this effectively skips most checks for SuperUser, instead of only skipping the root-only parts.. only the else part of $check_vm_modify_config_perm should check for superuser and die otherwise.. > > foreach my $opt (@$key_list) { > # some checks (e.g., disk, serial port, usb) need to be done somewhere > @@ -1117,9 +1117,10 @@ my $update_vm_api = sub { > push @paramarr, "-$key", $value; > } > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > my $delete_str = extract_param($param, 'delete'); > > @@ -1340,16 +1341,18 @@ my $update_vm_api = sub { > } elsif ($opt =~ m/^serial\d+$/) { > if ($val eq 'socket') { > $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); > - } elsif ($authuser ne 'root@pam') { > - die "only root can delete '$opt' config for real devices\n"; > + } elsif (!$is_superuser) { > + die "only superusers can delete '$opt' config for real devices\n" > + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); same as with check_vm_create_serial_perm above.. > } > PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force); > PVE::QemuConfig->write_config($vmid, $conf); > } elsif ($opt =~ m/^usb\d+$/) { > if ($val =~ m/spice/) { > $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); > - } elsif ($authuser ne 'root@pam') { > - die "only root can delete '$opt' config for real devices\n"; > + } elsif (!$is_superuser) { > + die "only superusers can delete '$opt' config for real devices\n" > + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); also same, but with check_vm_create_usb_perm.. > } > PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force); > PVE::QemuConfig->write_config($vmid, $conf); > @@ -1392,15 +1395,17 @@ my $update_vm_api = sub { > } elsif ($opt =~ m/^serial\d+/) { > if ((!defined($conf->{$opt}) || $conf->{$opt} eq 'socket') && $param->{$opt} eq 'socket') { > $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); > - } elsif ($authuser ne 'root@pam') { > - die "only root can modify '$opt' config for real devices\n"; > + } elsif (!$is_superuser) { > + die "only superuser can modify '$opt' config for real devices\n" > + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); again > } > $conf->{pending}->{$opt} = $param->{$opt}; > } elsif ($opt =~ m/^usb\d+/) { > if ((!defined($conf->{$opt}) || $conf->{$opt} =~ m/spice/) && $param->{$opt} =~ m/spice/) { > $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); > - } elsif ($authuser ne 'root@pam') { > - die "only root can modify '$opt' config for real devices\n"; > + } elsif (!$is_superuser) { > + die "only superuser can modify '$opt' config for real devices\n" > + if !$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.HWType']); again > } > $conf->{pending}->{$opt} = $param->{$opt}; > } else { > @@ -1644,9 +1649,11 @@ __PACKAGE__->register_method({ > my $authuser = $rpcenv->get_user(); > my $vmid = $param->{vmid}; > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = $param->{skiplock}; > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > my $early_checks = sub { > # test if VM exists > @@ -2291,10 +2298,12 @@ __PACKAGE__->register_method({ > my $machine = extract_param($param, 'machine'); > my $force_cpu = extract_param($param, 'force-cpu'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $get_root_param = sub { > my $value = extract_param($param, $_[0]); > - raise_param_exc({ "$_[0]" => "Only root may use this option." }) > - if $value && $authuser ne 'root@pam'; > + raise_param_exc({ "$_[0]" => "Only superusers may use this option." }) > + if $value && !$is_superuser; > return $value; this isn't 100% correct either - most of these are migration-internal parameters (which are only ever supposed to be set when called via SSH via `qm`, which runs as root@pam anyway) skiplock can switch to being superuser-limited, the rest should stay root@pam.. > }; > > @@ -2436,17 +2445,19 @@ __PACKAGE__->register_method({ > my $node = extract_param($param, 'node'); > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > my $keepActive = extract_param($param, 'keepActive'); > - raise_param_exc({ keepActive => "Only root may use this option." }) > - if $keepActive && $authuser ne 'root@pam'; > + raise_param_exc({ keepActive => "Only superusers may use this option." }) > + if $keepActive && !$is_superuser; same here - internal param only set in vzdump context > > my $migratedfrom = extract_param($param, 'migratedfrom'); > - raise_param_exc({ migratedfrom => "Only root may use this option." }) > - if $migratedfrom && $authuser ne 'root@pam'; > + raise_param_exc({ migratedfrom => "Only superusers may use this option." }) > + if $migratedfrom && !$is_superuser; and this one is again only set when stopping the target VM during migration (via ssh, via qm, so always root). > > > my $storecfg = PVE::Storage::config(); > @@ -2513,9 +2524,11 @@ __PACKAGE__->register_method({ > > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid); > > @@ -2580,13 +2593,15 @@ __PACKAGE__->register_method({ > my $node = extract_param($param, 'node'); > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > my $keepActive = extract_param($param, 'keepActive'); > - raise_param_exc({ keepActive => "Only root may use this option." }) > - if $keepActive && $authuser ne 'root@pam'; > + raise_param_exc({ keepActive => "Only superusers may use this option." }) > + if $keepActive && !$is_superuser; same as above - AFAICT this is vzdump only.. > > my $storecfg = PVE::Storage::config(); > > @@ -2739,9 +2754,11 @@ __PACKAGE__->register_method({ > > my $statestorage = extract_param($param, 'statestorage'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid); > > @@ -2811,13 +2828,15 @@ __PACKAGE__->register_method({ > > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > my $nocheck = extract_param($param, 'nocheck'); > - raise_param_exc({ nocheck => "Only root may use this option." }) > - if $nocheck && $authuser ne 'root@pam'; > + raise_param_exc({ nocheck => "Only superusers may use this option." }) > + if $nocheck && !$is_superuser; this is also migration only (for resuming while the config is still on the source node) > > my $to_disk_suspended; > eval { > @@ -2883,9 +2902,11 @@ __PACKAGE__->register_method({ > > my $vmid = extract_param($param, 'vmid'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > PVE::QemuServer::vm_sendkey($vmid, $skiplock, $param->{key}); > > @@ -3392,6 +3413,8 @@ __PACKAGE__->register_method({ > > my $storecfg = PVE::Storage::config(); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); not used? > + > my $move_updatefn = sub { > my $conf = PVE::QemuConfig->load_config($vmid); > PVE::QemuConfig->check_lock($conf); > @@ -3856,7 +3879,7 @@ __PACKAGE__->register_method({ > }, > force => { > type => 'boolean', > - description => "Allow to migrate VMs which use local devices. Only root may use this option.", > + description => "Allow to migrate VMs which use local devices. Only superusers may use this option.", > optional => 1, > }, > migration_type => { > @@ -3910,15 +3933,17 @@ __PACKAGE__->register_method({ > > my $vmid = extract_param($param, 'vmid'); > > - raise_param_exc({ force => "Only root may use this option." }) > - if $param->{force} && $authuser ne 'root@pam'; > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > > - raise_param_exc({ migration_type => "Only root may use this option." }) > - if $param->{migration_type} && $authuser ne 'root@pam'; > + raise_param_exc({ force => "Only superusers may use this option." }) > + if $param->{force} && !$is_superuser; > + > + raise_param_exc({ migration_type => "Only superusers may use this option." }) > + if $param->{migration_type} && !$is_superuser; > > # allow root only until better network permissions are available > - raise_param_exc({ migration_network => "Only root may use this option." }) > - if $param->{migration_network} && $authuser ne 'root@pam'; > + raise_param_exc({ migration_network => "Only superusers may use this option." }) > + if $param->{migration_network} && !$is_superuser; > > # test if VM exists > my $conf = PVE::QemuConfig->load_config($vmid); > @@ -4098,9 +4123,11 @@ __PACKAGE__->register_method({ > > my $sizestr = extract_param($param, 'size'); > > + my $is_superuser = $authuser eq 'root@pam' || $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1); > + > my $skiplock = extract_param($param, 'skiplock'); > - raise_param_exc({ skiplock => "Only root may use this option." }) > - if $skiplock && $authuser ne 'root@pam'; > + raise_param_exc({ skiplock => "Only superusers may use this option." }) > + if $skiplock && !$is_superuser; > > my $storecfg = PVE::Storage::config(); > > -- > 2.30.2 > > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas ` (4 preceding siblings ...) 2022-02-08 13:10 ` [pve-devel] [PATCH v1 qemu-server 5/5] add SuperUser privilege checks for root-only options Oguz Bektas @ 2022-02-10 15:28 ` Fabian Grünbichler 5 siblings, 0 replies; 13+ messages in thread From: Fabian Grünbichler @ 2022-02-10 15:28 UTC (permalink / raw) To: Proxmox VE development discussion see individual patches for in-depth review of changes, some broader remarks: - I am missing info about parts you looked at but left as-is (and rationale for why those parts stay root only) - especially relevant would be a list of currently unqualified/root-only-by-default API endpoints and actions taken or not taken + reasons e.g. some parts that are missing that I found with random grepping (in addition to stuff I mentioned in my other replies), where I have no idea whether you even look at them and decided they are okay as-is, or missed them: - PVE::API2::Backup (tmpdir, dumpdir, script parameters) - PVE::API2::VZDump (maxfiles prune-backups tmpdir dumpdir script bwlimit ionice) - PVE::API2::ClusterConfig (we talked about that off-list, but some mention in the actual patch series would still be good) - PVE::Storage::check_volume_access , which is used in quite a few places.. On February 8, 2022 2:10 pm, Oguz Bektas wrote: > "SuperUser" (henceforth referred as SU) privilege allows to give > root-only permissions to API users, enabling them to perform privileged > actions on behalf of root@pam. > > this privilege is enabled by default for "root@pam", and also mapped > inside "SuperAdministrator" (referred as SA) > > changes from RFC (thanks for the review fabian g.!): > * manager: allow SAs to see/edit certain things on GUI > * qemu-server: also check the required non-root > VM privileges along with the SU priv > * pve-container: adapted error messages, changed variable name to > "is_superuser" for better clarity (in comparison to prev. "is_root" > which is a bit confusing) > * access-control: TFA permissions adaptation for SAs > > > access-control: > > Oguz Bektas (2): > add "SuperAdministrator" role with the new "SuperUser" privilege > tfa: allow superusers to edit root@pam tfa > > src/PVE/API2/TFA.pm | 7 +++++-- > src/PVE/AccessControl.pm | 9 ++++++--- > src/PVE/RPCEnvironment.pm | 2 +- > 3 files changed, 12 insertions(+), 6 deletions(-) > > container: > > Oguz Bektas (1): > fix #2582: api: add checks for 'SuperUser' privilege for root-only > options > > src/PVE/API2/LXC.pm | 13 ++++++------- > src/PVE/API2/LXC/Status.pm | 8 ++++++-- > src/PVE/LXC.pm | 9 ++++++--- > 3 files changed, 18 insertions(+), 12 deletions(-) > > manager: > > Oguz Bektas (1): > change 'root@pam' checks with 'SuperUser' capability check > > www/manager6/Utils.js | 3 ++- > www/manager6/dc/Config.js | 2 +- > www/manager6/dc/UserView.js | 2 +- > www/manager6/lxc/Options.js | 2 +- > www/manager6/lxc/Resources.js | 2 +- > www/manager6/node/Config.js | 2 +- > www/manager6/window/Migrate.js | 4 ++-- > 7 files changed, 9 insertions(+), 8 deletions(-) > > qemu-server: > > Oguz Bektas (1): > add SuperUser privilege checks for root-only options > > PVE/API2/Qemu.pm | 119 +++++++++++++++++++++++++++++------------------ > 1 file changed, 73 insertions(+), 46 deletions(-) > > -- > 2.30.2 > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2022-02-25 12:24 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-02-08 13:10 [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 1/5] add default "SuperAdministrator" role with the new "SuperUser" privilege Oguz Bektas 2022-02-08 13:10 ` [pve-devel] [PATCH v1 access-control 2/5] tfa: allow superusers to edit root@pam tfa Oguz Bektas [not found] ` <<20220208131011.752134-3-o.bektas@proxmox.com> 2022-02-10 15:30 ` Fabian Grünbichler 2022-02-08 13:10 ` [pve-devel] [PATCH v1 container 3/5] fix #2582: api: add checks for 'SuperUser' privilege for root-only options Oguz Bektas [not found] ` <<20220208131011.752134-4-o.bektas@proxmox.com> 2022-02-10 15:30 ` Fabian Grünbichler 2022-02-08 13:10 ` [pve-devel] [PATCH v1 manager 4/5] change 'root@pam' checks with 'SuperUser' capability check Oguz Bektas [not found] ` <<20220208131011.752134-5-o.bektas@proxmox.com> 2022-02-10 15:29 ` Fabian Grünbichler 2022-02-25 10:13 ` Dominik Csapak 2022-02-25 12:24 ` Thomas Lamprecht 2022-02-08 13:10 ` [pve-devel] [PATCH v1 qemu-server 5/5] add SuperUser privilege checks for root-only options Oguz Bektas [not found] ` <<20220208131011.752134-6-o.bektas@proxmox.com> 2022-02-10 15:29 ` Fabian Grünbichler 2022-02-10 15:28 ` [pve-devel] [PATCH v1 access-control++ 0/5] SuperUser privilege Fabian Grünbichler
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox