[pve-devel] [PATCH qemu-server v2 2/3] suspend to disk: check more permissions

Dominik Csapak d.csapak at proxmox.com
Mon Dec 9 15:26:59 CET 2019


only VM.PowerMgmt is not enough, since we allocate space on a storage,
so we need VM.Config.Disk on the vm and Datastore.AllocateSpace on the storage

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
changes from v1:
* move priv check inside if condition in vm_susepnd and
  note that the caller has to check the privs if the storage is given
* remove lock from api call

 PVE/API2/Qemu.pm  | 17 +++++++++++++++++
 PVE/QemuServer.pm | 12 ++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index fbf036a..e7ed6e9 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -2387,6 +2387,9 @@ __PACKAGE__->register_method({
     proxyto => 'node',
     description => "Suspend virtual machine.",
     permissions => {
+	description => "You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk',".
+	    " you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace'".
+	    " on the storage for the vmstate.",
 	check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
     },
     parameters => {
@@ -2435,6 +2438,20 @@ __PACKAGE__->register_method({
 	die "Cannot suspend HA managed VM to disk\n"
 	    if $todisk && PVE::HA::Config::vm_is_ha_managed($vmid);
 
+	# early check for storage permission, for better user feedback
+	if ($todisk) {
+	    $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk']);
+
+	    if (!$statestorage) {
+		# get statestorage from config if none is given
+		my $conf = PVE::QemuConfig->load_config($vmid);
+		my $storecfg = PVE::Storage::config();
+		$statestorage = PVE::QemuServer::find_vmstate_storage($conf, $storecfg);
+	    }
+
+	    $rpcenv->check($authuser, "/storage/$statestorage", ['Datastore.AllocateSpace']);
+	}
+
 	my $realcmd = sub {
 	    my $upid = shift;
 
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 38287c2..daa328f 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -5733,6 +5733,7 @@ sub vm_reboot {
    });
 }
 
+# note: if using the statestorage parameter, the caller has to check privileges
 sub vm_suspend {
     my ($vmid, $skiplock, $includestate, $statestorage) = @_;
 
@@ -5756,6 +5757,17 @@ sub vm_suspend {
 	    $conf->{lock} = 'suspending';
 	    my $date = strftime("%Y-%m-%d", localtime(time()));
 	    $storecfg = PVE::Storage::config();
+	    if (!$statestorage) {
+		$statestorage = find_vmstate_storage($conf, $storecfg);
+		# check permissions for the storage
+		my $rpcenv = PVE::RPCEnvironment::get();
+		if ($rpcenv->{type} ne 'cli') {
+		    my $authuser = $rpcenv->get_user();
+		    $rpcenv->check($authuser, "/storage/$statestorage", ['Datastore.AllocateSpace']);
+		}
+	    }
+
+
 	    $vmstate = PVE::QemuConfig->__snapshot_save_vmstate($vmid, $conf, "suspend-$date", $storecfg, $statestorage, 1);
 	    $path = PVE::Storage::path($storecfg, $vmstate);
 	    PVE::QemuConfig->write_config($vmid, $conf);
-- 
2.20.1





More information about the pve-devel mailing list