简体   繁体   中英

Using .pgpass from Apache libphp5.so

We are trying to get our Apache PHP module to use the PostgreSQL .pgpass file for looking up passwords for database connections. We have been unable to get it to work. Is there some kind of limitation or bug that's preventing this from working?

Here is what we have and what we have checked. This is all on FreeBSD 10.1.

All works as expected from the command line. That is, the test is exactly the same except for the PHP executable is /usr/local/bin/php instead of the Apache PHP module.

We have verified via phpinfo() that both Apache and command line are built as identically as possible including using the same shared libraries, and the same php.ini file.

Apache version 2.2.29

  • /usr/local/libexec/apache22/libphp5.so
  • /usr/local/lib/php/20100525/pgsql.so

Command line PHP version 5.4.38

  • /usr/local/bin/php
  • /usr/local/lib/php/20100525/pgsql.so

In both cases, we set the environment variable PGPASSFILE to the same value and verify that it is correct from within PHP.

In both cases, we are using the same Unix username ('www'), so we are sure it is not a file path or permissions problem.

We have only one PostgreSQL library on our system, at /usr/local/lib/libpq.so. This is the binary where the .pgpass file usage should occur.

Has anyone else encountered this problem? Is there something we are overlooking?

Does Apache's libphp5.so somehow bypass usage of the PHP library pgsql.so and call libpq.so directly, despite it being configured to use the same PHP shared library directory (ie /usr/local/lib/php/20100525/)?

Even though php has PGPASSFILE in the environment it inherits from apache, as proven by getenv("PGPASSFILE") , it appears that this environment is not the one that's available to the shared libpq library that ultimately handles .pgpass . This is why this setting gets ignored.

A workaround is to reput into the environment the variable that's already there, in php before connecting to the database:

if (getenv("PGPASSFILE")!="")
  putenv("PGPASSFILE=".getenv("PGPASSFILE"));

The explicit putenv will push the variable in a way that makes it available to libpq 's calls of getenv() . This is weird since normally a process has only one environment, but it appears to work.

I've asked about the discordant environment problem between extensions and php's core in a separate question: Why is putenv() needed on an already defined environment variable?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM