mirror of https://github.com/fairyglade/ly.git
Implement /etc/login.defs in interop, TODO for FreeBSD
We should be able to parse the "minuid" and "maxuid" values in /etc/rc.conf to get the UID range of the system, with default values of 1000 to 32000 (as they don't seem to be present by default). Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
parent
ed88458efd
commit
02f5aa702d
|
|
@ -211,7 +211,8 @@ lang = en
|
||||||
# You can also set environment variables in there, they'll persist until logout
|
# You can also set environment variables in there, they'll persist until logout
|
||||||
login_cmd = null
|
login_cmd = null
|
||||||
|
|
||||||
# Path for login.defs file (used for listing all local users on the system)
|
# Path for login.defs file (used for listing all local users on the system on
|
||||||
|
# Linux)
|
||||||
login_defs_path = /etc/login.defs
|
login_defs_path = /etc/login.defs
|
||||||
|
|
||||||
# Command executed when logging out
|
# Command executed when logging out
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const UidRange = @import("UidRange.zig");
|
||||||
|
|
||||||
pub const termbox = @import("termbox2");
|
pub const termbox = @import("termbox2");
|
||||||
|
|
||||||
|
|
@ -155,6 +156,46 @@ fn PlatformStruct() type {
|
||||||
return error.NoTtyFound;
|
return error.NoTtyFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is very bad parsing, but we only need to get 2 values..
|
||||||
|
// and the format of the file seems to be standard? So this should
|
||||||
|
// be fine...
|
||||||
|
pub fn getUserIdRange(allocator: std.mem.Allocator, file_path: []const u8) !UidRange {
|
||||||
|
const login_defs_file = try std.fs.cwd().openFile(file_path, .{});
|
||||||
|
defer login_defs_file.close();
|
||||||
|
|
||||||
|
const login_defs_buffer = try login_defs_file.readToEndAlloc(allocator, std.math.maxInt(u16));
|
||||||
|
defer allocator.free(login_defs_buffer);
|
||||||
|
|
||||||
|
var iterator = std.mem.splitScalar(u8, login_defs_buffer, '\n');
|
||||||
|
var uid_range = UidRange{};
|
||||||
|
|
||||||
|
while (iterator.next()) |line| {
|
||||||
|
const trimmed_line = std.mem.trim(u8, line, " \n\r\t");
|
||||||
|
|
||||||
|
if (std.mem.startsWith(u8, trimmed_line, "UID_MIN")) {
|
||||||
|
uid_range.uid_min = try parseValue(std.posix.uid_t, "UID_MIN", trimmed_line);
|
||||||
|
} else if (std.mem.startsWith(u8, trimmed_line, "UID_MAX")) {
|
||||||
|
uid_range.uid_max = try parseValue(std.posix.uid_t, "UID_MAX", trimmed_line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uid_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseValue(comptime T: type, name: []const u8, buffer: []const u8) !T {
|
||||||
|
var iterator = std.mem.splitAny(u8, buffer, " \t");
|
||||||
|
var maybe_value: ?T = null;
|
||||||
|
|
||||||
|
while (iterator.next()) |slice| {
|
||||||
|
// Skip the slice if it's empty (whitespace) or is the name of the
|
||||||
|
// property (e.g. UID_MIN or UID_MAX)
|
||||||
|
if (slice.len == 0 or std.mem.eql(u8, slice, name)) continue;
|
||||||
|
maybe_value = std.fmt.parseInt(T, slice, 10) catch continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maybe_value orelse error.ValueNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
fn readBuffer(reader: *std.Io.Reader, buffer: []u8) !usize {
|
fn readBuffer(reader: *std.Io.Reader, buffer: []u8) !usize {
|
||||||
var bytes_read: usize = 0;
|
var bytes_read: usize = 0;
|
||||||
var byte: u8 = try reader.takeByte();
|
var byte: u8 = try reader.takeByte();
|
||||||
|
|
@ -198,6 +239,15 @@ fn PlatformStruct() type {
|
||||||
pub fn getActiveTtyImpl(_: std.mem.Allocator) !u8 {
|
pub fn getActiveTtyImpl(_: std.mem.Allocator) !u8 {
|
||||||
return error.FeatureUnimplemented;
|
return error.FeatureUnimplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getUserIdRange(_: std.mem.Allocator, _: []const u8) !UidRange {
|
||||||
|
return .{
|
||||||
|
// Hardcoded default values chosen from
|
||||||
|
// /usr/src/usr.sbin/pw/pw_conf.c
|
||||||
|
.uid_min = 1000,
|
||||||
|
.uid_max = 32000,
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
else => @compileError("Unsupported target: " ++ builtin.os.tag),
|
else => @compileError("Unsupported target: " ++ builtin.os.tag),
|
||||||
};
|
};
|
||||||
|
|
@ -330,3 +380,9 @@ pub fn getUsernameEntry(username: [:0]const u8) ?UsernameEntry {
|
||||||
pub fn closePasswordDatabase() void {
|
pub fn closePasswordDatabase() void {
|
||||||
pwd.endpwent();
|
pwd.endpwent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is very bad parsing, but we only need to get 2 values... and the format
|
||||||
|
// of the file doesn't seem to be standard? So this should be fine...
|
||||||
|
pub fn getUserIdRange(allocator: std.mem.Allocator, file_path: []const u8) !UidRange {
|
||||||
|
return platform_struct.getUserIdRange(allocator, file_path);
|
||||||
|
}
|
||||||
|
|
|
||||||
42
src/main.zig
42
src/main.zig
|
|
@ -25,7 +25,6 @@ const OldSave = @import("config/OldSave.zig");
|
||||||
const SavedUsers = @import("config/SavedUsers.zig");
|
const SavedUsers = @import("config/SavedUsers.zig");
|
||||||
const migrator = @import("config/migrator.zig");
|
const migrator = @import("config/migrator.zig");
|
||||||
const SharedError = @import("SharedError.zig");
|
const SharedError = @import("SharedError.zig");
|
||||||
const UidRange = @import("UidRange.zig");
|
|
||||||
|
|
||||||
const StringList = std.ArrayListUnmanaged([]const u8);
|
const StringList = std.ArrayListUnmanaged([]const u8);
|
||||||
const Ini = ini.Ini;
|
const Ini = ini.Ini;
|
||||||
|
|
@ -1151,7 +1150,7 @@ fn crawl(session: *Session, lang: Lang, path: []const u8, display_server: Displa
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8) !StringList {
|
fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8) !StringList {
|
||||||
const uid_range = try getUserIdRange(allocator, login_defs_path);
|
const uid_range = try interop.getUserIdRange(allocator, login_defs_path);
|
||||||
|
|
||||||
var usernames: StringList = .empty;
|
var usernames: StringList = .empty;
|
||||||
var maybe_entry = interop.getNextUsernameEntry();
|
var maybe_entry = interop.getNextUsernameEntry();
|
||||||
|
|
@ -1171,45 +1170,6 @@ fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8) !S
|
||||||
return usernames;
|
return usernames;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is very bad parsing, but we only need to get 2 values... and the format
|
|
||||||
// of the file doesn't seem to be standard? So this should be fine...
|
|
||||||
fn getUserIdRange(allocator: std.mem.Allocator, login_defs_path: []const u8) !UidRange {
|
|
||||||
const login_defs_file = try std.fs.cwd().openFile(login_defs_path, .{});
|
|
||||||
defer login_defs_file.close();
|
|
||||||
|
|
||||||
const login_defs_buffer = try login_defs_file.readToEndAlloc(allocator, std.math.maxInt(u16));
|
|
||||||
defer allocator.free(login_defs_buffer);
|
|
||||||
|
|
||||||
var iterator = std.mem.splitScalar(u8, login_defs_buffer, '\n');
|
|
||||||
var uid_range = UidRange{};
|
|
||||||
|
|
||||||
while (iterator.next()) |line| {
|
|
||||||
const trimmed_line = std.mem.trim(u8, line, " \n\r\t");
|
|
||||||
|
|
||||||
if (std.mem.startsWith(u8, trimmed_line, "UID_MIN")) {
|
|
||||||
uid_range.uid_min = try parseValue(std.posix.uid_t, "UID_MIN", trimmed_line);
|
|
||||||
} else if (std.mem.startsWith(u8, trimmed_line, "UID_MAX")) {
|
|
||||||
uid_range.uid_max = try parseValue(std.posix.uid_t, "UID_MAX", trimmed_line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return uid_range;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseValue(comptime T: type, name: []const u8, buffer: []const u8) !T {
|
|
||||||
var iterator = std.mem.splitAny(u8, buffer, " \t");
|
|
||||||
var maybe_value: ?T = null;
|
|
||||||
|
|
||||||
while (iterator.next()) |slice| {
|
|
||||||
// Skip the slice if it's empty (whitespace) or is the name of the
|
|
||||||
// property (e.g. UID_MIN or UID_MAX)
|
|
||||||
if (slice.len == 0 or std.mem.eql(u8, slice, name)) continue;
|
|
||||||
maybe_value = std.fmt.parseInt(T, slice, 10) catch continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return maybe_value orelse error.ValueNotFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
||||||
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
||||||
brightness.stdout_behavior = .Ignore;
|
brightness.stdout_behavior = .Ignore;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue