Commit 612ec0a5 authored by Dietmar Maurer's avatar Dietmar Maurer

implement new check attribute for permissions.

We use a simple prefix notation to express complex expressions.
parent e0993680
...@@ -291,8 +291,7 @@ __PACKAGE__->register_method({ ...@@ -291,8 +291,7 @@ __PACKAGE__->register_method({
method => 'GET', method => 'GET',
description => "Get datacenter options.", description => "Get datacenter options.",
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -313,8 +312,7 @@ __PACKAGE__->register_method({ ...@@ -313,8 +312,7 @@ __PACKAGE__->register_method({
method => 'PUT', method => 'PUT',
description => "Set datacenter options.", description => "Set datacenter options.",
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
protected => 1, protected => 1,
parameters => { parameters => {
......
...@@ -19,8 +19,7 @@ __PACKAGE__->register_method({ ...@@ -19,8 +19,7 @@ __PACKAGE__->register_method({
method => 'GET', method => 'GET',
description => "Directory index.", description => "Directory index.",
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -90,8 +89,7 @@ __PACKAGE__->register_method({ ...@@ -90,8 +89,7 @@ __PACKAGE__->register_method({
description => "Read cluster configuartion (cluster.conf). If you have any uncommitted changes in cluster.conf.new that content is returned instead.", description => "Read cluster configuartion (cluster.conf). If you have any uncommitted changes in cluster.conf.new that content is returned instead.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -120,8 +118,7 @@ __PACKAGE__->register_method({ ...@@ -120,8 +118,7 @@ __PACKAGE__->register_method({
description => "Get pending changes (unified diff between cluster.conf and cluster.conf.new", description => "Get pending changes (unified diff between cluster.conf and cluster.conf.new",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -143,8 +140,7 @@ __PACKAGE__->register_method({ ...@@ -143,8 +140,7 @@ __PACKAGE__->register_method({
description => "Revert pending changes (remove cluster.conf.new)", description => "Revert pending changes (remove cluster.conf.new)",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -168,8 +164,7 @@ __PACKAGE__->register_method({ ...@@ -168,8 +164,7 @@ __PACKAGE__->register_method({
description => "Commit cluster configuartion. Pending changes from cluster.conf.new are written to cluster.conf. This triggers a CMan reload on all nodes.", description => "Commit cluster configuartion. Pending changes from cluster.conf.new are written to cluster.conf. This triggers a CMan reload on all nodes.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -227,8 +222,7 @@ __PACKAGE__->register_method({ ...@@ -227,8 +222,7 @@ __PACKAGE__->register_method({
description => "List resource groups.", description => "List resource groups.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -270,8 +264,7 @@ __PACKAGE__->register_method({ ...@@ -270,8 +264,7 @@ __PACKAGE__->register_method({
description => "Create a new resource groups.", description => "Create a new resource groups.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -318,8 +311,7 @@ __PACKAGE__->register_method({ ...@@ -318,8 +311,7 @@ __PACKAGE__->register_method({
description => "Update resource groups settings.", description => "Update resource groups settings.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -373,8 +365,7 @@ __PACKAGE__->register_method({ ...@@ -373,8 +365,7 @@ __PACKAGE__->register_method({
description => "List resource groups.", description => "List resource groups.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
...@@ -422,8 +413,7 @@ __PACKAGE__->register_method({ ...@@ -422,8 +413,7 @@ __PACKAGE__->register_method({
description => "Delete resource group.", description => "Delete resource group.",
protected => 1, protected => 1,
permissions => { permissions => {
path => '/', check => ['perm', '/', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
parameters => { parameters => {
additionalProperties => 0, additionalProperties => 0,
......
...@@ -135,8 +135,7 @@ __PACKAGE__->register_method({ ...@@ -135,8 +135,7 @@ __PACKAGE__->register_method({
path => '', path => '',
method => 'POST', method => 'POST',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
description => "Create network device configuration", description => "Create network device configuration",
protected => 1, protected => 1,
...@@ -181,8 +180,7 @@ __PACKAGE__->register_method({ ...@@ -181,8 +180,7 @@ __PACKAGE__->register_method({
path => '{iface}', path => '{iface}',
method => 'PUT', method => 'PUT',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
description => "Update network device configuration", description => "Update network device configuration",
protected => 1, protected => 1,
...@@ -239,8 +237,7 @@ __PACKAGE__->register_method({ ...@@ -239,8 +237,7 @@ __PACKAGE__->register_method({
path => '{iface}', path => '{iface}',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Read network device configuration", description => "Read network device configuration",
proxyto => 'node', proxyto => 'node',
...@@ -278,8 +275,7 @@ __PACKAGE__->register_method({ ...@@ -278,8 +275,7 @@ __PACKAGE__->register_method({
path => '{iface}', path => '{iface}',
method => 'DELETE', method => 'DELETE',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
description => "Delete network device configuration", description => "Delete network device configuration",
protected => 1, protected => 1,
......
...@@ -147,8 +147,7 @@ __PACKAGE__->register_method({ ...@@ -147,8 +147,7 @@ __PACKAGE__->register_method({
name => 'beancounters_failcnt', name => 'beancounters_failcnt',
path => 'ubcfailcnt', path => 'ubcfailcnt',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
method => 'GET', method => 'GET',
proxyto => 'node', proxyto => 'node',
...@@ -189,8 +188,7 @@ __PACKAGE__->register_method({ ...@@ -189,8 +188,7 @@ __PACKAGE__->register_method({
path => 'network_changes', path => 'network_changes',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Get network configuration changes (diff) since last boot.", description => "Get network configuration changes (diff) since last boot.",
proxyto => 'node', proxyto => 'node',
...@@ -214,8 +212,7 @@ __PACKAGE__->register_method({ ...@@ -214,8 +212,7 @@ __PACKAGE__->register_method({
path => 'network_changes', path => 'network_changes',
method => 'DELETE', method => 'DELETE',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
privs => [ 'Sys.Modify' ],
}, },
protected => 1, protected => 1,
description => "Revert network configuration changes.", description => "Revert network configuration changes.",
...@@ -240,8 +237,7 @@ __PACKAGE__->register_method({ ...@@ -240,8 +237,7 @@ __PACKAGE__->register_method({
path => 'status', path => 'status',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Read node status", description => "Read node status",
proxyto => 'node', proxyto => 'node',
...@@ -313,8 +309,7 @@ __PACKAGE__->register_method({ ...@@ -313,8 +309,7 @@ __PACKAGE__->register_method({
path => 'status', path => 'status',
method => 'POST', method => 'POST',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.PowerMgmt' ]],
privs => [ 'Sys.PowerMgmt' ],
}, },
protected => 1, protected => 1,
description => "Reboot or shutdown a node.", description => "Reboot or shutdown a node.",
...@@ -350,8 +345,7 @@ __PACKAGE__->register_method({ ...@@ -350,8 +345,7 @@ __PACKAGE__->register_method({
method => 'GET', method => 'GET',
protected => 1, # fixme: can we avoid that? protected => 1, # fixme: can we avoid that?
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Read node RRD statistics (returns PNG)", description => "Read node RRD statistics (returns PNG)",
parameters => { parameters => {
...@@ -396,8 +390,7 @@ __PACKAGE__->register_method({ ...@@ -396,8 +390,7 @@ __PACKAGE__->register_method({
method => 'GET', method => 'GET',
protected => 1, # fixme: can we avoid that? protected => 1, # fixme: can we avoid that?
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Read node RRD statistics", description => "Read node RRD statistics",
parameters => { parameters => {
...@@ -438,8 +431,7 @@ __PACKAGE__->register_method({ ...@@ -438,8 +431,7 @@ __PACKAGE__->register_method({
description => "Read system log", description => "Read system log",
proxyto => 'node', proxyto => 'node',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Syslog' ]],
privs => [ 'Sys.Syslog' ],
}, },
protected => 1, protected => 1,
parameters => { parameters => {
...@@ -496,8 +488,7 @@ __PACKAGE__->register_method ({ ...@@ -496,8 +488,7 @@ __PACKAGE__->register_method ({
method => 'POST', method => 'POST',
protected => 1, protected => 1,
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Console' ]],
privs => [ 'Sys.Console' ],
}, },
description => "Creates a VNC Shell proxy.", description => "Creates a VNC Shell proxy.",
parameters => { parameters => {
...@@ -586,8 +577,7 @@ __PACKAGE__->register_method({ ...@@ -586,8 +577,7 @@ __PACKAGE__->register_method({
path => 'dns', path => 'dns',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Read DNS settings.", description => "Read DNS settings.",
proxyto => 'node', proxyto => 'node',
...@@ -677,9 +667,8 @@ __PACKAGE__->register_method({ ...@@ -677,9 +667,8 @@ __PACKAGE__->register_method({
path => 'time', path => 'time',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ], },
},
description => "Read server time and time zone settings.", description => "Read server time and time zone settings.",
proxyto => 'node', proxyto => 'node',
parameters => { parameters => {
...@@ -753,8 +742,7 @@ __PACKAGE__->register_method ({ ...@@ -753,8 +742,7 @@ __PACKAGE__->register_method ({
path => 'upload', path => 'upload',
method => 'POST', method => 'POST',
permissions => { permissions => {
path => '/storage/{storage}', check => ['perm', '/storage/{storage}', [ 'Datastore.AllocateSpace' ]],
privs => [ 'Datastore.AllocateSpace' ],
}, },
description => "Upload content.", description => "Upload content.",
parameters => { parameters => {
......
...@@ -446,8 +446,7 @@ __PACKAGE__->register_method({ ...@@ -446,8 +446,7 @@ __PACKAGE__->register_method({
method => 'GET', method => 'GET',
protected => 1, # fixme: can we avoid that? protected => 1, # fixme: can we avoid that?
permissions => { permissions => {
path => '/vms/{vmid}', check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
privs => [ 'VM.Audit' ],
}, },
description => "Read VM RRD statistics (returns PNG)", description => "Read VM RRD statistics (returns PNG)",
parameters => { parameters => {
...@@ -493,8 +492,7 @@ __PACKAGE__->register_method({ ...@@ -493,8 +492,7 @@ __PACKAGE__->register_method({
method => 'GET', method => 'GET',
protected => 1, # fixme: can we avoid that? protected => 1, # fixme: can we avoid that?
permissions => { permissions => {
path => '/vms/{vmid}', check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
privs => [ 'VM.Audit' ],
}, },
description => "Read VM RRD statistics", description => "Read VM RRD statistics",
parameters => { parameters => {
...@@ -536,8 +534,7 @@ __PACKAGE__->register_method({ ...@@ -536,8 +534,7 @@ __PACKAGE__->register_method({
protected => 1, protected => 1,
proxyto => 'node', proxyto => 'node',
permissions => { permissions => {
path => '/vms/{vmid}', check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
privs => [ 'VM.Audit' ],
}, },
description => "Read init log.", description => "Read init log.",
parameters => { parameters => {
...@@ -714,8 +711,7 @@ __PACKAGE__->register_method ({ ...@@ -714,8 +711,7 @@ __PACKAGE__->register_method ({
method => 'POST', method => 'POST',
protected => 1, protected => 1,
permissions => { permissions => {
path => '/vms/{vmid}', check => ['perm', '/vms/{vmid}', [ 'VM.Console' ]],
privs => [ 'VM.Console' ],
}, },
description => "Creates a TCP VNC proxy connections.", description => "Creates a TCP VNC proxy connections.",
parameters => { parameters => {
......
...@@ -153,8 +153,7 @@ __PACKAGE__->register_method ({ ...@@ -153,8 +153,7 @@ __PACKAGE__->register_method ({
path => '', path => '',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Service list.", description => "Service list.",
proxyto => 'node', proxyto => 'node',
...@@ -231,8 +230,7 @@ __PACKAGE__->register_method ({ ...@@ -231,8 +230,7 @@ __PACKAGE__->register_method ({
path => '{service}/state', path => '{service}/state',
method => 'GET', method => 'GET',
permissions => { permissions => {
path => '/nodes/{node}', check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
privs => [ 'Sys.Audit' ],
}, },
description => "Read service properties", description => "Read service properties",
proxyto => 'node', proxyto => 'node',
......
...@@ -271,6 +271,64 @@ sub proxy_handler { ...@@ -271,6 +271,64 @@ sub proxy_handler {
return OK; return OK;
} }
sub exec_perm_check {
my ($rpcenv, $check, $username, $param, $noerr) = @_;
my $test = shift @$check;
die "no permission test specified" if !$test;
if ($test eq 'and') {
while (my $subcheck = shift @$check) {
exec_perm_check($rpcenv, $subcheck, $username, $param);
}
return 1;
} elsif ($test eq 'or') {
while (my $subcheck = shift @$check) {
return 1 if exec_perm_check($rpcenv, $subcheck, $username, $param, 1);
}
return 0 if $noerr;
raise_perm_exc();
} elsif ($test eq 'perm') {
my ($tmplpath, $privs, %options) = @$check;
my $any = $options{any};
die "missing parameters" if !($tmplpath && $privs);
my $path = PVE::Tools::template_replace($tmplpath, $param);
if ($any) {
return $rpcenv->check_any($username, $path, $privs, $noerr);
} else {
return $rpcenv->check($username, $path, $privs, $noerr);
}
} elsif ($test eq 'userid-group') {
my $userid = $param->{userid};
return if !$rpcenv->check_user_exist($userid, $noerr);
my ($privs, %options) = @$check;
if (!$rpcenv->check_any($username, "/access", $privs, 1)) {
my $groups = $rpcenv->filter_groups($username, $privs, 1);
my $allowed_users = $rpcenv->group_member_join([keys %$groups]);
if (!$allowed_users->{$userid}) {
return 0 if $noerr;
raise_perm_exc();
}
}
return 1;
} elsif ($test eq 'userid-param') {
my $userid = $param->{userid};
return if !$rpcenv->check_user_exist($userid, $noerr);
my ($subtest) = @$check;
die "missing parameters" if !$subtest;
if ($subtest eq 'self') {
syslog("info", "TESTASQAS");
return 1 if $username eq 'userid';
return 0 if $noerr;
raise_perm_exc();
} else {
die "unknown userid-param test";
}
} else {
die "unknown permission test";
}
};
my $check_permissions = sub { my $check_permissions = sub {
my ($rpcenv, $perm, $username, $param) = @_; my ($rpcenv, $perm, $username, $param) = @_;
...@@ -284,14 +342,7 @@ my $check_permissions = sub { ...@@ -284,14 +342,7 @@ my $check_permissions = sub {
return 1 if $perm->{user} && $perm->{user} eq 'all'; return 1 if $perm->{user} && $perm->{user} eq 'all';
return 1 if $perm->{user} && $perm->{user} eq 'arg' && return exec_perm_check($rpcenv, $perm->{check}, $username, $param) if $perm->{check};
($username eq $param->{username} || $username eq $param->{userid});
if ($perm->{path} && $perm->{privs}) {
my $path = PVE::Tools::template_replace($perm->{path}, $param);
$rpcenv->check($username, $path, $perm->{privs});
return 1;
}
raise_perm_exc(); raise_perm_exc();
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment