diff --git a/src/common/context.rs b/src/common/context.rs index cbe4e2e8..2fa92082 100644 --- a/src/common/context.rs +++ b/src/common/context.rs @@ -62,7 +62,7 @@ pub enum LaunchType { impl Context { pub fn build_from_options( sudo_options: OptionsForContext, - path: String, + secure_path: Option<&str>, ) -> Result { let hostname = Hostname::resolve(); let current_user = CurrentUser::resolve()?; @@ -76,7 +76,18 @@ impl Context { // FIXME `Default` is being used as `Option::None` Default::default() } - _ => CommandAndArguments::build_from_args(shell, sudo_options.positional_args, &path), + _ => { + let system_path; + + let path = if let Some(path) = secure_path { + path + } else { + system_path = std::env::var("PATH").unwrap_or_default(); + system_path.as_ref() + }; + + CommandAndArguments::build_from_args(shell, sudo_options.positional_args, path) + } }; Ok(Context { @@ -117,7 +128,7 @@ mod tests { .unwrap(); let path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; let (ctx_opts, _pipe_opts) = options.into(); - let context = Context::build_from_options(ctx_opts, path.to_string()).unwrap(); + let context = Context::build_from_options(ctx_opts, Some(path)).unwrap(); let mut target_environment = HashMap::new(); target_environment.insert("SUDO_USER".to_string(), context.current_user.name.clone()); diff --git a/src/sudo/pipeline.rs b/src/sudo/pipeline.rs index 4fdd31df..41d13d34 100644 --- a/src/sudo/pipeline.rs +++ b/src/sudo/pipeline.rs @@ -3,7 +3,6 @@ use std::process::exit; use super::cli::{SudoRunOptions, SudoValidateOptions}; use super::diagnostic; -use crate::common::context::OptionsForContext; use crate::common::resolve::{AuthUser, CurrentUser}; use crate::common::{Context, Error}; use crate::exec::{ExecOutput, ExitReason}; @@ -75,7 +74,7 @@ impl Pipeline { ) } - let mut context = build_context(ctx_opts, &policy)?; + let mut context = Context::build_from_options(ctx_opts, policy.secure_path())?; let policy = judge(policy, &context)?; @@ -138,10 +137,10 @@ impl Pipeline { } pub fn run_validate(mut self, cmd_opts: SudoValidateOptions) -> Result<(), Error> { - let pre = read_sudoers()?; - let mut context = build_context(cmd_opts.into(), &pre)?; + let policy = read_sudoers()?; + let mut context = Context::build_from_options(cmd_opts.into(), policy.secure_path())?; - match pre.validate_authorization() { + match policy.validate_authorization() { Authorization::Forbidden => { return Err(Error::Authorization(context.current_user.name.to_string())); } @@ -233,14 +232,6 @@ impl Pipeline { } } -fn build_context(cmd_opts: OptionsForContext, pre: &Sudoers) -> Result { - let secure_path: String = pre - .secure_path() - .map(|s| s.to_owned()) - .unwrap_or_else(|| std::env::var("PATH").unwrap_or_default()); - Context::build_from_options(cmd_opts, secure_path) -} - /// This should determine what the authentication status for the given record /// match limit and origin/target user from the context is. fn determine_auth_status( diff --git a/src/sudo/pipeline/list.rs b/src/sudo/pipeline/list.rs index 96cebf17..c6e9262f 100644 --- a/src/sudo/pipeline/list.rs +++ b/src/sudo/pipeline/list.rs @@ -24,7 +24,8 @@ impl Pipeline { let original_command = cmd_opts.positional_args.first().cloned(); let sudoers = super::read_sudoers()?; - let mut context = super::build_context(cmd_opts.into(), &sudoers)?; + + let mut context = Context::build_from_options(cmd_opts.into(), sudoers.secure_path())?; if original_command.is_some() && !context.command.resolved { return Err(Error::CommandNotFound(context.command.command));