path => '',
method => 'GET',
description => "Directory index.",
+ permissions => {
+ user => 'all',
+ },
parameters => {
additionalProperties => 0,
properties => {},
path => 'password',
method => 'PUT',
permissions => {
- description => "Each user is allowed to change his own password. A user can change the password of another user if he has modify permission on /access/groups/<group> on a group where user <userid> is member of.",
+ description => "Each user is allowed to change his own password. A user can change the password of another user if he has 'Realm.AllocateUser' (on the realm of user <userid>) and 'User.Modify' permission on /access/groups/<group> on a group where user <userid> is member of.",
check => [ 'or',
['userid-param', 'self'],
- ['userid-group', ['User.Modify']],
+ [ 'and',
+ [ 'userid-param', 'Realm.AllocateUser'],
+ [ 'userid-group', ['User.Modify']]
+ ]
],
},
protected => 1, # else we can't access shadow files
path => '',
method => 'GET',
description => "Authentication domain index.",
- permissions => { user => 'world' },
+ permissions => {
+ description => "Anyone can access that, because we need that list for the login box (before the user is authenticated).",
+ user => 'world',
+ },
parameters => {
additionalProperties => 0,
properties => {},
path => '',
method => 'POST',
permissions => {
- check => ['perm', '/access', ['Sys.Modify']],
+ check => ['perm', '/access/realm', ['Realm.Allocate']],
},
description => "Add an authentication server.",
parameters => {
path => '{realm}',
method => 'PUT',
permissions => {
- check => ['perm', '/access', ['Sys.Modify']],
+ check => ['perm', '/access/realm', ['Realm.Allocate']],
},
description => "Update authentication server settings.",
protected => 1,
method => 'GET',
description => "Get auth server configuration.",
permissions => {
- check => ['perm', '/access', ['Sys.Audit']],
+ check => ['perm', '/access/realm', ['Realm.Allocate', 'Sys.Audit'], any => 1],
},
parameters => {
additionalProperties => 0,
path => '{realm}',
method => 'DELETE',
permissions => {
- check => ['perm', '/access', ['Sys.Modify']],
+ check => ['perm', '/access/realm', ['Realm.Allocate']],
},
description => "Delete an authentication server.",
protected => 1,
method => 'GET',
description => "Group index.",
permissions => {
- description => "The returned list is restricted to groups where you have 'User.Allocate' or 'Sys.Audit' permissions on '/access', or 'User.Allocate' on /access/groups/<group>.",
+ description => "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/<group>.",
user => 'all',
},
parameters => {
my $usercfg = cfs_read_file("user.cfg");
my $authuser = $rpcenv->get_user();
- my $privs = [ 'User.Allocate', 'Sys.Audit' ];
- my $allow = $rpcenv->check_any($authuser, "/access", $privs, 1);
- my $allowed_groups = $rpcenv->filter_groups($authuser, $privs, 1);
-
+ my $privs = [ 'User.Modify', 'Sys.Audit', 'Group.Allocate'];
+
foreach my $group (keys %{$usercfg->{groups}}) {
- next if !($allow || $allowed_groups->{$group});
+ next if !$rpcenv->check_any($authuser, "/access/groups/$group", $privs, 1);
my $data = $usercfg->{groups}->{$group};
my $entry = { groupid => $group };
$entry->{comment} = $data->{comment} if defined($data->{comment});
path => '',
method => 'POST',
permissions => {
- check => ['perm', '/access', ['Sys.Modify']],
+ check => ['perm', '/access/groups', ['Group.Allocate']],
},
description => "Create new group.",
parameters => {
path => '{groupid}',
method => 'PUT',
permissions => {
- check => ['perm', '/access', ['Sys.Modify']],
+ check => ['perm', '/access/groups', ['Group.Allocate']],
},
description => "Update group data.",
parameters => {
path => '{groupid}',
method => 'GET',
permissions => {
- check => ['perm', '/access', ['Sys.Audit']],
- },
+ check => ['perm', '/access/groups', ['Sys.Audit', 'Group.Allocate'], any => 1],
+ },
description => "Get group configuration.",
parameters => {
additionalProperties => 0,
path => '{groupid}',
method => 'DELETE',
permissions => {
- check => ['perm', '/access', ['Sys.Modify']],
+ check => ['perm', '/access/groups', ['Group.Allocate']],
},
description => "Delete group.",
parameters => {
method => 'GET',
description => "Role index.",
permissions => {
- check => ['perm', '/access', ['Sys.Audit']],
+ user => 'all',
},
parameters => {
additionalProperties => 0,
path => '{roleid}',
method => 'GET',
permissions => {
- check => ['perm', '/access', ['Sys.Audit']],
+ user => 'all',
},
description => "Get role configuration.",
parameters => {
method => 'GET',
description => "User index.",
permissions => {
- description => "The returned list is restricted to users where you have 'User.Modify' or 'User.Allocate' permissions on '/access' or on a group the user belongs too. But it always includes the current (authenticated) user.",
+ description => "The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.",
user => 'all',
},
parameters => {
my $res = [];
- my $privs = [ 'User.Modify', 'User.Allocate' ];
-
- my $canUserMod = $rpcenv->check_any($authuser, "/access", $privs, 1);
+ my $privs = [ 'User.Modify', 'Sys.Audit' ];
+ my $canUserMod = $rpcenv->check_any($authuser, "/access/groups", $privs, 1);
my $groups = $rpcenv->filter_groups($authuser, $privs, 1);
my $allowed_users = $rpcenv->group_member_join([keys %$groups]);
path => '',
method => 'POST',
permissions => {
- description => "You need 'User.Allocate' permissions to '/access/groups/<group>' for any group specified, or 'User.Allocate' on '/access' if you pass no groups.",
- check => ['userid-group', ['User.Allocate'], groups_param => 1],
+ description => "You need 'Realm.AllocateUser' on '/access/realm/<realm>' on the realm of user <userid>, and 'User.Modify' permissions to '/access/groups/<group>' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups.",
+ check => [ 'and',
+ [ 'userid-param', 'Realm.AllocateUser'],
+ [ 'userid-group', ['User.Modify'], groups_param => 1],
+ ],
},
description => "Create new user.",
parameters => {
method => 'GET',
description => "Get user configuration.",
permissions => {
- check => ['userid-group', ['User.Modify']],
+ check => ['userid-group', ['User.Modify', 'Sys.Audit']],
},
parameters => {
additionalProperties => 0,
method => 'DELETE',
description => "Delete user.",
permissions => {
- check => ['userid-group', ['User.Allocate']],
+ check => [ 'and',
+ [ 'userid-param', 'Realm.AllocateUser'],
+ [ 'userid-group', ['User.Modify']],
+ ],
},
parameters => {
additionalProperties => 0,
'VM.PowerMgmt',
],
audit => [
- 'VM.Audit'
+ 'VM.Audit',
],
},
Sys => {
],
},
User => {
- root => [],
+ root => [
+ 'Realm.Allocate',
+ ],
admin => [
'User.Modify',
- 'User.Allocate',
+ 'Group.Allocate', # edit/change group settings
+ 'Realm.AllocateUser',
],
user => [],
audit => [],
} elsif ($test eq 'userid-group') {
my $userid = $param->{userid};
my ($t, $privs, %options) = @$check;
- return if !$options{groups_param} && !$self->check_user_exist($userid, $noerr);
- if (!$self->check_any($username, "/access", $privs, 1)) {
+ return 0 if !$options{groups_param} && !$self->check_user_exist($userid, $noerr);
+ if (!$self->check_any($username, "/access/groups", $privs, 1)) {
my $groups = $self->filter_groups($username, $privs, 1);
if ($options{groups_param}) {
my @group_param = PVE::Tools::split_list($param->{groups});
- raise_perm_exc("/access, " . join("|", @$privs)) if !scalar(@group_param);
+ raise_perm_exc("/access/groups, " . join("|", @$privs)) if !scalar(@group_param);
foreach my $pg (@group_param) {
raise_perm_exc("/access/groups/$pg, " . join("|", @$privs))
if !$groups->{$pg};
}
return 1;
} elsif ($test eq 'userid-param') {
- my $userid = $param->{userid};
+ my ($userid, undef, $realm) = verify_username($param->{userid});
return if !$self->check_user_exist($userid, $noerr);
my ($t, $subtest) = @$check;
die "missing parameters" if !$subtest;
return 1 if $username eq 'userid';
return 0 if $noerr;
raise_perm_exc();
+ } elsif ($subtest eq 'Realm.AllocateUser') {
+ my $path = "/access/realm/$realm";
+ return $self->check($username, $path, ['Realm.AllocateUser'], $noerr);
+ return 0 if $noerr;
+ raise_perm_exc("$path, 'Realm.AllocateUser'");
} else {
die "unknown userid-param test";
}
- } elsif ($test eq 'perm-modify') {
+ } elsif ($test eq 'perm-modify') {
my ($t, $tmplpath) = @$check;
my $path = PVE::Tools::template_replace($tmplpath, $param);
$path = PVE::AccessControl::normalize_path($path);