1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2025-03-06 16:57:08 +00:00

Merge pull request #1344 from Mic92/fix_pam_module

fix: move `pam` configuration to `sudo_local`
This commit is contained in:
Michael Hoang 2025-02-25 10:06:11 +07:00 committed by GitHub
commit 42be12b510
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,69 +1,94 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.security.pam;
# Implementation Notes
#
# We don't use `environment.etc` because this would require that the user manually delete
# `/etc/pam.d/sudo` which seems unwise given that applying the nix-darwin configuration requires
# sudo. We also can't use `system.patchs` since it only runs once, and so won't patch in the
# changes again after OS updates (which remove modifications to this file).
#
# As such, we resort to line addition/deletion in place using `sed`. We add a comment to the
# added line that includes the name of the option, to make it easier to identify the line that
# should be deleted when the option is disabled.
mkSudoTouchIdAuthScript = isEnabled:
let
file = "/etc/pam.d/sudo";
option = "security.pam.enableSudoTouchIdAuth";
sed = "${pkgs.gnused}/bin/sed";
in ''
${if isEnabled then ''
# Enable sudo Touch ID authentication, if not already enabled
if ! grep 'pam_tid.so' ${file} > /dev/null; then
${sed} -i '2i\
auth sufficient pam_tid.so # nix-darwin: ${option}
' ${file}
fi
'' else ''
# Disable sudo Touch ID authentication, if added by nix-darwin
if grep '${option}' ${file} > /dev/null; then
${sed} -i '/${option}/d' ${file}
fi
''}
'';
cfg = config.security.pam.services.sudo_local;
in
{
imports = [
(lib.mkRemovedOptionModule [ "security" "pam" "enableSudoTouchIdAuth" ] ''
This option has been renamed to `security.pam.services.sudo_local.touchIdAuth` for consistency with NixOS.
'')
];
options = {
security.pam.enableSudoTouchIdAuth = mkEnableOption "" // {
description = ''
Enable sudo authentication with Touch ID.
security.pam.services.sudo_local = {
enable = lib.mkEnableOption "managing {file}`/etc/pam.d/sudo_local` with nix-darwin" // {
default = true;
example = false;
};
When enabled, this option adds the following line to
{file}`/etc/pam.d/sudo`:
text = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Contents of {file}`/etc/pam.d/sudo_local`
'';
};
```
auth sufficient pam_tid.so
```
touchIdAuth = lib.mkEnableOption "" // {
description = ''
Whether to enable Touch ID with sudo.
::: {.note}
macOS resets this file when doing a system update. As such, sudo
authentication with Touch ID won't work after a system update
until the nix-darwin configuration is reapplied.
:::
'';
This will also allow your Apple Watch to be used for sudo. If this doesn't work,
you can go into `System Settings > Touch ID & Password` and toggle the switch for
your Apple Watch.
'';
};
reattach = lib.mkEnableOption "" // {
description = ''
Whether to enable reattaching a program to the user's bootstrap session.
This fixes Touch ID for sudo not working inside tmux and screen.
This allows programs like tmux and screen that run in the background to
survive across user sessions to work with PAM services that are tied to the
bootstrap session.
'';
};
};
};
config = {
system.activationScripts.pam.text = ''
security.pam.services.sudo_local.text = lib.concatLines (
(lib.optional cfg.reattach "auth optional ${pkgs.pam-reattach}/lib/pam/pam_reattach.so")
++ (lib.optional cfg.touchIdAuth "auth sufficient pam_tid.so")
);
environment.etc."pam.d/sudo_local" = {
inherit (cfg) enable text;
};
system.activationScripts.pam.text =
let
file = "/etc/pam.d/sudo";
marker = "security.pam.services.sudo_local";
deprecatedOption = "security.pam.enableSudoTouchIdAuth";
sed = lib.getExe pkgs.gnused;
in
''
# PAM settings
echo >&2 "setting up pam..."
${mkSudoTouchIdAuthScript cfg.enableSudoTouchIdAuth}
# REMOVEME when macOS 13 no longer supported as macOS automatically
# nukes this file on system upgrade
# Always clear out older implementation if it is present
if grep '${deprecatedOption}' ${file} > /dev/null; then
${sed} -i '/${deprecatedOption}/d' ${file}
fi
${if cfg.enable then ''
# REMOVEME when macOS 13 no longer supported
# `sudo_local` is automatically included after macOS 14
if ! grep 'sudo_local' ${file} > /dev/null; then
${sed} -i '2iauth include sudo_local # nix-darwin: ${marker}' ${file}
fi
'' else ''
# Remove include line if we added it
if grep '${marker}' ${file} > /dev/null; then
${sed} -i '/${marker}/d' ${file}
fi
''}
'';
};
}