id: fix error handling for id_print()

This commit is contained in:
Jan Scheer 2021-07-13 10:40:07 +02:00
parent 7abc6a665e
commit 36a192c5f6
No known key found for this signature in database
GPG key ID: C62AD4C29E2B9828
2 changed files with 62 additions and 18 deletions

View file

@ -118,6 +118,7 @@ struct State {
// 1000 10 968 975 // 1000 10 968 975
// +++ exited with 0 +++ // +++ exited with 0 +++
user_specified: bool, user_specified: bool,
exit_code: i32,
} }
pub fn uumain(args: impl uucore::Args) -> i32 { pub fn uumain(args: impl uucore::Args) -> i32 {
@ -155,6 +156,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
}, },
user_specified: !users.is_empty(), user_specified: !users.is_empty(),
ids: None, ids: None,
exit_code: 0,
}; };
let default_format = { let default_format = {
@ -187,7 +189,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
'\n' '\n'
} }
}; };
let mut exit_code = 0;
if state.cflag { if state.cflag {
if state.selinux_supported { if state.selinux_supported {
@ -200,7 +201,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
// print error because `cflag` was explicitly requested // print error because `cflag` was explicitly requested
crash!(1, "can't get process context"); crash!(1, "can't get process context");
} }
return exit_code; return state.exit_code;
} else { } else {
crash!(1, "--context (-Z) works only on an SELinux-enabled kernel"); crash!(1, "--context (-Z) works only on an SELinux-enabled kernel");
} }
@ -214,7 +215,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
Ok(p) => Some(p), Ok(p) => Some(p),
Err(_) => { Err(_) => {
show_error!("'{}': no such user", users[i]); show_error!("'{}': no such user", users[i]);
exit_code = 1; state.exit_code = 1;
if i + 1 >= users.len() { if i + 1 >= users.len() {
break; break;
} else { } else {
@ -228,17 +229,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
if matches.is_present(options::OPT_PASSWORD) { if matches.is_present(options::OPT_PASSWORD) {
// BSD's `id` ignores all but the first specified user // BSD's `id` ignores all but the first specified user
pline(possible_pw.map(|v| v.uid())); pline(possible_pw.map(|v| v.uid()));
return exit_code; return state.exit_code;
}; };
if matches.is_present(options::OPT_HUMAN_READABLE) { if matches.is_present(options::OPT_HUMAN_READABLE) {
// BSD's `id` ignores all but the first specified user // BSD's `id` ignores all but the first specified user
pretty(possible_pw); pretty(possible_pw);
return exit_code; return state.exit_code;
} }
if matches.is_present(options::OPT_AUDIT) { if matches.is_present(options::OPT_AUDIT) {
// BSD's `id` ignores specified users // BSD's `id` ignores specified users
auditid(); auditid();
return exit_code; return state.exit_code;
} }
let (uid, gid) = possible_pw.map(|p| (p.uid(), p.gid())).unwrap_or(( let (uid, gid) = possible_pw.map(|p| (p.uid(), p.gid())).unwrap_or((
@ -258,7 +259,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
if state.nflag { if state.nflag {
entries::gid2grp(gid).unwrap_or_else(|_| { entries::gid2grp(gid).unwrap_or_else(|_| {
show_error!("cannot find name for group ID {}", gid); show_error!("cannot find name for group ID {}", gid);
exit_code = 1; state.exit_code = 1;
gid.to_string() gid.to_string()
}) })
} else { } else {
@ -273,7 +274,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
if state.nflag { if state.nflag {
entries::uid2usr(uid).unwrap_or_else(|_| { entries::uid2usr(uid).unwrap_or_else(|_| {
show_error!("cannot find name for user ID {}", uid); show_error!("cannot find name for user ID {}", uid);
exit_code = 1; state.exit_code = 1;
uid.to_string() uid.to_string()
}) })
} else { } else {
@ -298,7 +299,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
if state.nflag { if state.nflag {
entries::gid2grp(id).unwrap_or_else(|_| { entries::gid2grp(id).unwrap_or_else(|_| {
show_error!("cannot find name for group ID {}", id); show_error!("cannot find name for group ID {}", id);
exit_code = 1; state.exit_code = 1;
id.to_string() id.to_string()
}) })
} else { } else {
@ -317,7 +318,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
} }
if default_format { if default_format {
id_print(&state, groups); id_print(&mut state, groups);
} }
print!("{}", line_ending); print!("{}", line_ending);
@ -326,7 +327,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
} }
} }
exit_code state.exit_code
} }
pub fn uu_app() -> App<'static, 'static> { pub fn uu_app() -> App<'static, 'static> {
@ -543,25 +544,65 @@ fn auditid() {
println!("asid={}", auditinfo.ai_asid); println!("asid={}", auditinfo.ai_asid);
} }
fn id_print(state: &State, groups: Vec<u32>) { fn id_print(state: &mut State, groups: Vec<u32>) {
let uid = state.ids.as_ref().unwrap().uid; let uid = state.ids.as_ref().unwrap().uid;
let gid = state.ids.as_ref().unwrap().gid; let gid = state.ids.as_ref().unwrap().gid;
let euid = state.ids.as_ref().unwrap().euid; let euid = state.ids.as_ref().unwrap().euid;
let egid = state.ids.as_ref().unwrap().egid; let egid = state.ids.as_ref().unwrap().egid;
print!("uid={}({})", uid, entries::uid2usr(uid).unwrap()); print!(
print!(" gid={}({})", gid, entries::gid2grp(gid).unwrap()); "uid={}({})",
uid,
entries::uid2usr(uid).unwrap_or_else(|_| {
show_error!("cannot find name for user ID {}", uid);
state.exit_code = 1;
uid.to_string()
})
);
print!(
" gid={}({})",
gid,
entries::gid2grp(gid).unwrap_or_else(|_| {
show_error!("cannot find name for group ID {}", gid);
state.exit_code = 1;
gid.to_string()
})
);
if !state.user_specified && (euid != uid) { if !state.user_specified && (euid != uid) {
print!(" euid={}({})", euid, entries::uid2usr(euid).unwrap()); print!(
" euid={}({})",
euid,
entries::uid2usr(euid).unwrap_or_else(|_| {
show_error!("cannot find name for user ID {}", euid);
state.exit_code = 1;
euid.to_string()
})
);
} }
if !state.user_specified && (egid != gid) { if !state.user_specified && (egid != gid) {
print!(" egid={}({})", euid, entries::gid2grp(egid).unwrap()); print!(
" egid={}({})",
euid,
entries::gid2grp(egid).unwrap_or_else(|_| {
show_error!("cannot find name for group ID {}", egid);
state.exit_code = 1;
egid.to_string()
})
);
} }
print!( print!(
" groups={}", " groups={}",
groups groups
.iter() .iter()
.map(|&gr| format!("{}({})", gr, entries::gid2grp(gr).unwrap())) .map(|&gr| format!(
"{}({})",
gr,
entries::gid2grp(gr).unwrap_or_else(|_| {
show_error!("cannot find name for group ID {}", gr);
state.exit_code = 1;
gr.to_string()
})
))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(",") .join(",")
); );

View file

@ -431,8 +431,11 @@ fn test_id_no_specified_user_posixly() {
// gnu/tests/id/no-context.sh // gnu/tests/id/no-context.sh
let ts = TestScenario::new(util_name!()); let ts = TestScenario::new(util_name!());
let result = ts.ucmd().env("POSIXLY_CORRECT", "1").succeeds(); let result = ts.ucmd().env("POSIXLY_CORRECT", "1").run();
assert!(!result.stdout_str().contains("context=")); assert!(!result.stdout_str().contains("context="));
if !is_ci() {
result.success();
}
#[cfg(all(target_os = "linux", feature = "feat_selinux"))] #[cfg(all(target_os = "linux", feature = "feat_selinux"))]
{ {