Skip to content

Commit c861be2

Browse files
authored
Give better catchable error messages for ignored tags (#1401)
2 parents 501f2a4 + ffb8515 commit c861be2

File tree

3 files changed

+47
-27
lines changed

3 files changed

+47
-27
lines changed

src/sudoers/ast.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ pub struct Tag {
118118
pub(super) env: EnvironmentControl,
119119
pub(super) apparmor_profile: Option<String>,
120120
pub(super) noexec: ExecControl,
121+
pub(super) ignored: Vec<Span>,
121122
}
122123

123124
impl Tag {
@@ -388,25 +389,6 @@ impl Parse for MetaOrTag {
388389
};
389390

390391
let result: Modifier = match keyword.as_str() {
391-
// we do not support this, and that should make sudo-rs "fail safe"
392-
"INTERCEPT" => unrecoverable!(
393-
pos = start_pos,
394-
stream,
395-
"INTERCEPT is not supported by sudo-rs"
396-
),
397-
// this is less fatal
398-
"LOG_INPUT" | "NOLOG_INPUT" | "LOG_OUTPUT" | "NOLOG_OUTPUT" | "MAIL" | "NOMAIL"
399-
| "FOLLOW" => {
400-
eprintln_ignore_io_error!(
401-
"sudo-rs: {} tags in the sudoers policy are ignored",
402-
keyword.as_str()
403-
);
404-
switch(|_| {})?
405-
}
406-
407-
// 'NOFOLLOW' and 'NOINTERCEPT' are the default behaviour.
408-
"NOFOLLOW" | "NOINTERCEPT" => switch(|_| {})?,
409-
410392
"EXEC" => switch(|tag| tag.noexec = ExecControl::Exec)?,
411393
"NOEXEC" => switch(|tag| tag.noexec = ExecControl::Noexec)?,
412394

@@ -420,18 +402,35 @@ impl Parse for MetaOrTag {
420402
let path: ChDir = expect_nonterminal(stream)?;
421403
Box::new(move |tag| tag.cwd = Some(path.clone()))
422404
}
405+
423406
// we do not support these, and that should make sudo-rs "fail safe"
424-
spec @ ("CHROOT" | "TIMEOUT" | "NOTBEFORE" | "NOTAFTER") => unrecoverable!(
425-
pos = start_pos,
426-
stream,
427-
"{spec} is not supported by sudo-rs"
428-
),
407+
spec @ ("INTERCEPT" | "CHROOT" | "TIMEOUT" | "NOTBEFORE" | "NOTAFTER") => {
408+
unrecoverable!(
409+
pos = start_pos,
410+
stream,
411+
"{spec} is not supported by sudo-rs"
412+
)
413+
}
429414
"ROLE" | "TYPE" => unrecoverable!(
430415
pos = start_pos,
431416
stream,
432417
"SELinux role based access control is not yet supported by sudo-rs"
433418
),
434419

420+
// this is less fatal
421+
"LOG_INPUT" | "NOLOG_INPUT" | "LOG_OUTPUT" | "NOLOG_OUTPUT" | "MAIL" | "NOMAIL"
422+
| "FOLLOW" => {
423+
let ignored_location = Span {
424+
start: start_pos,
425+
end: stream.get_pos(),
426+
};
427+
expect_syntax(':', stream)?;
428+
Box::new(move |tag| tag.ignored.push(ignored_location))
429+
}
430+
431+
// 'NOFOLLOW' and 'NOINTERCEPT' are the default behaviour.
432+
"NOFOLLOW" | "NOINTERCEPT" => switch(|_| {})?,
433+
435434
"APPARMOR_PROFILE" => {
436435
expect_syntax('=', stream)?;
437436
let StringParameter(profile) = expect_nonterminal(stream)?;

src/sudoers/basic_parser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
/// Type holding a parsed object (or error information if parsing failed)
2929
pub type Parsed<T> = Result<T, Status>;
3030

31-
#[derive(Copy, Clone)]
32-
#[cfg_attr(test, derive(Debug, PartialEq))]
31+
#[derive(Copy, Clone, PartialEq)]
32+
#[cfg_attr(test, derive(Debug, Eq))]
3333
pub struct Span {
3434
pub start: (usize, usize),
3535
pub end: (usize, usize),

src/sudoers/mod.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,14 @@ fn analyze(
741741
Ok(line) => match line {
742742
Sudo::LineComment => {}
743743

744-
Sudo::Spec(permission) => cfg.rules.push(permission),
744+
Sudo::Spec(permission) => {
745+
diagnostics.extend(get_ignored_tags(&permission).map(|span| Error {
746+
source: Some(cur_path.to_owned()),
747+
location: Some(span),
748+
message: "this tag is ignored by sudo-rs".to_string(),
749+
}));
750+
cfg.rules.push(permission);
751+
}
745752

746753
Sudo::Decl(HostAlias(mut def)) => cfg.aliases.host.1.append(&mut def),
747754
Sudo::Decl(UserAlias(mut def)) => cfg.aliases.user.1.append(&mut def),
@@ -828,6 +835,20 @@ fn analyze(
828835
}
829836
}
830837

838+
fn get_ignored_tags(
839+
PermissionSpec { permissions, .. }: &PermissionSpec,
840+
) -> impl Iterator<Item = Span> + '_ {
841+
permissions
842+
.iter()
843+
.flat_map(|(_host, runas_cmds)| runas_cmds)
844+
.flat_map(|(_runas, CommandSpec(tags, _cmd))| tags)
845+
.flat_map(|modifier| {
846+
let mut tag = Tag::default();
847+
modifier(&mut tag);
848+
tag.ignored
849+
})
850+
}
851+
831852
let mut diagnostics = vec![];
832853
process(&mut result, path, sudoers, &mut diagnostics, &mut 0);
833854

0 commit comments

Comments
 (0)