maxLength => 50
};
-my $assert_param_permission = sub {
- my ($param, $user) = @_;
+# NOTE: also used by the vzdump API call.
+sub assert_param_permission_common {
+ my ($rpcenv, $user, $param, $is_delete) = @_;
return if $user eq 'root@pam'; # always OK
- for my $key (qw(tmpdir dumpdir script)) {
+ for my $key (qw(tmpdir dumpdir script job-id)) {
raise_param_exc({ $key => "Only root may set this option."}) if exists $param->{$key};
}
-};
+
+ if (grep { defined($param->{$_}) } qw(bwlimit ionice performance)) {
+ $rpcenv->check($user, "/", [ 'Sys.Modify' ]);
+ }
+
+ if ($param->{fleecing} && !$is_delete) {
+ my $fleecing = PVE::VZDump::parse_fleecing($param) // {};
+ $rpcenv->check($user, "/storage/$fleecing->{storage}", [ 'Datastore.AllocateSpace' ])
+ if $fleecing->{storage};
+ }
+}
+
+my sub assert_param_permission_create {
+ my ($rpcenv, $user, $param) = @_;
+ return if $user eq 'root@pam'; # always OK
+
+ assert_param_permission_common($rpcenv, $user, $param);
+
+ if (my $storeid = PVE::VZDump::get_storage_param($param)) {
+ $rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Allocate' ]);
+ }
+}
+
+my sub assert_param_permission_update {
+ my ($rpcenv, $user, $update, $delete, $current) = @_;
+ return if $user eq 'root@pam'; # always OK
+
+ assert_param_permission_common($rpcenv, $user, $update);
+ assert_param_permission_common($rpcenv, $user, $delete, 1);
+
+ if ($update->{storage}) {
+ $rpcenv->check($user, "/storage/$update->{storage}", [ 'Datastore.Allocate' ])
+ } elsif ($delete->{storage}) {
+ $rpcenv->check($user, "/storage/local", [ 'Datastore.Allocate' ]);
+ }
+
+ return if !$current; # early check done
+
+ if ($current->{dumpdir}) {
+ die "only root\@pam may edit jobs with a 'dumpdir' option.";
+ } else {
+ if (my $storeid = PVE::VZDump::get_storage_param($current)) {
+ $rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Allocate' ]);
+ }
+ }
+}
my $convert_to_schedule = sub {
my ($job) = @_;
my $rpcenv = PVE::RPCEnvironment::get();
my $user = $rpcenv->get_user();
- $assert_param_permission->($param, $user);
+ assert_param_permission_create($rpcenv, $user, $param);
if (my $pool = $param->{pool}) {
$rpcenv->check_pool_exist($pool);
my $rpcenv = PVE::RPCEnvironment::get();
my $user = $rpcenv->get_user();
- $assert_param_permission->($param, $user);
+ my $id = extract_param($param, 'id');
+ my $delete = extract_param($param, 'delete');
+ $delete = { map { $_ => 1 } PVE::Tools::split_list($delete) } if $delete;
+
+ assert_param_permission_update($rpcenv, $user, $param, $delete);
if (my $pool = $param->{pool}) {
$rpcenv->check_pool_exist($pool);
$schedule_param_check->($param);
- my $id = extract_param($param, 'id');
- my $delete = extract_param($param, 'delete');
- if ($delete) {
- $delete = [PVE::Tools::split_list($delete)];
- }
-
my $update_job = sub {
my $data = cfs_read_file('vzdump.cron');
my $jobs_data = cfs_read_file('jobs.cfg');
my $jobs = $data->{jobs} || [];
- die "no options specified\n" if !scalar(keys %$param);
+ die "no options specified\n" if !scalar(keys $param->%*) && !scalar(keys $delete->%*);
PVE::VZDump::verify_vzdump_parameters($param);
my $opts = PVE::VZDump::JobBase->check_config($id, $param, 0, 1);
die "no such vzdump job\n" if !$job || $job->{type} ne 'vzdump';
}
+ assert_param_permission_update($rpcenv, $user, $param, $delete, $job);
+
my $deletable = {
comment => 1,
'repeat-missed' => 1,
};
- foreach my $k (@$delete) {
+ for my $k (keys $delete->%*) {
if (!PVE::VZDump::option_exists($k) && !$deletable->{$k}) {
raise_param_exc({ delete => "unknown option '$k'" });
}