api: roles: forbid creatin new roles starting with "PVE" namespace

makes our reasoning when adding new top-level privileges way easier
in the future.
We already had two major upgrades with role additions where we had to
add special checks in the upgrade script and breaking changes, so
let's reserve any role starting with PVE (case-insensitive to avoid
confusion potential) and forbid creating those via API.

We might also think about letting the config parser choke on that, as
otherwise one could still create them via editing the config
manually.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht 2023-06-08 09:31:19 +02:00
parent d6fb84bfef
commit 00b90e7185

View File

@ -5,6 +5,7 @@ use warnings;
use PVE::AccessControl (); use PVE::AccessControl ();
use PVE::Cluster qw(cfs_read_file cfs_write_file); use PVE::Cluster qw(cfs_read_file cfs_write_file);
use PVE::Exception qw(raise_param_exc);
use PVE::JSONSchema qw(get_standard_option register_standard_option); use PVE::JSONSchema qw(get_standard_option register_standard_option);
use base qw(PVE::RESTHandler); use base qw(PVE::RESTHandler);
@ -82,11 +83,17 @@ __PACKAGE__->register_method ({
code => sub { code => sub {
my ($param) = @_; my ($param) = @_;
my $role = $param->{roleid};
if ($role =~ /^PVE/i) {
raise_param_exc({
roleid => "cannot use role ID starting with the (case-insensitive) 'PVE' namespace",
});
}
PVE::AccessControl::lock_user_config(sub { PVE::AccessControl::lock_user_config(sub {
my $usercfg = cfs_read_file("user.cfg"); my $usercfg = cfs_read_file("user.cfg");
my $role = $param->{roleid};
die "role '$role' already exists\n" if $usercfg->{roles}->{$role}; die "role '$role' already exists\n" if $usercfg->{roles}->{$role};
$usercfg->{roles}->{$role} = {}; $usercfg->{roles}->{$role} = {};