nixos: replace 'text' with structured PAM rules

Several modules define whole PAM service rule stacks by overwriting the
default value of the 'text' option. Instead, we disable useDefaultRules
for these services and declare a new set of rules using the 'rules'
option. This option is considered experimental and hidden from users,
but it is supported for use within nixpkgs.
This commit is contained in:
Majiir Paktu
2025-06-28 19:53:19 -04:00
parent ab27ce1f96
commit 4b864991aa
8 changed files with 873 additions and 160 deletions
+24 -10
View File
@@ -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;
+259 -45
View File
@@ -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";
}
];
};
};
};
};
+50 -8
View File
@@ -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 = {
@@ -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
+171 -26
View File
@@ -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 = {
+19 -4
View File
@@ -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;
};
};
};
}
+40 -7
View File
@@ -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;
@@ -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";