X-Git-Url: https://git.proxmox.com/?p=pve-access-control.git;a=blobdiff_plain;f=PVE%2FAPI2%2FDomains.pm;h=f78acbd13a0548f5d1e307905446d2793661db55;hp=26223d3a2a1d8a722efcb1c963ccf7e44a4a3990;hb=6084476178d2db030378ef402b9ba5a70df52d1e;hpb=2c3a6c0aaac7fbdaeb26bc5a596d21e897f3343a diff --git a/PVE/API2/Domains.pm b/PVE/API2/Domains.pm index 26223d3..f78acbd 100644 --- a/PVE/API2/Domains.pm +++ b/PVE/API2/Domains.pm @@ -2,15 +2,14 @@ package PVE::API2::Domains; use strict; use warnings; +use PVE::Tools qw(extract_param); use PVE::Cluster qw (cfs_read_file cfs_write_file); use PVE::AccessControl; use PVE::JSONSchema qw(get_standard_option); use PVE::SafeSyslog; - -use Data::Dumper; # fixme: remove - use PVE::RESTHandler; +use PVE::Auth::Plugin; my $domainconfigfile = "domains.cfg"; @@ -21,7 +20,10 @@ __PACKAGE__->register_method ({ path => '', method => 'GET', description => "Authentication domain index.", - permissions => { user => 'world' }, + permissions => { + description => "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + user => 'world', + }, parameters => { additionalProperties => 0, properties => {}, @@ -32,6 +34,13 @@ __PACKAGE__->register_method ({ type => "object", properties => { realm => { type => 'string' }, + tfa => { + description => "Two-factor authentication provider.", + type => 'string', + enum => [ 'yubico', 'oath' ], + optional => 1, + }, + comment => { type => 'string', optional => 1 }, comment => { type => 'string', optional => 1 }, }, }, @@ -43,12 +52,16 @@ __PACKAGE__->register_method ({ my $res = []; my $cfg = cfs_read_file($domainconfigfile); - - foreach my $realm (keys %$cfg) { - my $d = $cfg->{$realm}; + my $ids = $cfg->{ids}; + + foreach my $realm (keys %$ids) { + my $d = $ids->{$realm}; my $entry = { realm => $realm, type => $d->{type} }; $entry->{comment} = $d->{comment} if $d->{comment}; $entry->{default} = 1 if $d->{default}; + if ($d->{tfa} && (my $tfa_cfg = PVE::Auth::Plugin::parse_tfa_config($d->{tfa}))) { + $entry->{tfa} = $tfa_cfg->{type}; + } push @$res, $entry; } @@ -60,89 +73,43 @@ __PACKAGE__->register_method ({ protected => 1, path => '', method => 'POST', - description => "Add an authentication server.", - parameters => { - additionalProperties => 0, - properties => { - realm => get_standard_option('realm'), - type => { - description => "Server type.", - type => 'string', - enum => [ 'ad', 'ldap' ], - }, - server1 => { - description => "Server IP address (or DNS name)", - type => 'string', - }, - server2 => { - description => "Fallback Server IP address (or DNS name)", - type => 'string', - optional => 1, - }, - secure => { - description => "Use secure LDAPS protocol.", - type => 'boolean', - optional => 1, - }, - default => { - description => "Use this as default realm", - type => 'boolean', - optional => 1, - }, - comment => { - type => 'string', - optional => 1, - }, - port => { - description => "Server port", - type => 'integer', - minimum => 1, - maximum => 65535, - optional => 1, - }, - base_dn => { - description => "LDAP base domain name", - type => 'string', - optional => 1, - }, - user_attr => { - description => "LDAP user attribute name", - type => 'string', - optional => 1, - }, - }, + permissions => { + check => ['perm', '/access/realm', ['Realm.Allocate']], }, + description => "Add an authentication server.", + parameters => PVE::Auth::Plugin->createSchema(), returns => { type => 'null' }, code => sub { my ($param) = @_; - PVE::AccessControl::lock_domain_config( + PVE::Auth::Plugin::lock_domain_config( sub { my $cfg = cfs_read_file($domainconfigfile); + my $ids = $cfg->{ids}; - my $realm = $param->{realm}; + my $realm = extract_param($param, 'realm'); + my $type = $param->{type}; die "domain '$realm' already exists\n" - if $cfg->{$realm}; + if $ids->{$realm}; die "unable to use reserved name '$realm'\n" if ($realm eq 'pam' || $realm eq 'pve'); - if (defined($param->{secure})) { - $cfg->{$realm}->{secure} = $param->{secure} ? 1 : 0; - } - - if ($param->{default}) { - foreach my $r (keys %$cfg) { - delete $cfg->{$r}->{default}; + die "unable to create builtin type '$type'\n" + if ($type eq 'pam' || $type eq 'pve'); + + my $plugin = PVE::Auth::Plugin->lookup($type); + my $config = $plugin->check_config($realm, $param, 1, 1); + + if ($config->{default}) { + foreach my $r (keys %$ids) { + delete $ids->{$r}->{default}; } } - foreach my $p (keys %$param) { - next if $p eq 'realm'; - $cfg->{$realm}->{$p} = $param->{$p}; - } + $ids->{$realm} = $config; cfs_write_file($domainconfigfile, $cfg); }, "add auth server failed"); @@ -154,85 +121,48 @@ __PACKAGE__->register_method ({ name => 'update', path => '{realm}', method => 'PUT', + permissions => { + check => ['perm', '/access/realm', ['Realm.Allocate']], + }, description => "Update authentication server settings.", protected => 1, - parameters => { - additionalProperties => 0, - properties => { - realm => get_standard_option('realm'), - server1 => { - description => "Server IP address (or DNS name)", - type => 'string', - optional => 1, - }, - server2 => { - description => "Fallback Server IP address (or DNS name)", - type => 'string', - optional => 1, - }, - secure => { - description => "Use secure LDAPS protocol.", - type => 'boolean', - optional => 1, - }, - default => { - description => "Use this as default realm", - type => 'boolean', - optional => 1, - }, - comment => { - type => 'string', - optional => 1, - }, - port => { - description => "Server port", - type => 'integer', - minimum => 1, - maximum => 65535, - optional => 1, - }, - base_dn => { - description => "LDAP base domain name", - type => 'string', - optional => 1, - }, - user_attr => { - description => "LDAP user attribute name", - type => 'string', - optional => 1, - }, - }, - }, + parameters => PVE::Auth::Plugin->updateSchema(), returns => { type => 'null' }, code => sub { my ($param) = @_; - PVE::AccessControl::lock_domain_config( + PVE::Auth::Plugin::lock_domain_config( sub { my $cfg = cfs_read_file($domainconfigfile); + my $ids = $cfg->{ids}; - my $realm = $param->{realm}; - delete $param->{realm}; + my $digest = extract_param($param, 'digest'); + PVE::SectionConfig::assert_if_modified($cfg, $digest); - die "unable to modify bultin domain '$realm'\n" - if ($realm eq 'pam' || $realm eq 'pve'); + my $realm = extract_param($param, 'realm'); die "domain '$realm' does not exist\n" - if !$cfg->{$realm}; + if !$ids->{$realm}; + + my $delete_str = extract_param($param, 'delete'); + die "no options specified\n" if !$delete_str && !scalar(keys %$param); - if (defined($param->{secure})) { - $cfg->{$realm}->{secure} = $param->{secure} ? 1 : 0; + foreach my $opt (PVE::Tools::split_list($delete_str)) { + delete $ids->{$realm}->{$opt}; } + + my $plugin = PVE::Auth::Plugin->lookup($ids->{$realm}->{type}); + my $config = $plugin->check_config($realm, $param, 0, 1); - if ($param->{default}) { - foreach my $r (keys %$cfg) { - delete $cfg->{$r}->{default}; + if ($config->{default}) { + foreach my $r (keys %$ids) { + delete $ids->{$r}->{default}; } } - foreach my $p (keys %$param) { - $cfg->{$realm}->{$p} = $param->{$p}; + foreach my $p (keys %$config) { + $ids->{$realm}->{$p} = $config->{$p}; } cfs_write_file($domainconfigfile, $cfg); @@ -247,6 +177,9 @@ __PACKAGE__->register_method ({ path => '{realm}', method => 'GET', description => "Get auth server configuration.", + permissions => { + check => ['perm', '/access/realm', ['Realm.Allocate', 'Sys.Audit'], any => 1], + }, parameters => { additionalProperties => 0, properties => { @@ -261,9 +194,11 @@ __PACKAGE__->register_method ({ my $realm = $param->{realm}; - my $data = $cfg->{$realm}; + my $data = $cfg->{ids}->{$realm}; die "domain '$realm' does not exist\n" if !$data; + $data->{digest} = $cfg->{digest}; + return $data; }}); @@ -272,6 +207,9 @@ __PACKAGE__->register_method ({ name => 'delete', path => '{realm}', method => 'DELETE', + permissions => { + check => ['perm', '/access/realm', ['Realm.Allocate']], + }, description => "Delete an authentication server.", protected => 1, parameters => { @@ -284,16 +222,17 @@ __PACKAGE__->register_method ({ code => sub { my ($param) = @_; - PVE::AccessControl::lock_user_config( + PVE::Auth::Plugin::lock_domain_config( sub { my $cfg = cfs_read_file($domainconfigfile); + my $ids = $cfg->{ids}; my $realm = $param->{realm}; - die "domain '$realm' does not exist\n" if !$cfg->{$realm}; + die "domain '$realm' does not exist\n" if !$ids->{$realm}; - delete $cfg->{$realm}; + delete $ids->{$realm}; cfs_write_file($domainconfigfile, $cfg); }, "delete auth server failed");