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 5C4371FF137 for ; Tue, 14 Apr 2026 14:59:45 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8322618DB0; Tue, 14 Apr 2026 15:00:17 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v3 12/30] api: config: check sync owner has access to en-/decryption keys Date: Tue, 14 Apr 2026 14:59:05 +0200 Message-ID: <20260414125923.892345-13-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260414125923.892345-1-c.ebner@proxmox.com> References: <20260414125923.892345-1-c.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1776171499560 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.070 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: 3DDMXPPHS2HZBYV47ELTKMXFWJVATQEF X-Message-ID-Hash: 3DDMXPPHS2HZBYV47ELTKMXFWJVATQEF X-MailFrom: c.ebner@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 Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: So a sync job can not be configured with a non existing or non accessible key for given sync owner/local-user. Key access is checked by loading the key from the keyfile. When setting the active encryption key for push sync jobs it is further assured that the key is not archived yet. Signed-off-by: Christian Ebner --- changes since version 2: - fix check for key access when setting active encryption key. It must fail for archived keys. src/api2/config/sync.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/api2/config/sync.rs b/src/api2/config/sync.rs index 67fa3182c..75b99c2a7 100644 --- a/src/api2/config/sync.rs +++ b/src/api2/config/sync.rs @@ -62,6 +62,22 @@ fn is_correct_owner(auth_id: &Authid, job: &SyncJobConfig) -> bool { } } +// Check access and test key loading works as expected for sync job owner/user. +fn sync_user_can_access_optional_key( + key_id: Option<&str>, + owner: &Authid, + fail_on_archived: bool, +) -> Result<(), Error> { + if let Some(key_id) = key_id { + if crate::server::sync::check_privs_and_load_key_config(key_id, owner, fail_on_archived) + .is_err() + { + bail!("no such key or cannot access key '{key_id}'"); + } + } + Ok(()) +} + /// checks whether user can run the corresponding sync job, depending on sync direction /// /// namespace creation/deletion ACL and backup group ownership checks happen in the pull/push code @@ -251,6 +267,19 @@ pub fn create_sync_job( } } + let owner = config + .owner + .as_ref() + .unwrap_or_else(|| Authid::root_auth_id()); + + if sync_direction == SyncDirection::Push { + sync_user_can_access_optional_key(config.active_encryption_key.as_deref(), owner, true)?; + } else { + for key in config.associated_key.as_deref().unwrap_or(&[]) { + sync_user_can_access_optional_key(Some(key), owner, false)?; + } + } + let (mut section_config, _digest) = sync::config()?; if section_config.sections.contains_key(&config.id) { -- 2.47.3