Skip to content

Commit

Permalink
Implement rootpw
Browse files Browse the repository at this point in the history
FIXME: Add tests
  • Loading branch information
bjorn3 committed Jan 6, 2025
1 parent 33fd1c3 commit 66f3609
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 4 deletions.
11 changes: 10 additions & 1 deletion src/common/context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::common::resolve::AuthUser;
use crate::common::{HARDENED_ENUM_VALUE_0, HARDENED_ENUM_VALUE_1, HARDENED_ENUM_VALUE_2};
use crate::system::{Group, Hostname, Process, User};

Expand Down Expand Up @@ -43,6 +44,7 @@ pub struct Context {
// system
pub hostname: Hostname,
pub current_user: CurrentUser,
pub auth_user: AuthUser,
pub process: Process,
// policy
pub use_pty: bool,
Expand All @@ -60,9 +62,15 @@ impl Context {
pub fn build_from_options(
sudo_options: OptionsForContext,
path: String,
rootpw: bool,
) -> Result<Context, Error> {
let hostname = Hostname::resolve();
let current_user = CurrentUser::resolve()?;
let auth_user = if rootpw {
AuthUser::resolve_root_for_rootpw()?
} else {
AuthUser::from_current_user(current_user.clone())
};
let (target_user, target_group) =
resolve_target_user_and_group(&sudo_options.user, &sudo_options.group, &current_user)?;
let (launch, shell) = resolve_launch_and_shell(&sudo_options, &current_user, &target_user);
Expand All @@ -80,6 +88,7 @@ impl Context {
hostname,
command,
current_user,
auth_user,
target_user,
target_group,
use_session_records: !sudo_options.reset_timestamp,
Expand Down Expand Up @@ -112,7 +121,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, path.to_string(), false).unwrap();

let mut target_environment = HashMap::new();
target_environment.insert("SUDO_USER".to_string(), context.current_user.name.clone());
Expand Down
24 changes: 24 additions & 0 deletions src/common/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::system::interface::UserId;
use crate::system::{Group, User};
use core::fmt;
use std::{
Expand Down Expand Up @@ -71,6 +72,29 @@ impl CurrentUser {
}
}

#[derive(Clone, Debug)]
pub struct AuthUser(User);

impl AuthUser {
pub fn from_current_user(user: CurrentUser) -> Self {
Self(user.inner)
}

pub fn resolve_root_for_rootpw() -> Result<Self, Error> {
Ok(Self(
User::from_uid(UserId::ROOT)?.ok_or(Error::UserNotFound("current user".to_string()))?,
))
}
}

impl ops::Deref for AuthUser {
type Target = User;

fn deref(&self) -> &Self::Target {
&self.0
}
}

type Shell = Option<PathBuf>;

pub(super) fn resolve_launch_and_shell(
Expand Down
1 change: 1 addition & 0 deletions src/defaults/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ defaults! {
use_pty = true
visiblepw = false
env_editor = true
rootpw = false

passwd_tries = 3 [0..=1000]

Expand Down
5 changes: 4 additions & 1 deletion src/sudo/env/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::common::resolve::CurrentUser;
use crate::common::resolve::{AuthUser, CurrentUser};
use crate::common::{CommandAndArguments, Context};
use crate::sudo::{
cli::{SudoAction, SudoRunOptions},
Expand Down Expand Up @@ -94,6 +94,8 @@ fn create_test_context(sudo_options: &SudoRunOptions) -> Context {
groups: vec![],
});

let auth_user = AuthUser::from_current_user(current_user.clone());

let current_group = Group {
gid: GroupId::new(1000),
name: "test".to_string(),
Expand All @@ -119,6 +121,7 @@ fn create_test_context(sudo_options: &SudoRunOptions) -> Context {
hostname: Hostname::fake("test-ubuntu"),
command,
current_user: current_user.clone(),
auth_user,
target_user: if sudo_options.user.as_deref() == Some("test") {
current_user.into()
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/sudo/pam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl PamAuthenticator<CLIConverser> {
matches!(context.launch, LaunchType::Shell),
context.stdin,
context.non_interactive,
&context.current_user.name,
&context.auth_user.name,
&context.current_user.name,
)
})
Expand Down
3 changes: 2 additions & 1 deletion src/sudo/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ fn build_context(
let secure_path: String = pre
.secure_path()
.unwrap_or_else(|| std::env::var("PATH").unwrap_or_default());
Context::build_from_options(cmd_opts, secure_path)
let rootpw = pre.rootpw();
Context::build_from_options(cmd_opts, secure_path, rootpw)
}

/// This should determine what the authentication status for the given record
Expand Down
5 changes: 5 additions & 0 deletions src/sudoers/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ impl Policy for Judgement {

pub trait PreJudgementPolicy {
fn secure_path(&self) -> Option<String>;
fn rootpw(&self) -> bool;
fn validate_authorization(&self) -> Authorization;
}

Expand All @@ -106,6 +107,10 @@ impl PreJudgementPolicy for Sudoers {
.map(|s| s.to_string())
}

fn rootpw(&self) -> bool {
self.settings.flags.contains("rootpw")
}

fn validate_authorization(&self) -> Authorization {
Authorization::Allowed(AuthorizationAllowed {
must_authenticate: true,
Expand Down

0 comments on commit 66f3609

Please sign in to comment.