Skip to content

Commit 8bc7a48

Browse files
committed
On Linux, there is no clearly established "default", but "nano" and "vi"
are obvious choices. Let's use a `Defaults editor` value that reflect this. (Making choices at compile-time instead of through configuration files is anachronistic in ogsudo as well.) On FreeBSD, "vi" comes with the base system so is the clear default.
1 parent 29946bf commit 8bc7a48

File tree

5 files changed

+20
-13
lines changed

5 files changed

+20
-13
lines changed

docs/man/sudoers.5.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ sudo's behavior can be modified by Default_Entry lines, as explained earlier. A
430430

431431
* editor
432432

433-
A colon (‘:’) separated list of editor path names used by **sudoedit** and **visudo**. For **sudoedit**, this list is used to find an editor when none of the SUDO_EDITOR, VISUAL or EDITOR environment variables are set to an editor that exists and is executable. For **visudo**, it is used as a white list of allowed editors; **visudo** will choose the editor that matches the user's SUDO_EDITOR, VISUAL or EDITOR environment variable if possible, or the first editor in the list that exists and is executable if not. Unless invoked as **sudoedit**, sudo does not preserve the SUDO_EDITOR, VISUAL or EDITOR environment variables unless they are present in the **env_keep** list. The default on Linux is _/usr/bin/editor_, on FreeBSD _/usr/vim/vi_.
433+
A colon (‘:’) separated list of editor path names used by **sudoedit** and **visudo**. For **sudoedit**, this list is used to find an editor when none of the SUDO_EDITOR, VISUAL or EDITOR environment variables are set to an editor that exists and is executable. For **visudo**, it is used as a white list of allowed editors; **visudo** will choose the editor that matches the user's SUDO_EDITOR, VISUAL or EDITOR environment variable if possible, or the first editor in the list that exists and is executable if not. Unless invoked as **sudoedit**, sudo does not preserve the SUDO_EDITOR, VISUAL or EDITOR environment variables unless they are present in the **env_keep** list. The default on Linux is _/usr/bin/editor:/usr/bin/nano:/usr/bin/vi_. On FreeBSD the default is _/usr/bin/vi_.
434434

435435
## Strings that can be used in a boolean context:
436436

src/defaults/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use settings_dsl::{
2222
};
2323

2424
pub const SYSTEM_EDITOR: &str = if cfg!(target_os = "linux") {
25-
"/usr/bin/editor"
25+
"/usr/bin/editor:/usr/bin/nano:/usr/bin/vi"
2626
} else {
2727
"/usr/bin/vi"
2828
};

src/sudoers/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ impl Sudoers {
295295
on_host: &system::Hostname,
296296
am_user: &User,
297297
target_user: &User,
298-
) -> PathBuf {
298+
) -> Option<PathBuf> {
299299
self.specify_host_user_runas(on_host, am_user, Some(target_user));
300300

301301
select_editor(&self.settings, self.settings.env_editor())
@@ -304,7 +304,7 @@ impl Sudoers {
304304

305305
/// Retrieve the chosen editor from a settings object, filtering based on whether the
306306
/// environment is trusted (sudoedit) or maybe less so (visudo)
307-
fn select_editor(settings: &Settings, trusted_env: bool) -> PathBuf {
307+
fn select_editor(settings: &Settings, trusted_env: bool) -> Option<PathBuf> {
308308
let blessed_editors = settings.editor();
309309

310310
let is_whitelisted = |path: &Path| -> bool {
@@ -329,7 +329,7 @@ fn select_editor(settings: &Settings, trusted_env: bool) -> PathBuf {
329329
};
330330

331331
if is_whitelisted(&editor) {
332-
return editor;
332+
return Some(editor);
333333
}
334334
}
335335
}
@@ -339,13 +339,11 @@ fn select_editor(settings: &Settings, trusted_env: bool) -> PathBuf {
339339
for editor in blessed_editors.split(':') {
340340
let editor = PathBuf::from(editor);
341341
if is_valid_executable(&editor) {
342-
return editor;
342+
return Some(editor);
343343
}
344344
}
345345

346-
// fallback on hardcoded path -- always provide something to the caller
347-
348-
PathBuf::from(defaults::SYSTEM_EDITOR)
346+
None
349347
}
350348

351349
// a `take_while` variant that does not consume the first non-matching item

src/sudoers/policy.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ impl Judgement {
147147
}
148148

149149
pub(crate) fn preferred_editor(&self) -> std::path::PathBuf {
150+
//if no editor could be selected, fall back to /bin/vi;
151+
//note that /bin/vi is also likely to have been tried as part of
152+
//the "editor" setting, so this is a last-resort
150153
super::select_editor(&self.settings, true)
154+
.unwrap_or_else(|| std::path::PathBuf::from("/usr/bin/vi"))
151155
}
152156
}
153157

src/visudo/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ fn edit_sudoers_file(
260260

261261
let host_name = Hostname::resolve();
262262

263-
let editor_path = if existed {
263+
let Some(editor_path) = (if existed {
264264
// If the sudoers file existed, read its contents and write them into the temporary file.
265265
sudoers_file.read_to_end(&mut sudoers_contents)?;
266266
// Rewind the sudoers file so it can be written later.
@@ -270,10 +270,15 @@ fn edit_sudoers_file(
270270

271271
let (sudoers, _errors) = Sudoers::read(sudoers_contents.as_slice(), sudoers_path)?;
272272

273-
sudoers.visudo_editor_path(&host_name, &current_user, &current_user)
273+
sudoers
274274
} else {
275-
// there is no /etc/sudoers config yet, so use a system default
276-
PathBuf::from(crate::defaults::SYSTEM_EDITOR)
275+
Default::default()
276+
})
277+
.visudo_editor_path(&host_name, &current_user, &current_user) else {
278+
return Err(io::Error::new(
279+
io::ErrorKind::NotFound,
280+
"no usable editor could be found",
281+
));
277282
};
278283

279284
loop {

0 commit comments

Comments
 (0)