]> git.proxmox.com Git - qemu-server.git/commitdiff
suspend to disk: check more permissions
authorDominik Csapak <d.csapak@proxmox.com>
Mon, 9 Dec 2019 14:26:59 +0000 (15:26 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 11 Dec 2019 08:02:55 +0000 (09:02 +0100)
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@proxmox.com>
PVE/API2/Qemu.pm
PVE/QemuServer.pm

index b28373e0f53b141b673e3f4fa2a3d730672d1fab..25c2836071b810547ab6ce17d807faf1bbd2d981 100644 (file)
@@ -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;
 
index 7bcdb61a23459caf537dde55904a3011a23b724b..549ce3099608ec3a907ba24226c10fc3fc76b2c4 100644 (file)
@@ -5742,6 +5742,7 @@ sub vm_reboot {
    });
 }
 
+# note: if using the statestorage parameter, the caller has to check privileges
 sub vm_suspend {
     my ($vmid, $skiplock, $includestate, $statestorage) = @_;
 
@@ -5765,6 +5766,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);