diff --git a/hosts/common/polyunfill.nix b/hosts/common/polyunfill.nix index 57df50ff..a616a6f1 100644 --- a/hosts/common/polyunfill.nix +++ b/hosts/common/polyunfill.nix @@ -1,24 +1,125 @@ # strictly *decrease* the scope of the default nixos installation/config -{ lib, ... }: +{ lib, pkgs, ... }: +let + mkPrio = p: p.overrideAttrs (upstream: { + meta = (upstream.meta or {}) // { + # shadow the unpatched PAM with my patched PAM + priority = ((upstream.meta or {}).priority or 0) - 1; + }; + }); + suidlessPam = pkgs.pam.overrideAttrs (upstream: { + # nixpkgs' pam hardcodes unix_chkpwd path to the /run/wrappers one, + # but i don't want the wrapper, so undo that. + # ideally i would patch this via an overlay, but pam is in the bootstrap so that forces a full rebuild. + # TODO: add a `package` option to the nixos' pam module and substitute it that way. + postPatch = (if upstream.postPatch != null then upstream.postPatch else "") + '' + substituteInPlace modules/pam_unix/Makefile.am --replace-fail \ + "/run/wrappers/bin/unix_chkpwd" "$out/bin/unix_chkpwd" + ''; + }); + useSuidlessPam = p: p.override { pam = suidlessPam; }; +in { # remove a few items from /run/wrappers we don't need. - # these were populated by options.security.wrappers = lib.mkOption { apply = lib.filterAttrs (name: _: !(builtins.elem name [ + # from "newgidmap" "newgrp" "newuidmap" # "sg" # "su" + # from: + # requires associated `pam` patch to not hardcode unix_chkpwd path + "unix_chkpwd" + ])); + }; + options.security.pam.services = lib.mkOption { + apply = lib.filterAttrs (name: _: !(builtins.elem name [ + # from + "i3lock" + "i3lock-color" + "vlock" + "xlock" + "xscreensaver" + "runuser" + "runuser-l" + # from ?? + "chfn" + "chpasswd" + "chsh" + "groupadd" + "groupdel" + "groupmems" + "groupmod" + "useradd" + "userdel" + "usermod" ])); }; config = { - # from: - # removing this from /run/wrappers altogether is possible, but would require a full rebuild of pam - # (effectively a rebuild of the world) because it hardcodes that path - security.wrappers.unix_chkpwd.setuid = lib.mkForce false; + # TODO: do this generically (via option `apply`?) + security.pam.services.cups.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.cups.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.cups.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.cups.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.cups.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.login.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.login.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.login.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.login.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.login.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.other.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.other.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.other.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.other.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.other.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.passwd.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.passwd.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.passwd.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.passwd.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.passwd.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.polkit-1.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.polkit-1.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.polkit-1.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.polkit-1.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.polkit-1.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.sshd.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sshd.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + # security.pam.services.sshd.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sshd.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sshd.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.su.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.su.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.su.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.su.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.su.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.sudo.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sudo.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sudo.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sudo.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.sudo.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.swaylock.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.swaylock.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.swaylock.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.swaylock.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.swaylock.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + + security.pam.services.systemd-user.rules.account.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.systemd-user.rules.auth.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + # security.pam.services.systemd-user.rules.auth.unix-early.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.systemd-user.rules.password.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; + security.pam.services.systemd-user.rules.session.unix.modulePath = lib.mkForce "${suidlessPam}/lib/security/pam_unix.so"; # disable non-required packages like nano, perl, rsync, strace environment.defaultPackages = []; diff --git a/hosts/common/programs/assorted.nix b/hosts/common/programs/assorted.nix index a70bf07f..b48252b2 100644 --- a/hosts/common/programs/assorted.nix +++ b/hosts/common/programs/assorted.nix @@ -807,8 +807,6 @@ in sequoia.sandbox.whitelistPwd = true; sequoia.sandbox.autodetectCliPaths = true; - shadow.sandbox.enable = false; #< `login` can't be sandboxed, since it starts an interactive user session - shattered-pixel-dungeon.buildCost = 1; shattered-pixel-dungeon.persist.byStore.plaintext = [ ".local/share/.shatteredpixel/shattered-pixel-dungeon" ]; shattered-pixel-dungeon.sandbox.method = "bwrap"; diff --git a/hosts/common/programs/default.nix b/hosts/common/programs/default.nix index 58c50f2c..44eef4bf 100644 --- a/hosts/common/programs/default.nix +++ b/hosts/common/programs/default.nix @@ -110,6 +110,7 @@ ./sanebox.nix ./schlock.nix ./sfeed.nix + ./shadow.nix ./signal-desktop.nix ./splatmoji.nix ./spot.nix diff --git a/hosts/common/programs/shadow.nix b/hosts/common/programs/shadow.nix new file mode 100644 index 00000000..f3fad228 --- /dev/null +++ b/hosts/common/programs/shadow.nix @@ -0,0 +1,11 @@ +{ config, ... }: +let + cfg = config.sane.programs.shadow; +in +{ + sane.programs.shadow = { + sandbox.enable = false; #< `login` can't be sandboxed because it launches a user shell + }; + + services.getty.loginProgram = "${cfg.package}/bin/login"; +}