diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index a9c2d5fe6413..2c6b3419bf2f 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -2548,16 +2548,30 @@ in }; security.pam.services = { - other.text = '' - auth required ${package}/lib/security/pam_warn.so - auth required ${package}/lib/security/pam_deny.so - account required ${package}/lib/security/pam_warn.so - account required ${package}/lib/security/pam_deny.so - password required ${package}/lib/security/pam_warn.so - password required ${package}/lib/security/pam_deny.so - session required ${package}/lib/security/pam_warn.so - session required ${package}/lib/security/pam_deny.so - ''; + other = { + useDefaultRules = false; + rules = + let + rules = utils.pam.autoOrderRules [ + { + name = "warn"; + control = "required"; + modulePath = "${package}/lib/security/pam_warn.so"; + } + { + name = "deny"; + control = "required"; + modulePath = "${package}/lib/security/pam_deny.so"; + } + ]; + in + { + auth = rules; + account = rules; + password = rules; + session = rules; + }; + }; # Most of these should be moved to specific modules. i3lock.enable = lib.mkDefault config.programs.i3lock.enable; diff --git a/nixos/modules/services/display-managers/gdm.nix b/nixos/modules/services/display-managers/gdm.nix index 18998ddeb34f..6de21115eb2a 100644 --- a/nixos/modules/services/display-managers/gdm.nix +++ b/nixos/modules/services/display-managers/gdm.nix @@ -1,6 +1,7 @@ { config, lib, + utils, pkgs, ... }: @@ -383,67 +384,280 @@ in # GDM LFS PAM modules, adapted somehow to NixOS security.pam.services = { - gdm-launch-environment.text = '' - auth required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user ingroup gdm - auth optional ${config.security.pam.package}/lib/security/pam_permit.so + gdm-launch-environment = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "gdm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "ingroup" + "gdm" + ]; + } + { + name = "permit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; - account required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user ingroup gdm - account sufficient ${config.security.pam.package}/lib/security/pam_unix.so + account = utils.pam.autoOrderRules [ + { + name = "gdm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "ingroup" + "gdm" + ]; + } + { + name = "unix"; + control = "sufficient"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + ]; - password required ${config.security.pam.package}/lib/security/pam_deny.so + password = utils.pam.autoOrderRules [ + { + name = "deny"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_deny.so"; + } + ]; - session required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user ingroup gdm - session required ${config.security.pam.package}/lib/security/pam_env.so conffile=/etc/pam/environment readenv=0 - session optional ${config.systemd.package}/lib/security/pam_systemd.so - session optional ${config.security.pam.package}/lib/security/pam_keyinit.so force revoke - session optional ${config.security.pam.package}/lib/security/pam_permit.so - ''; + session = utils.pam.autoOrderRules [ + { + name = "gdm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "ingroup" + "gdm" + ]; + } + { + name = "env"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_env.so"; + settings.conffile = "/etc/pam/environment"; + settings.readenv = 0; + } + { + name = "systemd"; + control = "optional"; + modulePath = "${config.systemd.package}/lib/security/pam_systemd.so"; + } + { + name = "keyinit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_keyinit.so"; + settings.force = true; + settings.revoke = true; + } + { + name = "permit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; + }; + }; - gdm-password.text = '' - auth substack login - account include login - password substack login - session include login - ''; + gdm-password = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + account = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + password = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + session = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; - gdm-autologin.text = '' - auth requisite ${config.security.pam.package}/lib/security/pam_nologin.so - auth required ${config.security.pam.package}/lib/security/pam_succeed_if.so uid >= 1000 quiet - ${lib.optionalString (pamLogin.enable && pamLogin.enableGnomeKeyring) '' - auth [success=ok default=1] ${gdm}/lib/security/pam_gdm.so - auth optional ${pkgs.gnome-keyring}/lib/security/pam_gnome_keyring.so - ''} - auth required ${config.security.pam.package}/lib/security/pam_permit.so + gdm-autologin = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "nologin"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_nologin.so"; + } + { + name = "gdm-normal-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.quiet = true; + args = lib.mkBefore [ + "uid" + ">=" + "1000" + ]; + } + { + name = "gdm"; + enable = pamLogin.enable && pamLogin.enableGnomeKeyring; + control = "[success=ok default=1]"; + modulePath = "${gdm}/lib/security/pam_gdm.so"; + } + { + name = "gnome_keyring"; + enable = pamLogin.enable && pamLogin.enableGnomeKeyring; + control = "optional"; + modulePath = "${pkgs.gnome-keyring}/lib/security/pam_gnome_keyring.so"; + } + { + name = "permit"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; - account sufficient ${config.security.pam.package}/lib/security/pam_unix.so + account = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "sufficient"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + ]; - password requisite ${config.security.pam.package}/lib/security/pam_unix.so nullok yescrypt + password = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + settings.nullok = true; + settings.yescrypt = true; + } + ]; - session optional ${config.security.pam.package}/lib/security/pam_keyinit.so revoke - session include login - ''; + session = utils.pam.autoOrderRules [ + { + name = "keyinit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_keyinit.so"; + settings.revoke = true; + } + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; # This would block password prompt when included by gdm-password. # GDM will instead run gdm-fingerprint in parallel. login.fprintAuth = lib.mkIf config.services.fprintd.enable false; - gdm-fingerprint.text = lib.mkIf config.services.fprintd.enable '' - auth required ${config.security.pam.package}/lib/security/pam_shells.so - auth requisite ${config.security.pam.package}/lib/security/pam_nologin.so - auth requisite ${config.security.pam.package}/lib/security/pam_faillock.so preauth - auth required ${pkgs.fprintd}/lib/security/pam_fprintd.so - auth required ${config.security.pam.package}/lib/security/pam_env.so conffile=/etc/pam/environment readenv=0 - ${lib.optionalString (pamLogin.enable && pamLogin.enableGnomeKeyring) '' - auth [success=ok default=1] ${gdm}/lib/security/pam_gdm.so - auth optional ${pkgs.gnome-keyring}/lib/security/pam_gnome_keyring.so - ''} + gdm-fingerprint = lib.mkIf config.services.fprintd.enable { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "shells"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_shells.so"; + } + { + name = "nologin"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_nologin.so"; + } + { + name = "faillock"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_faillock.so"; + settings.preauth = true; + } + { + name = "fprintd"; + control = "required"; + modulePath = "${pkgs.fprintd}/lib/security/pam_fprintd.so"; + } + { + name = "env"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_env.so"; + settings.conffile = "/etc/pam/environment"; + settings.readenv = 0; + } + { + name = "gdm"; + enable = pamLogin.enable && pamLogin.enableGnomeKeyring; + control = "[success=ok default=1]"; + modulePath = "${gdm}/lib/security/pam_gdm.so"; + } + { + name = "gnome_keyring"; + enable = pamLogin.enable && pamLogin.enableGnomeKeyring; + control = "optional"; + modulePath = "${pkgs.gnome-keyring}/lib/security/pam_gnome_keyring.so"; + } + ]; - account include login + account = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; - password required ${config.security.pam.package}/lib/security/pam_deny.so + password = utils.pam.autoOrderRules [ + { + name = "deny"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_deny.so"; + } + ]; - session include login - ''; + session = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; }; }; diff --git a/nixos/modules/services/display-managers/ly.nix b/nixos/modules/services/display-managers/ly.nix index 8d671ca5242f..a75da6f68078 100644 --- a/nixos/modules/services/display-managers/ly.nix +++ b/nixos/modules/services/display-managers/ly.nix @@ -1,6 +1,7 @@ { config, lib, + utils, pkgs, ... }: @@ -105,17 +106,58 @@ in }; } // optionalAttrs dmcfg.autoLogin.enable { - ly-autologin.text = '' - auth requisite pam_nologin.so - auth required pam_succeed_if.so uid >= 1000 quiet - auth required pam_permit.so + ly-autologin = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "nologin"; + control = "requisite"; + modulePath = "pam_nologin.so"; + } + { + name = "ly-normal-user"; + control = "required"; + modulePath = "pam_succeed_if.so"; + settings.quiet = true; + args = lib.mkBefore [ + "uid" + ">=" + "1000" + ]; + } + { + name = "permit"; + control = "required"; + modulePath = "pam_permit.so"; + } + ]; - account include ly + account = utils.pam.autoOrderRules [ + { + name = "ly"; + control = "include"; + modulePath = "ly"; + } + ]; - password include ly + password = utils.pam.autoOrderRules [ + { + name = "ly"; + control = "include"; + modulePath = "ly"; + } + ]; - session include ly - ''; + session = utils.pam.autoOrderRules [ + { + name = "ly"; + control = "include"; + modulePath = "ly"; + } + ]; + }; + }; }; environment = { diff --git a/nixos/modules/services/display-managers/plasma-login-manager.nix b/nixos/modules/services/display-managers/plasma-login-manager.nix index 8bfcfc37f4f7..4c98f75b8973 100644 --- a/nixos/modules/services/display-managers/plasma-login-manager.nix +++ b/nixos/modules/services/display-managers/plasma-login-manager.nix @@ -1,6 +1,7 @@ { config, lib, + utils, pkgs, ... }: @@ -83,39 +84,133 @@ in environment.etc."plasmalogin.conf.d/99-user.conf".source = userConfigFile; security.pam.services = { - plasmalogin.text = '' - auth substack login - account include login - password substack login - session include login - ''; + plasmalogin = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + account = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + password = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + session = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; - plasmalogin-autologin.text = '' - auth requisite pam_nologin.so - auth required pam_permit.so + plasmalogin-autologin = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "nologin"; + control = "requisite"; + modulePath = "pam_nologin.so"; + } + { + name = "permit"; + control = "required"; + modulePath = "pam_permit.so"; + } + ]; - account include plasmalogin - password include plasmalogin - session include plasmalogin - ''; + account = utils.pam.autoOrderRules [ + { + name = "plasmalogin"; + control = "include"; + modulePath = "plasmalogin"; + } + ]; + password = utils.pam.autoOrderRules [ + { + name = "plasmalogin"; + control = "include"; + modulePath = "plasmalogin"; + } + ]; + session = utils.pam.autoOrderRules [ + { + name = "plasmalogin"; + control = "include"; + modulePath = "plasmalogin"; + } + ]; + }; + }; - plasmalogin-greeter.text = '' - # Load environment from /etc/environment and ~/.pam_environment - auth required pam_env.so conffile=/etc/pam/environment readenv=0 + plasmalogin-greeter = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + # Load environment from /etc/environment and ~/.pam_environment + name = "env"; + control = "required"; + modulePath = "pam_env.so"; + settings.conffile = "/etc/pam/environment"; + settings.readenv = 0; + } + { + # Always let the greeter start without authentication + name = "permit"; + control = "required"; + modulePath = "pam_permit.so"; + } + ]; - # Always let the greeter start without authentication - auth required pam_permit.so + account = utils.pam.autoOrderRules [ + { + # No action required for account management + name = "permit"; + control = "required"; + modulePath = "pam_permit.so"; + } + ]; - # No action required for account management - account required pam_permit.so + password = utils.pam.autoOrderRules [ + { + # Can't change password + name = "deny"; + control = "required"; + modulePath = "pam_deny.so"; + } + ]; - # Can't change password - password required pam_deny.so - - # Setup session - session required pam_unix.so - session optional ${config.systemd.package}/lib/security/pam_systemd.so - ''; + session = utils.pam.autoOrderRules [ + { + # Setup session + name = "unix"; + control = "required"; + modulePath = "pam_unix.so"; + } + { + name = "systemd"; + control = "optional"; + modulePath = "${config.systemd.package}/lib/security/pam_systemd.so"; + } + ]; + }; + }; }; # FIXME: use upstream sysusers diff --git a/nixos/modules/services/display-managers/sddm.nix b/nixos/modules/services/display-managers/sddm.nix index 25f63007f9ac..5cb750786b00 100644 --- a/nixos/modules/services/display-managers/sddm.nix +++ b/nixos/modules/services/display-managers/sddm.nix @@ -1,6 +1,7 @@ { config, lib, + utils, pkgs, ... }: @@ -368,40 +369,184 @@ in }; security.pam.services = { - sddm.text = '' - auth substack login - account include login - password substack login - session include login - ''; + sddm = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + account = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + password = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + session = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; - sddm-greeter.text = '' - auth required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user = sddm - auth optional ${config.security.pam.package}/lib/security/pam_permit.so + sddm-greeter = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "sddm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "=" + "sddm" + ]; + } + { + name = "permit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; - account required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user = sddm - account sufficient ${config.security.pam.package}/lib/security/pam_unix.so + account = utils.pam.autoOrderRules [ + { + name = "sddm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "=" + "sddm" + ]; + } + { + name = "unix"; + control = "sufficient"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + ]; - password required ${config.security.pam.package}/lib/security/pam_deny.so + password = utils.pam.autoOrderRules [ + { + name = "deny"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_deny.so"; + } + ]; - session required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user = sddm - session required ${config.security.pam.package}/lib/security/pam_env.so conffile=/etc/pam/environment readenv=0 - session optional ${config.systemd.package}/lib/security/pam_systemd.so - session optional ${config.security.pam.package}/lib/security/pam_keyinit.so force revoke - session optional ${config.security.pam.package}/lib/security/pam_permit.so - ''; + session = utils.pam.autoOrderRules [ + { + name = "sddm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "=" + "sddm" + ]; + } + { + name = "env"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_env.so"; + settings.conffile = "/etc/pam/environment"; + settings.readenv = 0; + } + { + name = "systemd"; + control = "optional"; + modulePath = "${config.systemd.package}/lib/security/pam_systemd.so"; + } + { + name = "keyinit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_keyinit.so"; + settings.force = true; + settings.revoke = true; + } + { + name = "permit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; + }; + }; - sddm-autologin.text = '' - auth requisite ${config.security.pam.package}/lib/security/pam_nologin.so - auth required ${config.security.pam.package}/lib/security/pam_succeed_if.so uid >= ${toString cfg.autoLogin.minimumUid} quiet - auth required ${config.security.pam.package}/lib/security/pam_permit.so + sddm-autologin = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "nologin"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_nologin.so"; + } + { + name = "sddm-autologin-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.quiet = true; + args = lib.mkBefore [ + "uid" + ">=" + (toString cfg.autoLogin.minimumUid) + ]; + } + { + name = "permit"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; - account include sddm + account = utils.pam.autoOrderRules [ + { + name = "sddm"; + control = "include"; + modulePath = "sddm"; + } + ]; - password include sddm + password = utils.pam.autoOrderRules [ + { + name = "sddm"; + control = "include"; + modulePath = "sddm"; + } + ]; - session include sddm - ''; + session = utils.pam.autoOrderRules [ + { + name = "sddm"; + control = "include"; + modulePath = "sddm"; + } + ]; + }; + }; }; users.users.sddm = { diff --git a/nixos/modules/services/networking/vsftpd.nix b/nixos/modules/services/networking/vsftpd.nix index 070f77115829..481ceb74886e 100644 --- a/nixos/modules/services/networking/vsftpd.nix +++ b/nixos/modules/services/networking/vsftpd.nix @@ -1,6 +1,7 @@ { config, lib, + utils, pkgs, ... }: @@ -333,9 +334,23 @@ in }; }; - security.pam.services.vsftpd.text = mkIf (cfg.enableVirtualUsers && cfg.userDbPath != null) '' - auth required ${config.security.pam.package}/lib/security/pam_userdb.so db=${cfg.userDbPath} - account required ${config.security.pam.package}/lib/security/pam_userdb.so db=${cfg.userDbPath} - ''; + security.pam.services.vsftpd = mkIf (cfg.enableVirtualUsers && cfg.userDbPath != null) { + useDefaultRules = false; + rules = + let + rules = utils.pam.autoOrderRules [ + { + name = "userdb"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_userdb.so"; + settings.db = cfg.userDbPath; + } + ]; + in + { + auth = rules; + account = rules; + }; + }; }; } diff --git a/nixos/modules/services/wayland/cage.nix b/nixos/modules/services/wayland/cage.nix index 76731622d50a..006520ea9b63 100644 --- a/nixos/modules/services/wayland/cage.nix +++ b/nixos/modules/services/wayland/cage.nix @@ -2,6 +2,7 @@ config, pkgs, lib, + utils, ... }: @@ -105,13 +106,45 @@ in security.polkit.enable = true; - security.pam.services.cage.text = '' - auth required ${config.security.pam.package}/lib/security/pam_unix.so nullok - account required ${config.security.pam.package}/lib/security/pam_unix.so - session required ${config.security.pam.package}/lib/security/pam_unix.so - session required ${config.security.pam.package}/lib/security/pam_env.so conffile=/etc/pam/environment readenv=0 - session required ${config.systemd.package}/lib/security/pam_systemd.so - ''; + security.pam.services.cage = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + settings.nullok = true; + } + ]; + account = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + ]; + session = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + { + name = "env"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_env.so"; + settings.conffile = "/etc/pam/environment"; + settings.readenv = 0; + } + { + name = "systemd"; + control = "required"; + modulePath = "${config.systemd.package}/lib/security/pam_systemd.so"; + } + ]; + }; + }; hardware.graphics.enable = mkDefault true; diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index b0e757b21f5f..699a9a9a07f3 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -1,6 +1,7 @@ { config, lib, + utils, pkgs, ... }: @@ -279,47 +280,201 @@ in security.polkit.enable = true; - security.pam.services.lightdm.text = '' - auth substack login - account include login - password substack login - session include login - '' - # https://github.com/elementary/switchboard-plug-parental-controls/blob/8.0.1/src/daemon/Server.vala#L325 - # Must specify conffile since pam_time defaults to ${linux-pam}/etc/security/time.conf. - + lib.optionalString config.services.pantheon.parental-controls.enable '' - account required ${config.security.pam.package}/lib/security/pam_time.so conffile=/etc/security/time.conf - ''; + security.pam.services.lightdm = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + account = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + { + name = "time"; + # https://github.com/elementary/switchboard-plug-parental-controls/blob/8.0.1/src/daemon/Server.vala#L325 + enable = config.services.pantheon.parental-controls.enable; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_time.so"; + # Must specify conffile since pam_time defaults to ${linux-pam}/etc/security/time.conf. + settings.conffile = "/etc/security/time.conf"; + } + ]; + password = utils.pam.autoOrderRules [ + { + name = "login"; + control = "substack"; + modulePath = "login"; + } + ]; + session = utils.pam.autoOrderRules [ + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; - security.pam.services.lightdm-greeter.text = '' - auth required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user = lightdm - auth optional ${config.security.pam.package}/lib/security/pam_permit.so + security.pam.services.lightdm-greeter = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "lightdm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "=" + "lightdm" + ]; + } + { + name = "permit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; - account required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user = lightdm - account sufficient ${config.security.pam.package}/lib/security/pam_unix.so + account = utils.pam.autoOrderRules [ + { + name = "lightdm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "=" + "lightdm" + ]; + } + { + name = "unix"; + control = "sufficient"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + ]; - password required ${config.security.pam.package}/lib/security/pam_deny.so + password = utils.pam.autoOrderRules [ + { + name = "deny"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_deny.so"; + } + ]; - session required ${config.security.pam.package}/lib/security/pam_succeed_if.so audit quiet_success user = lightdm - session required ${config.security.pam.package}/lib/security/pam_env.so conffile=/etc/pam/environment readenv=0 - session optional ${config.systemd.package}/lib/security/pam_systemd.so - session optional ${config.security.pam.package}/lib/security/pam_keyinit.so force revoke - session optional ${config.security.pam.package}/lib/security/pam_permit.so - ''; + session = utils.pam.autoOrderRules [ + { + name = "lightdm-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.audit = true; + settings.quiet_success = true; + args = lib.mkAfter [ + "user" + "=" + "lightdm" + ]; + } + { + name = "env"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_env.so"; + settings.conffile = "/etc/pam/environment"; + settings.readenv = 0; + } + { + name = "systemd"; + control = "optional"; + modulePath = "${config.systemd.package}/lib/security/pam_systemd.so"; + } + { + name = "keyinit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_keyinit.so"; + settings.force = true; + settings.revoke = true; + } + { + name = "permit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; + }; + }; - security.pam.services.lightdm-autologin.text = '' - auth requisite ${config.security.pam.package}/lib/security/pam_nologin.so + security.pam.services.lightdm-autologin = { + useDefaultRules = false; + rules = { + auth = utils.pam.autoOrderRules [ + { + name = "nologin"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_nologin.so"; + } + { + name = "lightdm-normal-user"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_succeed_if.so"; + settings.quiet = true; + args = lib.mkBefore [ + "uid" + ">=" + "1000" + ]; + } + { + name = "permit"; + control = "required"; + modulePath = "${config.security.pam.package}/lib/security/pam_permit.so"; + } + ]; - auth required ${config.security.pam.package}/lib/security/pam_succeed_if.so uid >= 1000 quiet - auth required ${config.security.pam.package}/lib/security/pam_permit.so + account = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "sufficient"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + } + ]; - account sufficient ${config.security.pam.package}/lib/security/pam_unix.so + password = utils.pam.autoOrderRules [ + { + name = "unix"; + control = "requisite"; + modulePath = "${config.security.pam.package}/lib/security/pam_unix.so"; + settings.nullok = true; + settings.yescrypt = true; + } + ]; - password requisite ${config.security.pam.package}/lib/security/pam_unix.so nullok yescrypt - - session optional ${config.security.pam.package}/lib/security/pam_keyinit.so revoke - session include login - ''; + session = utils.pam.autoOrderRules [ + { + name = "keyinit"; + control = "optional"; + modulePath = "${config.security.pam.package}/lib/security/pam_keyinit.so"; + settings.revoke = true; + } + { + name = "login"; + control = "include"; + modulePath = "login"; + } + ]; + }; + }; users.users.lightdm = { home = "/var/lib/lightdm";