]>
Commit | Line | Data |
---|---|---|
1 | package PVE::API2::Domains; | |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use PVE::Tools qw(extract_param); | |
6 | use PVE::Cluster qw (cfs_read_file cfs_write_file); | |
7 | use PVE::AccessControl; | |
8 | use PVE::JSONSchema qw(get_standard_option); | |
9 | ||
10 | use PVE::SafeSyslog; | |
11 | use PVE::RESTHandler; | |
12 | use PVE::Auth::Plugin; | |
13 | ||
14 | my $domainconfigfile = "domains.cfg"; | |
15 | ||
16 | use base qw(PVE::RESTHandler); | |
17 | ||
18 | __PACKAGE__->register_method ({ | |
19 | name => 'index', | |
20 | path => '', | |
21 | method => 'GET', | |
22 | description => "Authentication domain index.", | |
23 | permissions => { | |
24 | description => "Anyone can access that, because we need that list for the login box (before the user is authenticated).", | |
25 | user => 'world', | |
26 | }, | |
27 | parameters => { | |
28 | additionalProperties => 0, | |
29 | properties => {}, | |
30 | }, | |
31 | returns => { | |
32 | type => 'array', | |
33 | items => { | |
34 | type => "object", | |
35 | properties => { | |
36 | realm => { type => 'string' }, | |
37 | comment => { type => 'string', optional => 1 }, | |
38 | }, | |
39 | }, | |
40 | links => [ { rel => 'child', href => "{realm}" } ], | |
41 | }, | |
42 | code => sub { | |
43 | my ($param) = @_; | |
44 | ||
45 | my $res = []; | |
46 | ||
47 | my $cfg = cfs_read_file($domainconfigfile); | |
48 | my $ids = $cfg->{ids}; | |
49 | ||
50 | foreach my $realm (keys %$ids) { | |
51 | my $d = $ids->{$realm}; | |
52 | my $entry = { realm => $realm, type => $d->{type} }; | |
53 | $entry->{comment} = $d->{comment} if $d->{comment}; | |
54 | $entry->{default} = 1 if $d->{default}; | |
55 | push @$res, $entry; | |
56 | } | |
57 | ||
58 | return $res; | |
59 | }}); | |
60 | ||
61 | __PACKAGE__->register_method ({ | |
62 | name => 'create', | |
63 | protected => 1, | |
64 | path => '', | |
65 | method => 'POST', | |
66 | permissions => { | |
67 | check => ['perm', '/access/realm', ['Realm.Allocate']], | |
68 | }, | |
69 | description => "Add an authentication server.", | |
70 | parameters => PVE::Auth::Plugin->createSchema(), | |
71 | returns => { type => 'null' }, | |
72 | code => sub { | |
73 | my ($param) = @_; | |
74 | ||
75 | PVE::Auth::Plugin::lock_domain_config( | |
76 | sub { | |
77 | ||
78 | my $cfg = cfs_read_file($domainconfigfile); | |
79 | my $ids = $cfg->{ids}; | |
80 | ||
81 | my $realm = extract_param($param, 'realm'); | |
82 | my $type = $param->{type}; | |
83 | ||
84 | die "domain '$realm' already exists\n" | |
85 | if $ids->{$realm}; | |
86 | ||
87 | die "unable to use reserved name '$realm'\n" | |
88 | if ($realm eq 'pam' || $realm eq 'pve'); | |
89 | ||
90 | die "unable to create builtin type '$type'\n" | |
91 | if ($type eq 'pam' || $type eq 'pve'); | |
92 | ||
93 | my $plugin = PVE::Auth::Plugin->lookup($type); | |
94 | my $config = $plugin->check_config($realm, $param, 1, 1); | |
95 | ||
96 | if ($config->{default}) { | |
97 | foreach my $r (keys %$ids) { | |
98 | delete $ids->{$r}->{default}; | |
99 | } | |
100 | } | |
101 | ||
102 | $ids->{$realm} = $config; | |
103 | ||
104 | cfs_write_file($domainconfigfile, $cfg); | |
105 | }, "add auth server failed"); | |
106 | ||
107 | return undef; | |
108 | }}); | |
109 | ||
110 | __PACKAGE__->register_method ({ | |
111 | name => 'update', | |
112 | path => '{realm}', | |
113 | method => 'PUT', | |
114 | permissions => { | |
115 | check => ['perm', '/access/realm', ['Realm.Allocate']], | |
116 | }, | |
117 | description => "Update authentication server settings.", | |
118 | protected => 1, | |
119 | parameters => PVE::Auth::Plugin->updateSchema(), | |
120 | returns => { type => 'null' }, | |
121 | code => sub { | |
122 | my ($param) = @_; | |
123 | ||
124 | PVE::Auth::Plugin::lock_domain_config( | |
125 | sub { | |
126 | ||
127 | my $cfg = cfs_read_file($domainconfigfile); | |
128 | my $ids = $cfg->{ids}; | |
129 | ||
130 | my $digest = extract_param($param, 'digest'); | |
131 | PVE::SectionConfig::assert_if_modified($cfg, $digest); | |
132 | ||
133 | my $realm = extract_param($param, 'realm'); | |
134 | ||
135 | die "unable to modify bultin domain '$realm'\n" | |
136 | if ($realm eq 'pam' || $realm eq 'pve'); | |
137 | ||
138 | die "domain '$realm' does not exist\n" | |
139 | if !$ids->{$realm}; | |
140 | ||
141 | my $delete_str = extract_param($param, 'delete'); | |
142 | die "no options specified\n" if !$delete_str && !scalar(keys %$param); | |
143 | ||
144 | foreach my $opt (PVE::Tools::split_list($delete_str)) { | |
145 | delete $ids->{$realm}->{$opt}; | |
146 | } | |
147 | ||
148 | my $plugin = PVE::Auth::Plugin->lookup($ids->{$realm}->{type}); | |
149 | my $config = $plugin->check_config($realm, $param, 0, 1); | |
150 | ||
151 | if ($config->{default}) { | |
152 | foreach my $r (keys %$ids) { | |
153 | delete $ids->{$r}->{default}; | |
154 | } | |
155 | } | |
156 | ||
157 | foreach my $p (keys %$config) { | |
158 | $ids->{$realm}->{$p} = $config->{$p}; | |
159 | } | |
160 | ||
161 | cfs_write_file($domainconfigfile, $cfg); | |
162 | }, "update auth server failed"); | |
163 | ||
164 | return undef; | |
165 | }}); | |
166 | ||
167 | # fixme: return format! | |
168 | __PACKAGE__->register_method ({ | |
169 | name => 'read', | |
170 | path => '{realm}', | |
171 | method => 'GET', | |
172 | description => "Get auth server configuration.", | |
173 | permissions => { | |
174 | check => ['perm', '/access/realm', ['Realm.Allocate', 'Sys.Audit'], any => 1], | |
175 | }, | |
176 | parameters => { | |
177 | additionalProperties => 0, | |
178 | properties => { | |
179 | realm => get_standard_option('realm'), | |
180 | }, | |
181 | }, | |
182 | returns => {}, | |
183 | code => sub { | |
184 | my ($param) = @_; | |
185 | ||
186 | my $cfg = cfs_read_file($domainconfigfile); | |
187 | ||
188 | my $realm = $param->{realm}; | |
189 | ||
190 | my $data = $cfg->{ids}->{$realm}; | |
191 | die "domain '$realm' does not exist\n" if !$data; | |
192 | ||
193 | $data->{digest} = $cfg->{digest}; | |
194 | ||
195 | return $data; | |
196 | }}); | |
197 | ||
198 | ||
199 | __PACKAGE__->register_method ({ | |
200 | name => 'delete', | |
201 | path => '{realm}', | |
202 | method => 'DELETE', | |
203 | permissions => { | |
204 | check => ['perm', '/access/realm', ['Realm.Allocate']], | |
205 | }, | |
206 | description => "Delete an authentication server.", | |
207 | protected => 1, | |
208 | parameters => { | |
209 | additionalProperties => 0, | |
210 | properties => { | |
211 | realm => get_standard_option('realm'), | |
212 | } | |
213 | }, | |
214 | returns => { type => 'null' }, | |
215 | code => sub { | |
216 | my ($param) = @_; | |
217 | ||
218 | PVE::Auth::Plugin::lock_domain_config( | |
219 | sub { | |
220 | ||
221 | my $cfg = cfs_read_file($domainconfigfile); | |
222 | my $ids = $cfg->{ids}; | |
223 | ||
224 | my $realm = $param->{realm}; | |
225 | ||
226 | die "domain '$realm' does not exist\n" if !$ids->{$realm}; | |
227 | ||
228 | delete $ids->{$realm}; | |
229 | ||
230 | cfs_write_file($domainconfigfile, $cfg); | |
231 | }, "delete auth server failed"); | |
232 | ||
233 | return undef; | |
234 | }}); | |
235 | ||
236 | 1; |