aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/be-gssapi-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/be-gssapi-common.c')
-rw-r--r--src/backend/libpq/be-gssapi-common.c53
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);
+}