From: Oguz Bektas <o.bektas@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v2 container 08/12] fix #2582: api: add checks for 'SuperUser' privilege for root-only options
Date: Fri, 11 Mar 2022 12:25:00 +0100 [thread overview]
Message-ID: <20220311112504.595964-9-o.bektas@proxmox.com> (raw)
In-Reply-To: <20220311112504.595964-1-o.bektas@proxmox.com>
this way we can allow regular users to act as superuser on specific
paths by giving them the (new) builtin 'SuperAdministrator' role or a
custom role with the 'SuperUser' privilege
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
---
v1->v2:
* update the messages to reflect superuser instead of root@pam
src/PVE/API2/LXC.pm | 15 +++++++--------
src/PVE/API2/LXC/Config.pm | 2 +-
src/PVE/API2/LXC/Status.pm | 12 ++++++++----
src/PVE/LXC.pm | 21 ++++++++++++---------
4 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 84712f7..4631d0b 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -304,7 +304,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 = {};
@@ -339,8 +339,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);
@@ -380,7 +380,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});
@@ -414,8 +414,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 superusers\n" if !$is_superuser;
if ($mountpoint->{backup}) {
warn "WARNING - unsupported configuration!\n";
@@ -456,7 +455,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 {
@@ -2216,7 +2215,7 @@ __PACKAGE__->register_method({
raise_param_exc({ 'target-vmid' => $msg, 'storage' => $msg });
} elsif ($target_vmid) {
$rpcenv->check_vm_perm($authuser, $target_vmid, undef, ['VM.Config.Disk'])
- if $authuser ne 'root@pam';
+ if $authuser ne 'root@pam'; # no need to check for root@pam
if ($vmid eq $target_vmid) {
my $msg = "must be different than source VMID to move disk to another container";
diff --git a/src/PVE/API2/LXC/Config.pm b/src/PVE/API2/LXC/Config.pm
index 1fec048..6278b8a 100644
--- a/src/PVE/API2/LXC/Config.pm
+++ b/src/PVE/API2/LXC/Config.pm
@@ -99,7 +99,7 @@ __PACKAGE__->register_method({
description => "Set container options.",
permissions => {
check => ['perm', '/vms/{vmid}', $vm_config_perm_list, any => 1],
- description => 'non-volume mount points in rootfs and mp[n] are restricted to root@pam',
+ description => 'non-volume mount points in rootfs and mp[n] are restricted to superusers',
},
parameters => {
additionalProperties => 0,
diff --git a/src/PVE/API2/LXC/Status.pm b/src/PVE/API2/LXC/Status.pm
index f7e3128..92e37f8 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';
+ raise_param_exc({ skiplock => "Only superusers may use this option." })
+ 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';
+ raise_param_exc({ skiplock => "Only superusers may use this option." })
+ 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..60c4fce 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -1254,7 +1254,10 @@ 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';
+ return 1 if $authuser eq 'root@pam'; # early exit for root@pam
+
+ my $is_superuser = $rpcenv->check($authuser, "/vms/$vmid", ['SuperUser'], 1);
+
my $storage_cfg = PVE::Storage::config();
my $check = sub {
@@ -1265,8 +1268,8 @@ sub check_ct_modify_config_perm {
$rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Disk']);
return if $delete;
my $data = PVE::LXC::Config->parse_volume($opt, $newconf->{$opt});
- raise_perm_exc("mount point type $data->{type} is only allowed for root\@pam")
- if $data->{type} ne 'volume';
+ raise_perm_exc("mount point type $data->{type} is only allowed for superusers")
+ if $data->{type} ne 'volume' && !$is_superuser;
my $volid = $data->{volume};
if ($volid =~ $NEW_DISK_RE) {
my $sid = $1;
@@ -1280,8 +1283,8 @@ sub check_ct_modify_config_perm {
$opt eq 'searchdomain' || $opt eq 'hostname') {
$rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Network']);
} elsif ($opt eq 'features') {
- raise_perm_exc("changing feature flags for privileged container is only allowed for root\@pam")
- if !$unprivileged;
+ raise_perm_exc("changing feature flags for privileged container is only allowed for superusers")
+ if !$unprivileged && !$is_superuser;
my $nesting_changed = 0;
my $other_changed = 0;
@@ -1319,13 +1322,13 @@ sub check_ct_modify_config_perm {
$other_changed = 1;
}
}
- raise_perm_exc("changing feature flags (except nesting) is only allowed for root\@pam")
- if $other_changed;
+ raise_perm_exc("changing feature flags (except nesting) is only allowed for superusers")
+ 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 superusers")
+ if !$is_superuser;
} else {
$rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Options']);
}
--
2.30.2
next prev parent reply other threads:[~2022-03-11 11:26 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-11 11:24 [pve-devel] [PATCH v2 access-control++ 00/12] SuperUser privilege Oguz Bektas
2022-03-11 11:24 ` [pve-devel] [PATCH v2 docs 01/12] pveum: add SU privilege and SA role Oguz Bektas
2022-03-17 9:36 ` Fabian Grünbichler
2022-03-11 11:24 ` [pve-devel] [PATCH v2 qemu-server 02/12] api: allow SU privileged users to edit root-only options for VM configs Oguz Bektas
2022-03-17 10:05 ` Fabian Grünbichler
2022-03-11 11:24 ` [pve-devel] [PATCH v2 qemu-server 03/12] api: allow 'skiplock' option to be used by SU privileged users Oguz Bektas
2022-03-17 10:12 ` Fabian Grünbichler
2022-03-11 11:24 ` [pve-devel] [PATCH v2 manager 04/12] api: backup: allow SUs to use 'tmpdir', 'dumpdir' and 'script' options Oguz Bektas
2022-03-17 12:18 ` Fabian Grünbichler
2022-03-11 11:24 ` [pve-devel] [PATCH v2 manager 05/12] api: vzdump: allow SUs to use 'bwlimit' and 'ionice' parameters Oguz Bektas
2022-03-11 11:24 ` [pve-devel] [PATCH v2 manager 06/12] api: update comment about login prompt for non-root users Oguz Bektas
2022-03-17 12:33 ` Fabian Grünbichler
2022-03-11 11:24 ` [pve-devel] [PATCH v2 manager 07/12] ui: adapt sensible 'root@pam' checks to SU privilege Oguz Bektas
2022-03-17 12:28 ` Fabian Grünbichler
2022-03-11 11:25 ` Oguz Bektas [this message]
2022-03-17 12:11 ` [pve-devel] [PATCH v2 container 08/12] fix #2582: api: add checks for 'SuperUser' privilege for root-only options Fabian Grünbichler
2022-03-11 11:25 ` [pve-devel] [PATCH v2 storage 09/12] check_volume_access: allow superusers to pass arbitrary fs paths Oguz Bektas
2022-03-11 11:25 ` [pve-devel] [PATCH v2 access-control 10/12] add "SuperAdministrator" role with the new "SuperUser" privilege Oguz Bektas
2022-03-11 11:25 ` [pve-devel] [PATCH v2 access-control 11/12] api: allow superusers to edit tfa and password settings Oguz Bektas
[not found] ` <<20220311112504.595964-12-o.bektas@proxmox.com>
2022-03-17 9:30 ` Fabian Grünbichler
2022-03-11 11:25 ` [pve-devel] [PATCH v2 access-control 12/12] api: acl: only allow granting SU privilege if user already has it Oguz Bektas
2022-03-16 12:24 ` Fabian Grünbichler
[not found] ` <<20220311112504.595964-1-o.bektas@proxmox.com>
2022-03-17 13:04 ` [pve-devel] [PATCH v2 access-control++ 00/12] SuperUser privilege Fabian Grünbichler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220311112504.595964-9-o.bektas@proxmox.com \
--to=o.bektas@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.