]> git.proxmox.com Git - pve-access-control.git/blob - PVE/API2/Domains.pm
cleanup permission checks
[pve-access-control.git] / PVE / API2 / Domains.pm
1 package PVE::API2::Domains;
2
3 use strict;
4 use warnings;
5 use PVE::Cluster qw (cfs_read_file cfs_write_file);
6 use PVE::AccessControl;
7 use PVE::JSONSchema qw(get_standard_option);
8
9 use PVE::SafeSyslog;
10 use PVE::RESTHandler;
11
12 my $domainconfigfile = "domains.cfg";
13
14 use base qw(PVE::RESTHandler);
15
16 __PACKAGE__->register_method ({
17 name => 'index',
18 path => '',
19 method => 'GET',
20 description => "Authentication domain index.",
21 permissions => {
22 description => "Anyone can access that, because we need that list for the login box (before the user is authenticated).",
23 user => 'world',
24 },
25 parameters => {
26 additionalProperties => 0,
27 properties => {},
28 },
29 returns => {
30 type => 'array',
31 items => {
32 type => "object",
33 properties => {
34 realm => { type => 'string' },
35 comment => { type => 'string', optional => 1 },
36 },
37 },
38 links => [ { rel => 'child', href => "{realm}" } ],
39 },
40 code => sub {
41 my ($param) = @_;
42
43 my $res = [];
44
45 my $cfg = cfs_read_file($domainconfigfile);
46
47 foreach my $realm (keys %$cfg) {
48 my $d = $cfg->{$realm};
49 my $entry = { realm => $realm, type => $d->{type} };
50 $entry->{comment} = $d->{comment} if $d->{comment};
51 $entry->{default} = 1 if $d->{default};
52 push @$res, $entry;
53 }
54
55 return $res;
56 }});
57
58 __PACKAGE__->register_method ({
59 name => 'create',
60 protected => 1,
61 path => '',
62 method => 'POST',
63 permissions => {
64 check => ['perm', '/access/realm', ['Realm.Allocate']],
65 },
66 description => "Add an authentication server.",
67 parameters => {
68 additionalProperties => 0,
69 properties => {
70 realm => get_standard_option('realm'),
71 type => {
72 description => "Server type.",
73 type => 'string',
74 enum => [ 'ad', 'ldap' ],
75 },
76 server1 => {
77 description => "Server IP address (or DNS name)",
78 type => 'string',
79 },
80 server2 => {
81 description => "Fallback Server IP address (or DNS name)",
82 type => 'string',
83 optional => 1,
84 },
85 secure => {
86 description => "Use secure LDAPS protocol.",
87 type => 'boolean',
88 optional => 1,
89 },
90 default => {
91 description => "Use this as default realm",
92 type => 'boolean',
93 optional => 1,
94 },
95 comment => {
96 type => 'string',
97 optional => 1,
98 },
99 port => {
100 description => "Server port. Use '0' if you want to use default settings'",
101 type => 'integer',
102 minimum => 0,
103 maximum => 65535,
104 optional => 1,
105 },
106 domain => {
107 description => "AD domain name",
108 type => 'string',
109 optional => 1,
110 },
111 base_dn => {
112 description => "LDAP base domain name",
113 type => 'string',
114 optional => 1,
115 },
116 user_attr => {
117 description => "LDAP user attribute name",
118 type => 'string',
119 optional => 1,
120 },
121 },
122 },
123 returns => { type => 'null' },
124 code => sub {
125 my ($param) = @_;
126
127 PVE::AccessControl::lock_domain_config(
128 sub {
129
130 my $cfg = cfs_read_file($domainconfigfile);
131
132 my $realm = $param->{realm};
133
134 die "domain '$realm' already exists\n"
135 if $cfg->{$realm};
136
137 die "unable to use reserved name '$realm'\n"
138 if ($realm eq 'pam' || $realm eq 'pve');
139
140 if (defined($param->{secure})) {
141 $cfg->{$realm}->{secure} = $param->{secure} ? 1 : 0;
142 }
143
144 if ($param->{default}) {
145 foreach my $r (keys %$cfg) {
146 delete $cfg->{$r}->{default};
147 }
148 }
149
150 foreach my $p (keys %$param) {
151 next if $p eq 'realm';
152 $cfg->{$realm}->{$p} = $param->{$p} if $param->{$p};
153 }
154
155 # port 0 ==> use default
156 # server2 == '' ===> delete server2
157 for my $p (qw(port server2)) {
158 if (defined($param->{$p}) && !$param->{$p}) {
159 delete $cfg->{$realm}->{$p};
160 }
161 }
162
163 cfs_write_file($domainconfigfile, $cfg);
164 }, "add auth server failed");
165
166 return undef;
167 }});
168
169 __PACKAGE__->register_method ({
170 name => 'update',
171 path => '{realm}',
172 method => 'PUT',
173 permissions => {
174 check => ['perm', '/access/realm', ['Realm.Allocate']],
175 },
176 description => "Update authentication server settings.",
177 protected => 1,
178 parameters => {
179 additionalProperties => 0,
180 properties => {
181 realm => get_standard_option('realm'),
182 server1 => {
183 description => "Server IP address (or DNS name)",
184 type => 'string',
185 optional => 1,
186 },
187 server2 => {
188 description => "Fallback Server IP address (or DNS name)",
189 type => 'string',
190 optional => 1,
191 },
192 secure => {
193 description => "Use secure LDAPS protocol.",
194 type => 'boolean',
195 optional => 1,
196 },
197 default => {
198 description => "Use this as default realm",
199 type => 'boolean',
200 optional => 1,
201 },
202 comment => {
203 type => 'string',
204 optional => 1,
205 },
206 port => {
207 description => "Server port. Use '0' if you want to use default settings'",
208 type => 'integer',
209 minimum => 0,
210 maximum => 65535,
211 optional => 1,
212 },
213 domain => {
214 description => "AD domain name",
215 type => 'string',
216 optional => 1,
217 },
218 base_dn => {
219 description => "LDAP base domain name",
220 type => 'string',
221 optional => 1,
222 },
223 user_attr => {
224 description => "LDAP user attribute name",
225 type => 'string',
226 optional => 1,
227 },
228 },
229 },
230 returns => { type => 'null' },
231 code => sub {
232 my ($param) = @_;
233
234 PVE::AccessControl::lock_domain_config(
235 sub {
236
237 my $cfg = cfs_read_file($domainconfigfile);
238
239 my $realm = $param->{realm};
240 delete $param->{realm};
241
242 die "unable to modify bultin domain '$realm'\n"
243 if ($realm eq 'pam' || $realm eq 'pve');
244
245 die "domain '$realm' does not exist\n"
246 if !$cfg->{$realm};
247
248 if (defined($param->{secure})) {
249 $cfg->{$realm}->{secure} = $param->{secure} ? 1 : 0;
250 }
251
252 if ($param->{default}) {
253 foreach my $r (keys %$cfg) {
254 delete $cfg->{$r}->{default};
255 }
256 }
257
258 foreach my $p (keys %$param) {
259 if ($param->{$p}) {
260 $cfg->{$realm}->{$p} = $param->{$p};
261 } else {
262 delete $cfg->{$realm}->{$p};
263 }
264 }
265
266 cfs_write_file($domainconfigfile, $cfg);
267 }, "update auth server failed");
268
269 return undef;
270 }});
271
272 # fixme: return format!
273 __PACKAGE__->register_method ({
274 name => 'read',
275 path => '{realm}',
276 method => 'GET',
277 description => "Get auth server configuration.",
278 permissions => {
279 check => ['perm', '/access/realm', ['Realm.Allocate', 'Sys.Audit'], any => 1],
280 },
281 parameters => {
282 additionalProperties => 0,
283 properties => {
284 realm => get_standard_option('realm'),
285 },
286 },
287 returns => {},
288 code => sub {
289 my ($param) = @_;
290
291 my $cfg = cfs_read_file($domainconfigfile);
292
293 my $realm = $param->{realm};
294
295 my $data = $cfg->{$realm};
296 die "domain '$realm' does not exist\n" if !$data;
297
298 return $data;
299 }});
300
301
302 __PACKAGE__->register_method ({
303 name => 'delete',
304 path => '{realm}',
305 method => 'DELETE',
306 permissions => {
307 check => ['perm', '/access/realm', ['Realm.Allocate']],
308 },
309 description => "Delete an authentication server.",
310 protected => 1,
311 parameters => {
312 additionalProperties => 0,
313 properties => {
314 realm => get_standard_option('realm'),
315 }
316 },
317 returns => { type => 'null' },
318 code => sub {
319 my ($param) = @_;
320
321 PVE::AccessControl::lock_user_config(
322 sub {
323
324 my $cfg = cfs_read_file($domainconfigfile);
325
326 my $realm = $param->{realm};
327
328 die "domain '$realm' does not exist\n" if !$cfg->{$realm};
329
330 delete $cfg->{$realm};
331
332 cfs_write_file($domainconfigfile, $cfg);
333 }, "delete auth server failed");
334
335 return undef;
336 }});
337
338 1;