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