8000 Fix libpq to not require user's home directory to exist. · MSPawanRanjith/postgres@caeae88 · GitHub
[go: up one dir, main page]

Skip to content

Commit caeae88

Browse files
committed
Fix libpq to not require user's home directory to exist.
Some people like to run libpq-using applications in environments where there's no home directory. We've broken that scenario before (cf commits 5b40677 and bd58d9d), and commit ba005f1 broke it again, by making it a hard error if we fail to get the home directory name while looking for ~/.pgpass. The previous precedent is that if we can't get the home directory name, we should just silently act as though the file we hoped to find there doesn't exist. Rearrange the new code to honor that. Looking around, the service-file code added by commit 41a4e45 had the same disease. Apparently, that escaped notice because it only runs when a service name has been specified, which I guess the people who use this scenario don't do. Nonetheless, it's wrong too, so fix that case as well. Add a comment about this policy to pqGetHomeDirectory, in the probably vain hope of forestalling the same error in future. And upgrade the rather miserable commenting in parseServiceInfo, too. In passing, also back off parseServiceInfo's assumption that only ENOENT is an ignorable error from stat() when checking a service file. We would need to ignore at least ENOTDIR as well (cf 5b40677), and seeing that the far-better-tested code for ~/.pgpass treats all stat() failures alike, I think this code ought to as well. Per bug #14872 from Dan Watson. Back-patch the .pgpass change to v10 where ba005f1 came in. The service-file bugs are far older, so back-patch the other changes to all supported branches. Discussion: https://postgr.es/m/20171025200457.1471.34504@wrigleys.postgresql.org
1 parent 7e8d84c commit caeae88

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,6 +3908,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
39083908

39093909
#define MAXBUFSIZE 256
39103910

3911+
/*
3912+
* parseServiceInfo: if a service name has been given, look it up and absorb
3913+
* connection options from it into *options.
3914+
*
3915+
* Returns 0 on success, nonzero on failure. On failure, if errorMessage
3916+
* isn't null, also store an error message there. (Note: the only reason
3917+
* this function and related ones don't dump core on errorMessage == NULL
3918+
* is the undocumented fact that printfPQExpBuffer does nothing when passed
3919+
* a null PQExpBuffer pointer.)
3920+
*/
39113921
static int
39123922
parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
39133923
{
@@ -3926,23 +3936,24 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
39263936
if (service == NULL)
39273937
service = getenv("PGSERVICE");
39283938

3939+
/* If no service name given, nothing to do */
39293940
if (service == NULL)
39303941
return 0;
39313942

3943+
/*
3944+
* Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
3945+
* exists).
3946+
*/
39323947
if ((env = getenv("PGSERVICEFILE")) != NULL)
39333948
strlcpy(serviceFile, env, sizeof(serviceFile));
39343949
else
39353950
{
39363951
char homedir[MAXPGPATH];
39373952

39383953
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
3939-
{
3940-
printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
3941-
return 1;
3942-
}
3954+
goto next_file;
39433955
snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
3944-
errno = 0;
3945-
if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
3956+
if (stat(serviceFile, &stat_buf) != 0)
39463957
goto next_file;
39473958
}
39483959

@@ -3958,8 +3969,7 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
39583969
*/
39593970
snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
39603971
getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
3961-
errno = 0;
3962-
if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
3972+
if (stat(serviceFile, &stat_buf) != 0)
39633973
goto last_file;
39643974

39653975
status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
@@ -5807,7 +5817,15 @@ dot_pg_pass_warning(PGconn *conn)
58075817
*
58085818
* This is essentially the same as get_home_path(), but we don't use that
58095819
* because we don't want to pull path.c into libpq (it pollutes application
5810-
* namespace)
5820+
* namespace).
5821+
*
5822+
* Returns true on success, false on failure to obtain the directory name.
5823+
*
5824+
* CAUTION: although in most situations failure is unexpected, there are users
5825+
* who like to run applications in a home-directory-less environment. On
5826+
* failure, you almost certainly DO NOT want to report an error. Just act as
5827+
* though whatever file you were hoping to find in the home directory isn't
5828+
* there (which it isn't).
58115829
*/
58125830
bool
58135831
pqGetHomeDirectory(char *buf, int bufsize)

0 commit comments

Comments
 (0)
0