From 48f8b306db5323b39e4b2763a1d8af0e519b56a0 Mon Sep 17 00:00:00 2001 From: AnErrupTion Date: Thu, 5 Feb 2026 20:07:52 +0100 Subject: [PATCH] [Backport] Better systemd-homed user detection Signed-off-by: AnErrupTion --- src/interop.zig | 16 ---------------- src/main.zig | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/interop.zig b/src/interop.zig index 4d52f49..d55e850 100644 --- a/src/interop.zig +++ b/src/interop.zig @@ -81,9 +81,6 @@ fn PlatformStruct() type { pub const vt_activate = vt.VT_ACTIVATE; pub const vt_waitactive = vt.VT_WAITACTIVE; - const SYSTEMD_HOMED_UID_MIN = 60001; - const SYSTEMD_HOMED_UID_MAX = 60513; - pub fn setUserContextImpl(username: [*:0]const u8, entry: UsernameEntry) !void { const status = grp.initgroups(username, @intCast(entry.gid)); if (status != 0) return error.GroupInitializationFailed; @@ -187,19 +184,6 @@ fn PlatformStruct() type { if (!nameFound) return error.UidNameNotFound; - // This code assumes the OS has a login.defs file with UID_MIN - // and UID_MAX values defined in it, which should be the case - // for most systemd-based Linux distributions out there. - // This should be a good enough safeguard for now, as there's - // no reliable (and clean) way to check for systemd support - if (uid_range.uid_min > SYSTEMD_HOMED_UID_MIN) { - uid_range.uid_min = SYSTEMD_HOMED_UID_MIN; - } - - if (uid_range.uid_max < SYSTEMD_HOMED_UID_MAX) { - uid_range.uid_max = SYSTEMD_HOMED_UID_MAX; - } - return uid_range; } diff --git a/src/main.zig b/src/main.zig index dfbe496..c9da945 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1320,13 +1320,33 @@ fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8, ui }; }; + // There's no reliable (and clean) way to check for systemd support, so + // let's just define a range and check if a user is within it + const SYSTEMD_HOMED_UID_MIN = 60001; + const SYSTEMD_HOMED_UID_MAX = 60513; + const homed_uid_range = UidRange{ + .uid_min = SYSTEMD_HOMED_UID_MIN, + .uid_max = SYSTEMD_HOMED_UID_MAX, + }; + var usernames: StringList = .empty; var maybe_entry = interop.getNextUsernameEntry(); while (maybe_entry) |entry| { // We check if the UID is equal to 0 because we always want to add root // as a username (even if you can't log into it) - if (entry.uid >= uid_range.uid_min and entry.uid <= uid_range.uid_max or entry.uid == 0 and entry.username != null) { + const is_within_range = + entry.uid >= uid_range.uid_min and + entry.uid <= uid_range.uid_max; + const is_within_homed_range = + builtin.os.tag == .linux and + entry.uid >= homed_uid_range.uid_min and + entry.uid <= homed_uid_range.uid_max; + const is_root = + entry.uid == 0 and + entry.username != null; + + if (is_within_range or is_within_homed_range or is_root) { const username = try allocator.dupe(u8, entry.username.?); try usernames.append(allocator, username); }