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 8037D1FF140 for ; Fri, 24 Apr 2026 13:20:41 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 503E3145A5; Fri, 24 Apr 2026 13:20:41 +0200 (CEST) From: Hannes Laimer To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup] cli: fix move-namespace and move-group running as root Date: Fri, 24 Apr 2026 13:20:01 +0200 Message-ID: <20260424112001.206897-1-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1777029515648 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.080 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 URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [datastore.rs] Message-ID-Hash: MDKUXHUECURRZUH5A33SPUVBWSG7S5RX X-Message-ID-Hash: MDKUXHUECURRZUH5A33SPUVBWSG7S5RX X-MailFrom: h.laimer@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: The 'move-namespace' and 'move-group' commands of called their api handler in-process via the CLI's rpcenv, so the worker task ran inside the manager process and wrote into the datastore as root. Route them through the api with connect_to_localhost() instead. Reported-by: Michael Köppl Fixes: 4d74e20d ("cli: add move-namespace and move-group commands") Signed-off-by: Hannes Laimer --- src/bin/proxmox_backup_manager/datastore.rs | 43 +++++++++++---------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/bin/proxmox_backup_manager/datastore.rs b/src/bin/proxmox_backup_manager/datastore.rs index 0ad97fda..738d0fa5 100644 --- a/src/bin/proxmox_backup_manager/datastore.rs +++ b/src/bin/proxmox_backup_manager/datastore.rs @@ -325,7 +325,6 @@ async fn uuid_mount(mut param: Value, _rpcenv: &mut dyn RpcEnvironment) -> Resul } #[api( - protected: true, input: { properties: { store: { @@ -356,28 +355,27 @@ async fn uuid_mount(mut param: Value, _rpcenv: &mut dyn RpcEnvironment) -> Resul namespace, merge snapshots into it. Requires matching ownership and \ non-overlapping snapshot times.", }, + "output-format": { + schema: OUTPUT_FORMAT, + optional: true, + }, }, }, )] /// Move a backup namespace to a new location within the same datastore. -async fn cli_move_namespace( - mut param: Value, - rpcenv: &mut dyn RpcEnvironment, -) -> Result<(), Error> { - param["node"] = "localhost".into(); +async fn cli_move_namespace(store: String, mut param: Value) -> Result<(), Error> { + let output_format = extract_output_format(&mut param); - let info = &api2::admin::namespace::API_METHOD_MOVE_NAMESPACE; - let result = match info.handler { - ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, - _ => unreachable!(), - }; + let client = connect_to_localhost()?; + let path = format!("api2/json/admin/datastore/{store}/move-namespace"); + let result = client.post(&path, Some(param)).await?; + + view_task_result(&client, result, &output_format).await?; - crate::wait_for_local_worker(result.as_str().unwrap()).await?; Ok(()) } #[api( - protected: true, input: { properties: { store: { @@ -401,20 +399,23 @@ async fn cli_move_namespace( snapshots into it. Requires matching ownership and non-overlapping \ snapshot times.", }, + "output-format": { + schema: OUTPUT_FORMAT, + optional: true, + }, }, }, )] /// Move a backup group to a different namespace within the same datastore. -async fn cli_move_group(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> { - param["node"] = "localhost".into(); +async fn cli_move_group(store: String, mut param: Value) -> Result<(), Error> { + let output_format = extract_output_format(&mut param); - let info = &api2::admin::datastore::API_METHOD_MOVE_GROUP; - let result = match info.handler { - ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, - _ => unreachable!(), - }; + let client = connect_to_localhost()?; + let path = format!("api2/json/admin/datastore/{store}/move-group"); + let result = client.post(&path, Some(param)).await?; + + view_task_result(&client, result, &output_format).await?; - crate::wait_for_local_worker(result.as_str().unwrap()).await?; Ok(()) } -- 2.47.3