Skip to content

Commit

Permalink
pam: switch to using sudo_local file
Browse files Browse the repository at this point in the history
  • Loading branch information
Enzime committed Feb 20, 2025
1 parent c9c2d40 commit b6b7804
Showing 1 changed file with 46 additions and 49 deletions.
95 changes: 46 additions & 49 deletions modules/security/pam.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,63 @@

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
''}
'';
in

{
options = {
security.pam.enableSudoTouchIdAuth = lib.mkEnableOption "" // {
description = ''
Enable sudo authentication with Touch ID.
When enabled, this option adds the following line to
{file}`/etc/pam.d/sudo`:
security.pam = {
enable = lib.mkEnableOption "managing PAM with nix-darwin" // {
default = true;
example = false;
};

```
auth sufficient pam_tid.so
```
enableSudoTouchIdAuth = 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.
'';
};
};
};

config = {
system.activationScripts.pam.text = ''
environment.etc."pam.d/sudo_local" = {
inherit (cfg) enable;
text = lib.optionalString cfg.enableSudoTouchIdAuth "auth sufficient pam_tid.so";
};

system.activationScripts.pam.text =
let
file = "/etc/pam.d/sudo";
marker = "security.pam.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
''}
'';
};
}

0 comments on commit b6b7804

Please sign in to comment.