diff --git a/PVE/API2/Storage/Config.pm b/PVE/API2/Storage/Config.pm index 7d3826e..34c2150 100755 --- a/PVE/API2/Storage/Config.pm +++ b/PVE/API2/Storage/Config.pm @@ -9,8 +9,7 @@ use PVE::Storage; use HTTP::Status qw(:constants); use Storable qw(dclone); use PVE::JSONSchema qw(get_standard_option); - -use Data::Dumper; # fixme: remove +use PVE::RPCEnvironment; use PVE::RESTHandler; @@ -41,6 +40,10 @@ __PACKAGE__->register_method ({ path => '', method => 'GET', description => "Storage index.", + permissions => { + description => "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + user => 'all', + }, parameters => { additionalProperties => 0, properties => { @@ -64,12 +67,18 @@ __PACKAGE__->register_method ({ code => sub { my ($param) = @_; + my $rpcenv = PVE::RPCEnvironment::get(); + my $authuser = $rpcenv->get_user(); + my $cfg = cfs_read_file("storage.cfg"); - my @sids = PVE::Storage::storage_ids($cfg); + my @sids = PVE::Storage::storage_ids($cfg); my $res = []; foreach my $storeid (@sids) { + my $privs = [ 'Datastore.Audit', 'Datastore.AllocateSpace' ]; + next if !$rpcenv->check_any($authuser, "/storage/$storeid", $privs, 1); + my $scfg = &$api_storage_config($cfg, $storeid); next if $param->{type} && $param->{type} ne $scfg->{type}; push @$res, $scfg; @@ -83,6 +92,9 @@ __PACKAGE__->register_method ({ path => '{storage}', method => 'GET', description => "Read storage configuration.", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { @@ -104,6 +116,9 @@ __PACKAGE__->register_method ({ path => '', method => 'POST', description => "Create a new storage.", + permissions => { + check => ['perm', '/storage', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { @@ -227,6 +242,9 @@ __PACKAGE__->register_method ({ path => '{storage}', method => 'PUT', description => "Update storage configuration.", + permissions => { + check => ['perm', '/storage', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { @@ -298,6 +316,9 @@ __PACKAGE__->register_method ({ path => '{storage}', # /storage/config/{storage} method => 'DELETE', description => "Delete storage configuration.", + permissions => { + check => ['perm', '/storage', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { diff --git a/PVE/API2/Storage/Content.pm b/PVE/API2/Storage/Content.pm index 5544ea7..38cd1e9 100644 --- a/PVE/API2/Storage/Content.pm +++ b/PVE/API2/Storage/Content.pm @@ -21,6 +21,9 @@ __PACKAGE__->register_method ({ path => '', method => 'GET', description => "List storage content.", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1], + }, protected => 1, proxyto => 'node', parameters => { @@ -92,6 +95,9 @@ __PACKAGE__->register_method ({ path => '', method => 'POST', description => "Allocate disk images.", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']], + }, protected => 1, proxyto => 'node', parameters => { @@ -189,6 +195,9 @@ __PACKAGE__->register_method ({ path => '{volume}', method => 'GET', description => "Get volume attributes", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1], + }, protected => 1, proxyto => 'node', parameters => { @@ -226,6 +235,9 @@ __PACKAGE__->register_method ({ path => '{volume}', method => 'DELETE', description => "Delete volume", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']], + }, protected => 1, proxyto => 'node', parameters => { @@ -256,7 +268,7 @@ __PACKAGE__->register_method ({ name => 'copy', path => '{volume}', method => 'POST', - description => "Copy a volume.", + description => "Copy a volume. This is experimental code - do not use.", protected => 1, proxyto => 'node', parameters => { diff --git a/PVE/API2/Storage/Scan.pm b/PVE/API2/Storage/Scan.pm index 3aaa066..d0c3c6e 100644 --- a/PVE/API2/Storage/Scan.pm +++ b/PVE/API2/Storage/Scan.pm @@ -17,6 +17,9 @@ __PACKAGE__->register_method ({ path => '', method => 'GET', description => "Index of available scan methods", + permissions => { + user => 'all', + }, parameters => { additionalProperties => 0, properties => { @@ -51,6 +54,9 @@ __PACKAGE__->register_method ({ description => "Scan remote NFS server.", protected => 1, proxyto => "node", + permissions => { + check => ['perm', '/storage', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { @@ -88,6 +94,9 @@ __PACKAGE__->register_method ({ description => "Scan remote iSCSI server.", protected => 1, proxyto => "node", + permissions => { + check => ['perm', '/storage', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { @@ -125,6 +134,9 @@ __PACKAGE__->register_method ({ description => "List local LVM volume groups.", protected => 1, proxyto => "node", + permissions => { + check => ['perm', '/storage', ['Datastore.Allocate']], + }, parameters => { additionalProperties => 0, properties => { @@ -154,6 +166,9 @@ __PACKAGE__->register_method ({ description => "List local USB devices.", protected => 1, proxyto => "node", + permissions => { + check => ['perm', '/', ['Sys.Modify']], + }, parameters => { additionalProperties => 0, properties => { diff --git a/PVE/API2/Storage/Status.pm b/PVE/API2/Storage/Status.pm index 68f3d39..9e5790a 100644 --- a/PVE/API2/Storage/Status.pm +++ b/PVE/API2/Storage/Status.pm @@ -30,6 +30,10 @@ __PACKAGE__->register_method ({ path => '', method => 'GET', description => "Get status for all datastores.", + permissions => { + description => "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + user => 'all', + }, protected => 1, proxyto => 'node', parameters => { @@ -59,21 +63,26 @@ __PACKAGE__->register_method ({ code => sub { my ($param) = @_; + my $rpcenv = PVE::RPCEnvironment::get(); + my $authuser = $rpcenv->get_user(); + my $cfg = cfs_read_file("storage.cfg"); my $info = PVE::Storage::storage_info($cfg, $param->{content}); - if ($param->{storage}) { - my $data = $info->{$param->{storage}}; - - raise_param_exc({ storage => "No such storage." }) - if !defined($data); - - $data->{storage} = $param->{storage}; - - return [ $data ]; + raise_param_exc({ storage => "No such storage." }) + if $param->{storage} && !defined($info->{$param->{storage}}); + + my $res = {}; + my @sids = PVE::Storage::storage_ids($cfg); + foreach my $storeid (@sids) { + my $privs = [ 'Datastore.Audit', 'Datastore.AllocateSpace' ]; + next if !$rpcenv->check_any($authuser, "/storage/$storeid", $privs, 1); + next if $param->{storage} && $param->{storage} ne $storeid; + $res->{$storeid} = $info->{$storeid}; } - return PVE::RESTHandler::hash_to_array($info, 'storage'); + + return PVE::RESTHandler::hash_to_array($res, 'storage'); }}); __PACKAGE__->register_method ({ @@ -81,6 +90,9 @@ __PACKAGE__->register_method ({ path => '{storage}', method => 'GET', description => "", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1], + }, parameters => { additionalProperties => 0, properties => { @@ -117,6 +129,9 @@ __PACKAGE__->register_method ({ path => '{storage}/status', method => 'GET', description => "Read storage status.", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1], + }, protected => 1, proxyto => 'node', parameters => { @@ -150,6 +165,9 @@ __PACKAGE__->register_method ({ path => '{storage}/rrd', method => 'GET', description => "Read storage RRD statistics (returns PNG).", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1], + }, protected => 1, proxyto => 'node', parameters => { @@ -194,6 +212,9 @@ __PACKAGE__->register_method ({ path => '{storage}/rrddata', method => 'GET', description => "Read storage RRD statistics.", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1], + }, protected => 1, proxyto => 'node', parameters => { @@ -234,6 +255,9 @@ __PACKAGE__->register_method ({ path => '{storage}/upload', method => 'POST', description => "Upload file.", + permissions => { + check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']], + }, protected => 1, parameters => { additionalProperties => 0,