Skip to content

Commit

Permalink
Handle differing sudoers path on FreeBSD in the test framework
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Nov 19, 2024
1 parent d34a00f commit 818bf2b
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
source: sudo-compliance-tests/src/visudo.rs
expression: stderr
---
visudo: unable to re-open temporary file (/tmp/[mkdtemp]/sudoers), /etc/sudoers unchanged: No such file or directory (os error 2)
visudo: unable to re-open temporary file (/tmp/[mkdtemp]/sudoers), <ETC_SUDOERS> unchanged: No such file or directory (os error 2)
14 changes: 7 additions & 7 deletions test-framework/sudo-compliance-tests/src/sudo/sudoers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashSet;

use sudo_test::{Command, Env, TextFile, User};
use sudo_test::{Command, Env, TextFile, User, ETC_SUDOERS};

use crate::{Result, PASSWORD, SUDOERS_ROOT_ALL_NOPASSWD, USERNAME};

Expand Down Expand Up @@ -95,9 +95,9 @@ fn cannot_sudo_if_sudoers_file_is_world_writable() -> Result<()> {
assert_eq!(Some(1), output.status().code());

let diagnostic = if sudo_test::is_original_sudo() {
"/etc/sudoers is world writable"
format!("{ETC_SUDOERS} is world writable")
} else {
"invalid configuration: /etc/sudoers cannot be world-writable"
format!("invalid configuration: {ETC_SUDOERS} cannot be world-writable")
};
assert_contains!(output.stderr(), diagnostic);

Expand All @@ -116,9 +116,9 @@ fn cannot_sudo_if_sudoers_file_is_group_writable() -> Result<()> {
assert_eq!(Some(1), output.status().code());

let diagnostic = if sudo_test::is_original_sudo() {
"/etc/sudoers is owned by gid 1234, should be 0"
format!("{ETC_SUDOERS} is owned by gid 1234, should be 0")
} else {
"invalid configuration: /etc/sudoers cannot be group-writable"
format!("invalid configuration: {ETC_SUDOERS} cannot be group-writable")
};
assert_contains!(output.stderr(), diagnostic);

Expand All @@ -145,9 +145,9 @@ fn cannot_sudo_if_sudoers_file_is_not_owned_by_root() -> Result<()> {
assert_eq!(Some(1), output.status().code());

let diagnostic = if sudo_test::is_original_sudo() {
"/etc/sudoers is owned by uid 1234, should be 0"
format!("{ETC_SUDOERS} is owned by uid 1234, should be 0")
} else {
"invalid configuration: /etc/sudoers must be owned by root"
format!("invalid configuration: {ETC_SUDOERS} must be owned by root")
};
assert_contains!(output.stderr(), diagnostic);

Expand Down
26 changes: 15 additions & 11 deletions test-framework/sudo-compliance-tests/src/sudo/sudoers/include.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use sudo_test::{Command, Env, TextFile};
use std::path::Path;

use sudo_test::{Command, Env, TextFile, ETC_SUDOERS};

use crate::{Result, SUDOERS_ALL_ALL_NOPASSWD, USERNAME};

#[test]
fn relative_path() -> Result<()> {
let env = Env("@include sudoers2")
.file("/etc/sudoers2", SUDOERS_ALL_ALL_NOPASSWD)
.file(format!("{ETC_SUDOERS}2"), SUDOERS_ALL_ALL_NOPASSWD)
.build()?;

Command::new("sudo")
Expand Down Expand Up @@ -118,7 +120,7 @@ fn double_quote_in_name_double_quotes() -> Result<()> {
#[test]
fn include_loop_error_messages() -> Result<()> {
let env = Env("@include /etc/sudoers2")
.file(r#"/etc/sudoers2"#, "@include /etc/sudoers")
.file(r#"/etc/sudoers2"#, format!("@include {ETC_SUDOERS}"))
.build()?;

let output = Command::new("sudo").arg("true").output(&env)?;
Expand All @@ -138,7 +140,7 @@ fn include_loop_error_messages() -> Result<()> {
#[test]
fn include_loop_not_fatal() -> Result<()> {
let env = Env([SUDOERS_ALL_ALL_NOPASSWD, "@include /etc/sudoers2"])
.file(r#"/etc/sudoers2"#, "@include /etc/sudoers")
.file(r#"/etc/sudoers2"#, format!("@include {ETC_SUDOERS}"))
.build()?;

let output = Command::new("sudo").arg("true").output(&env)?;
Expand Down Expand Up @@ -180,16 +182,16 @@ fn permissions_check() -> Result<()> {
#[test]
fn permissions_check_not_fatal() -> Result<()> {
let env = Env([SUDOERS_ALL_ALL_NOPASSWD, "@include sudoers2"])
.file(r#"/etc/sudoers2"#, TextFile("").chmod("777"))
.file(format!("{ETC_SUDOERS}2"), TextFile("").chmod("777"))
.build()?;

let output = Command::new("sudo").arg("true").output(&env)?;

assert!(output.status().success());
let diagnostic = if sudo_test::is_original_sudo() {
"sudo: /etc/sudoers2 is world writable"
format!("sudo: {ETC_SUDOERS}2 is world writable")
} else {
"sudo-rs: /etc/sudoers2 cannot be world-writable"
format!("sudo-rs: {ETC_SUDOERS}2 cannot be world-writable")
};
assert_contains!(output.stderr(), diagnostic);

Expand Down Expand Up @@ -269,17 +271,19 @@ fn relative_path_parent_directory() -> Result<()> {

#[test]
fn relative_path_grandparent_directory() -> Result<()> {
// base path is `/etc/sudoers` so grandparent does not exist
// base path is `/etc/sudoers` or `/usr/local/etc/sudoers` so grandparent does not exist
let env = Env("@include ../../sudoers2").build()?;

let output = Command::new("sudo").arg("true").output(&env)?;

assert!(!output.status().success());
assert_eq!(Some(1), output.status().code());

let path = Path::new(ETC_SUDOERS).parent().unwrap().to_str().unwrap().to_owned() + "/../../sudoers2";
let diagnostic = if sudo_test::is_original_sudo() {
"sudo: unable to open /etc/../../sudoers2: No such file or directory"
format!("sudo: unable to open {path}: No such file or directory")
} else {
"sudo-rs: cannot open sudoers file '/etc/../../sudoers2'"
format!("sudo-rs: cannot open sudoers file '{path}'")
};
assert_contains!(output.stderr(), diagnostic);
Ok(())
Expand All @@ -288,7 +292,7 @@ fn relative_path_grandparent_directory() -> Result<()> {
#[test]
fn relative_path_dot_slash() -> Result<()> {
let env = Env("@include ./sudoers2")
.file("/etc/sudoers2", SUDOERS_ALL_ALL_NOPASSWD)
.file(format!("{ETC_SUDOERS}2"), SUDOERS_ALL_ALL_NOPASSWD)
.build()?;

Command::new("sudo")
Expand Down
Loading

0 comments on commit 818bf2b

Please sign in to comment.