diff --git a/.github/workflows/build2.yaml b/.github/workflows/build2.yaml index 9bb2ae6..f5b8da0 100644 --- a/.github/workflows/build2.yaml +++ b/.github/workflows/build2.yaml @@ -28,6 +28,7 @@ jobs: - name: test run: | + id whoami set echo $HOME diff --git a/build.zig b/build.zig index d1310ef..d13b1da 100644 --- a/build.zig +++ b/build.zig @@ -51,6 +51,8 @@ pub fn build(b: *std.Build) !void { const test_step = b.step("test", "Run tests"); const uid = b.option(u32, "uid", "uid to run as") orelse 1001; + const gid = b.option(u32, "gid", "gid to run as") orelse 1001; + const groups = b.option([]const u8, "groups", "list of supplemental groups") orelse "1001"; const username = b.option([]const u8, "username", "username to run as") orelse "github"; const tail = tail: { const tail = b.option([]const u8, "tail", "real tail binary") orelse try find(b, "tail"); @@ -63,6 +65,16 @@ pub fn build(b: *std.Build) !void { const options = b.addOptions(); options.addOption(u32, "uid", uid); + options.addOption(u32, "gid", gid); + options.addOption([]const u32, "groups", groups: { + var list: std.ArrayList(u32) = .empty; + var it = std.mem.splitScalar(u8, groups, ','); + while (it.next()) |v| { + const g = try std.fmt.parseUnsigned(u32, v, 10); + try list.append(b.allocator, g); + } + break :groups list.items; + }); options.addOption([]const u8, "username", username); options.addOption([]const u8, "tail", tail); options.addOption([]const u8, "nix", nix); diff --git a/flake.nix b/flake.nix index 19057be..7722a84 100644 --- a/flake.nix +++ b/flake.nix @@ -120,6 +120,7 @@ pkgs.nushell pkgs.pinact pkgs.podman + pkgs.procps pkgs.reuse pkgs.regctl pkgs.stdenv.cc.cc.lib @@ -488,6 +489,15 @@ let execas-github = pkgs.callPackage ./package.nix { uid = 1001; + gid = 1001; + groups = lib.concatStringsSep "," ( + map toString [ + groups.wheel.gid + groups.github.gid + groups.nixbld.gid + ] + ); + username = "github"; zig = zig.packages.${pkgs.stdenv.hostPlatform.system}.master; }; in diff --git a/package.nix b/package.nix index ce34772..e9c6c73 100644 --- a/package.nix +++ b/package.nix @@ -6,7 +6,10 @@ stdenv, zig, uid, - coreutils, + gid, + username, + groups, + coreutils-full, bashInteractive, nix, ... @@ -19,7 +22,10 @@ stdenv.mkDerivation (finalAttrs: { ]; zigBuildFlags = [ "-Duid=${toString uid}" - "-Dtail=${lib.getExe' coreutils "tail"}" + "-Dgid=${toString gid}" + "-Dgroups=${groups}" + "-Dusername=${username}" + "-Dtail=${lib.getExe' coreutils-full "tail"}" "-Dnix=${lib.getExe' nix "nix"}" "-Dbash=${lib.getExe' bashInteractive "bash"}" ]; diff --git a/src/lib/env.zig b/src/lib/env.zig index 3c99af6..8dc0750 100644 --- a/src/lib/env.zig +++ b/src/lib/env.zig @@ -21,7 +21,7 @@ pub fn fixupEnvironMap(alloc: std.mem.Allocator, old: *const std.process.Environ defer writer.deinit(); while (it.next()) |entry| : (index += 1) { - if (index != 0) try writer.writer.writeByte(std.fs.path.sep); + if (index != 0) try writer.writer.writeByte(':'); try writer.writer.writeAll(entry); } diff --git a/src/lib/setuid.zig b/src/lib/setuid.zig index b1b8fd2..95b59c1 100644 --- a/src/lib/setuid.zig +++ b/src/lib/setuid.zig @@ -5,13 +5,37 @@ const std = @import("std"); const options = @import("options"); pub fn setUID() !void { - const rc = std.os.linux.setuid(options.uid); - switch (std.os.linux.errno(rc)) { - .SUCCESS => return, - .PERM => return error.NoPermission, - else => |err| { - std.debug.print("unexpected error: {t}\n", .{err}); - return error.UnexpectedError; - }, + { + const rc = std.os.linux.setgroups(options.groups.len, options.groups.ptr); + switch (std.os.linux.errno(rc)) { + .SUCCESS => {}, + .PERM => return error.NoPermission, + else => |err| { + std.debug.print("unexpected error: {t}\n", .{err}); + return error.UnexpectedError; + }, + } + } + { + const rc = std.os.linux.setgid(options.gid); + switch (std.os.linux.errno(rc)) { + .SUCCESS => {}, + .PERM => return error.NoPermission, + else => |err| { + std.debug.print("unexpected error: {t}\n", .{err}); + return error.UnexpectedError; + }, + } + } + { + const rc = std.os.linux.setuid(options.uid); + switch (std.os.linux.errno(rc)) { + .SUCCESS => {}, + .PERM => return error.NoPermission, + else => |err| { + std.debug.print("unexpected error: {t}\n", .{err}); + return error.UnexpectedError; + }, + } } }