diff --git a/src/sudo/cli/mod.rs b/src/sudo/cli/mod.rs index bec51154b..8caa5bcf4 100644 --- a/src/sudo/cli/mod.rs +++ b/src/sudo/cli/mod.rs @@ -4,6 +4,7 @@ use std::os::unix::ffi::OsStrExt; use std::{borrow::Cow, mem}; use crate::common::{SudoPath, SudoString}; +use crate::log::user_warn; pub mod help; pub mod help_edit; @@ -649,8 +650,8 @@ impl SudoOptions { options.bell = true; } "-E" | "--preserve-env" => { - eprintln_ignore_io_error!( - "warning: preserving the entire environment is not supported, `{flag}` is ignored" + user_warn!( + "preserving the entire environment is not supported, `{flag}` is ignored" ) } "-e" | "--edit" if !invoked_as_sudoedit => { @@ -740,7 +741,7 @@ impl SudoOptions { && !is_dir && (cmd.ends_with("sudoedit") || cmd.ends_with("sudoedit-rs")) { - eprintln_ignore_io_error!("sudoedit doesn't need to be run via sudo"); + user_warn!("sudoedit doesn't need to be run via sudo"); options.edit = true; rest.remove(0); } diff --git a/src/sudo/diagnostic.rs b/src/sudo/diagnostic.rs index 1142f9c50..5996bf8c0 100644 --- a/src/sudo/diagnostic.rs +++ b/src/sudo/diagnostic.rs @@ -43,11 +43,11 @@ macro_rules! diagnostic { if let Some(range) = $pos { $crate::sudo::diagnostic::cited_error(&format!($str), range, $path); } else { - eprintln_ignore_io_error!("sudo-rs: {}", format!($str)); + eprintln_ignore_io_error!("sudo: {}", format!($str)); } }; ($str:expr) => {{ - eprintln_ignore_io_error!("sudo-rs: {}", format!($str)); + eprintln_ignore_io_error!("sudo: {}", format!($str)); }}; } diff --git a/src/sudo/edit.rs b/src/sudo/edit.rs index 37f17f840..d043d2f01 100644 --- a/src/sudo/edit.rs +++ b/src/sudo/edit.rs @@ -10,7 +10,7 @@ use std::{io, process}; use crate::common::SudoPath; use crate::exec::ExitReason; -use crate::log::user_info; +use crate::log::{user_error, user_info}; use crate::system::file::{create_temporary_dir, FileLock}; use crate::system::wait::{Wait, WaitError, WaitOptions}; use crate::system::{fork, ForkResult}; @@ -157,8 +157,8 @@ struct TempDirDropGuard(PathBuf); impl Drop for TempDirDropGuard { fn drop(&mut self) { if let Err(e) = std::fs::remove_dir_all(&self.0) { - eprintln_ignore_io_error!( - "Failed to remove temporary directory {}: {e}", + user_error!( + "failed to remove temporary directory {}: {e}", self.0.display(), ); }; @@ -169,7 +169,7 @@ fn handle_child(editor: &Path, file: Vec>) -> ! { match handle_child_inner(editor, file) { Ok(()) => process::exit(0), Err(err) => { - eprintln_ignore_io_error!("{err}"); + user_error!("{err}"); process::exit(1); } } @@ -184,7 +184,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul } let tempdir = TempDirDropGuard( - create_temporary_dir().map_err(|e| format!("Failed to create temporary directory: {e}"))?, + create_temporary_dir().map_err(|e| format!("failed to create temporary directory: {e}"))?, ); for (i, file) in files.iter_mut().enumerate() { @@ -192,7 +192,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul let dir = tempdir.0.join(format!("{i}")); std::fs::create_dir(&dir).map_err(|e| { format!( - "Failed to create temporary directory {}: {e}", + "failed to create temporary directory {}: {e}", dir.display(), ) })?; @@ -205,7 +205,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul .open(&tempfile_path) .map_err(|e| { format!( - "Failed to create temporary file {}: {e}", + "failed to create temporary file {}: {e}", tempfile_path.display(), ) })?; @@ -213,7 +213,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul // Write to temp file tempfile.write_all(&file.old_data).map_err(|e| { format!( - "Failed to write to temporary file {}: {e}", + "failed to write to temporary file {}: {e}", tempfile_path.display(), ) })?; @@ -229,7 +229,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul .map(|file| file.tempfile_path.as_ref().expect("filled in above")), ) .status() - .map_err(|e| format!("Failed to run editor {}: {e}", editor.display()))?; + .map_err(|e| format!("failed to run editor {}: {e}", editor.display()))?; if !status.success() { drop(tempdir); @@ -246,7 +246,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul // Read from temp file let new_data = std::fs::read(tempfile_path).map_err(|e| { format!( - "Failed to read from temporary file {}: {e}", + "failed to read from temporary file {}: {e}", tempfile_path.display(), ) })?; @@ -254,7 +254,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul // FIXME preserve temporary file if the original couldn't be written to std::fs::remove_file(tempfile_path).map_err(|e| { format!( - "Failed to remove temporary file {}: {e}", + "failed to remove temporary file {}: {e}", tempfile_path.display(), ) })?; @@ -271,11 +271,11 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul ) { Ok(b'y') => {} _ => { - eprintln_ignore_io_error!("Not overwriting {}", file.path.display()); + user_info!("not overwriting {}", file.path.display()); // Parent ignores write when new data matches old data write_stream(&mut file.new_data_tx, &file.old_data) - .map_err(|e| format!("Failed to write data to parent: {e}"))?; + .map_err(|e| format!("failed to write data to parent: {e}"))?; continue; } @@ -284,7 +284,7 @@ fn handle_child_inner(editor: &Path, mut files: Vec>) -> Resul // Write to socket write_stream(&mut file.new_data_tx, &new_data) - .map_err(|e| format!("Failed to write data to parent: {e}"))?; + .map_err(|e| format!("failed to write data to parent: {e}"))?; } process::exit(0); diff --git a/src/sudo/mod.rs b/src/sudo/mod.rs index 52e86b6a3..0cf2c0a09 100644 --- a/src/sudo/mod.rs +++ b/src/sudo/mod.rs @@ -81,11 +81,11 @@ fn sudo_process() -> Result<(), Error> { match SudoAction::from_env() { Ok(action) => match action { SudoAction::Help(_) => { - eprintln_ignore_io_error!("{}", long_help()); + println_ignore_io_error!("{}", long_help()); std::process::exit(0); } SudoAction::Version(_) => { - eprintln_ignore_io_error!("sudo-rs {VERSION}"); + println_ignore_io_error!("sudo-rs {VERSION}"); std::process::exit(0); } SudoAction::RemoveTimestamp(_) => { diff --git a/src/sudoers/ast.rs b/src/sudoers/ast.rs index b514f8f84..d27489647 100644 --- a/src/sudoers/ast.rs +++ b/src/sudoers/ast.rs @@ -397,8 +397,8 @@ impl Parse for MetaOrTag { // this is less fatal "LOG_INPUT" | "NOLOG_INPUT" | "LOG_OUTPUT" | "NOLOG_OUTPUT" | "MAIL" | "NOMAIL" | "FOLLOW" => { - eprintln_ignore_io_error!( - "warning: {} tags are ignored by sudo-rs", + crate::log::user_warn!( + "{} tags in the sudoers policy are ignored by sudo-rs", keyword.as_str() ); switch(|_| {})? diff --git a/test-framework/e2e-tests/src/regression.rs b/test-framework/e2e-tests/src/regression.rs index 2ed0b1880..803293eef 100644 --- a/test-framework/e2e-tests/src/regression.rs +++ b/test-framework/e2e-tests/src/regression.rs @@ -27,7 +27,7 @@ fn no_permissions_should_not_violate_io_safety() { assert_eq!( stderr, - "sudo-rs: cannot execute '/usr/bin/foo': Permission denied (os error 13)" + "sudo: cannot execute '/usr/bin/foo': Permission denied (os error 13)" ); } diff --git a/test-framework/sudo-compliance-tests/src/sudo/flag_help.rs b/test-framework/sudo-compliance-tests/src/sudo/flag_help.rs index 657633ddb..e51d94ffd 100644 --- a/test-framework/sudo-compliance-tests/src/sudo/flag_help.rs +++ b/test-framework/sudo-compliance-tests/src/sudo/flag_help.rs @@ -16,3 +16,22 @@ fn does_not_panic_on_io_errors() -> Result<()> { Ok(()) } + +#[test] +fn prints_on_stdout() -> Result<()> { + let env = Env("").build(); + + let output = Command::new("sudo").args(["--help"]).output(&env); + + let output = output.stdout(); + assert_starts_with!( + output, + if sudo_test::is_original_sudo() { + "sudo - execute a command as another user" + } else { + "sudo - run commands as another user" + } + ); + + Ok(()) +} diff --git a/test-framework/sudo-compliance-tests/src/sudo/flag_list.rs b/test-framework/sudo-compliance-tests/src/sudo/flag_list.rs index 8dbe88729..c9d5bed29 100644 --- a/test-framework/sudo-compliance-tests/src/sudo/flag_list.rs +++ b/test-framework/sudo-compliance-tests/src/sudo/flag_list.rs @@ -404,7 +404,7 @@ fn resolves_command_in_invoking_users_path_fail() { let diagnostic = if sudo_test::is_original_sudo() { "sudo: true: command not found" } else { - "sudo-rs: 'true': command not found" + "sudo: 'true': command not found" }; assert_eq!(output.stderr(), diagnostic); } @@ -453,7 +453,7 @@ fn relative_path_does_not_exist() { let diagnostic = if sudo_test::is_original_sudo() { format!("sudo: {prog_rel_path}: command not found") } else { - format!("sudo-rs: '{prog_rel_path}': command not found") + format!("sudo: '{prog_rel_path}': command not found") }; assert_contains!(output.stderr(), diagnostic); } diff --git a/test-framework/sudo-compliance-tests/src/sudo/flag_list/flag_other_user.rs b/test-framework/sudo-compliance-tests/src/sudo/flag_list/flag_other_user.rs index fc682a9c0..db4f773e0 100644 --- a/test-framework/sudo-compliance-tests/src/sudo/flag_list/flag_other_user.rs +++ b/test-framework/sudo-compliance-tests/src/sudo/flag_list/flag_other_user.rs @@ -16,7 +16,7 @@ fn other_user_does_not_exist() { let diagnostic = if sudo_test::is_original_sudo() { format!("sudo: unknown user {USERNAME}") } else { - format!("sudo-rs: user '{USERNAME}' not found") + format!("sudo: user '{USERNAME}' not found") }; assert_contains!(output.stderr(), diagnostic); } diff --git a/test-framework/sudo-compliance-tests/src/sudo/flag_version.rs b/test-framework/sudo-compliance-tests/src/sudo/flag_version.rs index 853c1ef50..dd60d99dc 100644 --- a/test-framework/sudo-compliance-tests/src/sudo/flag_version.rs +++ b/test-framework/sudo-compliance-tests/src/sudo/flag_version.rs @@ -19,3 +19,22 @@ fn does_not_panic_on_io_errors() -> Result<()> { Ok(()) } + +#[test] +fn prints_on_stdout() -> Result<()> { + let env = Env("").build(); + + let output = Command::new("sudo").args(["--version"]).output(&env); + + let output = output.stdout(); + assert_starts_with!( + output, + if sudo_test::is_original_sudo() { + "Sudo version" + } else { + "sudo-rs" + } + ); + + Ok(()) +} diff --git a/test-framework/sudo-compliance-tests/src/sudo/nopasswd.rs b/test-framework/sudo-compliance-tests/src/sudo/nopasswd.rs index 9266d0846..33537a586 100644 --- a/test-framework/sudo-compliance-tests/src/sudo/nopasswd.rs +++ b/test-framework/sudo-compliance-tests/src/sudo/nopasswd.rs @@ -143,7 +143,7 @@ fn v_flag_without_pwd_fails_if_nopasswd_is_not_set_for_all_users_entries() { } else { assert_contains!( stderr, - "[sudo: authenticate] Password: \nsudo: Authentication failed, try again.\n[sudo: authenticate] Password: \nsudo: Authentication failed, try again.\n[sudo: authenticate] Password: \nsudo-rs: Maximum 3 incorrect authentication attempts" + "[sudo: authenticate] Password: \nsudo: Authentication failed, try again.\n[sudo: authenticate] Password: \nsudo: Authentication failed, try again.\n[sudo: authenticate] Password: \nsudo: Maximum 3 incorrect authentication attempts" ); } } diff --git a/test-framework/sudo-compliance-tests/src/sudoedit.rs b/test-framework/sudo-compliance-tests/src/sudoedit.rs index 4a6c46e02..90a89de08 100644 --- a/test-framework/sudo-compliance-tests/src/sudoedit.rs +++ b/test-framework/sudo-compliance-tests/src/sudoedit.rs @@ -203,7 +203,7 @@ rm $1", if sudo_test::is_original_sudo() { assert_contains!(stderr, format!("sudoedit: {ETC_SUDOERS} left unmodified")); } else { - assert_contains!(stderr, format!("Failed to read from temporary file")); + assert_contains!(stderr, format!("sudo: failed to read from temporary file")); } }