-
-
Notifications
You must be signed in to change notification settings - Fork 494
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1344 from Mic92/fix_pam_module
fix: move `pam` configuration to `sudo_local`
- Loading branch information
Showing
1 changed file
with
76 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
}; | ||
|
||
text = lib.mkOption { | ||
type = lib.types.lines; | ||
default = ""; | ||
description = '' | ||
Contents of {file}`/etc/pam.d/sudo_local` | ||
''; | ||
}; | ||
|
||
touchIdAuth = lib.mkEnableOption "" // { | ||
description = '' | ||
Whether to enable Touch ID with sudo. | ||
When enabled, this option adds the following line to | ||
{file}`/etc/pam.d/sudo`: | ||
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. | ||
''; | ||
}; | ||
|
||
``` | ||
auth sufficient pam_tid.so | ||
``` | ||
reattach = lib.mkEnableOption "" // { | ||
description = '' | ||
Whether to enable reattaching a program to the user's bootstrap session. | ||
::: {.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 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 | ||
''} | ||
''; | ||
}; | ||
} |