Skip to content

Commit 85b0373

Browse files
committed
add argument resolution
1 parent 43d0f4c commit 85b0373

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

src/common/context.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ pub struct Context {
3434
pub use_pty: bool,
3535
pub noexec: bool,
3636
pub umask: Umask,
37+
// sudoedit
38+
#[cfg_attr(not(feature = "sudoedit"), allow(unused))]
39+
pub files_to_edit: Vec<Option<std::path::PathBuf>>,
3740
}
3841

3942
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
@@ -98,6 +101,7 @@ impl Context {
98101
use_pty: true,
99102
noexec: false,
100103
umask: Umask::Preserve,
104+
files_to_edit: vec![],
101105
})
102106
}
103107

@@ -109,12 +113,35 @@ impl Context {
109113
let (target_user, target_group) =
110114
resolve_target_user_and_group(&sudo_options.user, &sudo_options.group, &current_user)?;
111115

116+
// resolve file arguments; if something can't be resolved, don't add it to the "edit" list
117+
let resolved_args = sudo_options.positional_args.iter().map(|arg| {
118+
std::fs::canonicalize(arg)
119+
.map_err(|_| arg)
120+
.and_then(|path| path.into_os_string().into_string().map_err(|_| arg))
121+
});
122+
123+
let files_to_edit = resolved_args
124+
.clone()
125+
.map(|path| path.ok().map(|path| path.into()))
126+
.collect();
127+
128+
// if a path resolved to something that isn't in UTF-8, it means it isn't in the sudoers file
129+
// as well and so we treat it "as is" wrt. the policy lookup and fail if the user is allowed
130+
// by the policy to edit that file. this is to prevent leaking information.
131+
let arguments = resolved_args
132+
.map(|arg| match arg {
133+
Ok(arg) => arg,
134+
Err(arg) => arg.to_owned(),
135+
})
136+
.collect();
137+
112138
// TODO: the more Rust way of doing things would be to create an alternative for sudoedit instead;
113139
// but a stringly typed interface feels the most decent thing to do (if we can pull it off)
114-
// since "sudoedit" really is like a builtin command to sudo.
140+
// since "sudoedit" really is like a builtin command to sudo. We may want to be a bit 'better' than
141+
// ogsudo in the future.
115142
let command = CommandAndArguments {
116143
command: std::path::PathBuf::from("sudoedit"),
117-
arguments: sudo_options.positional_args,
144+
arguments,
118145
..Default::default()
119146
};
120147

@@ -135,6 +162,7 @@ impl Context {
135162
use_pty: true,
136163
noexec: false,
137164
umask: Umask::Preserve,
165+
files_to_edit,
138166
})
139167
}
140168
pub fn from_validate_opts(sudo_options: SudoValidateOptions) -> Result<Context, Error> {
@@ -160,6 +188,7 @@ impl Context {
160188
use_pty: true,
161189
noexec: false,
162190
umask: Umask::Preserve,
191+
files_to_edit: vec![],
163192
})
164193
}
165194

@@ -206,6 +235,7 @@ impl Context {
206235
use_pty: true,
207236
noexec: false,
208237
umask: Umask::Preserve,
238+
files_to_edit: vec![],
209239
})
210240
}
211241

src/sudo/env/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ fn create_test_context(sudo_options: SudoRunOptions) -> Context {
136136
noexec: false,
137137
bell: false,
138138
umask: Umask::Preserve,
139+
files_to_edit: vec![],
139140
}
140141
}
141142

src/sudo/pipeline/edit.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,19 @@ pub fn run_edit(edit_opts: SudoEditOptions) -> Result<(), Error> {
2121

2222
let pid = context.process.pid;
2323

24+
for (path, arg) in context.files_to_edit.iter().zip(&context.command.arguments) {
25+
if path.is_none() {
26+
eprintln_ignore_io_error!("invalid path: {arg}")
27+
}
28+
}
29+
2430
// run command and return corresponding exit code
2531
let command_exit_reason = {
2632
super::log_command_execution(&context);
2733

2834
eprintln_ignore_io_error!(
2935
"this would launch sudoedit as requested, to edit the files: {:?}",
30-
context.command.arguments.as_slice()
36+
context.files_to_edit.as_slice()
3137
);
3238

3339
Ok::<_, std::io::Error>(ExitReason::Code(42))

0 commit comments

Comments
 (0)