Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdb6986f

Browse files
committed
Fix libpq to not require user's home directory to exist.
Some people like to run libpq-using applications in environments wherethere's no home directory. We've broken that scenario before (cf commits5b40677 andbd58d9d), and commitba005f1 broke it again, by makingit a hard error if we fail to get the home directory name while lookingfor ~/.pgpass. The previous precedent is that if we can't get the homedirectory name, we should just silently act as though the file we hopedto find there doesn't exist. Rearrange the new code to honor that.Looking around, the service-file code added by commit41a4e45 had thesame disease. Apparently, that escaped notice because it only runs whena service name has been specified, which I guess the people who use thisscenario don't do. Nonetheless, it's wrong too, so fix that case as well.Add a comment about this policy to pqGetHomeDirectory, in the probablyvain hope of forestalling the same error in future. And upgrade therather miserable commenting in parseServiceInfo, too.In passing, also back off parseServiceInfo's assumption that only ENOENTis an ignorable error from stat() when checking a service file. We wouldneed to ignore at least ENOTDIR as well (cf5b40677), and seeing thatthe 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 v10whereba005f1 came in. The service-file bugs are far older, soback-patch the other changes to all supported branches.Discussion:https://postgr.es/m/20171025200457.1471.34504@wrigleys.postgresql.org
1 parent18fc4ec commitdb6986f

File tree

1 file changed

+63
-46
lines changed

1 file changed

+63
-46
lines changed

‎src/interfaces/libpq/fe-connect.c

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,52 +1063,51 @@ connectOptions2(PGconn *conn)
10631063
*/
10641064
if (conn->pgpass==NULL||conn->pgpass[0]=='\0')
10651065
{
1066-
inti;
1067-
1066+
/* If password file wasn't specified, use ~/PGPASSFILE */
10681067
if (conn->pgpassfile==NULL||conn->pgpassfile[0]=='\0')
10691068
{
1070-
/* Identify password file to use; fail if we can't */
10711069
charhomedir[MAXPGPATH];
10721070

1073-
if (!pqGetHomeDirectory(homedir,sizeof(homedir)))
1071+
if (pqGetHomeDirectory(homedir,sizeof(homedir)))
10741072
{
1075-
conn->status=CONNECTION_BAD;
1076-
printfPQExpBuffer(&conn->errorMessage,
1077-
libpq_gettext("could not get home directory to locate password file\n"));
1078-
return false;
1073+
if (conn->pgpassfile)
1074+
free(conn->pgpassfile);
1075+
conn->pgpassfile=malloc(MAXPGPATH);
1076+
if (!conn->pgpassfile)
1077+
gotooom_error;
1078+
snprintf(conn->pgpassfile,MAXPGPATH,"%s/%s",
1079+
homedir,PGPASSFILE);
10791080
}
1080-
1081-
if (conn->pgpassfile)
1082-
free(conn->pgpassfile);
1083-
conn->pgpassfile=malloc(MAXPGPATH);
1084-
if (!conn->pgpassfile)
1085-
gotooom_error;
1086-
1087-
snprintf(conn->pgpassfile,MAXPGPATH,"%s/%s",homedir,PGPASSFILE);
10881081
}
10891082

1090-
for (i=0;i<conn->nconnhost;i++)
1083+
if (conn->pgpassfile!=NULL&&conn->pgpassfile[0]!='\0')
10911084
{
1092-
/*
1093-
* Try to get a password for this host from pgpassfile. We use
1094-
* host name rather than host address in the same manner to
1095-
* PQhost().
1096-
*/
1097-
char*pwhost=conn->connhost[i].host;
1098-
1099-
if (conn->connhost[i].type==CHT_HOST_ADDRESS&&
1100-
conn->connhost[i].host!=NULL&&conn->connhost[i].host[0]!='\0')
1101-
pwhost=conn->connhost[i].hostaddr;
1102-
1103-
conn->connhost[i].password=
1104-
passwordFromFile(pwhost,
1105-
conn->connhost[i].port,
1106-
conn->dbName,
1107-
conn->pguser,
1108-
conn->pgpassfile);
1109-
/* If we got one, set pgpassfile_used */
1110-
if (conn->connhost[i].password!=NULL)
1111-
conn->pgpassfile_used= true;
1085+
inti;
1086+
1087+
for (i=0;i<conn->nconnhost;i++)
1088+
{
1089+
/*
1090+
* Try to get a password for this host from pgpassfile. We use
1091+
* host name rather than host address in the same manner as
1092+
* PQhost().
1093+
*/
1094+
char*pwhost=conn->connhost[i].host;
1095+
1096+
if (conn->connhost[i].type==CHT_HOST_ADDRESS&&
1097+
conn->connhost[i].host!=NULL&&
1098+
conn->connhost[i].host[0]!='\0')
1099+
pwhost=conn->connhost[i].hostaddr;
1100+
1101+
conn->connhost[i].password=
1102+
passwordFromFile(pwhost,
1103+
conn->connhost[i].port,
1104+
conn->dbName,
1105+
conn->pguser,
1106+
conn->pgpassfile);
1107+
/* If we got one, set pgpassfile_used */
1108+
if (conn->connhost[i].password!=NULL)
1109+
conn->pgpassfile_used= true;
1110+
}
11121111
}
11131112
}
11141113

@@ -4469,6 +4468,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
44694468

44704469
#defineMAXBUFSIZE 256
44714470

4471+
/*
4472+
* parseServiceInfo: if a service name has been given, look it up and absorb
4473+
* connection options from it into *options.
4474+
*
4475+
* Returns 0 on success, nonzero on failure. On failure, if errorMessage
4476+
* isn't null, also store an error message there. (Note: the only reason
4477+
* this function and related ones don't dump core on errorMessage == NULL
4478+
* is the undocumented fact that printfPQExpBuffer does nothing when passed
4479+
* a null PQExpBuffer pointer.)
4480+
*/
44724481
staticint
44734482
parseServiceInfo(PQconninfoOption*options,PQExpBuffererrorMessage)
44744483
{
@@ -4487,23 +4496,24 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
44874496
if (service==NULL)
44884497
service=getenv("PGSERVICE");
44894498

4499+
/* If no service name given, nothing to do */
44904500
if (service==NULL)
44914501
return0;
44924502

4503+
/*
4504+
* Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
4505+
* exists).
4506+
*/
44934507
if ((env=getenv("PGSERVICEFILE"))!=NULL)
44944508
strlcpy(serviceFile,env,sizeof(serviceFile));
44954509
else
44964510
{
44974511
charhomedir[MAXPGPATH];
44984512

44994513
if (!pqGetHomeDirectory(homedir,sizeof(homedir)))
4500-
{
4501-
printfPQExpBuffer(errorMessage,libpq_gettext("could not get home directory to locate service definition file"));
4502-
return1;
4503-
}
4514+
gotonext_file;
45044515
snprintf(serviceFile,MAXPGPATH,"%s/%s",homedir,".pg_service.conf");
4505-
errno=0;
4506-
if (stat(serviceFile,&stat_buf)!=0&&errno==ENOENT)
4516+
if (stat(serviceFile,&stat_buf)!=0)
45074517
gotonext_file;
45084518
}
45094519

@@ -4519,8 +4529,7 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
45194529
*/
45204530
snprintf(serviceFile,MAXPGPATH,"%s/pg_service.conf",
45214531
getenv("PGSYSCONFDIR") ?getenv("PGSYSCONFDIR") :SYSCONFDIR);
4522-
errno=0;
4523-
if (stat(serviceFile,&stat_buf)!=0&&errno==ENOENT)
4532+
if (stat(serviceFile,&stat_buf)!=0)
45244533
gotolast_file;
45254534

45264535
status=parseServiceFile(serviceFile,service,options,errorMessage,&group_found);
@@ -6510,7 +6519,15 @@ pgpassfileWarning(PGconn *conn)
65106519
*
65116520
* This is essentially the same as get_home_path(), but we don't use that
65126521
* because we don't want to pull path.c into libpq (it pollutes application
6513-
* namespace)
6522+
* namespace).
6523+
*
6524+
* Returns true on success, false on failure to obtain the directory name.
6525+
*
6526+
* CAUTION: although in most situations failure is unexpected, there are users
6527+
* who like to run applications in a home-directory-less environment. On
6528+
* failure, you almost certainly DO NOT want to report an error. Just act as
6529+
* though whatever file you were hoping to find in the home directory isn't
6530+
* there (which it isn't).
65146531
*/
65156532
bool
65166533
pqGetHomeDirectory(char*buf,intbufsize)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp