From 8181d2a7c120902a66ed15824c2d4ad054f06379 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 28 Feb 2025 20:28:25 +0100 Subject: [PATCH 1/2] nixos/user-groups: Don't double-UTF8-encode subUidMapFile Because with it only being single-UTF8-decoded, this lead to the file ~doubling in size whenever it contained any non-ascii characters! --- nixos/modules/config/update-users-groups.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl index f0b692a759d1..a2be448d625b 100644 --- a/nixos/modules/config/update-users-groups.pl +++ b/nixos/modules/config/update-users-groups.pl @@ -376,4 +376,4 @@ foreach my $u (values %usersOut) { updateFile("/etc/subuid", join("\n", @subUids) . "\n"); updateFile("/etc/subgid", join("\n", @subGids) . "\n"); -updateFile($subUidMapFile, encode_json($subUidMap) . "\n"); +updateFile($subUidMapFile, to_json($subUidMap) . "\n"); From b602f8682923e4f71b3a39af68d25bfe1e94693f Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 28 Feb 2025 20:35:33 +0100 Subject: [PATCH 2/2] nixos/users-groups: Catch invalid usernames early Prevents running into the problem from the parent commit in the first place. --- nixos/modules/config/users-groups.nix | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index 0fe5cc357b87..5b05acd7e163 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -931,6 +931,21 @@ in { } ] ++ flatten (flip mapAttrsToList cfg.users (name: user: [ + ( + let + # Things fail in various ways with especially non-ascii usernames. + # This regex mirrors the one from shadow's is_valid_name: + # https://github.com/shadow-maint/shadow/blob/bee77ffc291dfed2a133496db465eaa55e2b0fec/lib/chkname.c#L68 + # though without the trailing $, because Samba 3 got its last release + # over 10 years ago and is not in Nixpkgs anymore, + # while later versions don't appear to require anything like that. + nameRegex = "[a-zA-Z0-9_.][a-zA-Z0-9_.-]*"; + in + { + assertion = builtins.match nameRegex user.name != null; + message = "The username \"${user.name}\" is not valid, it does not match the regex \"${nameRegex}\"."; + } + ) { assertion = (user.hashedPassword != null) -> (match ".*:.*" user.hashedPassword == null);