diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index c1882cc6bdbd..77938ed1ac28 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1184,6 +1184,7 @@ in 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-pgsql = runTest ./pam/pam-pgsql.nix; pam-u2f = runTest ./pam/pam-u2f.nix; pam-ussh = runTest ./pam/pam-ussh.nix; pam-zfs-key = runTest ./pam/zfs-key.nix; diff --git a/nixos/tests/pam/pam-pgsql.nix b/nixos/tests/pam/pam-pgsql.nix new file mode 100644 index 000000000000..9a4ec121c348 --- /dev/null +++ b/nixos/tests/pam/pam-pgsql.nix @@ -0,0 +1,88 @@ +{ lib, ... }: +let + dbName = "authdb"; + dbUser = "authuser"; +in +{ + name = "pam-pgsql"; + meta.maintainers = with lib.maintainers; [ moraxyc ]; + + nodes.machine = + { lib, pkgs, ... }: + { + environment.systemPackages = with pkgs; [ pamtester ]; + environment.etc."pam_pgsql.conf".text = lib.generators.toKeyValue { } { + connect = "host=/run/postgresql port=5432 dbname=${dbName} user=${dbUser} connect_timeout=15"; + auth_query = "select password from account where username = %u"; + acct_query = "select (expired = 'y' OR expired = '1'), (newtok = 'y' OR newtok = '1'), (password IS NULL OR password = '') from account where username = %u"; + pwd_query = "update account set password = %p where username = %u"; + pw_type = "crypt"; + }; + + services.postgresql = { + enable = true; + authentication = '' + local ${dbName} ${dbUser} trust + ''; + initialScript = + pkgs.writeText "init.psql" + # sql + '' + CREATE USER ${dbUser}; + CREATE DATABASE ${dbName} OWNER ${dbUser}; + \c ${dbName} + + -- https://github.com/pam-pgsql/pam-pgsql/blob/master/sample.sql + CREATE TABLE account ( + username varchar(256) UNIQUE NOT NULL, + password varchar(200), + expired boolean, + newtok boolean + ); + + GRANT ALL PRIVILEGES ON TABLE account TO ${dbUser}; + + CREATE EXTENSION IF NOT EXISTS pgcrypto; + INSERT INTO account (username, password, expired, newtok) + VALUES ( + 'alice', + crypt('secret', gen_salt('bf')), + false, + false + ); + ''; + }; + security.pam.services.pgsql-test.text = + let + pam-pgsql-so = "${pkgs.pam-pgsql}/lib/security/pam_pgsql.so"; + in + '' + auth required ${pam-pgsql-so} + account required ${pam-pgsql-so} + password required ${pam-pgsql-so} + session required ${pam-pgsql-so} + ''; + }; + + testScript = + # python + '' + start_all() + + machine.wait_for_unit("postgresql-setup.service") + + with subtest("Testing successful login..."): + machine.succeed("echo 'secret' | pamtester -v pgsql-test alice authenticate") + + with subtest("Testing failed login..."): + machine.fail("echo 'wrongpass' | pamtester -v pgsql-test alice authenticate") + + with subtest("Testing non-existent user..."): + machine.fail("echo 'secret' | pamtester -v pgsql-test bob authenticate") + + with subtest("Testing expired user..."): + machine.succeed("psql -U ${dbUser} -d ${dbName} -c 'UPDATE account SET expired = TRUE;'") + machine.succeed("echo 'secret' | pamtester -v pgsql-test alice authenticate") + machine.fail("pamtester -v pgsql-test alice acct_mgmt") + ''; +} diff --git a/pkgs/by-name/pa/pam_pgsql/package.nix b/pkgs/by-name/pa/pam-pgsql/package.nix similarity index 55% rename from pkgs/by-name/pa/pam_pgsql/package.nix rename to pkgs/by-name/pa/pam-pgsql/package.nix index 1d66101a7891..c37206caea6c 100644 --- a/pkgs/by-name/pa/pam_pgsql/package.nix +++ b/pkgs/by-name/pa/pam-pgsql/package.nix @@ -8,23 +8,27 @@ libgcrypt, pam, libxcrypt, + unstableGitUpdater, + nixosTests, }: stdenv.mkDerivation { - pname = "pam_pgsql"; - version = "unstable-2020-05-05"; + pname = "pam-pgsql"; + version = "0-unstable-2025-01-24"; src = fetchFromGitHub { owner = "pam-pgsql"; repo = "pam-pgsql"; - rev = "f9fd1e1a0daf754e6764a31db5cbec6f9fc02b3d"; - sha256 = "1bvddrwyk1479wibyayzc24h62qzfnlbk9qvdhb31yw9yn17gp6k"; + rev = "7834ce21c4f633e3eadc9abe86fa02991efc43ed"; + hash = "sha256-hBkDEYZ8RBHav3tqDOD2uQ9m3U95wi4U9ebyQPqd5bo="; }; nativeBuildInputs = [ autoreconfHook pkg-config + libpq.pg_config ]; + buildInputs = [ libgcrypt pam @@ -32,11 +36,16 @@ stdenv.mkDerivation { libxcrypt ]; + passthru = { + updateScript = unstableGitUpdater { hardcodeZeroVersion = true; }; + tests = { inherit (nixosTests) pam-pgsql; }; + }; + meta = { - description = "Support to authenticate against PostgreSQL for PAM-enabled appliations"; + description = "Support to authenticate against PostgreSQL for PAM-enabled applications"; homepage = "https://github.com/pam-pgsql/pam-pgsql"; license = lib.licenses.gpl2Plus; platforms = lib.platforms.linux; - maintainers = [ ]; + maintainers = with lib.maintainers; [ moraxyc ]; }; } diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index d4e4927d9930..f370a755de55 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -1242,6 +1242,7 @@ mapAliases { pacup = throw "'pacup' has been renamed to/replaced by 'perlPackages.pacup'"; # Converted to throw 2025-10-27 PageEdit = throw "'PageEdit' has been renamed to/replaced by 'pageedit'"; # Converted to throw 2025-10-27 pal = throw "pal has been removed, as it was broken"; # Added 2025-08-25 + pam_pgsql = pam-pgsql; # Added 2025-12-16 pangolin = throw "pangolin has been removed due to lack of maintenance"; # Added 2025-11-17 paperless-ng = throw "'paperless-ng' has been renamed to/replaced by 'paperless-ngx'"; # Converted to throw 2025-10-27 parcellite = throw "'parcellite' was remove due to lack of maintenance and relying on gtk2"; # Added 2025-10-03