]> git.proxmox.com Git - pve-access-control.git/blobdiff - PVE/AccessControl.pm
refactor acl transformation code
[pve-access-control.git] / PVE / AccessControl.pm
index ad97a426c6df7aa4627383d5e2a12b6d42ac7583..2517ca74ef53f2280e44d4b95c3bc467ec03035e 100644 (file)
@@ -533,7 +533,7 @@ sub authenticate_user {
     my $domain_cfg = cfs_read_file('domains.cfg');
 
     my $cfg = $domain_cfg->{ids}->{$realm};
-    die "auth domain '$realm' does not exists\n" if !$cfg;
+    die "auth domain '$realm' does not exist\n" if !$cfg;
     my $plugin = PVE::Auth::Plugin->lookup($cfg->{type});
     $plugin->authenticate_user($cfg, $realm, $ruid, $password);
 
@@ -683,6 +683,16 @@ my $privgroups = {
            'Datastore.Audit',
        ],
     },
+    SDN => {
+       root => [],
+       admin => [
+           'SDN.Allocate',
+           'SDN.Audit',
+       ],
+       audit => [
+           'SDN.Audit',
+       ],
+    },
     User => {
        root => [
            'Realm.Allocate',
@@ -1094,16 +1104,16 @@ sub write_user_config {
 
     $data .= "\n";
 
-    foreach my $path (sort keys %{$cfg->{acl}}) {
-       my $d = $cfg->{acl}->{$path};
+    my $collect_rolelist_members = sub {
+       my ($acl_members, $result, $prefix, $exclude) = @_;
 
-       my $ra = {};
+       foreach my $member (keys %$acl_members) {
+           next if $exclude && $member eq $exclude;
 
-       foreach my $group (keys %{$d->{groups}}) {
            my $l0 = '';
            my $l1 = '';
-           foreach my $role (sort keys %{$d->{groups}->{$group}}) {
-               my $propagate = $d->{groups}->{$group}->{$role};
+           foreach my $role (sort keys %{$acl_members->{$member}}) {
+               my $propagate = $acl_members->{$member}->{$role};
                if ($propagate) {
                    $l1 .= ',' if $l1;
                    $l1 .= $role;
@@ -1112,37 +1122,27 @@ sub write_user_config {
                    $l0 .= $role;
                }
            }
-           $ra->{0}->{$l0}->{"\@$group"} = 1 if $l0;
-           $ra->{1}->{$l1}->{"\@$group"} = 1 if $l1;
+           $result->{0}->{$l0}->{"${prefix}${member}"} = 1 if $l0;
+           $result->{1}->{$l1}->{"${prefix}${member}"} = 1 if $l1;
        }
+    };
 
-       foreach my $user (keys %{$d->{users}}) {
-           # no need to save, because root is always 'Administrator'
-           next if $user eq 'root@pam';
+    foreach my $path (sort keys %{$cfg->{acl}}) {
+       my $d = $cfg->{acl}->{$path};
 
-           my $l0 = '';
-           my $l1 = '';
-           foreach my $role (sort keys %{$d->{users}->{$user}}) {
-               my $propagate = $d->{users}->{$user}->{$role};
-               if ($propagate) {
-                   $l1 .= ',' if $l1;
-                   $l1 .= $role;
-               } else {
-                   $l0 .= ',' if $l0;
-                   $l0 .= $role;
-               }
-           }
-           $ra->{0}->{$l0}->{$user} = 1 if $l0;
-           $ra->{1}->{$l1}->{$user} = 1 if $l1;
-       }
+       my $rolelist_members = {};
 
-       foreach my $rolelist (sort keys %{$ra->{0}}) {
-           my $uglist = join (',', sort keys %{$ra->{0}->{$rolelist}});
-           $data .= "acl:0:$path:$uglist:$rolelist:\n";
-       }
-       foreach my $rolelist (sort keys %{$ra->{1}}) {
-           my $uglist = join (',', sort keys %{$ra->{1}->{$rolelist}});
-           $data .= "acl:1:$path:$uglist:$rolelist:\n";
+       $collect_rolelist_members->($d->{'groups'}, $rolelist_members, '@');
+
+       # no need to save 'root@pam', it is always 'Administrator'
+       $collect_rolelist_members->($d->{'users'}, $rolelist_members, '', 'root@pam');
+
+       foreach my $propagate (0,1) {
+           my $filtered = $rolelist_members->{$propagate};
+           foreach my $rolelist (sort keys %$filtered) {
+               my $uglist = join (',', sort keys %{$filtered->{$rolelist}});
+               $data .= "acl:$propagate:$path:$uglist:$rolelist:\n";
+           }
        }
     }
 
@@ -1211,7 +1211,7 @@ sub roles {
     my ($cfg, $user, $path) = @_;
 
     # NOTE: we do not consider pools here.
-    # You need to use $rpcenv->roles() instead if you want that.
+    # Use $rpcenv->permission() for any actual permission checks!
 
     return 'Administrator' if $user eq 'root@pam'; # root can do anything