Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n6dPR-00017i-Po for pgsql-hackers@arkaria.postgresql.org; Sun, 09 Jan 2022 18:59:18 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1n6dPO-00014R-Ub for pgsql-hackers@arkaria.postgresql.org; Sun, 09 Jan 2022 18:59:14 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n6dPO-00014I-JR for pgsql-hackers@lists.postgresql.org; Sun, 09 Jan 2022 18:59:14 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n6dPK-0005hX-7O for pgsql-hackers@lists.postgresql.org; Sun, 09 Jan 2022 18:59:12 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 209Ix2b01769428; Sun, 9 Jan 2022 13:59:02 -0500 From: Tom Lane To: Anders Kaseorg cc: Daniel Gustafsson , Kyotaro Horiguchi , alvherre@alvh.no-ip.org, pgsql-hackers@lists.postgresql.org Subject: Re: [PATCH] Prefer getenv("HOME") to find the UNIX home directory In-reply-to: References: <202110182223.zeze33l55qa5@alvherre.pgsql> <20211019.173422.706584612464055211.horikyota.ntt@gmail.com> <5d675cbe-7837-e9ae-961d-be7d03201f3b@mit.edu> <20211020.144014.580443822870543857.horikyota.ntt@gmail.com> <07CA67A0-A46C-4ED5-99C6-24D41BDDC8CA@yesql.se> Comments: In-reply-to Anders Kaseorg message dated "Wed, 20 Oct 2021 10:09:51 -0700" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <1769411.1641754724.0@sss.pgh.pa.us> Date: Sun, 09 Jan 2022 13:59:02 -0500 Message-ID: <1769427.1641754742@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="UTF-8" Content-ID: <1769411.1641754724.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Anders Kaseorg writes: > On 10/20/21 04:55, Daniel Gustafsson wrote: >> Is the proposed change portable across all linux/unix systems we suppor= t? >> Reading aobut indicates that it's likely to be, but neither NetBSD nor = FreeBSD >> have the upthread referenced wording in their manpages. > Since the proposed change falls back to the old behavior if HOME is = > unset or empty, I assume this is a question about convention and not = > literally about whether it will work on these systems. I don=E2=80=99t f= ind it = > surprising that this convention isn=E2=80=99t explicitly called out in e= very = > system=E2=80=99s manpage for the wrong function, but it still applies to= these = > systems. Given the POSIX requirements, it's basically impossible to believe that there are interesting cases where $HOME isn't set. Thus, it seems to me that keeping the getpwuid calls will just mean carrying untestable dead code, so we should simplify matters by ripping those out and *only* consulting $HOME. The v1 patch also neglects the matter of documentation. I think the simplest and most transparent thing to do is just to explicitly mention $HOME everyplace we talk about files that are sought there, in place of our current convention to write "~". (I'm too lazy to go digging in the git history, but I have a feeling that this is undoing somebody's intentional change from a long time back.) BTW, not directly impacted by this patch but adjacent to it, I noted that on Windows psql's \cd defaults to changing to "/". That seems a bit surprising, and we definitely fail to document it. I settled for noting it in the documentation, but should we make it do something else? PFA v2 patch. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="v2-0001-use-HOME-for-home-directory.patch"; charset="us-ascii" Content-ID: <1769411.1641754724.2@sss.pgh.pa.us> Content-Description: v2-0001-use-HOME-for-home-directory.patch Content-Transfer-Encoding: quoted-printable diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 14f35d37f6..faf36f051f 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1214,7 +1214,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname Specifies the name of the file used to store passwords (see ). - Defaults to ~/.pgpass, or + Defaults to $HOME/.pgpass, or %APPDATA%\postgresql\pgpass.conf on Microsoft= Windows. (No error is reported if this file does not exist.) @@ -1670,7 +1670,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname This parameter specifies the file name of the client SSL certificate, replacing the default - ~/.postgresql/postgresql.crt. + $HOME/.postgresql/postgresql.crt. This parameter is ignored if an SSL connection is not made. @@ -1683,7 +1683,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname This parameter specifies the location for the secret key used for the client certificate. It can either specify a file name that wi= ll be used instead of the default - ~/.postgresql/postgresql.key, or it can spec= ify a key + $HOME/.postgresql/postgresql.key, or it can = specify a key obtained from an external engine (engines are OpenSSL loadable modules). An externa= l engine specification should consist of a colon-separated engine name and @@ -1733,7 +1733,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities. The default is - ~/.postgresql/root.crt. + $HOME/.postgresql/root.crt. @@ -1749,7 +1749,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname nor is set, this setting = is taken as - ~/.postgresql/root.crl. + $HOME/.postgresql/root.crl. @@ -7776,7 +7776,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *pa= ssThrough) PGSERVICEFILE specifies the name of the per-user connection service file. If not set, it defaults - to ~/.pg_service.conf + to $HOME/.pg_service.conf (see ). @@ -8151,7 +8151,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *pa= ssThrough) system-wide file. If the same service name exists in both the user and the system file, the user file takes precedence. By default, the per-user service file is located - at ~/.pg_service.conf; this can be overridden by + at $HOME/.pg_service.conf; this can be overridden= by setting the environment variable PGSERVICEFILE. The system-wide file is named pg_service.conf. By default it is sought in the etc directory @@ -8354,8 +8354,8 @@ ldap://ldap.acme.com/cn=3Ddbserver,cn=3Dhosts?pgconn= ectinfo?base?(objectclass=3D*) = To allow server certificate verification, one or more root certificate= s - must be placed in the file ~/.postgresql/root.crt - in the user's home directory. (On Microsoft Windows the file is named + must be placed in the file $HOME/.postgresql/root.crt. + (On Microsoft Windows the file is named %APPDATA%\postgresql\root.crt.) Intermediate certificates should also be added to the file if they are needed to li= nk the certificate chain sent by the server to the root certificates @@ -8364,7 +8364,7 @@ ldap://ldap.acme.com/cn=3Ddbserver,cn=3Dhosts?pgconn= ectinfo?base?(objectclass=3D*) = Certificate Revocation List (CRL) entries are also checked - if the file ~/.postgresql/root.crl exists + if the file $HOME/.postgresql/root.crl exists (%APPDATA%\postgresql\root.crl on Microsoft Windows). @@ -8398,10 +8398,10 @@ ldap://ldap.acme.com/cn=3Ddbserver,cn=3Dhosts?pgco= nnectinfo?base?(objectclass=3D*) If the server attempts to verify the identity of the client by requesting the client's leaf certificate, libpq will send the certificates stored in - file ~/.postgresql/postgresql.crt in the user's h= ome - directory. The certificates must chain to the root certificate truste= d + the file $HOME/.postgresql/postgresql.crt. + The certificates must chain to the root certificate trusted by the server. A matching - private key file ~/.postgresql/postgresql.key mus= t also + private key file $HOME/.postgresql/postgresql.key= must also be present. The private key file must not allow any access to world or group; achieve this by = the command chmod 0600 ~/.postgresql/postgresql.key. @@ -8643,27 +8643,27 @@ ldap://ldap.acme.com/cn=3Ddbserver,cn=3Dhosts?pgco= nnectinfo?base?(objectclass=3D*) = - ~/.postgresql/postgresql.crt + $HOME/.postgresql/postgresql.crt client certificate sent to server = - ~/.postgresql/postgresql.key + $HOME/.postgresql/postgresql.key client private key proves client certificate sent by owner; does not indicate certificate owner is trustworthy = - ~/.postgresql/root.crt + $HOME/.postgresql/root.crt trusted certificate authorities checks that server certificate is signed by a trusted certif= icate authority = - ~/.postgresql/root.crl + $HOME/.postgresql/root.crl certificates revoked by certificate authorities server certificate must not be on this list diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sg= ml index 1ab200a4ad..6b6f5b1864 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -553,7 +553,7 @@ EOF Do not read the start-up file (neither the system-wide psqlrc file nor the user's - ~/.psqlrc file). + $HOME/.psqlrc file). @@ -677,7 +677,7 @@ EOF PGPORT and/or PGUSER to appropriate values. (For additional environment variables, see .) It is also convenient to have a - ~/.pgpass file to avoid regularly having to type= in + $HOME/.pgpass file to avoid regularly having to = type in passwords. See for more information. = @@ -984,7 +984,8 @@ testdb=3D> Changes the current working directory to directory. Without argument, changes - to the current user's home directory. + to the current user's home directory ($HOME),= or + the root directory on Windows. = @@ -3791,7 +3792,7 @@ bar behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you might wish to set it in the system-wi= de psqlrc file or your - ~/.psqlrc file. + $HOME/.psqlrc file. @@ -3960,13 +3961,13 @@ bar The file name that will be used to store the history list. If un= set, the file name is taken from the PSQL_HISTORY environment variable. If that is not set either, the default - is ~/.psql_history, + is $HOME/.psql_history, or %APPDATA%\postgresql\psql_history on Wind= ows. For example, putting: \set HISTFILE ~/.psql_history-:DBNAME - in ~/.psqlrc will cause + in $HOME/.psqlrc will cause psql to maintain a separate history fo= r each database. @@ -4774,13 +4775,13 @@ PSQL_EDITOR_LINENUMBER_ARG=3D'--line ' = - psqlrc and ~/.psqlrc + psqlrc and $HOME/.psqlrc Unless it is passed an option, psql attempts to read and execute command= s from the system-wide startup file (psqlrc) and = then - the user's personal startup file (~/.psqlrc), a= fter + the user's personal startup file ($HOME/.psqlrc= ), after connecting to the database but before accepting normal commands. These files can be used to set up the client and/or the server to ta= ste, typically with \set and SET @@ -4809,8 +4810,8 @@ PSQL_EDITOR_LINENUMBER_ARG=3D'--line ' can be made psql-version-specific by appending a dash and the PostgreSQL major or minor release number to the file name, - for example ~/.psqlrc-9.2 or - ~/.psqlrc-9.2.5. The most specific + for example $HOME/.psqlrc-9.2 or + $HOME/.psqlrc-9.2.5. The most specific version-matching file will be read in preference to a non-version-specific file. @@ -4822,7 +4823,7 @@ PSQL_EDITOR_LINENUMBER_ARG=3D'--line ' The command-line history is stored in the file - ~/.psql_history, or + $HOME/.psql_history, or %APPDATA%\postgresql\psql_history on Windows. diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 053332e7af..e2ea0d11aa 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -558,19 +558,13 @@ exec_command_cd(PsqlScanState scan_state, bool activ= e_branch, const char *cmd) else { #ifndef WIN32 - struct passwd *pw; - uid_t user_id =3D geteuid(); - - errno =3D 0; /* clear errno before call */ - pw =3D getpwuid(user_id); - if (!pw) + /* On Unix-like systems, consult $HOME */ + dir =3D getenv("HOME"); + if (dir =3D=3D NULL || dir[0] =3D=3D '\0') { - pg_log_error("could not get home directory for user ID %ld: %s", - (long) user_id, - errno ? strerror(errno) : _("user does not exist")); - exit(EXIT_FAILURE); + pg_log_error("HOME environment variable is not set"); + success =3D false; } - dir =3D pw->pw_dir; #else /* WIN32 */ = /* @@ -581,7 +575,8 @@ exec_command_cd(PsqlScanState scan_state, bool active_= branch, const char *cmd) #endif /* WIN32 */ } = - if (chdir(dir) =3D=3D -1) + if (success && + chdir(dir) < 0) { pg_log_error("\\%s: could not change directory to \"%s\": %m", cmd, dir); diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-c= onnect.c index 72914116ee..f018bf6a9c 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -7267,14 +7267,11 @@ bool pqGetHomeDirectory(char *buf, int bufsize) { #ifndef WIN32 - char pwdbuf[BUFSIZ]; - struct passwd pwdstr; - struct passwd *pwd =3D NULL; + const char *home =3D getenv("HOME"); = - (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd); - if (pwd =3D=3D NULL) + if (home =3D=3D NULL || home[0] =3D=3D '\0') return false; - strlcpy(buf, pwd->pw_dir, bufsize); + strlcpy(buf, home, bufsize); return true; #else char tmppath[MAX_PATH]; diff --git a/src/port/path.c b/src/port/path.c index ee4227ec98..a5a2e9238c 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -807,14 +807,11 @@ bool get_home_path(char *ret_path) { #ifndef WIN32 - char pwdbuf[BUFSIZ]; - struct passwd pwdstr; - struct passwd *pwd =3D NULL; + const char *home =3D getenv("HOME"); = - (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd); - if (pwd =3D=3D NULL) + if (home =3D=3D NULL || home[0] =3D=3D '\0') return false; - strlcpy(ret_path, pwd->pw_dir, MAXPGPATH); + strlcpy(ret_path, home, MAXPGPATH); return true; #else char *tmppath; ------- =_aaaaaaaaaa0--