Skip to content

Commit

Permalink
test sudoers CWD
Browse files Browse the repository at this point in the history
  • Loading branch information
japaric committed May 16, 2023
1 parent f85df17 commit ffc00b1
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
1 change: 1 addition & 0 deletions test-framework/sudo-compliance-tests/src/sudoers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use sudo_test::{Command, Env, TextFile, User};
use crate::{Result, PASSWORD, SUDOERS_ROOT_ALL_NOPASSWD, USERNAME};

mod cmnd;
mod cwd;
mod host_list;
mod run_as;
mod secure_path;
Expand Down
193 changes: 193 additions & 0 deletions test-framework/sudo-compliance-tests/src/sudoers/cwd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
use sudo_test::{Command, Env, User};

use crate::{Result, USERNAME};

#[test]
fn sets_the_working_directory_of_the_executed_command() -> Result<()> {
let expected_path = "/root";
let env = Env(format!("ALL ALL=(ALL:ALL) CWD={expected_path} ALL")).build()?;

let stdout = Command::new("sh")
.args(["-c", "cd /; sudo pwd"])
.exec(&env)?
.stdout()?;

assert_eq!(expected_path, stdout);

Ok(())
}

#[test]
fn glob_has_no_effect_on_its_own() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=* ALL").build()?;

let expected_path = "/";
let stdout = Command::new("sh")
.args(["-c", "cd {expected_path}; sudo pwd"])
.exec(&env)?
.stdout()?;

assert_eq!(expected_path, stdout);

Ok(())
}

#[test]
fn non_absolute_path_is_rejected() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=usr ALL").build()?;

let output = Command::new("sh")
.args(["-c", "cd /; sudo pwd"])
.exec(&env)?;

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

if sudo_test::is_original_sudo() {
assert_contains!(
output.stderr(),
"values for \"CWD\" must start with a '/', '~', or '*'"
);
}

Ok(())
}

#[test]
fn dot_slash_is_rejected() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=./usr ALL").build()?;

let output = Command::new("sh")
.args(["-c", "cd /; sudo pwd"])
.exec(&env)?;

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

if sudo_test::is_original_sudo() {
assert_contains!(
output.stderr(),
"values for \"CWD\" must start with a '/', '~', or '*'"
);
}

Ok(())
}

#[test]
fn tilde_when_target_user_is_root() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=~ ALL").build()?;

let stdout = Command::new("sh")
.args(["-c", "cd /; sudo pwd"])
.exec(&env)?
.stdout()?;

assert_eq!("/root", stdout);

Ok(())
}

#[test]
fn tilde_when_target_user_is_regular_user() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=~ NOPASSWD: ALL")
.user(User(USERNAME).create_home_directory())
.build()?;

let stdout = Command::new("sh")
.arg("-c")
.arg(format!("cd /; sudo -u {USERNAME} pwd"))
.exec(&env)?
.stdout()?;

assert_eq!(format!("/home/{USERNAME}"), stdout);

Ok(())
}

#[test]
fn tilde_username() -> Result<()> {
let env = Env(format!("ALL ALL=(ALL:ALL) CWD=~{USERNAME} NOPASSWD: ALL"))
.user(User(USERNAME).create_home_directory())
.build()?;

for target_user in ["root", USERNAME] {
let stdout = Command::new("sh")
.arg("-c")
.arg(format!("cd /; sudo -u {target_user} pwd"))
.exec(&env)?
.stdout()?;

assert_eq!(format!("/home/{USERNAME}"), stdout);
}

Ok(())
}

#[test]
fn path_does_not_exist() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=/path/to/nowhere NOPASSWD: ALL").build()?;

let output = Command::new("sh")
.arg("-c")
.arg("cd /; sudo pwd")
.exec(&env)?;

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

if sudo_test::is_original_sudo() {
assert_contains!(
output.stderr(),
"sudo: unable to change directory to /path/to/nowhere: No such file or directory"
);
}

Ok(())
}

#[test]
fn path_is_file() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=/dev/null NOPASSWD: ALL").build()?;

let output = Command::new("sh")
.arg("-c")
.arg("cd /; sudo pwd")
.exec(&env)?;

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

if sudo_test::is_original_sudo() {
assert_contains!(
output.stderr(),
"sudo: unable to change directory to /dev/null: Not a directory"
);
}

Ok(())
}

#[test]
fn target_user_has_insufficient_permissions() -> Result<()> {
let env = Env("ALL ALL=(ALL:ALL) CWD=/root NOPASSWD: ALL")
.user(USERNAME)
.build()?;

let output = Command::new("sh")
.arg("-c")
.arg(format!("cd /; sudo -u {USERNAME} pwd"))
.exec(&env)?;

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

if sudo_test::is_original_sudo() {
assert_contains!(
output.stderr(),
"sudo: unable to change directory to /root: Permission denied"
);
}

Ok(())
}

0 comments on commit ffc00b1

Please sign in to comment.