diff options
| author | 2026-02-26 17:34:49 -0500 | |
|---|---|---|
| committer | 2026-02-26 17:34:49 -0500 | |
| commit | 44388f8de44ba13f740a5fc7e0f838c961fad084 (patch) | |
| tree | ca0e92573e6e4e52ee2c22475ec5dcbe6dd8f60b /src/config.rs | |
| parent | proper config command handling (diff) | |
begin permissions shift for build commands
Diffstat (limited to 'src/config.rs')
| -rw-r--r-- | src/config.rs | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/config.rs b/src/config.rs index 7c6cf2b..4976af3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,8 +1,11 @@ use serde::Deserialize; use std::fs; +use std::os::unix::process::CommandExt; use std::path::{Path, PathBuf}; use std::process::Command; +use crate::util::get_invoking_user_env; + pub const TEMP_CONFIG_PATH: &str = "/var/lib/forge/.tmp"; pub enum ConfigCommand { @@ -66,6 +69,9 @@ pub fn run_config_command( command: ConfigCommand, ) -> Result<(), String> { let config = Config::new(config_path).ok_or("config not found".to_string())?; + + let is_build = matches!(command, ConfigCommand::Build); + let cmd = match command { ConfigCommand::Build => config.build, ConfigCommand::Install => config.install, @@ -77,9 +83,23 @@ pub fn run_config_command( let cmd_base = parts.next().ok_or("empty command".to_string())?; let args: Vec<&str> = parts.collect(); - let status = Command::new(cmd_base) - .args(&args) - .current_dir(repo_path) + let mut command = Command::new(cmd_base); + command.args(&args).current_dir(repo_path); + + if is_build { + if let Some((uid, gid, home, path)) = get_invoking_user_env() { + command.env("HOME", home).env("PATH", path); + unsafe { + command.pre_exec(move || { + nix::unistd::setgid(nix::unistd::Gid::from_raw(gid))?; + nix::unistd::setuid(nix::unistd::Uid::from_raw(uid))?; + Ok(()) + }); + } + } + } + + let status = command .status() .map_err(|e| format!("failed to execute command: {}", e))?; |
