X-Git-Url: https://git.proxmox.com/?p=pve-access-control.git;a=blobdiff_plain;f=PVE%2FAPI2%2FDomains.pm;h=b5fa65efc9253847ee49e73bef577c0ab9cf2bf9;hp=c79e44e0f033a1cbc08a645efabe029677ef9812;hb=98eb404f77d95b8fa449db48b6d38196b7582549;hpb=0c1563637a036cda7297d7741c8b2c717ed65890 diff --git a/PVE/API2/Domains.pm b/PVE/API2/Domains.pm index c79e44e..b5fa65e 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,7 +34,17 @@ __PACKAGE__->register_method ({ type => "object", properties => { realm => { type => 'string' }, - comment => { type => 'string', optional => 1 }, + tfa => { + description => "Two-factor authentication provider.", + type => 'string', + enum => [ 'yubico', 'oath' ], + optional => 1, + }, + comment => { + description => "A comment. The GUI use this text when you select a domain (Realm) on the login window.", + type => 'string', + optional => 1, + }, }, }, links => [ { rel => 'child', href => "{realm}" } ], @@ -43,12 +55,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,103 +76,44 @@ __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. Use '0' if you want to use default settings'", - type => 'integer', - minimum => 0, - maximum => 65535, - optional => 1, - }, - domain => { - description => "AD domain name", - type => 'string', - 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'); - foreach my $p (keys %$param) { - next if $p eq 'realm'; - $cfg->{$realm}->{$p} = $param->{$p} if $param->{$p}; - } + my $plugin = PVE::Auth::Plugin->lookup($type); + my $config = $plugin->check_config($realm, $param, 1, 1); - # port 0 ==> use default - # server2 == '' ===> delete server2 - for my $p (qw(port server2)) { - if (defined($param->{$p}) && !$param->{$p}) { - delete $cfg->{$realm}->{$p}; + if ($config->{default}) { + foreach my $r (keys %$ids) { + delete $ids->{$r}->{default}; } } + $ids->{$realm} = $config; + cfs_write_file($domainconfigfile, $cfg); }, "add auth server failed"); @@ -167,94 +124,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. Use '0' if you want to use default settings'", - type => 'integer', - minimum => 0, - maximum => 65535, - optional => 1, - }, - domain => { - description => "AD domain name", - type => 'string', - 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}; - if (defined($param->{secure})) { - $cfg->{$realm}->{secure} = $param->{secure} ? 1 : 0; + my $delete_str = extract_param($param, 'delete'); + die "no options specified\n" if !$delete_str && !scalar(keys %$param); + + 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) { - if ($param->{$p}) { - $cfg->{$realm}->{$p} = $param->{$p}; - } else { - delete $cfg->{$realm}->{$p}; - } + foreach my $p (keys %$config) { + $ids->{$realm}->{$p} = $config->{$p}; } cfs_write_file($domainconfigfile, $cfg); @@ -269,6 +180,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 => { @@ -283,9 +197,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; }}); @@ -294,6 +210,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 => { @@ -306,16 +225,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");