1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-21 00:42:43 +03:00

De-Revert "Add support for Kerberos credential delegation"

This reverts commit 3d03b24c3 (Revert Add support for Kerberos
credential delegation) which was committed on the grounds of concern
about portability, but on further review and discussion, it's clear that
we are better off explicitly requiring MIT Kerberos as that appears to
be the only GSSAPI library currently that's under proper maintenance
and ongoing development.  The API used for storing credentials was added
to MIT Kerberos over a decade ago while for the other libraries which
appear to be mainly based on Heimdal, which exists explicitly to be a
re-implementation of MIT Kerberos, the API never made it to a released
version (even though it was added to the Heimdal git repo over 5 years
ago..).

This post-feature-freeze change was approved by the RMT.

Discussion: https://postgr.es/m/ZDDO6jaESKaBgej0%40tamriel.snowman.net
This commit is contained in:
Stephen Frost
2023-04-13 08:55:07 -04:00
parent e2922702a3
commit 6633cfb216
36 changed files with 761 additions and 142 deletions

View File

@@ -165,6 +165,7 @@ static int CheckCertAuth(Port *port);
*/
char *pg_krb_server_keyfile;
bool pg_krb_caseins_users;
bool pg_gss_accept_deleg;
/*----------------------------------------------------------------
@@ -918,6 +919,7 @@ pg_GSS_recvauth(Port *port)
int mtype;
StringInfoData buf;
gss_buffer_desc gbuf;
gss_cred_id_t delegated_creds;
/*
* Use the configured keytab, if there is one. Unfortunately, Heimdal
@@ -947,6 +949,9 @@ pg_GSS_recvauth(Port *port)
*/
port->gss->ctx = GSS_C_NO_CONTEXT;
delegated_creds = GSS_C_NO_CREDENTIAL;
port->gss->delegated_creds = false;
/*
* Loop through GSSAPI message exchange. This exchange can consist of
* multiple messages sent in both directions. First message is always from
@@ -997,7 +1002,7 @@ pg_GSS_recvauth(Port *port)
&port->gss->outbuf,
&gflags,
NULL,
NULL);
pg_gss_accept_deleg ? &delegated_creds : NULL);
/* gbuf no longer used */
pfree(buf.data);
@@ -1009,6 +1014,12 @@ pg_GSS_recvauth(Port *port)
CHECK_FOR_INTERRUPTS();
if (delegated_creds != GSS_C_NO_CREDENTIAL && gflags & GSS_C_DELEG_FLAG)
{
pg_store_delegated_credential(delegated_creds);
port->gss->delegated_creds = true;
}
if (port->gss->outbuf.length != 0)
{
/*

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);
}

View File

@@ -497,6 +497,7 @@ secure_open_gssapi(Port *port)
bool complete_next = false;
OM_uint32 major,
minor;
gss_cred_id_t delegated_creds;
/*
* Allocate subsidiary Port data for GSSAPI operations.
@@ -504,6 +505,9 @@ secure_open_gssapi(Port *port)
port->gss = (pg_gssinfo *)
MemoryContextAllocZero(TopMemoryContext, sizeof(pg_gssinfo));
delegated_creds = GSS_C_NO_CREDENTIAL;
port->gss->delegated_creds = false;
/*
* Allocate buffers and initialize state variables. By malloc'ing the
* buffers at this point, we avoid wasting static data space in processes
@@ -588,7 +592,8 @@ secure_open_gssapi(Port *port)
GSS_C_NO_CREDENTIAL, &input,
GSS_C_NO_CHANNEL_BINDINGS,
&port->gss->name, NULL, &output, NULL,
NULL, NULL);
NULL, pg_gss_accept_deleg ? &delegated_creds : NULL);
if (GSS_ERROR(major))
{
pg_GSS_error(_("could not accept GSSAPI security context"),
@@ -605,6 +610,12 @@ secure_open_gssapi(Port *port)
complete_next = true;
}
if (delegated_creds != GSS_C_NO_CREDENTIAL)
{
pg_store_delegated_credential(delegated_creds);
port->gss->delegated_creds = true;
}
/* Done handling the incoming packet, reset our buffer */
PqGSSRecvLength = 0;
@@ -731,3 +742,16 @@ be_gssapi_get_princ(Port *port)
return port->gss->princ;
}
/*
* Return if GSSAPI delegated credentials were included on this
* connection.
*/
bool
be_gssapi_get_deleg(Port *port)
{
if (!port || !port->gss)
return NULL;
return port->gss->delegated_creds;
}