diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 40df6c67ef84..70bce783a90b 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -410,46 +410,64 @@ let # Samba stuff to the Samba module. This requires that the PAM # module provides the right hooks. text = mkDefault - ('' - # Account management. - account required pam_unix.so - ${optionalString use_ldap - "account sufficient ${pam_ldap}/lib/security/pam_ldap.so"} - ${optionalString (config.services.sssd.enable && cfg.sssdStrictAccess==false) - "account sufficient ${pkgs.sssd}/lib/security/pam_sss.so"} - ${optionalString (config.services.sssd.enable && cfg.sssdStrictAccess) - "account [default=bad success=ok user_unknown=ignore] ${pkgs.sssd}/lib/security/pam_sss.so"} - ${optionalString config.krb5.enable - "account sufficient ${pam_krb5}/lib/security/pam_krb5.so"} - ${optionalString cfg.googleOsLoginAccountVerification '' + ( + '' + # Account management. + account required pam_unix.so + '' + + optionalString use_ldap '' + account sufficient ${pam_ldap}/lib/security/pam_ldap.so + '' + + optionalString (config.services.sssd.enable && cfg.sssdStrictAccess==false) '' + account sufficient ${pkgs.sssd}/lib/security/pam_sss.so + '' + + optionalString (config.services.sssd.enable && cfg.sssdStrictAccess) '' + account [default=bad success=ok user_unknown=ignore] ${pkgs.sssd}/lib/security/pam_sss.so + '' + + optionalString config.krb5.enable '' + account sufficient ${pam_krb5}/lib/security/pam_krb5.so + '' + + optionalString cfg.googleOsLoginAccountVerification '' account [success=ok ignore=ignore default=die] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so account [success=ok default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so - ''} + '' + + '' - # Authentication management. - ${optionalString cfg.googleOsLoginAuthentication - "auth [success=done perm_denied=bad default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so"} - ${optionalString cfg.rootOK - "auth sufficient pam_rootok.so"} - ${optionalString cfg.requireWheel - "auth required pam_wheel.so use_uid"} - ${optionalString cfg.logFailures - "auth required pam_faillock.so"} - ${optionalString (config.security.pam.enableSSHAgentAuth && cfg.sshAgentAuth) - "auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=${lib.concatStringsSep ":" config.services.openssh.authorizedKeysFiles}"} - ${let p11 = config.security.pam.p11; in optionalString cfg.p11Auth - "auth ${p11.control} ${pkgs.pam_p11}/lib/security/pam_p11.so ${pkgs.opensc}/lib/opensc-pkcs11.so"} - ${let u2f = config.security.pam.u2f; in optionalString cfg.u2fAuth - "auth ${u2f.control} ${pkgs.pam_u2f}/lib/security/pam_u2f.so ${optionalString u2f.debug "debug"} ${optionalString (u2f.authFile != null) "authfile=${u2f.authFile}"} ${optionalString u2f.interactive "interactive"} ${optionalString u2f.cue "cue"} ${optionalString (u2f.appId != null) "appid=${u2f.appId}"}"} - ${optionalString cfg.usbAuth - "auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"} - ${let oath = config.security.pam.oath; in optionalString cfg.oathAuth - "auth requisite ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"} - ${let yubi = config.security.pam.yubico; in optionalString cfg.yubicoAuth - "auth ${yubi.control} ${pkgs.yubico-pam}/lib/security/pam_yubico.so mode=${toString yubi.mode} ${optionalString (yubi.challengeResponsePath != null) "chalresp_path=${yubi.challengeResponsePath}"} ${optionalString (yubi.mode == "client") "id=${toString yubi.id}"} ${optionalString yubi.debug "debug"}"} - ${optionalString cfg.fprintAuth - "auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so"} - '' + + # Authentication management. + '' + + optionalString cfg.googleOsLoginAuthentication '' + auth [success=done perm_denied=bad default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so + '' + + optionalString cfg.rootOK '' + auth sufficient pam_rootok.so + '' + + optionalString cfg.requireWheel '' + auth required pam_wheel.so use_uid + '' + + optionalString cfg.logFailures '' + auth required pam_faillock.so + '' + + optionalString (config.security.pam.enableSSHAgentAuth && cfg.sshAgentAuth) '' + auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=${lib.concatStringsSep ":" config.services.openssh.authorizedKeysFiles} + '' + + (let p11 = config.security.pam.p11; in optionalString cfg.p11Auth '' + auth ${p11.control} ${pkgs.pam_p11}/lib/security/pam_p11.so ${pkgs.opensc}/lib/opensc-pkcs11.so + '') + + (let u2f = config.security.pam.u2f; in optionalString cfg.u2fAuth '' + auth ${u2f.control} ${pkgs.pam_u2f}/lib/security/pam_u2f.so ${optionalString u2f.debug "debug"} ${optionalString (u2f.authFile != null) "authfile=${u2f.authFile}"} ${optionalString u2f.interactive "interactive"} ${optionalString u2f.cue "cue"} ${optionalString (u2f.appId != null) "appid=${u2f.appId}"} + '') + + optionalString cfg.usbAuth '' + auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so + '' + + (let oath = config.security.pam.oath; in optionalString cfg.oathAuth '' + auth requisite ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits} + '') + + (let yubi = config.security.pam.yubico; in optionalString cfg.yubicoAuth '' + auth ${yubi.control} ${pkgs.yubico-pam}/lib/security/pam_yubico.so mode=${toString yubi.mode} ${optionalString (yubi.challengeResponsePath != null) "chalresp_path=${yubi.challengeResponsePath}"} ${optionalString (yubi.mode == "client") "id=${toString yubi.id}"} ${optionalString yubi.debug "debug"} + '') + + optionalString cfg.fprintAuth '' + auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so + '' + # Modules in this block require having the password set in PAM_AUTHTOK. # pam_unix is marked as 'sufficient' on NixOS which means nothing will run # after it succeeds. Certain modules need to run after pam_unix @@ -457,115 +475,151 @@ let # earlier point and it will run again with 'sufficient' further down. # We use try_first_pass the second time to avoid prompting password twice (optionalString (cfg.unixAuth && - (config.security.pam.enableEcryptfs - || cfg.pamMount - || cfg.enableKwallet - || cfg.enableGnomeKeyring - || cfg.googleAuthenticator.enable - || cfg.gnupg.enable - || cfg.duoSecurity.enable)) '' - auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} ${optionalString cfg.nodelay "nodelay"} likeauth - ${optionalString config.security.pam.enableEcryptfs - "auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"} - ${optionalString cfg.pamMount - "auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so disable_interactive"} - ${optionalString cfg.enableKwallet - ("auth optional ${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so" + - " kwalletd=${pkgs.plasma5Packages.kwallet.bin}/bin/kwalletd5")} - ${optionalString cfg.enableGnomeKeyring - "auth optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so"} - ${optionalString cfg.gnupg.enable - "auth optional ${pkgs.pam_gnupg}/lib/security/pam_gnupg.so" - + optionalString cfg.gnupg.storeOnly " store-only" - } - ${optionalString cfg.googleAuthenticator.enable - "auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"} - ${optionalString cfg.duoSecurity.enable - "auth required ${pkgs.duo-unix}/lib/security/pam_duo.so"} - '') + '' - ${optionalString cfg.unixAuth - "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} ${optionalString cfg.nodelay "nodelay"} likeauth try_first_pass"} - ${optionalString cfg.otpwAuth - "auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so"} - ${optionalString use_ldap - "auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"} - ${optionalString config.services.sssd.enable - "auth sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_first_pass"} - ${optionalString config.krb5.enable '' + (config.security.pam.enableEcryptfs + || cfg.pamMount + || cfg.enableKwallet + || cfg.enableGnomeKeyring + || cfg.googleAuthenticator.enable + || cfg.gnupg.enable + || cfg.duoSecurity.enable)) + ( + '' + auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} ${optionalString cfg.nodelay "nodelay"} likeauth + '' + + optionalString config.security.pam.enableEcryptfs '' + auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap + '' + + optionalString cfg.pamMount '' + auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so disable_interactive + '' + + optionalString cfg.enableKwallet '' + auth optional ${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so kwalletd=${pkgs.plasma5Packages.kwallet.bin}/bin/kwalletd5 + '' + + optionalString cfg.enableGnomeKeyring '' + auth optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so + '' + + optionalString cfg.gnupg.enable '' + auth optional ${pkgs.pam_gnupg}/lib/security/pam_gnupg.so ${optionalString cfg.gnupg.storeOnly " store-only"} + '' + + optionalString cfg.googleAuthenticator.enable '' + auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp + '' + + optionalString cfg.duoSecurity.enable '' + auth required ${pkgs.duo-unix}/lib/security/pam_duo.so + '' + )) + + optionalString cfg.unixAuth '' + auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} ${optionalString cfg.nodelay "nodelay"} likeauth try_first_pass + '' + + optionalString cfg.otpwAuth '' + auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so + '' + + optionalString use_ldap '' + auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass + '' + + optionalString config.services.sssd.enable '' + auth sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_first_pass + '' + + optionalString config.krb5.enable '' auth [default=ignore success=1 service_err=reset] ${pam_krb5}/lib/security/pam_krb5.so use_first_pass auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass auth sufficient ${pam_ccreds}/lib/security/pam_ccreds.so action=store use_first_pass - ''} - auth required pam_deny.so + '' + + '' + auth required pam_deny.so - # Password management. - password sufficient pam_unix.so nullok sha512 - ${optionalString config.security.pam.enableEcryptfs - "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} - ${optionalString cfg.pamMount - "password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"} - ${optionalString use_ldap - "password sufficient ${pam_ldap}/lib/security/pam_ldap.so"} - ${optionalString config.services.sssd.enable - "password sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_authtok"} - ${optionalString config.krb5.enable - "password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass"} - ${optionalString cfg.enableGnomeKeyring - "password optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so use_authtok"} + # Password management. + password sufficient pam_unix.so nullok sha512 + '' + + optionalString config.security.pam.enableEcryptfs '' + password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so + '' + + optionalString cfg.pamMount '' + password optional ${pkgs.pam_mount}/lib/security/pam_mount.so + '' + + optionalString use_ldap '' + password sufficient ${pam_ldap}/lib/security/pam_ldap.so + '' + + optionalString config.services.sssd.enable '' + password sufficient ${pkgs.sssd}/lib/security/pam_sss.so use_authtok + '' + + optionalString config.krb5.enable '' + password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass + '' + + optionalString cfg.enableGnomeKeyring '' + password optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so use_authtok + '' + + '' - # Session management. - ${optionalString cfg.setEnvironment '' + # Session management. + '' + + optionalString cfg.setEnvironment '' session required pam_env.so conffile=/etc/pam/environment readenv=0 - ''} - session required pam_unix.so - ${optionalString cfg.setLoginUid - "session ${ - if config.boot.isContainer then "optional" else "required" - } pam_loginuid.so"} - ${optionalString cfg.ttyAudit.enable - "session required ${pkgs.pam}/lib/security/pam_tty_audit.so + '' + + '' + session required pam_unix.so + '' + + optionalString cfg.setLoginUid '' + session ${if config.boot.isContainer then "optional" else "required"} pam_loginuid.so + '' + + optionalString cfg.ttyAudit.enable '' + session required ${pkgs.pam}/lib/security/pam_tty_audit.so open_only=${toString cfg.ttyAudit.openOnly} ${optionalString (cfg.ttyAudit.enablePattern != null) "enable=${cfg.ttyAudit.enablePattern}"} ${optionalString (cfg.ttyAudit.disablePattern != null) "disable=${cfg.ttyAudit.disablePattern}"} - "} - ${optionalString cfg.makeHomeDir - "session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=${config.security.pam.makeHomeDir.skelDirectory} umask=0077"} - ${optionalString cfg.updateWtmp - "session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"} - ${optionalString config.security.pam.enableEcryptfs - "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} - ${optionalString cfg.pamMount - "session optional ${pkgs.pam_mount}/lib/security/pam_mount.so disable_interactive"} - ${optionalString use_ldap - "session optional ${pam_ldap}/lib/security/pam_ldap.so"} - ${optionalString config.services.sssd.enable - "session optional ${pkgs.sssd}/lib/security/pam_sss.so"} - ${optionalString config.krb5.enable - "session optional ${pam_krb5}/lib/security/pam_krb5.so"} - ${optionalString cfg.otpwAuth - "session optional ${pkgs.otpw}/lib/security/pam_otpw.so"} - ${optionalString cfg.startSession - "session optional ${pkgs.systemd}/lib/security/pam_systemd.so"} - ${optionalString cfg.forwardXAuth - "session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99"} - ${optionalString (cfg.limits != []) - "session required ${pkgs.pam}/lib/security/pam_limits.so conf=${makeLimitsConf cfg.limits}"} - ${optionalString (cfg.showMotd && config.users.motd != null) - "session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd}"} - ${optionalString (cfg.enableAppArmor && config.security.apparmor.enable) - "session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"} - ${optionalString (cfg.enableKwallet) - ("session optional ${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so" + - " kwalletd=${pkgs.plasma5Packages.kwallet.bin}/bin/kwalletd5")} - ${optionalString (cfg.enableGnomeKeyring) - "session optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start"} - ${optionalString cfg.gnupg.enable - "session optional ${pkgs.pam_gnupg}/lib/security/pam_gnupg.so" - + optionalString cfg.gnupg.noAutostart " no-autostart" - } - ${optionalString (config.virtualisation.lxc.lxcfs.enable) - "session optional ${pkgs.lxc}/lib/security/pam_cgfs.so -c all"} - ''); + '' + + optionalString cfg.makeHomeDir '' + session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=${config.security.pam.makeHomeDir.skelDirectory} umask=0077 + '' + + optionalString cfg.updateWtmp '' + session required ${pkgs.pam}/lib/security/pam_lastlog.so silent + '' + + optionalString config.security.pam.enableEcryptfs '' + session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so + '' + + optionalString cfg.pamMount '' + session optional ${pkgs.pam_mount}/lib/security/pam_mount.so disable_interactive + '' + + optionalString use_ldap '' + session optional ${pam_ldap}/lib/security/pam_ldap.so + '' + + optionalString config.services.sssd.enable '' + session optional ${pkgs.sssd}/lib/security/pam_sss.so + '' + + optionalString config.krb5.enable '' + session optional ${pam_krb5}/lib/security/pam_krb5.so + '' + + optionalString cfg.otpwAuth '' + session optional ${pkgs.otpw}/lib/security/pam_otpw.so + '' + + optionalString cfg.startSession '' + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + '' + + optionalString cfg.forwardXAuth '' + session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99 + '' + + optionalString (cfg.limits != []) '' + session required ${pkgs.pam}/lib/security/pam_limits.so conf=${makeLimitsConf cfg.limits} + '' + + optionalString (cfg.showMotd && config.users.motd != null) '' + session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd} + '' + + optionalString (cfg.enableAppArmor && config.security.apparmor.enable) '' + session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug + '' + + optionalString (cfg.enableKwallet) '' + session optional ${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so kwalletd=${pkgs.plasma5Packages.kwallet.bin}/bin/kwalletd5 + '' + + optionalString (cfg.enableGnomeKeyring) '' + session optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start + '' + + optionalString cfg.gnupg.enable '' + session optional ${pkgs.pam_gnupg}/lib/security/pam_gnupg.so ${optionalString cfg.gnupg.noAutostart " no-autostart"} + '' + + optionalString (config.virtualisation.lxc.lxcfs.enable) '' + session optional ${pkgs.lxc}/lib/security/pam_cgfs.so -c all + '' + ); }; };