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