diff options
Diffstat (limited to 'src/backend/libpq/be-gssapi-common.c')
-rw-r--r-- | src/backend/libpq/be-gssapi-common.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/backend/libpq/be-gssapi-common.c b/src/backend/libpq/be-gssapi-common.c index fb39c760d8c..64d41e52915 100644 --- a/src/backend/libpq/be-gssapi-common.c +++ b/src/backend/libpq/be-gssapi-common.c @@ -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); +} |