diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 3eba6d4b519e0..e5e8d09a4f571 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -1311,7 +1311,7 @@ let name = "lastlog"; enable = cfg.updateWtmp; control = "required"; - modulePath = "${package}/lib/security/pam_lastlog.so"; + modulePath = "${pkgs.util-linux.lastlog}/lib/security/pam_lastlog2.so"; settings = { silent = true; }; @@ -2311,6 +2311,12 @@ in environment.etc = lib.mapAttrs' makePAMService enabledServices; + systemd = lib.optionalAttrs config.security.pam.services.login.updateWtmp { + tmpfiles.packages = [ pkgs.util-linux.lastlog ]; # /lib/tmpfiles.d/lastlog2-tmpfiles.conf + services.lastlog2-import.enable = true; + packages = [ pkgs.util-linux.lastlog ]; # lib/systemd/system/lastlog2-import.service + }; + security.pam.services = { other.text = '' auth required pam_warn.so diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index b24bc4d7d7af0..2032e5ae051e6 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1115,6 +1115,7 @@ in packagekit = runTest ./packagekit.nix; paisa = runTest ./paisa.nix; pam-file-contents = runTest ./pam/pam-file-contents.nix; + pam-lastlog = runTest ./pam/pam-lastlog.nix; pam-oath-login = runTest ./pam/pam-oath-login.nix; pam-u2f = runTest ./pam/pam-u2f.nix; pam-ussh = runTest ./pam/pam-ussh.nix; diff --git a/nixos/tests/pam/pam-lastlog.nix b/nixos/tests/pam/pam-lastlog.nix new file mode 100644 index 0000000000000..837c84e1e601a --- /dev/null +++ b/nixos/tests/pam/pam-lastlog.nix @@ -0,0 +1,21 @@ +{ ... }: + +{ + name = "pam-lastlog"; + + nodes.machine = + { ... }: + { + # we abuse run0 for a quick login as root as to not require setting up accounts and passwords + security.pam.services.systemd-run0 = { + updateWtmp = true; # enable lastlog + }; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + machine.succeed("run0 --pty true") # perform full login + print(machine.succeed("lastlog2 --active --user root")) + machine.succeed("stat /var/lib/lastlog/lastlog2.db") + ''; +} diff --git a/pkgs/by-name/li/linux-pam/package.nix b/pkgs/by-name/li/linux-pam/package.nix index 1078aaebbba27..97b67d2131bf0 100644 --- a/pkgs/by-name/li/linux-pam/package.nix +++ b/pkgs/by-name/li/linux-pam/package.nix @@ -84,6 +84,7 @@ stdenv.mkDerivation rec { inherit (nixosTests) pam-oath-login pam-u2f + pam-lastlog shadow sssd-ldap ; diff --git a/pkgs/by-name/ut/util-linux/package.nix b/pkgs/by-name/ut/util-linux/package.nix index fb957238eaad2..6451e9f4834bb 100644 --- a/pkgs/by-name/ut/util-linux/package.nix +++ b/pkgs/by-name/ut/util-linux/package.nix @@ -28,7 +28,10 @@ installShellFiles, writeSupport ? stdenv.hostPlatform.isLinux, shadowSupport ? stdenv.hostPlatform.isLinux, + # Doesn't build on Darwin, also doesn't really make sense on Darwin + withLastlog ? !stdenv.hostPlatform.isDarwin, gitUpdater, + nixosTests, }: let @@ -72,10 +75,15 @@ stdenv.mkDerivation (finalPackage: rec { "out" "lib" "man" + "login" ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ "mount" ] - ++ [ "login" ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ "swap" ]; + ++ lib.optionals stdenv.hostPlatform.isLinux [ + "mount" + "swap" + ] + ++ lib.optionals withLastlog [ + "lastlog" + ]; separateDebugInfo = true; postPatch = '' @@ -129,8 +137,7 @@ stdenv.mkDerivation (finalPackage: rec { "--disable-ipcrm" "--disable-ipcs" ] - ++ lib.optionals stdenv.hostPlatform.isDarwin [ - # Doesn't build on Darwin, also doesn't really make sense on Darwin + ++ lib.optionals (!withLastlog) [ "--disable-liblastlog2" ] ++ lib.optionals stdenv.hostPlatform.isStatic [ @@ -183,6 +190,18 @@ stdenv.mkDerivation (finalPackage: rec { prefix=$login _moveSbin ln -svf "$login/bin/"* $bin/bin/ '' + + lib.optionalString withLastlog '' + # moveToOutput "lib/liblastlog2*" "$lastlog" + ${lib.optionalString (!stdenv.hostPlatform.isStatic) ''moveToOutput "lib/security" "$lastlog"''} + moveToOutput "lib/tmpfiles.d/lastlog2-tmpfiles.conf" "$lastlog" + + moveToOutput "lib/systemd/system/lastlog2-import.service" "$lastlog" + substituteInPlace $lastlog/lib/systemd/system/lastlog2-import.service \ + --replace-fail "$bin/bin/lastlog2" "$lastlog/bin/lastlog2" + + moveToOutput "bin/lastlog2" "$lastlog" + ln -svf "$lastlog/bin/"* $bin/bin/ + '' + lib.optionalString stdenv.hostPlatform.isLinux '' moveToOutput sbin/swapon "$swap" @@ -209,6 +228,10 @@ stdenv.mkDerivation (finalPackage: rec { # encode upstream assumption to be used in man-db # https://github.com/util-linux/util-linux/commit/8886d84e25a457702b45194d69a47313f76dc6bc hasCol = stdenv.hostPlatform.libc == "glibc"; + + tests = { + inherit (nixosTests) pam-lastlog; + }; }; meta = { diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index c0e953a8d19e6..dc785cce91a05 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11387,6 +11387,7 @@ with pkgs; shadowSupport = false; systemdSupport = false; translateManpages = false; + withLastlog = false; }; v4l-utils = qt6.callPackage ../os-specific/linux/v4l-utils { };