1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-22 21:53:06 +03:00

Add support for Kerberos credential delegation

Support GSSAPI/Kerberos credentials being delegated to the server by a
client.  With this, a user authenticating to PostgreSQL using Kerberos
(GSSAPI) credentials can choose to delegate their credentials to the
PostgreSQL server (which can choose to accept them, or not), allowing
the server to then use those delegated credentials to connect to
another service, such as with postgres_fdw or dblink or theoretically
any other service which is able to be authenticated using Kerberos.

Both postgres_fdw and dblink are changed to allow non-superuser
password-less connections but only when GSSAPI credentials have been
delegated to the server by the client and GSSAPI is used to
authenticate to the remote system.

Authors: Stephen Frost, Peifeng Qiu
Reviewed-By: David Christensen
Discussion: https://postgr.es/m/CO1PR05MB8023CC2CB575E0FAAD7DF4F8A8E29@CO1PR05MB8023.namprd05.prod.outlook.com
This commit is contained in:
Stephen Frost
2023-04-07 21:58:04 -04:00
parent edc627ae27
commit 3d4fa227bc
36 changed files with 761 additions and 142 deletions

View File

@@ -92,3 +92,56 @@ pg_GSS_error(const char *errmsg,
(errmsg_internal("%s", errmsg),
errdetail_internal("%s: %s", msg_major, msg_minor)));
}
/*
* Store the credentials passed in into the memory cache for later usage.
*
* This allows credentials to be delegated to us for us to use to connect
* to other systems with, using, e.g. postgres_fdw or dblink.
*/
#define GSS_MEMORY_CACHE "MEMORY:"
void
pg_store_delegated_credential(gss_cred_id_t cred)
{
OM_uint32 major,
minor;
gss_OID_set mech;
gss_cred_usage_t usage;
gss_key_value_element_desc cc;
gss_key_value_set_desc ccset;
cc.key = "ccache";
cc.value = GSS_MEMORY_CACHE;
ccset.count = 1;
ccset.elements = &cc;
/* Make the delegated credential only available to current process */
major = gss_store_cred_into(&minor,
cred,
GSS_C_INITIATE, /* credential only used for
* starting libpq connection */
GSS_C_NULL_OID, /* store all */
true, /* overwrite */
true, /* make default */
&ccset,
&mech,
&usage);
if (major != GSS_S_COMPLETE)
{
pg_GSS_error("gss_store_cred", major, minor);
}
/* Credential stored, so we can release our credential handle. */
major = gss_release_cred(&minor, &cred);
if (major != GSS_S_COMPLETE)
{
pg_GSS_error("gss_release_cred", major, minor);
}
/*
* Set KRB5CCNAME for this backend, so that later calls to
* gss_acquire_cred will find the delegated credentials we stored.
*/
setenv("KRB5CCNAME", GSS_MEMORY_CACHE, 1);
}