Hello, I noticed that there are currently no tests for the PAM authentication functionality in postgres so I came up with the attached patch to add some. I suspect that no tests were added previously because it would have involved using root privileges to set up the environment for the test or just rely on the individual set up the root environment before running the test similar to `src/interfaces/libpq/t/004_load_balance_dns.pl` [0] and then adding validations to skip if the environment wasn't set up.
This patch allows the PAM tests to be set up and run without root by use of the `pam_start_confdir`[1] function that was added in linux-pam 1.4.0 [2]. This function is essentially the same as `pam_start` but has one extra parameter that allows you to either pass NULL for the same behavior as `pam_start` or pass a char * to the location of an alternative location for `/etc/pam.d`. This functionality is exposed via an added `pamconfdir` option that can be used in the pg_hba.conf file after `pam` method is specified. This option is conditionally available via macros on the absence or presence of the `pam_start_confdir` function. I had to make the use of this function conditional because its use in linux-pam is recent enough to where some older LTS linux distros will not support it. For example rocky8 uses PAM 1.3.1 which does not container `pam_start_confdir`, rocky9 uses PAM 1.5.1 which will support it. The tests are skipped if: - postgres was not built with PAM - postgres was not build with a PAM that has the `pam_start_confdir` function - PG_EXTRA_TESTS does not include pam (similar to how LDAP and GSSAPI tests are set up) The tests set up a temporary pam configuration folder and only use pamconfdir in hba. Though this means that we cannot test a non existent pamconfdir in the HBA file I think this is still better than no testing at all as the code paths are mostly the same. Multiple pamservices are tested using `pam_permit` [3] and `pam_exec` [4] pam modules. These modules are both built into the linux-pam source tree. `pam_permit` just allows everything, more fine grained testing can be done with `pam_exec` which essentially passes the password, username, etc to a custom made bash script and acceptance or rejection of the auth request essentially comes down to a zero or non zero return from that script. I have tested this functionality using the make build system and using the meson build system. I tested on nixos with both pam 1.3.1 and 1.7.2 so that I know it builds both with and without this function. Happy to make any changes and appreciate any feedback. Thanks, Andrew Jackson [0] https://github.com/postgres/postgres/blob/ec13f71049cda06ea55a67783b822d98824f4d15/src/interfaces/libpq/t/004_load_balance_dns.pl [1] https://man7.org/linux/man-pages/man3/pam_start.3.html [2] https://github.com/linux-pam/linux-pam/blob/master/NEWS [3] https://man7.org/linux/man-pages/man8/pam_permit.8.html [4] https://linux.die.net/man/8/pam_exec
0001-Add-PAM-tests.patch
Description: Binary data
