Skip to content

Commit 18a50ff

Browse files
frendsicksylvestre
andauthored
id: Fix incorrect human-readable output (#7814)
Co-authored-by: Sylvestre Ledru <[email protected]>
1 parent efa1aa7 commit 18a50ff

File tree

4 files changed

+69
-14
lines changed

4 files changed

+69
-14
lines changed

src/uu/id/locales/en-US.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,5 @@ id-output-uid = uid
4848
id-output-groups = groups
4949
id-output-login = login
5050
id-output-euid = euid
51+
id-output-rgid = rgid
5152
id-output-context = context

src/uu/id/locales/fr-FR.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,5 @@ id-output-uid = uid
4848
id-output-groups = groupes
4949
id-output-login = connexion
5050
id-output-euid = euid
51+
id-output-rgid = rgid
5152
id-output-context = contexte

src/uu/id/src/id.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
55

6-
// spell-checker:ignore (ToDO) asid auditid auditinfo auid cstr egid emod euid getaudit getlogin gflag nflag pline rflag termid uflag gsflag zflag cflag
6+
// spell-checker:ignore (ToDO) asid auditid auditinfo auid cstr egid rgid emod euid getaudit getlogin gflag nflag pline rflag termid uflag gsflag zflag cflag
77

88
// README:
99
// This was originally based on BSD's `id`
@@ -474,31 +474,32 @@ fn pretty(possible_pw: Option<Passwd>) {
474474
);
475475
} else {
476476
let login = cstr2cow!(getlogin().cast_const());
477-
let rid = getuid();
478-
if let Ok(p) = Passwd::locate(rid) {
477+
let uid = getuid();
478+
if let Ok(p) = Passwd::locate(uid) {
479479
if let Some(user_name) = login {
480480
println!("{}\t{user_name}", translate!("id-output-login"));
481481
}
482482
println!("{}\t{}", translate!("id-output-uid"), p.name);
483483
} else {
484-
println!("{}\t{rid}", translate!("id-output-uid"));
484+
println!("{}\t{uid}", translate!("id-output-uid"));
485485
}
486486

487-
let eid = getegid();
488-
if eid == rid {
489-
if let Ok(p) = Passwd::locate(eid) {
487+
let euid = geteuid();
488+
if euid != uid {
489+
if let Ok(p) = Passwd::locate(euid) {
490490
println!("{}\t{}", translate!("id-output-euid"), p.name);
491491
} else {
492-
println!("{}\t{eid}", translate!("id-output-euid"));
492+
println!("{}\t{euid}", translate!("id-output-euid"));
493493
}
494494
}
495495

496-
let rid = getgid();
497-
if rid != eid {
498-
if let Ok(g) = Group::locate(rid) {
499-
println!("{}\t{}", translate!("id-output-euid"), g.name);
496+
let rgid = getgid();
497+
let egid = getegid();
498+
if egid != rgid {
499+
if let Ok(g) = Group::locate(rgid) {
500+
println!("{}\t{}", translate!("id-output-rgid"), g.name);
500501
} else {
501-
println!("{}\t{rid}", translate!("id-output-euid"));
502+
println!("{}\t{rgid}", translate!("id-output-rgid"));
502503
}
503504
}
504505

tests/by-util/test_id.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
55

6-
// spell-checker:ignore (ToDO) coreutil
6+
// spell-checker:ignore (ToDO) coreutil euid rgid
77

88
use std::process::{Command, Stdio};
99
use uutests::new_ucmd;
1010
use uutests::unwrap_or_return;
1111
use uutests::util::{TestScenario, check_coreutil_version, expected_result, is_ci, whoami};
1212
use uutests::util_name;
1313

14+
#[cfg(all(feature = "chmod", feature = "chown"))]
15+
use tempfile::TempPath;
16+
1417
const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31
1518

1619
#[test]
@@ -477,6 +480,55 @@ fn test_id_pretty_print_password_record() {
477480
.stderr_contains("the argument '-p' cannot be used with '-P'");
478481
}
479482

483+
#[test]
484+
#[cfg(all(feature = "chmod", feature = "chown"))]
485+
fn test_id_pretty_print_suid_binary() {
486+
use uucore::process::{getgid, getuid};
487+
488+
if let Some(suid_coreutils_path) = create_root_owned_suid_coreutils_binary() {
489+
let result = TestScenario::new(util_name!())
490+
.cmd(suid_coreutils_path.to_str().unwrap())
491+
.args(&[util_name!(), "-p"])
492+
.succeeds();
493+
494+
// The `euid` line should be present only if the real UID does not belong to `root`
495+
if getuid() == 0 {
496+
result.stdout_does_not_contain("euid\t");
497+
} else {
498+
result.stdout_contains_line("euid\troot");
499+
}
500+
501+
// The `rgid` line should be present only if the real GID does not belong to `root`
502+
if getgid() == 0 {
503+
result.stdout_does_not_contain("rgid\t");
504+
} else {
505+
result.stdout_contains("rgid\t");
506+
}
507+
} else {
508+
print!("Test skipped; requires root user");
509+
}
510+
}
511+
512+
/// Create SUID temp file owned by `root:root` with the contents of the `coreutils` binary
513+
#[cfg(all(feature = "chmod", feature = "chown"))]
514+
fn create_root_owned_suid_coreutils_binary() -> Option<TempPath> {
515+
use std::fs::read;
516+
use std::io::Write;
517+
use tempfile::NamedTempFile;
518+
use uutests::util::{get_tests_binary, run_ucmd_as_root};
519+
520+
let mut temp_file = NamedTempFile::new().unwrap();
521+
let coreutils_binary = read(get_tests_binary()).unwrap();
522+
temp_file.write_all(&coreutils_binary).unwrap();
523+
let temp_path = temp_file.into_temp_path();
524+
let temp_path_str = temp_path.to_str().unwrap();
525+
526+
run_ucmd_as_root(&TestScenario::new("chown"), &["root:root", temp_path_str]).ok()?;
527+
run_ucmd_as_root(&TestScenario::new("chmod"), &["+xs", temp_path_str]).ok()?;
528+
529+
Some(temp_path)
530+
}
531+
480532
/// This test requires user with username 200 on system
481533
#[test]
482534
#[cfg(unix)]

0 commit comments

Comments
 (0)