From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 543871FF14C for ; Fri, 26 Jun 2026 12:53:33 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D6C7CC79E; Fri, 26 Jun 2026 12:53:26 +0200 (CEST) From: David Riley To: pve-devel@lists.proxmox.com Subject: [PATCH pve-access-control v4 1/5] fix: #7520: sdn: prune orphaned ACLs on resource deletion Date: Fri, 26 Jun 2026 12:52:54 +0200 Message-ID: <20260626105258.56914-2-d.riley@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260626105258.56914-1-d.riley@proxmox.com> References: <20260626105258.56914-1-d.riley@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1782471196474 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.147 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: PLXNVQWBISP5HSCNX3MT4JG6OSRI3OJG X-Message-ID-Hash: PLXNVQWBISP5HSCNX3MT4JG6OSRI3OJG X-MailFrom: d.riley@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add a helper routine to prune ACL entries under the '/sdn/' path when the corresponding resources are deleted. Compare the running configuration against the newly compiled state during config commit. This prevents dangling permission states and ensures configuration consistency across manual API/UI applies as well as automatic reloads during system boot. Link: https://bugzilla.proxmox.com/show_bug.cgi?id=7520 Signed-off-by: David Riley --- src/PVE/AccessControl.pm | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/PVE/AccessControl.pm b/src/PVE/AccessControl.pm index 0d632b3..10526db 100644 --- a/src/PVE/AccessControl.pm +++ b/src/PVE/AccessControl.pm @@ -1974,6 +1974,52 @@ sub remove_vm_from_pool { lock_user_config($delVMfromPoolFn, "pool cleanup for VM $vmid failed"); } +sub remove_sdn_resource_access { + my ($paths) = @_; # [ ['zones', ''], ['zones', '', ''] ] + + my $delete_resource_fn = sub { + my $usercfg = cfs_read_file("user.cfg"); + my $modified = 0; + + for my $segments (@$paths) { + my @full_path = ('sdn', @$segments); + my $current = $usercfg->{acl_root}; + my ($parent, $last_key) = lookup_acl_node($current, \@full_path); + + if ($parent && $last_key) { + delete $parent->{children}->{$last_key}; + $modified = 1; + } + } + + if ($modified) { + cfs_write_file("user.cfg", $usercfg); + } + }; + + lock_user_config($delete_resource_fn, "SDN ACL cleanup failed"); +} + +sub lookup_acl_node { + my ($root, $path) = @_; + + my $current = $root; + my $parent = undef; + my $last_key = undef; + + for my $step (@$path) { + if (defined($current->{children}) && defined($current->{children}->{$step})) { + $parent = $current; + $last_key = $step; + $current = $current->{children}->{$step}; + } else { + return (undef, undef, undef); + } + } + + return ($parent, $last_key, $current); +} + my $USER_CONTROLLED_TFA_TYPES = { u2f => 1, oath => 1, -- 2.47.3