implement helper to check if we can modify permission
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 26 Jan 2012 07:25:16 +0000 (08:25 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 26 Jan 2012 07:25:16 +0000 (08:25 +0100)
PVE/API2/ACL.pm
PVE/RPCEnvironment.pm

index 66f4129..8c5c388 100644 (file)
@@ -21,7 +21,7 @@ __PACKAGE__->register_method ({
     method => 'GET',
     description => "Get Access Control List (ACLs).",
     permissions => { 
-       check => ['perm', '/access', ['Sys.Audit', 'Permissions.Modify'], any => 1],
+       user => 'all',
     },
     parameters => {
        additionalProperties => 0,
@@ -44,19 +44,23 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
     
+       my $rpcenv = PVE::RPCEnvironment::get();
+       my $authuser = $rpcenv->get_user();
        my $res = [];
 
-       my $usercfg = cfs_read_file("user.cfg");
-
+       my $usercfg = $rpcenv->{user_cfg};
        if (!$usercfg || !$usercfg->{acl}) {
            return {};
        }
 
+       my $audit = $rpcenv->check($authuser, '/access', ['Sys.Audit'], 1);
+
        my $acl = $usercfg->{acl};
        foreach my $path (keys %$acl) {
            foreach my $type (qw(users groups)) {
                my $d = $acl->{$path}->{$type};
                next if !$d;
+               next if !($audit || $rpcenv->check_perm_modify($authuser, $path, 1));
                foreach my $id (keys %$d) {
                    foreach my $role (keys %{$d->{$id}}) {
                        my $propagate = $d->{$id}->{$role};
@@ -81,7 +85,7 @@ __PACKAGE__->register_method ({
     path => '', 
     method => 'PUT',
     permissions => { 
-       check => ['perm', '/access', ['Permissions.Modify']],
+       check => ['perm-modify', '{path}'],
     },
     description => "Update Access Control List (add or remove permissions).",
     parameters => {
index 0df71dc..0b8147e 100644 (file)
@@ -299,6 +299,21 @@ sub group_member_join {
     return $users;
 }
 
+sub check_perm_modify {
+    my ($self, $username, $path, $noerr) = @_;
+
+    return $self->check($username, '/access', [ 'Permissions.Modify' ], $noerr) if !$path;
+
+    my $testperms = [ 'Permissions.Modify' ];
+    if ($path =~ m|^/storage/.+$|) {
+       push @$testperms, 'Datastore.Allocate';
+    } elsif ($path =~ m|^/vms/.+$|) {
+       push @$testperms, 'VM.Allocate';
+    }
+
+    return $self->check_any($username, $path, $testperms, $noerr);
+}
+
 sub exec_api2_perm_check {
     my ($self, $check, $username, $param, $noerr) = @_;
 
@@ -324,6 +339,7 @@ sub exec_api2_perm_check {
        my $any = $options{any};
        die "missing parameters" if !($tmplpath && $privs);
        my $path = PVE::Tools::template_replace($tmplpath, $param);
+       $path = PVE::AccessControl::normalize_path($path);
        if ($any) {
            return $self->check_any($username, $path, $privs, $noerr);
        } else {
@@ -363,7 +379,12 @@ sub exec_api2_perm_check {
        } else {
            die "unknown userid-param test";
        }
-    } else {
+    } elsif ($test eq 'perm-modify') {
+       my ($t, $tmplpath) = @$check;
+       my $path = PVE::Tools::template_replace($tmplpath, $param);
+       $path = PVE::AccessControl::normalize_path($path);
+       return $self->check_perm_modify($username, $path, $noerr);
+   } else {
        die "unknown permission test";
     }
 };