-
-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: move pam
configuration to sudo_local
#1344
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,81 @@ | ||
{ 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 | ||
''} | ||
''; | ||
in | ||
|
||
{ | ||
options = { | ||
security.pam.enableSudoTouchIdAuth = mkEnableOption "" // { | ||
description = '' | ||
Enable sudo authentication with Touch ID. | ||
security.pam = { | ||
enable = lib.mkEnableOption "managing PAM with nix-darwin" // { | ||
default = true; | ||
example = false; | ||
}; | ||
|
||
enableSudoTouchIdAuth = lib.mkEnableOption "" // { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per the previous comment, since we’re adding more options and moving stuff around, this could be renamed to |
||
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 | ||
``` | ||
enableSudoPamReattach = lib.mkEnableOption "" // { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, this could be introduced as |
||
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. | ||
''; | ||
default = cfg.enableSudoTouchIdAuth; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said in the previous PR I think we shouldn’t turn this on by default. It brings a third‐party PAM module into the |
||
example = false; | ||
}; | ||
}; | ||
}; | ||
|
||
config = { | ||
system.activationScripts.pam.text = '' | ||
environment.etc."pam.d/sudo_local" = { | ||
inherit (cfg) enable; | ||
text = lib.concatLines ( | ||
(lib.optional cfg.enableSudoPamReattach "auth optional ${pkgs.pam-reattach}/lib/pam/pam_reattach.so") | ||
++ (lib.optional cfg.enableSudoTouchIdAuth "auth sufficient pam_tid.so") | ||
Comment on lines
+44
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I’d prefer to trim the unnecessary alignment whitespace here, but it doesn’t matter. |
||
); | ||
}; | ||
|
||
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 | ||
''} | ||
''; | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it this is to accommodate users that want a custom
sudo_local
file?I’m wondering if this should be
security.pam.services.sudo_local.enable
. That’s not an option that exists in NixOS, but it brings us closer to NixOS’s structure forsecurity.pam.*
. We’re just managing thesudo_local
configuration rather than PAM as a whole here.I might prefer something like @mirkolenz’s solution, which could also increase NixOS compatibility: we could have
security.pam.services.sudo_local.text
which islib.types.lines
and populate it with our settings by default; users who want extra configuration could uselib.mkAfter
; users who want to replace the entire configuration could override it completely. If someone really wants a totally unmanagedsudo_local
file, we could makeenvironment.etc."pam.d/sudo_local".enable
just alib.mkDefault
so that they can disable it directly. (Or we could keep the non‐standard.enable
, but I think in the presence of.text
it would be niche enough that it’s fine to expect someone to toggle the file like that.)(if not for
.text
, we could make itsecurity.pam.services.sudo.*
since we’re effectively extending thesudo
configuration. But if we add.text
– which seems nicer than.enable
here – then we should make sure it’ssudo_local
, assecurity.pam.services.sudo_local.text
will not be able to overwrite the entire PAMsudo
service configuration, as a NixOS user or configuration might expect.)