From b01fe3f6c57ff42c9c98ef380c5757632444543a Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sat, 23 Apr 2022 12:39:43 -0400 Subject: [PATCH] chown: allow setting arbitrary numeric user ID Update `chown` to allow setting the owner of a file to a numeric user ID regardless of whether a corresponding username exists on the system. For example, $ touch f && sudo chown 12345 f succeeds even though there is no named user with ID 12345. Fixes #3380. --- src/uu/chown/src/chown.rs | 15 +++++++++++---- tests/by-util/test_chown.rs | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 3add9df1f06..c5869612165 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -197,10 +197,17 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option, Option)> { // So, try to parse it this way return parse_spec(spec, '.'); } else { - return Err(USimpleError::new( - 1, - format!("invalid user: {}", spec.quote()), - )); + // It's possible that the `user` string contains a + // numeric user ID, in which case, we respect that. + match user.parse() { + Ok(uid) => uid, + Err(_) => { + return Err(USimpleError::new( + 1, + format!("invalid user: {}", spec.quote()), + )) + } + } } } }) diff --git a/tests/by-util/test_chown.rs b/tests/by-util/test_chown.rs index 4470260f439..ccaf103938d 100644 --- a/tests/by-util/test_chown.rs +++ b/tests/by-util/test_chown.rs @@ -418,6 +418,27 @@ fn test_chown_only_user_id() { .stderr_contains(&"failed to change"); } +/// Test for setting the owner to a user ID for a user that does not exist. +/// +/// For example: +/// +/// $ touch f && chown 12345 f +/// +/// succeeds with exit status 0 and outputs nothing. The owner of the +/// file is set to 12345, even though no user with that ID exists. +/// +/// This test must be run as root, because only the root user can +/// transfer ownership of a file. +#[test] +fn test_chown_only_user_id_nonexistent_user() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("f"); + ucmd.args(&["12345", "f"]) + .succeeds() + .no_stdout() + .no_stderr(); +} + #[test] // FixME: stderr = chown: ownership of 'test_chown_file1' retained as cuuser:wheel #[cfg(not(target_os = "freebsd"))]