diff options
author | Tom Lane | 2020-12-30 16:38:42 +0000 |
---|---|---|
committer | Tom Lane | 2020-12-30 16:38:42 +0000 |
commit | 860fe27ee1e2a4a1c36c2f874c37656533cccce9 (patch) | |
tree | cbf3f64b956e54753feade50c056f67ea69b7d97 | |
parent | e665769e6d1e84b6650f53ed297058fc11152f7f (diff) |
Fix up usage of krb_server_keyfile GUC parameter.
secure_open_gssapi() installed the krb_server_keyfile setting as
KRB5_KTNAME unconditionally, so long as it's not empty. However,
pg_GSS_recvauth() only installed it if KRB5_KTNAME wasn't set already,
leading to a troubling inconsistency: in theory, clients could see
different sets of server principal names depending on whether they
use GSSAPI encryption. Always using krb_server_keyfile seems like
the right thing, so make both places do that. Also fix up
secure_open_gssapi()'s lack of a check for setenv() failure ---
it's unlikely, surely, but security-critical actions are no place
to be sloppy.
Also improve the associated documentation.
This patch does nothing about secure_open_gssapi()'s use of setenv(),
and indeed causes pg_GSS_recvauth() to use it too. That's nominally
against project portability rules, but since this code is only built
with --with-gssapi, I do not feel a need to do something about this
in the back branches. A fix will be forthcoming for HEAD though.
Back-patch to v12 where GSSAPI encryption was introduced. The
dubious behavior in pg_GSS_recvauth() goes back further, but it
didn't have anything to be inconsistent with, so let it be.
Discussion: https://postgr.es/m/[email protected]
-rw-r--r-- | doc/src/sgml/client-auth.sgml | 6 | ||||
-rw-r--r-- | doc/src/sgml/config.sgml | 12 | ||||
-rw-r--r-- | src/backend/libpq/auth.c | 31 | ||||
-rw-r--r-- | src/backend/libpq/be-secure-gssapi.c | 12 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 2 |
5 files changed, 31 insertions, 32 deletions
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index 9a5c9318ce..c4b9971a20 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -1265,11 +1265,7 @@ omicron bryanh guest1 <para> The location of the server's keytab file is specified by the <xref - linkend="guc-krb-server-keyfile"/> configuration - parameter. The default is - <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</filename> - (where the directory part is whatever was specified - as <varname>sysconfdir</varname> at build time). + linkend="guc-krb-server-keyfile"/> configuration parameter. For security reasons, it is recommended to use a separate keytab just for the <productname>PostgreSQL</productname> server rather than allowing the server to read the system keytab file. diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 048bd6aa08..67de4150b8 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1057,10 +1057,16 @@ include_dir 'conf.d' </term> <listitem> <para> - Sets the location of the Kerberos server key file. See - <xref linkend="gssapi-auth"/> - for details. This parameter can only be set in the + Sets the location of the server's Kerberos key file. The default is + <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</filename> + (where the directory part is whatever was specified + as <varname>sysconfdir</varname> at build time; use + <literal>pg_config --sysconfdir</literal> to determine that). + If this parameter is set to an empty string, it is ignored and a + system-dependent default is used. + This parameter can only be set in the <filename>postgresql.conf</filename> file or on the server command line. + See <xref linkend="gssapi-auth"/> for more information. </para> </listitem> </varlistentry> diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 515ae95fe1..e51ede5a22 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -1054,29 +1054,18 @@ pg_GSS_recvauth(Port *port) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("GSSAPI is not supported in protocol version 2"))); - if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0) + /* + * Use the configured keytab, if there is one. Unfortunately, Heimdal + * doesn't support the cred store extensions, so use the env var. + */ + if (pg_krb_server_keyfile != NULL && pg_krb_server_keyfile[0] != '\0') { - /* - * Set default Kerberos keytab file for the Krb5 mechanism. - * - * setenv("KRB5_KTNAME", pg_krb_server_keyfile, 0); except setenv() - * not always available. - */ - if (getenv("KRB5_KTNAME") == NULL) + if (setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1) != 0) { - size_t kt_len = strlen(pg_krb_server_keyfile) + 14; - char *kt_path = malloc(kt_len); - - if (!kt_path || - snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", - pg_krb_server_keyfile) != kt_len - 2 || - putenv(kt_path) != 0) - { - ereport(LOG, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - return STATUS_ERROR; - } + /* The only likely failure cause is OOM, so use that errcode */ + ereport(FATAL, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("could not set environment: %m"))); } } diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c index 1747fccb14..547c7d6a17 100644 --- a/src/backend/libpq/be-secure-gssapi.c +++ b/src/backend/libpq/be-secure-gssapi.c @@ -525,8 +525,16 @@ secure_open_gssapi(Port *port) * Use the configured keytab, if there is one. Unfortunately, Heimdal * doesn't support the cred store extensions, so use the env var. */ - if (pg_krb_server_keyfile != NULL && strlen(pg_krb_server_keyfile) > 0) - setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1); + if (pg_krb_server_keyfile != NULL && pg_krb_server_keyfile[0] != '\0') + { + if (setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1) != 0) + { + /* The only likely failure cause is OOM, so use that errcode */ + ereport(FATAL, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("could not set environment: %m"))); + } + } while (true) { diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index b7fb2ec1fe..5298e18ecd 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -92,7 +92,7 @@ #db_user_namespace = off # GSSAPI using Kerberos -#krb_server_keyfile = '' +#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' #krb_caseins_users = off # - SSL - |