1 package PVE
::API2
::ACL
;
5 use PVE
::Cluster qw
(cfs_read_file cfs_write_file
);
6 use PVE
::Tools
qw(split_list);
7 use PVE
::AccessControl
;
8 use PVE
::Exception
qw(raise_param_exc);
9 use PVE
::JSONSchema
qw(get_standard_option register_standard_option);
15 use base
qw(PVE::RESTHandler);
17 register_standard_option
('acl-propagate', {
18 description
=> "Allow to propagate (inherit) permissions.",
24 register_standard_option
('acl-path', {
25 description
=> "Access control path",
30 __PACKAGE__-
>register_method ({
34 description
=> "Get Access Control List (ACLs).",
36 description
=> "The returned list is restricted to objects where you have rights to modify permissions.",
40 additionalProperties
=> 0,
47 additionalProperties
=> 0,
49 propagate
=> get_standard_option
('acl-propagate'),
50 path
=> get_standard_option
('acl-path'),
51 type
=> { type
=> 'string', title
=> 'Type', enum
=> ['user', 'group'] },
52 ugid
=> { type
=> 'string', title
=> 'ID' },
53 roleid
=> { type
=> 'string', title
=> 'Role' },
60 my $rpcenv = PVE
::RPCEnvironment
::get
();
61 my $authuser = $rpcenv->get_user();
64 my $usercfg = $rpcenv->{user_cfg
};
65 if (!$usercfg || !$usercfg->{acl
}) {
69 my $audit = $rpcenv->check($authuser, '/access', ['Sys.Audit'], 1);
71 my $acl = $usercfg->{acl
};
72 foreach my $path (keys %$acl) {
73 foreach my $type (qw(users groups)) {
74 my $d = $acl->{$path}->{$type};
76 next if !($audit || $rpcenv->check_perm_modify($authuser, $path, 1));
77 foreach my $id (keys %$d) {
78 foreach my $role (keys %{$d->{$id}}) {
79 my $propagate = $d->{$id}->{$role};
82 type
=> $type eq 'groups' ?
'group' : 'user',
85 propagate
=> $propagate,
95 __PACKAGE__-
>register_method ({
101 check
=> ['perm-modify', '{path}'],
103 description
=> "Update Access Control List (add or remove permissions).",
105 additionalProperties
=> 0,
107 propagate
=> get_standard_option
('acl-propagate'),
108 path
=> get_standard_option
('acl-path'),
110 description
=> "List of users.",
111 type
=> 'string', format
=> 'pve-userid-list',
115 description
=> "List of groups.",
116 type
=> 'string', format
=> 'pve-groupid-list',
120 description
=> "List of roles.",
121 type
=> 'string', format
=> 'pve-roleid-list',
124 description
=> "Remove permissions (instead of adding it).",
130 returns
=> { type
=> 'null' },
134 if (!($param->{users
} || $param->{groups
})) {
136 users
=> "either 'users' or 'groups' is required.",
137 groups
=> "either 'users' or 'groups' is required." });
140 my $path = PVE
::AccessControl
::normalize_path
($param->{path
});
141 raise_param_exc
({ path
=> "invalid ACL path '$param->{path}'" }) if !$path;
143 PVE
::AccessControl
::lock_user_config
(
146 my $cfg = cfs_read_file
("user.cfg");
150 if (defined($param->{propagate
})) {
151 $propagate = $param->{propagate
} ?
1 : 0;
154 foreach my $role (split_list
($param->{roles
})) {
155 die "role '$role' does not exist\n"
156 if !$cfg->{roles
}->{$role};
158 foreach my $group (split_list
($param->{groups
})) {
160 die "group '$group' does not exist\n"
161 if !$cfg->{groups
}->{$group};
163 if ($param->{delete}) {
164 delete($cfg->{acl
}->{$path}->{groups
}->{$group}->{$role});
166 $cfg->{acl
}->{$path}->{groups
}->{$group}->{$role} = $propagate;
170 foreach my $userid (split_list
($param->{users
})) {
171 my $username = PVE
::AccessControl
::verify_username
($userid);
173 die "user '$username' does not exist\n"
174 if !$cfg->{users
}->{$username};
176 if ($param->{delete}) {
177 delete($cfg->{acl
}->{$path}->{users
}->{$username}->{$role});
179 $cfg->{acl
}->{$path}->{users
}->{$username}->{$role} = $propagate;
184 cfs_write_file
("user.cfg", $cfg);
185 }, "ACL update failed");