]> git.proxmox.com Git - pve-access-control.git/blob - PVE/API2/Domains.pm
117ef3c92fd58a5f020349507b0789aee7c0e102
[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
11 use Data::Dumper; # fixme: remove
12
13 use PVE::RESTHandler;
14
15 my $domainconfigfile = "domains.cfg";
16
17 use base qw(PVE::RESTHandler);
18
19 __PACKAGE__->register_method ({
20 name => 'index',
21 path => '',
22 method => 'GET',
23 description => "Authentication domain index.",
24 permissions => { user => 'world' },
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 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};
150 }
151
152 # port 0 ==> use default
153 if (defined($param->{port}) && !$param->{port}) {
154 delete $cfg->{$realm}->{port};
155 }
156
157 cfs_write_file($domainconfigfile, $cfg);
158 }, "add auth server failed");
159
160 return undef;
161 }});
162
163 __PACKAGE__->register_method ({
164 name => 'update',
165 path => '{realm}',
166 method => 'PUT',
167 description => "Update authentication server settings.",
168 protected => 1,
169 parameters => {
170 additionalProperties => 0,
171 properties => {
172 realm => get_standard_option('realm'),
173 server1 => {
174 description => "Server IP address (or DNS name)",
175 type => 'string',
176 optional => 1,
177 },
178 server2 => {
179 description => "Fallback Server IP address (or DNS name)",
180 type => 'string',
181 optional => 1,
182 },
183 secure => {
184 description => "Use secure LDAPS protocol.",
185 type => 'boolean',
186 optional => 1,
187 },
188 default => {
189 description => "Use this as default realm",
190 type => 'boolean',
191 optional => 1,
192 },
193 comment => {
194 type => 'string',
195 optional => 1,
196 },
197 port => {
198 description => "Server port. Use '0' if you want to use default settings'",
199 type => 'integer',
200 minimum => 0,
201 maximum => 65535,
202 optional => 1,
203 },
204 domain => {
205 description => "AD domain name",
206 type => 'string',
207 optional => 1,
208 },
209 base_dn => {
210 description => "LDAP base domain name",
211 type => 'string',
212 optional => 1,
213 },
214 user_attr => {
215 description => "LDAP user attribute name",
216 type => 'string',
217 optional => 1,
218 },
219 },
220 },
221 returns => { type => 'null' },
222 code => sub {
223 my ($param) = @_;
224
225 PVE::AccessControl::lock_domain_config(
226 sub {
227
228 my $cfg = cfs_read_file($domainconfigfile);
229
230 my $realm = $param->{realm};
231 delete $param->{realm};
232
233 die "unable to modify bultin domain '$realm'\n"
234 if ($realm eq 'pam' || $realm eq 'pve');
235
236 die "domain '$realm' does not exist\n"
237 if !$cfg->{$realm};
238
239 if (defined($param->{secure})) {
240 $cfg->{$realm}->{secure} = $param->{secure} ? 1 : 0;
241 }
242
243 if ($param->{default}) {
244 foreach my $r (keys %$cfg) {
245 delete $cfg->{$r}->{default};
246 }
247 }
248
249 foreach my $p (keys %$param) {
250 $cfg->{$realm}->{$p} = $param->{$p};
251 }
252
253 # port 0 ==> use default
254 if (defined($param->{port}) && !$param->{port}) {
255 delete $cfg->{$realm}->{port};
256 }
257
258 cfs_write_file($domainconfigfile, $cfg);
259 }, "update auth server failed");
260
261 return undef;
262 }});
263
264 # fixme: return format!
265 __PACKAGE__->register_method ({
266 name => 'read',
267 path => '{realm}',
268 method => 'GET',
269 description => "Get auth server configuration.",
270 parameters => {
271 additionalProperties => 0,
272 properties => {
273 realm => get_standard_option('realm'),
274 },
275 },
276 returns => {},
277 code => sub {
278 my ($param) = @_;
279
280 my $cfg = cfs_read_file($domainconfigfile);
281
282 my $realm = $param->{realm};
283
284 my $data = $cfg->{$realm};
285 die "domain '$realm' does not exist\n" if !$data;
286
287 return $data;
288 }});
289
290
291 __PACKAGE__->register_method ({
292 name => 'delete',
293 path => '{realm}',
294 method => 'DELETE',
295 description => "Delete an authentication server.",
296 protected => 1,
297 parameters => {
298 additionalProperties => 0,
299 properties => {
300 realm => get_standard_option('realm'),
301 }
302 },
303 returns => { type => 'null' },
304 code => sub {
305 my ($param) = @_;
306
307 PVE::AccessControl::lock_user_config(
308 sub {
309
310 my $cfg = cfs_read_file($domainconfigfile);
311
312 my $realm = $param->{realm};
313
314 die "domain '$realm' does not exist\n" if !$cfg->{$realm};
315
316 delete $cfg->{$realm};
317
318 cfs_write_file($domainconfigfile, $cfg);
319 }, "delete auth server failed");
320
321 return undef;
322 }});
323
324 1;