From 04a13668b9b6e15d3aed36ba00ad538b99a9dc15 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 18 Jan 2017 17:14:07 +0100 Subject: [PATCH] PVE::Storage: new helper check_volume_access() Copied from PVE::RPCEnvironment to avoid cyclic dependency (pve-storgae => pve-access-control => pve-storage). --- PVE/API2/Storage/Content.pm | 4 ++-- PVE/CLI/pvesm.pm | 2 +- PVE/Storage.pm | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/PVE/API2/Storage/Content.pm b/PVE/API2/Storage/Content.pm index 47ef03b..699823b 100644 --- a/PVE/API2/Storage/Content.pm +++ b/PVE/API2/Storage/Content.pm @@ -72,7 +72,7 @@ __PACKAGE__->register_method ({ my $res = []; foreach my $item (@$vollist) { - eval { $rpcenv->check_volume_access($authuser, $cfg, undef, $item->{volid}); }; + eval { PVE::Storage::check_volume_access($rpcenv, $authuser, $cfg, undef, $item->{volid}); }; next if $@; push @$res, $item; } @@ -219,7 +219,7 @@ __PACKAGE__->register_method ({ my $cfg = PVE::Storage::config(); - $rpcenv->check_volume_access($authuser, $cfg, undef, $volid); + PVE::Storage::check_volume_access($rpcenv, $rpcenv->$authuser, $cfg, undef, $volid); my $path = PVE::Storage::path($cfg, $volid); my ($size, $format, $used, $parent) = PVE::Storage::file_size_info($path); diff --git a/PVE/CLI/pvesm.pm b/PVE/CLI/pvesm.pm index 3767810..3b99436 100755 --- a/PVE/CLI/pvesm.pm +++ b/PVE/CLI/pvesm.pm @@ -86,7 +86,7 @@ __PACKAGE__->register_method ({ my $authuser = $rpcenv->get_user(); my $storage_cfg = PVE::Storage::config(); - $rpcenv->check_volume_access($authuser, $storage_cfg, undef, $volume); + PVE::Storage::check_volume_access($rpcenv, $authuser, $storage_cfg, undef, $volume); my $config_raw = PVE::Storage::extract_vzdump_config($storage_cfg, $volume); diff --git a/PVE/Storage.pm b/PVE/Storage.pm index 683c920..bfc34d4 100755 --- a/PVE/Storage.pm +++ b/PVE/Storage.pm @@ -344,6 +344,32 @@ sub parse_volume_id { return PVE::Storage::Plugin::parse_volume_id($volid, $noerr); } +# test if we have read access to volid +sub check_volume_access { + my ($rpcenv, $user, $cfg, $vmid, $volid) = @_; + + my ($sid, $volname) = parse_volume_id($volid, 1); + if ($sid) { + my ($vtype, undef, $ownervm) = parse_volname($cfg, $volid); + if ($vtype eq 'iso' || $vtype eq 'vztmpl') { + # we simply allow access + } elsif (defined($ownervm) && defined($vmid) && ($ownervm == $vmid)) { + # we are owner - allow access + } elsif ($vtype eq 'backup' && $ownervm) { + $rpcenv->check($user, "/storage/$sid", ['Datastore.AllocateSpace']); + $rpcenv->check($user, "/vms/$ownervm", ['VM.Backup']); + } else { + # allow if we are Datastore administrator + $rpcenv->check($user, "/storage/$sid", ['Datastore.Allocate']); + } + } else { + die "Only root can pass arbitrary filesystem paths." + if $user ne 'root@pam'; + } + + return undef; +} + my $volume_is_base_and_used__no_lock = sub { my ($scfg, $storeid, $plugin, $volname) = @_; -- 2.39.2